Closed frankiesimon closed 4 years ago
This is a long standing bug in Apple's sequencer and since that is closed source we had to write our own. My suggestion is to switch to AKSequencer. I have.
I would be happy to but there is no playground or sample of how to use it in a simple scenario, like connecting to a sampler and playing a MIDI file. Also I couldn't use the callback instrument and there is no way to add tracks.
open func addTrack(for node: AKNode) -> AKSequencerTrack {
let track = AKSequencerTrack(targetNode: node)
tracks.append(track)
return track
}
I'll work on the playgrounds
I understand this function was added in 4.9.2 but I have to say with XCode 11.1 so I can't upgrade yet.
I initialize AKSequencer with my MIDI file but something is wrong with my signal chain since I'm not hearing sounds, regardless of whether I'm using AKSampler or AKAppleSampler.
I wrote this class to wrap loading a MIDI and playing different ranges of it.
class MIDIPlayer {
var sampler: AKSampler
var legacySampler: AKAppleSampler
var sequencer: AKSequencer
init(withSfz sfz: String, orSf2 sf2: String) {
self.sampler = AKSampler()
self.legacySampler = AKAppleSampler()
try? legacySampler.loadSoundFont(sf2, preset: 0, bank: 0)
sampler.loadSFZ(url: Bundle.main.url(forResource: sfz, withExtension: "sfz")!)
AudioKit.output = sampler
try? AudioKit.start()
// Is this the right way to connect the sequencer to the sampler?
sequencer = AKSequencer(targetNode: sampler)
// sequencer = AKSequencer(targetNode: legacySampler)
}
func setupMIDIFile(_ midiFile: String) {
if (sequencer.isPlaying) {
sequencer.stop()
}
let midi = AKMIDIFile(url: Bundle.main.url(forResource: midiFile, withExtension: "mid")!)
sequencer.load(midiFile: midi)
}
func play() {
sequencer.stop()
sequencer.playFromStart()
}
func playBeatRange(from startTime: Float64, to endTime: Float64) {
sequencer.stop()
sequencer.length = endTime
sequencer.playAfterDelay(beats: startTime)
}
func isPlaying() -> Bool {
return sequencer.isPlaying
}
func stop() {
sequencer.stop()
}
}
Am I missing something obvious in the initialization?
I believe your answer is now on https://stackoverflow.com/questions/58833495/how-to-play-midi-with-audiokits-new-aksequencer/58863420#58863420
Thank you for responding! Unfortunately that doesn't work (I am getting a compilation error: Cannot convert value of type 'AKSequencer' to expected argument type 'AKNode?')
I'm sorry to continue the discussion here I am not sure if comments on questions are with notifications.
I updated the answer.
I'm using AudioKit 4.9.1 with XCode 11.1, MacOS Mojave 10.14.6 (18G87).
I had a problem with playing MIDI using AKAppleSequencer, it seemed like the first couple of MIDI notes sounded a bit too close together.
This luckily reproduces even in the Playgrounds, Drum Sequencer. Start the sound and you'll hear in the first loop iteration the first drum and hihat are slightly closer together than in the subsequent loops. If you start/stop a few times you'll hear it.
I found this relevant SO question: https://stackoverflow.com/a/52309782/336702
The people who answered considered this to be a start-up lag but based on the original poster's answer this seems to be related to the next notes playing too early rather than having the first one delayed. And I'm not sure I understand how to implement the workaround he suggested anyway.
Please let me know if I can provide more information.