diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index 2e7b752..56e645d 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -15632,11 +15632,11 @@ const App = () => { } // Requirement 2: chọn VST3 qua nút Synth → load xong mở native GUI // (C++ attach editor vào cửa sổ bridge tự tạo — control type=4, hwnd=0). - // SF→VSTi BUG 2026-08-13: GUI mở → C++ mute channel tới khi đóng GUI → - // đang play thì âm tắt ngay (reloading_=true, note-on drop). Khi đang - // play chỉ load instrument im lặng; GUI mở qua nút GUI riêng - // (ensureAndOpenVstGui) — không tự mở giữa lúc phát. - if (ok && btype === 'VST3' && !isPlayingRef.current && window.NativeBridgeService.openNativeGUI) { + // LEVEL-1 (2026-08-15): mở GUI ngay cả khi đang play. C++ đã bỏ defer + // transport STOP; setReloading trước job (G0.1b) + 1 UiThread (G1.2) + // chặn race 2 thread 1 DLL. Mute ngắn ~0.1-0.3s lần đầu, note đang + // ngân không mất. Reopen sau khi đóng vẫn mute 1-3s (reload) — level 2. + if (ok && btype === 'VST3' && window.NativeBridgeService.openNativeGUI) { try { await openVstGuiRetry(instrumentId, bch, 20); } catch (e) {} } } diff --git a/app/static/js/app.precompiled.js b/app/static/js/app.precompiled.js index 1fa151f..045e81f 100644 --- a/app/static/js/app.precompiled.js +++ b/app/static/js/app.precompiled.js @@ -823,11 +823,11 @@ if(isSf&&window.__bridgeLoadedChannels)delete window.__bridgeLoadedChannels[bch] // phải gửi lại program change để ra ĐÚNG instrument. if(ok&&window.__bridgeLastProgram){const _pfx=trackId+':';Object.keys(window.__bridgeLastProgram).forEach(k=>{if(k.indexOf(_pfx)===0)delete window.__bridgeLastProgram[k];});}if(ok){if(!window.__bridgeLoadedChannels)window.__bridgeLoadedChannels={};window.__bridgeLoadedChannels[bch]=true;}if(ok&&btype==='VST3'&&p){try{if(!window.__bridgePluginPaths)window.__bridgePluginPaths={};window.__bridgePluginPaths[instrumentId]=p;updateActiveTracks(prev=>prev.map(t=>t.id===trackId?{...t,synth_engine:{...(t.synth_engine||{}),plugin_path:p}}:t));}catch(e){}}// Requirement 2: chọn VST3 qua nút Synth → load xong mở native GUI // (C++ attach editor vào cửa sổ bridge tự tạo — control type=4, hwnd=0). -// SF→VSTi BUG 2026-08-13: GUI mở → C++ mute channel tới khi đóng GUI → -// đang play thì âm tắt ngay (reloading_=true, note-on drop). Khi đang -// play chỉ load instrument im lặng; GUI mở qua nút GUI riêng -// (ensureAndOpenVstGui) — không tự mở giữa lúc phát. -if(ok&&btype==='VST3'&&!isPlayingRef.current&&window.NativeBridgeService.openNativeGUI){try{await openVstGuiRetry(instrumentId,bch,20);}catch(e){}}}})();};const setTrackInstrumentWithProgram=(trackId,instrumentId,programNumber,displayName,bankNumber)=>{const isSfInstrument=instrumentId&&typeof instrumentId==='string'&&instrumentId.startsWith('sf_');const sfBank=bankNumber!==undefined?bankNumber:isSfInstrument?0:undefined;const sfProg=programNumber!==undefined?programNumber:undefined;var mt=activeTracksRef.current||tracks;var curTrk=null;for(var ci=0;ci{const isSfInstrument=instrumentId&&typeof instrumentId==='string'&&instrumentId.startsWith('sf_');const sfBank=bankNumber!==undefined?bankNumber:isSfInstrument?0:undefined;const sfProg=programNumber!==undefined?programNumber:undefined;var mt=activeTracksRef.current||tracks;var curTrk=null;for(var ci=0;ciprev.map(t=>{if(t.id!==trackId)return t;const hasInstrument=!!instrumentId;const instrType=isSfInstrument?'soundfont':hasInstrument?'vst3':'default';const synthEngine=hasInstrument?{type:instrType,plugin_id:instrumentId,soundfont_bank:sfBank!==undefined?sfBank:0,soundfont_program:sfProg!==undefined?sfProg:0,soundfont_id:isSfInstrument?instrumentId.replace('sf_',''):''}:undefined;return{...t,midiChannel:mch,instrumentId,instrumentProgram:sfProg,instrumentName:displayName,soundfont_bank:sfBank,soundfont_program:sfProg,synth_engine:synthEngine,type:hasInstrument?'MIDI':t.type==='MIDI'?'audio':t.type};}));setInstrumentDropdownTrackId(null);setInstrumentDropdownBtnRect(null);setSynthCategory(null);// Trigger FluidSynth load + program change when soundfont instrument selected diff --git a/install/daw_vst_bridge.exe b/install/daw_vst_bridge.exe index d0b4ed2..b7a29f3 100644 Binary files a/install/daw_vst_bridge.exe and b/install/daw_vst_bridge.exe differ diff --git a/native_bridge/src/main.cpp b/native_bridge/src/main.cpp index 7fc729d..90cc25a 100644 --- a/native_bridge/src/main.cpp +++ b/native_bridge/src/main.cpp @@ -796,19 +796,14 @@ int main(int argc, char* argv[]) { })) { return; } - // G0.1 (BUG_REPORT): mo GUI khi dang PLAY -> attachView chay tren worker - // thread trong luc audio loop process() cung DLL (2 thread 1 plugin) -> - // Nexus throw (createView/attached) -> GUI khong load + retry spam -> - // stall 3s -> watchdog kill bridge -> mat het instrument -> cam. Defer - // OPEN_GUI toi khi transport STOP (sweep duoi fulfill khi loaded && - // transportStopped). Khong doi: tranh mat am; user STOP la GUI tu mo. - if (!transportStopped) { - std::cerr << "[NativeBridge] GUI deferred ch=" << guiCh - << " plugin=" << pluginId << " (transport PLAY) - queued" << std::endl; - std::lock_guard lock(g_pendingGuiMutex); - g_pendingGui[guiCh] = { (void*)arg1, pluginId }; - return; - } + // G0.1 (historical): mo GUI khi dang PLAY bi defer toi khi STOP vi 2 + // thread 1 plugin (audio loop process + attach worker) -> Nexus throw. + // LEVEL-1 (2026-08-15): bo defer. G0.1b (setReloading tren MAIN thread + // truoc job, o duoi) da silence same-path channels va G1.2 (1 UiThread, + // audio loop khong pump window messages) chan race 2 thread 1 DLL. + // GUI mo ngay khi play; mute ngan (~0.1-0.3s lan dau: hasAttachedOnce_ + // false nen reloadForGUI khong reload, Vst3Instrument.cpp 688). Note + // dang ngan khong mat. Reopen sau khi dong VAN reload (1-3s mute). // G1.2: window + attach chay tren UiThread (1 thread chung, COM STA + // message pump + job queue). Window messages do UiThread pump dispatch — // audio loop khong con PeekMessageW (xoa block pump o main loop).