Web MIDI API如何检测send()方法是否执行完成?
Web MIDI API SYSEX发送完成检测方案
最优方案:监听原生ondrain事件
Web MIDI API的MIDIOutput接口原生提供ondrain事件,会在输出队列中的所有待发数据全部完成发送、队列变为空时自动触发,完全不需要硬编码延时,是最准确的实现方式。
示例代码:
// 替换为你实际获取到的MIDI输出设备实例 const d50Output = /* 你的Roland D-50对应的MIDIOutput实例 */; // 你的64个音色SYSEX转储数据 const sysexDump = new Uint8Array(/* 实际SYSEX字节数组 */); // 绑定发送完成回调 d50Output.ondrain = () => { console.log("SYSEX sent"); // 事件触发后解绑,避免后续其他发送操作重复触发该回调 d50Output.ondrain = null; }; // 执行发送 d50Output.send(sysexDump);
兼容方案:动态计算发送延时
如果运行环境不支持ondrain事件,可以基于MIDI协议的固定传输速率计算所需延时,比硬编码12秒的通用性更强,适配不同长度的SYSEX数据:
MIDI 1.0的标准传输速率为31250bps,每个字节传输包含1位起始位、8位数据位、1位停止位共10位,因此每秒最多传输3125个字节,可以按以下逻辑计算延时:
示例代码:
const d50Output = /* 你的Roland D-50对应的MIDIOutput实例 */; const sysexDump = new Uint8Array(/* 实际SYSEX字节数组 */); // 计算理论传输时长,额外加100ms作为冗余容错 const sendTime = Math.ceil(sysexDump.byteLength * 10 / 31250 * 1000) + 100; d50Output.send(sysexDump); setTimeout(() => { console.log("SYSEX sent"); }, sendTime);
如果你是分多批次发送多个SYSEX包,可以累计所有包的总字节数计算延时,或者每发送一个包就等待
ondrain触发后再发下一个包,最后一个包的ondrain触发时机就是全部转储完成的时机。
内容的提问来源于stack exchange,提问作者PGhere
相关产品推荐
相关产品推荐

