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
+26 -3
View File
@@ -15738,6 +15738,9 @@ const App = () => {
var allTracks = activeTracksRef.current || [];
var arSubs = subTabsRef && subTabsRef.current ? subTabsRef.current.filter(function(s) { return s.type === 'PIANO_ROLL' && s.isArmed; }) : [];
var armedTracks = allTracks.filter(function(t) { return t.isArmed; });
// T7: UnifiedMidiRouter gom targets, dispatch 1 lan sau 2 vong.
var hwRouter = _getMidiRouter();
var hwTargets = [];
// Piano Roll arming has priority: route to each armed sub-tab's parent track
if (arSubs.length > 0) {
arSubs.forEach(function(as) {
@@ -15753,7 +15756,9 @@ const App = () => {
try {
heldMidiNotesRef.current[as.trackId] = (heldMidiNotesRef.current[as.trackId] || 0) + 1;
} catch (err) { }
if (isStandaloneSf() && isSfTrackEngine(asSe) && !shouldRouteCarla(asSe)) {
if (hwRouter && asTrk && asTrk.id) {
hwTargets.push({ trackId: asTrk.id, ch: asCh, engine: new window.TrackInstrument(asTrk.id, _makeCtx(asCh, asProg, asSe, null)) });
} else if (isStandaloneSf() && isSfTrackEngine(asSe) && !shouldRouteCarla(asSe)) {
if (!_routeNoteOn(asTrk && asTrk.id, _makeCtx(asCh, asProg, asSe, null), pitch, scaledVel / 127, 60000, 'HARDWARE_KEYBOARD')) {
window.SonicSF.playNote(pitch, scaledVel, 60000, undefined, asProg, null, asCh, asSe);
}
@@ -15780,7 +15785,9 @@ const App = () => {
try {
heldMidiNotesRef.current[at.id] = (heldMidiNotesRef.current[at.id] || 0) + 1;
} catch (err) { }
if (isStandaloneSf() && isSfTrackEngine(atSe) && !shouldRouteCarla(atSe)) {
if (hwRouter && at && at.id) {
hwTargets.push({ trackId: at.id, ch: atCh, engine: new window.TrackInstrument(at.id, _makeCtx(atCh, atProg, atSe, atDest)) });
} else if (isStandaloneSf() && isSfTrackEngine(atSe) && !shouldRouteCarla(atSe)) {
if (!_routeNoteOn(at && at.id, _makeCtx(atCh, atProg, atSe, atDest), pitch, scaledVel / 127, 60000, 'HARDWARE_KEYBOARD')) {
window.SonicSF.playNote(pitch, scaledVel, 60000, undefined, atProg, atDest, atCh, atSe);
}
@@ -15795,7 +15802,12 @@ const App = () => {
try { window.SonicCarlaMidi.noteOn(atCh, pitch, scaledVel); } catch (e) {}
}
});
// T7: dispatch 1 lan qua router - keybed/scheduler/hardware
// chung 1 voice tracker (chong stuck note khi doi engine).
if (hwRouter && hwTargets.length) {
hwRouter.handleHardwareKeyboardMessage(msg.data, hwTargets, []);
}
}
} else if (cmd === 0x8 || (cmd === 0x9 && rawVel === 0)) {
activeMidiPitchesRef.current.delete(pitch);
setActiveMidiPitches(new Set(activeMidiPitchesRef.current));
@@ -15809,13 +15821,19 @@ const App = () => {
// when ARM is toggled off while a key is held
if (window.SonicSF && window.SonicSF.stopNote) {
var stopTracks = activeTracksRef.current || [];
var hwRouterOff = _getMidiRouter();
var hwStopTargets = [];
stopTracks.forEach(function(st) {
// Only stop channels that actually carry this track's notes
// an index-based fallback could hit another track's dedicated
// channel and kill its sound.
if (!st.synth_engine && st.midiChannel === undefined) return;
var stCh = assignTrackMidiChannel(st, stopTracks);
if (isStandaloneSf()) _routeNoteOff(st.id, { ch: stCh }, pitch, 'HARDWARE_KEYBOARD');
if (hwRouterOff && st.id) {
hwStopTargets.push({ trackId: st.id, ch: stCh });
} else if (isStandaloneSf()) {
_routeNoteOff(st.id, { ch: stCh }, pitch, 'HARDWARE_KEYBOARD');
}
window.SonicSF.stopNote(stCh, pitch);
// MIDI Keyboard Carla bridge: note-off khi th phím tránh
// kt âm VSTi (ging keybed o).
@@ -15833,6 +15851,11 @@ const App = () => {
}
} catch (err) { }
});
// T7: note-off dispatch qua router - engine voice giu tu note-on;
// SonicSF.stopNote o tren van giu belt-and-suspenders.
if (hwRouterOff && hwStopTargets.length) {
hwRouterOff.handleHardwareKeyboardMessage(msg.data, [], hwStopTargets);
}
}
}