You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CoreMIDI中MIDIInputPortCreateWithProtocol多按键事件丢失问题排查

问题原因及修复方案

你的代码存在一个致命逻辑错误,直接导致了事件丢失:

在遍历MIDI数据包的words时,你使用了else { return }——这意味着只要遇到一个无效的uint32(比如值为0的word),就会直接退出整个回调函数,后续的数据包、当前包内的其他有效事件都不会被处理。

对应场景分析:

  • 单键操作时,数据包通常只有一个有效word,不会触发这个return,所以事件接收正常;
  • 多键同时按下时,一个MIDI数据包可能包含多个事件,或者某个word填充了0值,此时代码会中途停止处理,直接丢弃后续按键事件;
  • 逐个按键按下不松开时,每个事件可能在单独的数据包中,单个数据包内的有效word不会触发return,所以能接收全事件。

修复代码:

把遍历words时的return改成continue,跳过无效word,继续处理后续内容:

for word in words {
    guard let uint32 = word.value as? UInt32,
          uint32 > 0 else { 
              // 替换return为continue,跳过无效项不中断整体流程
              continue 
          }
    
    // 原有事件处理逻辑保持不变...
}

额外优化建议:

  1. 兼容MIDI协议细节:部分设备会用力度为0的NOTE_ON事件替代NOTE_OFF事件,建议统一处理这种情况,避免遗漏按键松开事件;
  2. 规范数据包遍历逻辑:使用MIDIEventListGetPacket获取每个数据包,替代手动调用MIDIEventPacketNext,避免潜在的越界问题,示例:
for packetIndex in 0..<midiEventList.numPackets {
    let packet = MIDIEventListGetPacket(&midiEventList, packetIndex).pointee
    // 处理当前packet的逻辑...
}

内容的提问来源于stack exchange,提问作者sidneivl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:20:36