如何足够准确地同步两个音乐序列 (Audiokit.AKAppleSequencer)?
How to sync accurately enough two music sequences (Audiokit.AKAppleSequencer)?
我有 2 个音序器:
let sequencer1 = AKAppleSequencer(filename: "filename1")
let sequencer2 = AKAppleSequencer(filename: "filename2")
两者的 bpm 值相同。
当 sequencer1 开始播放一个 midi 曲目(只播放一次)时,我需要 sequencer2 在第一个音序器完成后开始播放。我怎样才能做到这一点?
请注意,sequencer2 已循环。
目前我有这种方法,但不够准确:
let callbackInstrument = AKMIDICallbackInstrument(midiInputName: "callbackInstrument", callback: nil)
let callbackTrack = sequencer1.newTrack()!
callbackTrack.setMIDIOutput(callbackInstrument.midiIn)
let beatsCount = sequencer1.length.beats
callbackTrack.add(noteNumber: MIDINoteNumber(beatsCount),
velocity: 1,
position: AKDuration(beats: beatsCount),
duration: AKDuration(beats: 0.1))
callbackInstrument.callback = { status, _, _ in
guard AKMIDIStatusType.from(byte: status) == .noteOn else { return }
DispatchQueue.main.async { self.sequencer2.play() }//not accurate
}
let sampler = AKMIDISampler(midiOutputName: nil)
sequencer1.tracks[0].setMIDIOutput(sampler.midiIn)
感谢任何想法。
Apple 的 MusicSequence
是 AKAppleSequencer
的基础,它总是在启动后的前 100 毫秒左右出现时间错误。这是封闭源代码中的一个已知问题,永远不会修复。这里有两种可能的解决方法。
使用新的AKSequencer
。它可能足以使这项工作准确(但不保证)。下面是使用 AKSequencer
和 AKCallbackInstrument
的示例:
使用单个 AKAppleSequencer
,但将 'sequencer2' 内容放在 'sequencer1' 内容之后。你不能自动循环它,但你可以从你的回调函数中重复 re-write 它(或者 pre-write 它 300 次或类似的东西)。根据我的经验,在播放时将 MIDI 写入 AKAppleSequencer
是没有问题的。示例应用程序 https://github.com/AudioKit/MIDIFileEditAndSync 包含时移 MIDI 音符数据的示例,可用于完成此操作。
我有 2 个音序器:
let sequencer1 = AKAppleSequencer(filename: "filename1")
let sequencer2 = AKAppleSequencer(filename: "filename2")
两者的 bpm 值相同。
当 sequencer1 开始播放一个 midi 曲目(只播放一次)时,我需要 sequencer2 在第一个音序器完成后开始播放。我怎样才能做到这一点? 请注意,sequencer2 已循环。
目前我有这种方法,但不够准确:
let callbackInstrument = AKMIDICallbackInstrument(midiInputName: "callbackInstrument", callback: nil)
let callbackTrack = sequencer1.newTrack()!
callbackTrack.setMIDIOutput(callbackInstrument.midiIn)
let beatsCount = sequencer1.length.beats
callbackTrack.add(noteNumber: MIDINoteNumber(beatsCount),
velocity: 1,
position: AKDuration(beats: beatsCount),
duration: AKDuration(beats: 0.1))
callbackInstrument.callback = { status, _, _ in
guard AKMIDIStatusType.from(byte: status) == .noteOn else { return }
DispatchQueue.main.async { self.sequencer2.play() }//not accurate
}
let sampler = AKMIDISampler(midiOutputName: nil)
sequencer1.tracks[0].setMIDIOutput(sampler.midiIn)
感谢任何想法。
Apple 的 MusicSequence
是 AKAppleSequencer
的基础,它总是在启动后的前 100 毫秒左右出现时间错误。这是封闭源代码中的一个已知问题,永远不会修复。这里有两种可能的解决方法。
使用新的
AKSequencer
。它可能足以使这项工作准确(但不保证)。下面是使用AKSequencer
和AKCallbackInstrument
的示例:使用单个
AKAppleSequencer
,但将 'sequencer2' 内容放在 'sequencer1' 内容之后。你不能自动循环它,但你可以从你的回调函数中重复 re-write 它(或者 pre-write 它 300 次或类似的东西)。根据我的经验,在播放时将 MIDI 写入AKAppleSequencer
是没有问题的。示例应用程序 https://github.com/AudioKit/MIDIFileEditAndSync 包含时移 MIDI 音符数据的示例,可用于完成此操作。