AudioKit:AppleSequencer与AudioPlayer定时同步及任意偏移定位方案咨询
AudioKit:AppleSequencer与AudioPlayer定时同步及任意偏移定位方案咨询
背景
我正在尝试通过AppleSequencer播放音频文件,要求音频文件的播放能精准同步到AppleSequencer的预定义节拍序列:文件1在第4拍开始播放,文件2在第8拍开始,文件N在第4N拍开始(所有音频文件时长都小于4拍,不会出现重叠)。
核心问题
有没有一种解决方案,能支持将音序器定位到任意偏移位置?举个例子,如果我将音序器定位到第4.123拍,那么文件1应该从对应“第0.123拍”的位置开始播放——意思是播放要和音序器保持同步,就像音序器从第0拍启动时的同步状态一样。
当前尝试的方案
我目前的同步方案不支持任意偏移定位(当我定位到某个音频文件播放过程中的偏移位置时,这个音频文件不会被播放,只有后续的文件会播放)。我最初尝试参考了针对N=1场景的思路:启动AppleSequencer实例,获取对应第4拍的hostTime,然后在该时间点启动AudioPlayer实例。
实际上,这个思路在使用AudioKit的AppleSequencer时无法实现精准同步,所以我换成了AVAudioSequencer作为音序器来追求完美同步。
针对N≥1的通用场景,我使用了MIDICallbackInstrument,让它在每个4的倍数节拍到来前一点触发上述策略(下面的代码片段里为了简化,我复用了同一个AudioPlayer实例):
// 添加MIDI事件,这些事件会在4的倍数节拍前被回调捕获 let track = appleSequencer.tracks[0] for i in 0..<N { track.add(noteNumber: 66, velocity: 127, position: Duration(beats: 3.5 + 4.0 * Double(i)), duration: Duration(beats: 1)) } // 设置回调,当捕获到指定事件时播放AudioPlayer实例 midiCallbackInstrument.callback = { _, note, _ in if note == 66 { let nextAudioStartInBeats = ceil(self.appleSequencer.currentPosition.beats / 4.0) * 4.0 do { let nextAudioStartInHostTime = try AVAudioTime(hostTime: self.appleSequencer.hostTime(forBeats: nextAudioStartInBeats)) audioplayer.play(at: nextAudioStartInHostTime) } catch { /* ... */ } } }
备注:内容来源于stack exchange,提问作者Georges_Abitbol
相关产品推荐
相关产品推荐

