cmccorkle21416
cmccorkle21416

Reputation: 3

How to play MIDI File with AKAppleSequencer

I'm attempting to play a basic MIDI file using AudioKits legacy sequencer, AKAppleSequencer. I've gotten it to play the first note of the file, but nothing after. (I couldn't get any output from the new AKSequencer.) Here is my code which is essentially identical to the MIDI playback code from AudioKits Playgrounds.

class MIDIPlayer {

    var piano: AKMIDISampler?
    var sequencer: AKAppleSequencer?
    var mixer: AKMixer?
    var reverb: AKCostelloReverb?
    var dryWetMixer: AKDryWetMixer?

func playMidiFile() {
    piano = AKMIDISampler()
    try? piano!.loadWav("FM Piano")
    mixer = AKMixer(piano)
    reverb = AKCostelloReverb(mixer)
    dryWetMixer = AKDryWetMixer(mixer!, reverb!, balance: 0.2)
    AudioKit.output = dryWetMixer

    sequencer = AKAppleSequencer(filename: "Score")
    sequencer!.setGlobalMIDIOutput(piano!.midiIn)
    sequencer!.setLength(AKDuration(beats: 16))

    try? AudioKit.start()
    sequencer!.play()
    print("MIDIPlayer playing...")
}

}

I hear the first note of the MIDI File and get the following errors/warnings.

2020-04-24 16:30:19.653852-0400 TauMusicTest[20668:3188919] [seq] SequenceTrack.cpp:918:Clear: Invalid beat range or track is empty
2020-04-24 16:30:19.654171-0400 TauMusicTest[20668:3188919] [seq] SequenceTrack.cpp:1028:Merge: Invalid beat range
2020-04-24 16:30:20.349048-0400 TauMusicTest[20668:3189067]  HALC_ProxyIOContext::IOWorkLoop: failed to send the final message to the server, Error: 0x10000003
2020-04-24 16:30:20.450640-0400 TauMusicTest[20668:3189034] [ddagg]        AggregateDevice.mm:331   Output: index 1 >= allChannelDescs size 1
2020-04-24 16:30:20.532394-0400 TauMusicTest[20668:3189251] [aqme] AQMEIO_HAL.cpp:1526:IOProc: AQDefaultDevice: Abandoning I/O cycle because reconfig pending (1).
MDIDPlayer playing...
2020-04-24 16:30:20.542721-0400 TauMusicTest[20668:3188919] [general] AKAppleSequencer.swift:deinit:41:deinit: (AKAppleSequencer.swift:deinit:41)
2020-04-24 16:30:20.542882-0400 TauMusicTest[20668:3188919] [general] AKAppleSequencer.swift:deinit:41:deinit: (AKAppleSequencer.swift:deinit:41)
2020-04-24 16:30:20.543023-0400 TauMusicTest[20668:3188919] [general] AKAppleSequencer.swift:deinit:41:deinit: (AKAppleSequencer.swift:deinit:41)
2020-04-24 16:30:20.543149-0400 TauMusicTest[20668:3188919] [general] AKAppleSequencer.swift:deinit:41:deinit: (AKAppleSequencer.swift:deinit:41)
2020-04-24 16:30:20.543264-0400 TauMusicTest[20668:3188919] [general] AKAppleSequencer.swift:deinit:41:deinit: (AKAppleSequencer.swift:deinit:41)
2020-04-24 16:30:20.698072-0400 TauMusicTest[20668:3188919] [general] AKAppleSequencer.swift:deinit:41:deinit: (AKAppleSequencer.swift:deinit:41)
2020-04-24 16:30:20.698443-0400 TauMusicTest[20668:3188919] [general] AKAppleSequencer.swift:deinit:41:deinit: (AKAppleSequencer.swift:deinit:41)
2020-04-24 16:30:20.698718-0400 TauMusicTest[20668:3188919] [general] AKAppleSequencer.swift:deinit:41:deinit: (AKAppleSequencer.swift:deinit:41)```

Upvotes: 0

Views: 532

Answers (1)

c_booth
c_booth

Reputation: 2225

You've declared your sampler, mixer, sequencer etc all within the scope of a single function. When the function completes, the OS assumes you're done with them, and will try to free up the memory they used.

This function is actually a method within a class. Try declaring these variables at the class level, so that they can persist after the method completes. E.g.,

class MySequencer {
   var piano: AKMIDISampler?
   var sequencer: AKAppleSequencer?
   // etc. . .

   func playMIDIFile() {
      piano = AKMIDISampler()
      try? piano!.loadWav("FM Piano")
      // etc . . .
   }
}

Upvotes: 1

Related Questions