AudioKit / AudioKitEX

C-backed AudioKit DSP
MIT License
48 stars 35 forks source link

AudioKitEx Sequencer not playing first note, issues adding notes while playing #10

Closed emurray2 closed 2 years ago

emurray2 commented 2 years ago

From @kenwheeler Original Ticket: AudioKit/AudioKit#2727

Describe the bug I'm witnessing two issues with the Sequencer.

1. When I have two tracks, and add a note at 0.0 for each:
conductor.sequencer.tracks[selected].sequence.add(noteNumber: 60, position: Double((index)) * 0.25, duration: 1.0)

I'm seeing that the first note of the second track isn't played. All subsequent notes play alright.

2. When adding notes programmatically using the same API above, _while the sequencer is playing_, I'm hearing offset note timings. If I stop the sequencer and restart it, the timing is correct.

To Reproduce Steps to reproduce the behavior:

1. Add two notes programmatically using the above API at the 0.0 position and play with looping enabled

2. For the other issue, use the same API as above to add notes programmatically while the sequencer is playing

Expected behavior I would expect a) two tracks, each with a note at 0.0 position to be able to play simultaneously. and b) I would expect notes added when the sequencer is playing to be time accurate in the current play context.

Screenshots If applicable, add screenshots to help explain your problem.

Details (please complete the following information):

* Type: [e.g. iPhone6, iPad, Mac] iPhone 13 pro

* OS: [e.g. iOS13.1] iOS 15.4.1

* AudioKit Version [e.g. 5.0] 5.3.3,
  **Other Context**
  I'm using samplers.

p.s. Thanks so much, this project rules

emurray2 commented 2 years ago

Hi @kenwheeler, I ran some tests using the code below and looking for the issues you mentioned. I wasn't able to reproduce the behavior in this issue. Is there something I should change about this code to get the issue to pop up? Otherwise, I suggest maybe trying to run your project with the main branches of both AudioKit/AudioKit and AudioKit/AudioKitEX on iOS 15.5 (latest as of now) and seeing if that resolves the issue.

Code I used ``` func testAddNoteWhilePlaying() { let engine = AudioEngine() let sampler = AppleSampler() let sampleURL = Bundle.module.url(forResource: "TestResources/middleC", withExtension: "wav") guard let sampleURL = sampleURL else { Log("Problem getting sample URL") return } let audioFile = try? AVAudioFile(forReading: sampleURL) guard let audioFile = audioFile else { Log("Problem getting sample file") return } try? sampler.loadAudioFile(audioFile) let sequencer = Sequencer(targetNode: sampler) engine.output = sampler try? engine.start() sequencer.addTrack(for: sampler) sequencer.play() XCTAssertTrue(sequencer.isPlaying) sequencer.tracks[0].add(noteNumber: 60, position: 0.0, duration: 1.0) sequencer.tracks[1].add(noteNumber: 64, position: 0.0, duration: 1.0) sleep(2) } ```
kenwheeler commented 2 years ago

I ran the .add code on button press, not sure if that changes anything. Maybe try with looping enabled with a note added to the last 1/16th note?

On Wed, May 25, 2022 at 6:41 PM Evan Murray @.***> wrote:

Hi @kenwheeler https://github.com/kenwheeler, I ran some tests using the code below and looking for the issues you mentioned. I wasn't able to reproduce the behavior in this issue. Is there something I should change about this code to get the issue to pop up? Otherwise, I suggest maybe trying to run your project with the main branches of both AudioKit/AudioKit and AudioKit/AudioKitEX on iOS 15.5 (latest as of now) and seeing if that resolves the issue. Code I used

func testAddNoteWhilePlaying() {
    let engine = AudioEngine()
    let sampler = AppleSampler()
    let sampleURL = Bundle.module.url(forResource: "TestResources/middleC", withExtension: "wav")
    guard let sampleURL = sampleURL else {
        Log("Problem getting sample URL")
        return
    }
    let audioFile = try? AVAudioFile(forReading: sampleURL)
    guard let audioFile = audioFile else {
        Log("Problem getting sample file")
        return
    }
    try? sampler.loadAudioFile(audioFile)
    let sequencer = Sequencer(targetNode: sampler)
    engine.output = sampler
    try? engine.start()
    sequencer.addTrack(for: sampler)
    sequencer.play()
    XCTAssertTrue(sequencer.isPlaying)
    sequencer.tracks[0].add(noteNumber: 60, position: 0.0, duration: 1.0)
    sequencer.tracks[1].add(noteNumber: 64, position: 0.0, duration: 1.0)
    sleep(2)
}

