FIX: preview soundfont (MIDI keyboard) không tự động qua mastering FX main out
- Thêm ensureMasteringRouting() đồng bộ graph mastering + routing SF + route gains NGAY trước khi preview (keybed onMouseDown, playDrawPreview, playMidiPreview, mở piano roll tab) — hết phải bật/tắt nút power mới có tác dụng - applyMasteringSettings sig thêm masterConnected/isBypassed — toggle power luôn re-apply tham số module
This commit is contained in:
+36
-1
@@ -336,7 +336,7 @@ function applyMasteringSettings(s) {
|
||||
// Re-applying identical values in rapid bursts is "fast parameter automation"
|
||||
// and makes Chromium flag the biquad EQ filters as unstable ("state is bad").
|
||||
// Only touch the graph when a value actually changed.
|
||||
const sig = [s.eqActive, s.eqLowGain, s.eqMid1Gain, s.eqMid2Gain, s.eqHighGain, s.imagerActive, s.w1, s.w2, s.w3, s.w4, s.maximizerActive, s.maxGain, s.maxSoftClip, s.maxUpward, s.ceiling, s.compActive, s.compThreshold, s.compRatio, s.compMakeup, s.limActive, s.limThreshold, s.excActive, s.excDrive, s.rebalActive, s.rebalMid, s.rebalSide].join('|');
|
||||
const sig = [s.masterConnected, s.isBypassed, s.eqActive, s.eqLowGain, s.eqMid1Gain, s.eqMid2Gain, s.eqHighGain, s.imagerActive, s.w1, s.w2, s.w3, s.w4, s.maximizerActive, s.maxGain, s.maxSoftClip, s.maxUpward, s.ceiling, s.compActive, s.compThreshold, s.compRatio, s.compMakeup, s.limActive, s.limThreshold, s.excActive, s.excDrive, s.rebalActive, s.rebalMid, s.rebalSide].join('|');
|
||||
if (sig === _lastMasteringSig) return;
|
||||
_lastMasteringSig = sig;
|
||||
|
||||
@@ -8704,6 +8704,9 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
||||
|
||||
function playDrawPreview(p, durMs) {
|
||||
stopPreviewNote();
|
||||
// Đồng bộ mastering + routing SF trước khi preview draw (âm qua
|
||||
// mastering FX của main out khi chain bật)
|
||||
try { if (window.__ensureMasteringRouting) window.__ensureMasteringRouting(); } catch (er) {}
|
||||
if (window.SonicSF && window.SonicSF.playNote) {
|
||||
var pvCtx = getAudioContext();
|
||||
var pvTrk = activeTracks.find(function(t) { return t.id === st.trackId; });
|
||||
@@ -9090,6 +9093,10 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
||||
e.stopPropagation();
|
||||
keybedMouseDownRef.current = true;
|
||||
try {
|
||||
// Đồng bộ mastering + routing SF NGAY trước khi preview — âm
|
||||
// keybed PHẢI qua mastering FX của main out khi chain đang bật
|
||||
// (trước đây phải bật/tắt power mới có tác dụng).
|
||||
try { if (window.__ensureMasteringRouting) window.__ensureMasteringRouting(); } catch (er) {}
|
||||
if (window.triggerMidiVuActivity) {
|
||||
window.triggerMidiVuActivity((st.parent_tab_id && st.parent_tab_id.startsWith('session_') ? '_sess_' : '') + st.trackId, 100);
|
||||
}
|
||||
@@ -13807,6 +13814,9 @@ const MediaExplorerPanel = ({ height, clipboardRef, active }) => {
|
||||
tempoRef.current = newTempo;
|
||||
try { localStorage.setItem('studio_media_explorer_tempo', String(newTempo)); } catch (e) {}
|
||||
const ctx = getAudioContext();
|
||||
// Đồng bộ mastering + routing SF trước khi preview MIDI file (âm qua
|
||||
// mastering FX của main out khi chain bật)
|
||||
try { if (window.__ensureMasteringRouting) window.__ensureMasteringRouting(); } catch (e3) {}
|
||||
const bpmVal = tempoRef.current || 120;
|
||||
const secondsPerBeat = 60.0 / bpmVal;
|
||||
const startWallTime = ctx.currentTime + 0.05;
|
||||
@@ -18170,6 +18180,9 @@ const App = () => {
|
||||
};
|
||||
setSubTabs(prev => [...prev, newTab]);
|
||||
setActiveTab(tabId);
|
||||
// Đồng bộ routing SF + mastering ngay khi mở piano roll — preview keybed
|
||||
// phải đi qua mastering FX của main out (không cần bật/tắt power).
|
||||
setTimeout(() => { try { if (window.__ensureMasteringRouting) window.__ensureMasteringRouting(); } catch (e) {} }, 60);
|
||||
// KHÔNG loadSoundFont ở đây (kể cả nền): sfload SF mới bất đồng bộ làm
|
||||
// WASM heap 256MB đầy → FluidSynth stall → CÂM TOÀN CỤC (mọi âm thanh
|
||||
// chết sau khi mở tab). playNote TỰ load + retry đúng lúc note cần.
|
||||
@@ -20843,6 +20856,28 @@ const App = () => {
|
||||
}
|
||||
};
|
||||
const updateSfRoutingRef = useRef(null);
|
||||
// ── Đồng bộ mastering + routing NGAY TRƯỚC KHI PREVIEW (keybed/draw/MIDI file) ──
|
||||
// Bug: preview instrument soundfont với MIDI keyboard KHÔNG tự động đi qua
|
||||
// mastering FX của main out — phải bật/tắt nút power mới có tác dụng. Nguyên
|
||||
// nhân: routing SF (setOutputDestination + sfRouteGain/sfDryGain) và graph
|
||||
// mastering chỉ được đồng bộ khi masteringSettings ĐỔI (toggle power), không
|
||||
// chạy khi bắt đầu preview. Hàm này ép đồng bộ 3 lớp (graph theo trạng thái
|
||||
// hiện tại — early-return nếu đã đúng; tham số module; route SF + route
|
||||
// gains) — gọi tại mọi điểm preview → âm preview LUÔN qua mastering khi bật.
|
||||
const ensureMasteringRouting = () => {
|
||||
try {
|
||||
const _s = window.currentMasteringSettings;
|
||||
if (!_s || !masterBus || !audioCtx) return;
|
||||
toggleMasteringOnMaster(!!_s.masterConnected, !!_s.isBypassed);
|
||||
applyMasteringSettings(_s);
|
||||
updateSfRouting();
|
||||
} catch (e) {
|
||||
console.warn('ensureMasteringRouting error:', e);
|
||||
}
|
||||
};
|
||||
const ensureMasteringRoutingRef = useRef(null);
|
||||
ensureMasteringRoutingRef.current = ensureMasteringRouting;
|
||||
window.__ensureMasteringRouting = ensureMasteringRouting;
|
||||
// ── MIDI preview cache (bounce nhanh offline) ──
|
||||
// Khi preview: capture tiếng đàn (SF output — pre track-FX) vào cache theo
|
||||
// track. Khi export: nếu cache đủ độ dài → render OFFLINE NHANH bằng cache
|
||||
|
||||
Reference in New Issue
Block a user