
本文介绍如何利用 tone.js 的 transport.schedule 方法,在 midi 文件真实播放过程中精确同步显示每个音符的名称、时间与持续时长,避免因 javascript 定时器误差导致的显示不同步问题。
本文介绍如何利用 tone.js 的 transport.schedule 方法,在 midi 文件真实播放过程中精确同步显示每个音符的名称、时间与持续时长,避免因 javascript 定时器误差导致的显示不同步问题。
在基于 Web 的音乐应用开发中,仅提前遍历 MIDI 音符并一次性打印(如 console.log)或使用 setTimeout 触发 UI 更新,往往会导致显示时间严重偏移——这是因为 setTimeout 依赖系统时钟且不受音频调度器控制,而浏览器渲染、事件循环延迟及音频引擎内部缓冲都会造成毫秒级偏差,尤其在变速、暂停/恢复或高精度节拍场景下完全不可靠。
Tone.js 提供了专为音乐时间线设计的全局调度器:Tone.Transport。它以“音乐时间为单位”(如秒、四分音符等)进行调度,并与音频引擎深度同步,确保回调函数在音频事件(如 synth.triggerAttackRelease)精确发生的同一时刻执行。这才是实现真正实时音符可视化的核心机制。
✅ 正确做法是:将音符显示逻辑封装为回调函数,通过 Transport.schedule() 注册到对应音乐时间点:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
async function initiateMidi() {
const midi = await Tone.Midi.fromUrl('src/static/saliha-ya-khdoud-ettefeh.mid');
const synth = new Tone.Synth().toDestination();
synths.push(synth);
// 启动 Transport(可选:设置 BPM)
Tone.Transport.bpm.value = 120;
Tone.Transport.start();
const now = Tone.Transport.time + 0.5; // 使用 Transport.time 而非 Tone.now()
midi.tracks.forEach(track => {
track.notes.forEach(note => {
const noteTime = note.time + now;
const noteDuration = note.duration;
// ✅ 关键:使用 Transport.schedule 确保与音频严格同步
Tone.Transport.schedule(time => {
console.log(`Note: ${note.name}, Time: ${time.toFixed(3)}s, Duration: ${noteDuration}`);
// ✅ 此处可安全更新 DOM,例如:document.getElementById('current-note').textContent = note.name;
}, noteTime);
// 音频触发保持不变
synth.triggerAttackRelease(note.name, noteDuration, noteTime, note.velocity);
});
});
}⚠️ 注意事项:
-
务必调用
Tone.Transport.start():否则schedule不会触发; -
时间基准统一:所有时间参数(如
note.time,now,noteTime)必须基于Tone.Transport.time或Tone.Transport.seconds,而非Date.now()或performance.now(); -
避免混用调度器:不要同时使用
setTimeout和Transport.schedule处理同一音符流,否则将破坏时间一致性; -
暂停/恢复支持:
Transport.pause()/Transport.start()会自动暂停/恢复所有已调度任务,UI 更新天然同步; -
扩展性建议:若需高亮当前音符或绘制钢琴卷帘图,可将
note对象与 DOM 元素绑定,并在schedule回调中动态添加 CSS 类或更新 SVG 坐标。
总结:Tone.js 的 Transport.schedule() 不仅是替代 setTimeout 的语法糖,更是连接音频引擎与用户界面的时间桥梁。它让“实时显示”真正成为“音乐时间上的实时”,这是构建专业级 Web 音乐工具(如交互式乐谱、教学反馈系统、MIDI 分析器)不可或缺的基础能力。

















