问题描述
我正在为 iOS12.4x 开发基于 AUSampler 的应用程序(我使用的是 High Sierra,因此无法为 iOS13+ 开发,我使用的是 Xcode 10.3)。
它通过 MIDIReadProc 处理程序管理传入的 MIDI 消息。
当同时重复播放多个音符时,我注意到卡住的音符(好像一些音符关闭消息没有被处理)。 我直接从 MIDIReadProc 处理程序调用了 MusicDeviceMIDIEvent,但它没有解决问题。
更新:使用新的 AVAudioUnitSampler(和 AVAudioEngine/AVAudioSession 代替 AUGraph)没有帮助。
更新: 使用 Apple 的 AVAudioUnitSampler 的 AudioKit 4.8 和包装类 (AKMidisampler/AKAppleSampler) 解决了这个问题,所以问题可能来自我管理 midi 消息的方式(但它与 AudioKit 的做法类似)。
我正在使用的新代码(带有 MIDIReadProc 的旧代码是 Objective-C):
err = MIDIInputPortCreateWithBlock(client,portName,&port,onMIDIMessageReceived)
并且处理程序定义为:
func onMIDIMessageReceived(message: UnsafePointer<MIDIPacketList>,srcConnRefCon: UnsafeMutableRawPointer?) {
let packetList: MIDIPacketList = message.pointee
let n = packetList.numPackets
var packet = packetList.packet
for _ in 0 ..< n {
let mes: UInt8 = packet.data.0 & 0xF0
let ch: UInt8 = packet.data.0 & 0x0F
if mes == 0x90 && packet.data.2 != 0 {
let noteNo = packet.data.1
let veLocity = packet.data.2
dispatchQueue.main.async {
self.delegate?.noteOn(ch: ch,note: noteNo,vel: veLocity)
}
} else if (mes == 0x80 || mes == 0x90) {
let noteNo = packet.data.1
let veLocity = packet.data.2
dispatchQueue.main.async {
self.delegate?.noteOff(ch: ch,vel: veLocity)
}
}
let packetPtr = MIDIPacketNext(&packet)
packet = packetPtr.pointee
}
}
我还测试了没有 dispatchQueue.main.async(在调用采样器方法时在委托中使用它),同样的问题。
我不想依赖 Audiokit,因为我认为这是我计划的开销(我想学习/控制我的所有代码)。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)