我想播放音频文件(例如,wav文件),并且在音轨的特定位置,我要触发将控制外部设备的事件或触发器。
我现在的想法是生成一个与音频轨道同步播放的MIDI轨道,并且当MIDI轨道音符播放时,会生成一些触发事件,我们可以处理这些触发事件以执行我们想要的任何事情。
我现在遇到的问题是如何播放.mid文件并在演奏midi音符时生成事件。我也想同步播放wav和mid文件,但这不是我目前要解决的问题。
我研究了AudioKit,但是示例似乎过时了,文档没有太大帮助。
MIDI是执行此操作的正确方法吗?在iOS中有没有一种更简单的方法,我不必使用AudioKit,而只需使用AVFoundation的某些方法。
我想了解哪种工具最适合检测播放.mid文件中的midi音符并处理该事件。
我的研究指出我要使用AKAppleSequencer。一个简单的示例可能会有所帮助,该示例加载一个Midi文件,然后在演奏音符时基本上打印出一些东西。
我碰到这些帖子,
How to connect AKSequencer to a AKCallbackInstrument?
Play MIDI file together with wav AudioKit
但是现在,AKSequencer被AKAppleSequencer取代。
所以我想通了。答案基本上是在上面的帖子中,只是更新了代码,因此它使用了AKAppleSequencer。
let sequencer = AKAppleSequencer(filename: "SaReGaMa") // the .mid file
let callbackInstr = AKMIDICallbackInstrument()
var player: AKPlayer!
func initializeSession() {
callbackInstr.callback = myCallBack
sequencer.setGlobalMIDIOutput(callbackInstr.midiIn)
if let audioFile = try? AKAudioFile(readFileName: "SaReGaMa.wav") {
player = AKPlayer(audioFile: audioFile)
player.completionHandler = { print("Finished playing file")}
player.buffering = .always
AudioKit.output = player
do {
try AudioKit.start()
} catch {
print("Error starting audiokit, \(error)")
}
}
}
// The callback gets triggered when each midi note is played by the sequencer.
func myCallBack(a: UInt8, b:MIDINoteNumber, c:MIDIVelocity) -> () {
print(a,b,c);
}
// These functions let you control the playback.
func play() {
player.play()
sequencer.play()
}
func pause() {
sequencer.stop()
player.pause()
}