T7: hardware MIDI keyboard route qua UnifiedMidiRouter (3 nguon 1 router)
This commit is contained in:
+26
-3
@@ -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
|
||||
// kẹt âm VSTi (giống 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user