T7: hardware MIDI keyboard route qua UnifiedMidiRouter (3 nguon 1 router)

This commit is contained in:
2026-08-11 15:57:12 +07:00
parent 9dcc37e037
commit 9fc5498999
3 changed files with 84 additions and 10 deletions
@@ -99,6 +99,52 @@ window.SonicUnifiedMidiRouter = window.SonicUnifiedMidiRouter || {};
return false; // CC / unknown
};
// Hardware MIDI keyboard message → dispatch tới targets đã gom sẵn (armed
// tracks). app.jsx thu thập noteOnTargets [{trackId, ch, engine}] ở note-on
// và noteOffTargets [{trackId, ch}] ở note-off, gọi 1 lần mỗi message.
// parse giống handler cũ (cmd 4-bit, pitch clamp, velocity 1-127) rồi đẩy
// qua dispatchMidiEvent → 3 nguồn (keybed/scheduler/hardware) chung router.
UnifiedMidiRouter.prototype.handleHardwareKeyboardMessage = function (msg, noteOnTargets, noteOffTargets) {
var cmd = Number(msg[0]) >> 4;
var pitch = clampPitch(msg[1]);
var rawVel = Number(msg[2]) || 0;
var velocity = Math.min(127, Math.max(1, Math.round(rawVel)));
var noteOn = (cmd === 0x9 && rawVel > 0);
var noteOff = (cmd === 0x8 || (cmd === 0x9 && rawVel === 0));
if (noteOn && noteOnTargets) {
noteOnTargets.forEach(function (t) {
if (!t || t.trackId === undefined || t.trackId === null) return;
if (t.engine) this.registerEngine(t.trackId, t.engine);
this.dispatchMidiEvent({
trackId: t.trackId,
command: COMMAND_NOTE_ON,
channel: t.ch,
pitch: pitch,
velocity: velocity / 127,
durationMs: 60000,
source: 'HARDWARE_KEYBOARD'
});
}, this);
}
if (noteOff && noteOffTargets) {
noteOffTargets.forEach(function (t) {
if (!t || t.trackId === undefined || t.trackId === null) return;
this.dispatchMidiEvent({
trackId: t.trackId,
command: COMMAND_NOTE_OFF,
channel: t.ch,
pitch: pitch,
source: 'HARDWARE_KEYBOARD'
});
}, this);
}
console.log('[MidiRouter] hardware ->', { noteOn: noteOn, noteOff: noteOff, pitch: pitch, velocity: velocity, targets: (noteOnTargets ? noteOnTargets.length : 0) + '/' + (noteOffTargets ? noteOffTargets.length : 0) });
return { noteOn: noteOn, noteOff: noteOff, pitch: pitch, velocity: velocity };
};
// All Notes Off: quét voice tracker, gửi note-off cho engine sở hữu từng
// voice, xóa tracker. Gọi khi dừng playback / đổi instrument giữa chừng.
UnifiedMidiRouter.prototype.panicAllNotesOff = function () {