— Reply to this email directly, view it on GitHub https://github.com/AudioKit/AudioKitEX/issues/10#issuecomment-1137918028, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACF7GCGOJNWOEOVBCCXHGDVL2UDDANCNFSM5W6LTZKA . You are receiving this because you were mentioned.Message ID: @.***>

emurray2 commented 2 years ago

I ran the .add code on button press, not sure if that changes anything. Maybe try with looping enabled with a note added to the last 1/16th note? On Wed, May 25, 2022 at 6:41 PM Evan Murray @.> wrote: Hi @kenwheeler https://github.com/kenwheeler, I ran some tests using the code below and looking for the issues you mentioned. I wasn't able to reproduce the behavior in this issue. Is there something I should change about this code to get the issue to pop up? Otherwise, I suggest maybe trying to run your project with the main branches of both AudioKit/AudioKit and AudioKit/AudioKitEX on iOS 15.5 (latest as of now) and seeing if that resolves the issue. Code I used func testAddNoteWhilePlaying() { let engine = AudioEngine() let sampler = AppleSampler() let sampleURL = Bundle.module.url(forResource: "TestResources/middleC", withExtension: "wav") guard let sampleURL = sampleURL else { Log("Problem getting sample URL") return } let audioFile = try? AVAudioFile(forReading: sampleURL) guard let audioFile = audioFile else { Log("Problem getting sample file") return } try? sampler.loadAudioFile(audioFile) let sequencer = Sequencer(targetNode: sampler) engine.output = sampler try? engine.start() sequencer.addTrack(for: sampler) sequencer.play() XCTAssertTrue(sequencer.isPlaying) sequencer.tracks[0].add(noteNumber: 60, position: 0.0, duration: 1.0) sequencer.tracks[1].add(noteNumber: 64, position: 0.0, duration: 1.0) sleep(2) } — Reply to this email directly, view it on GitHub <#10 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACF7GCGOJNWOEOVBCCXHGDVL2UDDANCNFSM5W6LTZKA . You are receiving this because you were mentioned.Message ID: @.>

Ideally it shouldn't change how the sequencer works itself. The tests run without any UI interaction, but I don't think UI should have an impact in this case.

I did try with looping, and now I see something happening. I believe this is another issue still open AudioKit/AudioKit#2536. Is that the same behavior you notice? If so, have you checked that the total duration of all the notes in your track are less than the track's length?

Another example ``` let engine = AudioEngine() let sampler = AppleSampler() let sampleURL = Bundle.module.url(forResource: "TestResources/middleC", withExtension: "wav") guard let sampleURL = sampleURL else { Log("Problem getting sample URL") return } let audioFile = try? AVAudioFile(forReading: sampleURL) guard let audioFile = audioFile else { Log("Problem getting sample file") return } try? sampler.loadAudioFile(audioFile) let sequencer = Sequencer(targetNode: sampler) engine.output = sampler try? engine.start() // Click track sequencer.addTrack(for: sampler) sequencer.tracks[0].sequence.add(noteNumber: 72, position: 0.0, duration: 1.0) sequencer.tracks[0].sequence.add(noteNumber: 72, position: 1.0, duration: 1.0) sequencer.tracks[0].sequence.add(noteNumber: 72, position: 2.0, duration: 1.0) sequencer.tracks[0].sequence.add(noteNumber: 72, position: 3.0, duration: 1.0) sequencer.tracks.first?.length = 4.01 sequencer.addTrack(for: sampler) sequencer.tracks[1].loopEnabled = true sequencer.tracks[2].loopEnabled = true sequencer.play() XCTAssertTrue(sequencer.isPlaying) sequencer.tracks[1].sequence.add(noteNumber: 60, position: 0.0, duration: 1.0) sequencer.tracks[2].sequence.add(noteNumber: 64, position: 0.0, duration: 1.0) sleep(10) ```

Notice how I set the track's duration .01 beats more to get the first note to play on the loop. Otherwise it won't. Does trying this fix the issue you mentioned?

kenwheeler commented 2 years ago

I’ll check and report back. Thanks so much for the prompt responses and outstanding support

On Wed, May 25, 2022 at 6:59 PM Evan Murray @.***> wrote:

