Fix bypass JSON bool + load SF2 tracks into bridge on restore

- RenderFxJob: parse bypass as JSON bool (memberBool) — bypass:true
  previously ignored (memberInt parses numbers only), plugin kept
  processing. Verified: bypass RMS == plain, VST3 loaded once.
- preloadTrackInstruments / bridge reconnect: load SF2 instruments
  into bridge too (loadAnyTrackToBridge) — opened projects with SF2
  tracks sent MIDI to empty bridge channels (C++ silent), never
  reaching the native mastering chain.
- rebuild app.precompiled.js from app.jsx (was stale: missing A14).
This commit is contained in:
2026-08-19 21:55:48 +07:00
parent 51f12113fa
commit 819257a1b3
3 changed files with 51 additions and 10 deletions
+34 -4
View File
@@ -6610,6 +6610,36 @@ const loadVstToBridge = async (track) => {
return !!ok;
} catch (e) { console.warn('[Bridge] loadVstToBridge fail:', track.id, e); return false; }
};
// D12: load track instrument (VST *hoặc* SF2) vào bridge. preloadTrackInstruments
// trước đây chỉ load VST → mở project có SF2 track + bridge active → MIDI tới
// channel bridge rỗng → C++ silent (không qua mastering chain native).
const loadAnyTrackToBridge = async (track) => {
if (!window.NativeBridgeService || !window.SonicMidiRouter || !window.SonicMidiRouter.isBridgeActive()) return false;
const inst = track.instrumentId || (track.synth_engine && track.synth_engine.plugin_id);
if (!inst) return false;
if (typeof inst === 'string' && inst.startsWith('sf_')) {
const se = track.synth_engine || {};
const bank = se.soundfont_bank !== undefined ? se.soundfont_bank : (track.soundfont_bank !== undefined ? track.soundfont_bank : 0);
const bch = window.SonicMidiRouter.allocateChannel(track.id || track.trackId, bank === 128);
try {
const sfId = inst.replace('sf_', '');
let bpath = null;
try {
const pl = await window.SonicAPI.listPlugins();
const s0 = ((pl && pl.soundfonts) || []).find(s => String(s.id).replace('sf_', '') === sfId);
bpath = s0 && (s0.file || s0.path);
} catch (e) {}
const r = await window.SonicAPI.bridgeLoad({ name: inst, path: bpath || null, instrumentType: 'SF2', channel: bch });
const p = r && r.path ? r.path : null;
if (!p) { console.warn('[Bridge] SF2 resolve fail:', track.id, inst); return false; }
const ok = await window.NativeBridgeService.loadInstrument(p, 'SF2', bch);
if (ok) { if (!window.__bridgeLoadedChannels) window.__bridgeLoadedChannels = {}; window.__bridgeLoadedChannels[bch] = true; if (!window.__bridgeLoadedPaths) window.__bridgeLoadedPaths = {}; window.__bridgeLoadedPaths[bch] = p; }
console.log('[Bridge] preload SF2 track', track.id, '-> ch', bch, ok ? 'OK' : 'FAIL', p);
return !!ok;
} catch (e) { console.warn('[Bridge] preload SF2 fail:', track.id, e); return false; }
}
try { return await loadVstToBridge(track); } catch (e) { return false; }
};
const ensureAndOpenVstGui = async (track) => {
const trackId = track.id || track.trackId;
const instrumentId = track.instrumentId || (track.synth_engine && track.synth_engine.plugin_id);
@@ -6730,8 +6760,8 @@ const preloadTrackInstruments = async (tracks) => {
for (let i = 0; i < list.length; i++) {
const t = list[i];
const inst = t.instrumentId || (t.synth_engine && t.synth_engine.plugin_id);
if (!inst || (typeof inst === 'string' && inst.startsWith('sf_'))) continue;
try { await loadVstToBridge(t); } catch (e) {}
if (!inst) continue;
try { await loadAnyTrackToBridge(t); } catch (e) {}
}
}
};
@@ -18136,8 +18166,8 @@ const App = () => {
for (let i = 0; i < _tl.length; i++) {
const _t = _tl[i];
const _inst = _t.instrumentId || (_t.synth_engine && _t.synth_engine.plugin_id);
if (!_inst || (typeof _inst === 'string' && _inst.startsWith('sf_'))) continue;
loadVstToBridge(_t).catch(function () {});
if (!_inst) continue;
loadAnyTrackToBridge(_t).catch(function () {});
}
} catch (e) { console.warn('[Bridge] reconnect reload fail:', e); }
});
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1104,7 +1104,7 @@ std::shared_ptr<RealtimeFxChain::Impl::Chain> RealtimeFxChain::Impl::buildChain(
const std::string path = memberString(o, "path", "");
if (path.empty()) continue;
Entry ent;
ent.bypass = memberInt(o, "bypass", 0) != 0;
ent.bypass = memberBool(o, "bypass", false);
if (!ent.bypass) {
auto fx = std::make_shared<Vst3Fx>();
if (fx->load(path, sampleRate_, blockSize_)) {