如何足够准确地同步两个音乐序列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)

赞赏任何想法。

解决方法

建立在MusicSequence上的Apple AKAppleSequencer总是在启动后的前100毫秒左右忽略时间。这是封闭源代码中的一个已知问题,永远不会得到解决。有两种可能的解决方法。

  1. 使用新的AKSequencer。进行这项工作可能足够准确(但不能保证)。这是将AKSequencerAKCallbackInstrument结合使用的示例:https://stackoverflow.com/a/61545391/2717159

  2. 使用单个AKAppleSequencer,但是将您的“ sequencer2”内容放在“ sequencer1”内容之后。您将无法自动循环它,但是您可以从回调函数中反复重写它(或预写300次或类似的操作)。以我的经验,在播放时将MIDI写入AKAppleSequencer是没有问题的。样例应用https://github.com/AudioKit/MIDIFileEditAndSync带有一些时移MIDI音符数据的示例,可以用来完成此操作。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...