feat(native): realtime master FX chain + fx-gui fast start, hide/show, non-topmost

- FxGuiServer: HWND_TOP (no longer always-on-top), /hide + /show endpoints,
  onStarted callback prints SF_FXGUI_PORT before plugin load (fast connect)
- RenderFxJob: RealtimeFxChain (mutex+worker, SEH-guarded, bypass slots,
  deferred Vst3Fx dtor); --fx-gui split into parse/create/load-attach stages
- main: FreeConsole unless SF_KEEP_CONSOLE; control type 6 SET_FX_CHAIN feeds
  g_fxChain on the audio loop; shutdown before CoUninitialize
- plugins.py: CREATE_NO_WINDOW on both Popen paths
- lib.rs: set_fx_chain command -> push_control(6)
- app.jsx/nativeBridgeService: setFxChain sync from MasteringModal; panel close
  uses /hide + refs to fix closure bug; VstGuiEmbed rect refresh -> /show
This commit is contained in:
2026-08-19 09:59:13 +07:00
parent c6de0720f4
commit da0f8fa40e
11 changed files with 391 additions and 40 deletions
+14
View File
@@ -292,6 +292,7 @@ pub fn run() {
open_vst_gui,
bridge_status,
transport_control,
set_fx_chain,
restart_bridge_with_sample_rate
])
.setup(|app| {
@@ -857,6 +858,19 @@ fn transport_control(app: AppHandle, kind: String, playhead: Option<u32>) -> Res
.ok_or_else(|| "control queue full".to_string())
}
#[tauri::command]
fn set_fx_chain(app: AppHandle, chain_json: String) -> Result<(), String> {
if chain_json.len() >= shm::CONTROL_PATH_MAX {
return Err("fx chain JSON too large".to_string());
}
let state = app.state::<ShmState>();
let guard = state.0.lock().map_err(|e| e.to_string())?;
let shm = guard.as_ref().ok_or("bridge shm unavailable")?;
shm.push_control(6, 0, 0, 0, &chain_json)
.then_some(())
.ok_or_else(|| "control queue full".to_string())
}
#[tauri::command]
fn restart_bridge_with_sample_rate(app: AppHandle, sample_rate: u32) -> Result<(), String> {
println!("restart_bridge_with_sample_rate: {}", sample_rate);