CallbackInstrument的MIDIEndpointRef是什么?AudioKit回调乐器语法及方案咨询
我来帮你梳理这几个问题,结合AudioKit最新版本的实践给出解决方案:
CallbackInstrument对应的MIDIEndpointRef获取方式
在AudioKit v5及以后的版本中,AKCallbackInstrument基于MIDIKit完成了重构,如果你需要底层CoreMIDI的MIDIEndpointRef,可以通过它的输入端点属性获取:
if let inputEndpoint = callbackInst.input { let endpointRef = inputEndpoint.endpointRef // 在这里使用endpointRef进行CoreMIDI层面的操作 }
如果你使用的是更早的AudioKit版本,AKCallbackInstrument的midiIn属性本身就是MIDIEndpointRef类型,可以直接取用。
AKCallbackInstrument语法变更后的输出设置写法
旧版本的setMIDIOutput(_:)方法已经被废弃,新版本中AKSequencer的轨道支持直接接收符合MIDIReceiver协议的对象,而AKCallbackInstrument默认实现了该协议,所以代码可以改成:
callbackTrack?.setOutput(to: callbackInst)
这样就能将轨道的MIDI输出定向到回调乐器,触发你定义的回调逻辑。
更优的运行时UI变更实现方案
除了你之前用编码轨道+Callback Instrument的方式,还有几个更灵活、易维护的方案:
- 订阅音序器播放位置变化:利用Combine框架监听音序器的播放进度,结合序列事件数据更新UI:
sequencer.$sequencePosition .receive(on: DispatchQueue.main) .sink { position in // 根据当前播放位置查找对应的音符/事件 // 执行UI更新逻辑,比如高亮当前小节、切换控件状态 } .store(in: &cancellables) - 添加轨道级MIDI事件回调:直接给目标轨道绑定事件回调,精准捕获该轨道的所有MIDI事件:
callbackTrack?.addMIDIEventCallback { track, event, time in DispatchQueue.main.async { // 根据事件类型(音符开/关、控制变化等)处理UI更新 if event.type == .noteOn { // 例如:高亮当前播放的音符按钮 } } } - 自定义全局MIDI监听器:实现
MIDIListener协议,监听所有MIDI输入事件,适合需要响应全量MIDI信号的场景:class UIMIDIListener: MIDIListener { func receivedMIDINoteOn(note: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel, portID: MIDIUniqueID?, offset: MIDITimeStamp) { DispatchQueue.main.async { // 处理音符触发事件,更新UI元素 } } } // 注册监听器 let uiListener = UIMIDIListener() AudioKit.midi.addListener(uiListener)
内容的提问来源于stack exchange,提问作者NickTheFairy
相关产品推荐
相关产品推荐

