FIX: sửa lỗi MIDI item với fx mastering tồn tại và không qua Carla
This commit is contained in:
@@ -15283,6 +15283,11 @@ const App = () => {
|
|||||||
setLastMidiNote({ pitch, velocity: scaledVel, length: 0, time: Date.now() });
|
setLastMidiNote({ pitch, velocity: scaledVel, length: 0, time: Date.now() });
|
||||||
activeMidiPitchesRef.current.add(pitch);
|
activeMidiPitchesRef.current.add(pitch);
|
||||||
setActiveMidiPitches(new Set(activeMidiPitchesRef.current));
|
setActiveMidiPitches(new Set(activeMidiPitchesRef.current));
|
||||||
|
// MIDI Keyboard → Mastering FX Chain (main out): đồng bộ routing
|
||||||
|
// mastering + SF NGAY trước khi phát — âm MIDI keyboard hardware
|
||||||
|
// PHẢI qua mastering FX khi chain đang bật (giống keybed; trước
|
||||||
|
// đây chỉ keybed ảo gọi __ensureMasteringRouting).
|
||||||
|
try { if (window.__ensureMasteringRouting) window.__ensureMasteringRouting(); } catch (er) {}
|
||||||
// Route MIDI input to ALL armed tracks on their dedicated channels
|
// Route MIDI input to ALL armed tracks on their dedicated channels
|
||||||
// Do NOT use raw MIDI hardware channel (msg.data[0] & 0x0F)
|
// Do NOT use raw MIDI hardware channel (msg.data[0] & 0x0F)
|
||||||
if (window.SonicSF) {
|
if (window.SonicSF) {
|
||||||
@@ -15305,6 +15310,11 @@ const App = () => {
|
|||||||
heldMidiNotesRef.current[as.trackId] = (heldMidiNotesRef.current[as.trackId] || 0) + 1;
|
heldMidiNotesRef.current[as.trackId] = (heldMidiNotesRef.current[as.trackId] || 0) + 1;
|
||||||
} catch (err) { }
|
} catch (err) { }
|
||||||
window.SonicSF.playNote(pitch, scaledVel, 60000, undefined, asProg, null, asCh, asSe);
|
window.SonicSF.playNote(pitch, scaledVel, 60000, undefined, asProg, null, asCh, asSe);
|
||||||
|
// MIDI Keyboard → Carla bridge (piano roll sub-tab ARM):
|
||||||
|
// track VSTi của sub-tab phát VSTi realtime giống keybed.
|
||||||
|
if (window.SonicCarlaMidi && window.SonicCarlaMidi.shouldRoute(asSe, true)) {
|
||||||
|
try { window.SonicCarlaMidi.noteOn(asCh, pitch, scaledVel); } catch (e) {}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Route to ALL armed tracks (not just the first one)
|
// Route to ALL armed tracks (not just the first one)
|
||||||
@@ -15321,6 +15331,13 @@ const App = () => {
|
|||||||
heldMidiNotesRef.current[at.id] = (heldMidiNotesRef.current[at.id] || 0) + 1;
|
heldMidiNotesRef.current[at.id] = (heldMidiNotesRef.current[at.id] || 0) + 1;
|
||||||
} catch (err) { }
|
} catch (err) { }
|
||||||
window.SonicSF.playNote(pitch, scaledVel, 60000, undefined, atProg, atDest, atCh, atSe);
|
window.SonicSF.playNote(pitch, scaledVel, 60000, undefined, atProg, atDest, atCh, atSe);
|
||||||
|
// MIDI Keyboard → Carla bridge (track VSTi + ARM + Carla
|
||||||
|
// local): phát VSTi realtime — giống hệt keybed ảo. Trước
|
||||||
|
// đây chỉ keybed gọi SonicCarlaMidi; keyboard hardware bị
|
||||||
|
// bỏ sót → track VSTi không kêu khi bấm đàn thật.
|
||||||
|
if (window.SonicCarlaMidi && window.SonicCarlaMidi.shouldRoute(atSe, at.isArmed)) {
|
||||||
|
try { window.SonicCarlaMidi.noteOn(atCh, pitch, scaledVel); } catch (e) {}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (cmd === 0x8 || (cmd === 0x9 && rawVel === 0)) {
|
} else if (cmd === 0x8 || (cmd === 0x9 && rawVel === 0)) {
|
||||||
@@ -15343,6 +15360,11 @@ const App = () => {
|
|||||||
if (!st.synth_engine && st.midiChannel === undefined) return;
|
if (!st.synth_engine && st.midiChannel === undefined) return;
|
||||||
var stCh = assignTrackMidiChannel(st, stopTracks);
|
var stCh = assignTrackMidiChannel(st, stopTracks);
|
||||||
window.SonicSF.stopNote(stCh, pitch);
|
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).
|
||||||
|
if (window.SonicCarlaMidi && window.SonicCarlaMidi.shouldRoute(st.synth_engine, st.isArmed)) {
|
||||||
|
try { window.SonicCarlaMidi.noteOff(stCh, pitch); } catch (e) {}
|
||||||
|
}
|
||||||
// Giảm counter note đang giữ — hết note → VU được phép decay/tắt
|
// Giảm counter note đang giữ — hết note → VU được phép decay/tắt
|
||||||
// (tick sẽ thấy counter = 0 và không còn giữ peak nữa)
|
// (tick sẽ thấy counter = 0 và không còn giữ peak nữa)
|
||||||
try {
|
try {
|
||||||
@@ -24686,6 +24708,15 @@ const App = () => {
|
|||||||
try {
|
try {
|
||||||
toggleMasteringOnMaster(!!(masteringSettings && masteringSettings.masterConnected), !!(masteringSettings && masteringSettings.isBypassed));
|
toggleMasteringOnMaster(!!(masteringSettings && masteringSettings.masterConnected), !!(masteringSettings && masteringSettings.isBypassed));
|
||||||
} catch (e) { console.warn('offline mastering toggle error:', e); }
|
} catch (e) { console.warn('offline mastering toggle error:', e); }
|
||||||
|
// Main out volume (master fader) áp vào offline bus — file export phải
|
||||||
|
// đúng độ lớn nghe được (flow: ... → Mastering FX Chain → Main out).
|
||||||
|
// Trước đây offline masterBus.output luôn = 1.0 → export sai volume.
|
||||||
|
try {
|
||||||
|
if (masterBus && masterBus.output) {
|
||||||
|
const mv = (typeof masterVolume === 'number' && isFinite(masterVolume)) ? masterVolume : 0;
|
||||||
|
masterBus.output.gain.setValueAtTime(mv <= -50 ? 0 : Math.pow(10, mv / 20), 0);
|
||||||
|
}
|
||||||
|
} catch (e) { console.warn('offline main-out volume error:', e); }
|
||||||
activeTracks.forEach(t => {
|
activeTracks.forEach(t => {
|
||||||
const node = buildOfflineTrackNode(t, offlineCtx, offlineNodes);
|
const node = buildOfflineTrackNode(t, offlineCtx, offlineNodes);
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -231,3 +231,25 @@ plugin/preset** (khác "Preview Synth WASM" cũ — âm giả).
|
|||||||
- [ ] Docker (`SF_DOCKER=1`): capabilities `runtime=headless`, không hiện Carla Bridge, preset upload hoạt động, render VSTi Linux + soundfont từ mount OK
|
- [ ] Docker (`SF_DOCKER=1`): capabilities `runtime=headless`, không hiện Carla Bridge, preset upload hoạt động, render VSTi Linux + soundfont từ mount OK
|
||||||
- [ ] `SF_RUNTIME=desktop` trên Linux có DISPLAY → chạy như desktop
|
- [ ] `SF_RUNTIME=desktop` trên Linux có DISPLAY → chạy như desktop
|
||||||
- [ ] pytest: `86 passed, 7 skipped`
|
- [ ] pytest: `86 passed, 7 skipped`
|
||||||
|
|
||||||
|
## 9. Flow MIDI Keyboard hardware (Web MIDI) — route đầy đủ
|
||||||
|
|
||||||
|
Hardware MIDI keyboard (Web MIDI API) đi qua ĐÚNG flow như keybed ảo:
|
||||||
|
|
||||||
|
```
|
||||||
|
MIDI Keyboard (hardware, Web MIDI)
|
||||||
|
├─ note-on → ensureMasteringRouting() (ép âm qua Mastering FX Chain khi bật)
|
||||||
|
│ → SonicSF.playNote() (track soundfont/GM — qua track node → mastering)
|
||||||
|
│ → SonicCarlaMidi.noteOn() (track VSTi + ARM + Carla local — OSC /Carla/0/note_on)
|
||||||
|
├─ note-off → SonicSF.stopNote() (dừng soundfont)
|
||||||
|
│ → SonicCarlaMidi.noteOff() (dừng VSTi trong Carla — tránh kẹt âm)
|
||||||
|
└─ CC64/CC1/Pitch Bend → SonicSF.controllerChange()/pitchBend() (armed tracks)
|
||||||
|
```
|
||||||
|
|
||||||
|
Trước đây chỉ keybed ảo (piano roll) gọi `SonicCarlaMidi` + `__ensureMasteringRouting`;
|
||||||
|
keyboard hardware bị bỏ sót → track VSTi không kêu khi bấm đàn thật, và âm soundfont
|
||||||
|
không qua mastering cho tới khi bật/tắt power. Đã sửa tại `onmidimessage` handler
|
||||||
|
(`app.jsx`): note-on/note-off route qua Carla bridge + ép đồng bộ mastering routing.
|
||||||
|
|
||||||
|
Export offline (`clientSideExport`) cũng áp **Main out volume** (master fader) vào
|
||||||
|
offline master bus — file WAV đúng độ lớn nghe được (trước đây luôn 1.0).
|
||||||
|
|||||||
Reference in New Issue
Block a user