I ran the .add code on button press, not sure if that changes anything. Maybe try with looping enabled with a note added to the last 1/16th note? … <#m4501019684232871078> On Wed, May 25, 2022 at 6:41 PM Evan Murray @.> wrote: Hi @kenwheeler https://github.com/kenwheeler https://github.com/kenwheeler https://github.com/kenwheeler, I ran some tests using the code below and looking for the issues you mentioned. I wasn't able to reproduce the behavior in this issue. Is there something I should change about this code to get the issue to pop up? Otherwise, I suggest maybe trying to run your project with the main branches of both AudioKit/AudioKit and AudioKit/AudioKitEX on iOS 15.5 (latest as of now) and seeing if that resolves the issue. Code I used func testAddNoteWhilePlaying() { let engine = AudioEngine() let sampler = AppleSampler() let sampleURL = Bundle.module.url(forResource: "TestResources/middleC", withExtension: "wav") guard let sampleURL = sampleURL else { Log("Problem getting sample URL") return } let audioFile = try? AVAudioFile(forReading: sampleURL) guard let audioFile = audioFile else { Log("Problem getting sample file") return } try? sampler.loadAudioFile(audioFile) let sequencer = Sequencer(targetNode: sampler) engine.output = sampler try? engine.start() sequencer.addTrack(for: sampler) sequencer.play() XCTAssertTrue(sequencer.isPlaying) sequencer.tracks[0].add(noteNumber: 60, position: 0.0, duration: 1.0) sequencer.tracks[1].add(noteNumber: 64, position: 0.0, duration: 1.0) sleep(2) } — Reply to this email directly, view it on GitHub <#10 (comment) https://github.com/AudioKit/AudioKitEX/issues/10#issuecomment-1137918028>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACF7GCGOJNWOEOVBCCXHGDVL2UDDANCNFSM5W6LTZKA https://github.com/notifications/unsubscribe-auth/AACF7GCGOJNWOEOVBCCXHGDVL2UDDANCNFSM5W6LTZKA . You are receiving this because you were mentioned.Message ID: @.>

Ideally it shouldn't change how the sequencer works itself. The tests run without any UI interaction, but I don't think UI should have an impact in this case.

I did try with looping, and now I see something happening. I believe this is another issue still open AudioKit/AudioKit#2536 https://github.com/AudioKit/AudioKit/issues/2536. Is that the same behavior you notice? If so, have you checked that the total duration of all the notes in your track are less than the track's length? Another example

let engine = AudioEngine()

    let sampler = AppleSampler()

    let sampleURL = Bundle.module.url(forResource: "TestResources/middleC", withExtension: "wav")

    guard let sampleURL = sampleURL else {

        Log("Problem getting sample URL")

        return

    }

    let audioFile = try? AVAudioFile(forReading: sampleURL)

    guard let audioFile = audioFile else {

        Log("Problem getting sample file")

        return

    }

    try? sampler.loadAudioFile(audioFile)

    let sequencer = Sequencer(targetNode: sampler)

    engine.output = sampler

    try? engine.start()

    // Click track

    sequencer.addTrack(for: sampler)

    sequencer.tracks[0].sequence.add(noteNumber: 72, position: 0.0, duration: 1.0)

    sequencer.tracks[0].sequence.add(noteNumber: 72, position: 1.0, duration: 1.0)

    sequencer.tracks[0].sequence.add(noteNumber: 72, position: 2.0, duration: 1.0)

    sequencer.tracks[0].sequence.add(noteNumber: 72, position: 3.0, duration: 1.0)

    sequencer.tracks.first?.length = 4.01

    sequencer.addTrack(for: sampler)

    sequencer.tracks[1].loopEnabled = true

    sequencer.tracks[2].loopEnabled = true

    sequencer.play()

    XCTAssertTrue(sequencer.isPlaying)

    sequencer.tracks[1].sequence.add(noteNumber: 60, position: 0.0, duration: 1.0)

    sequencer.tracks[2].sequence.add(noteNumber: 64, position: 0.0, duration: 1.0)

    sleep(10)

Notice how I set the track's duration .01 beats more to get the first note to play on the loop. Otherwise it won't. Does trying this fix the issue you mentioned?

— Reply to this email directly, view it on GitHub https://github.com/AudioKit/AudioKitEX/issues/10#issuecomment-1137927043, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACF7GATOX4XBRXOYKFYBRDVL2WDRANCNFSM5W6LTZKA . You are receiving this because you were mentioned.Message ID: @.***>

emurray2 commented 2 years ago

I believe this is fixed now via df20fdce67a85a441664fb0c7c815a144ecaf8cb, but please re-open another ticket here in AudioKitEX if the same issue appears.