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
+21
View File
@@ -2,6 +2,8 @@
#ifndef RENDER_FX_JOB_H
#define RENDER_FX_JOB_H
#include <cstdint>
#include <memory>
#include <string>
// Offline FX render mode (Phase 0 of PLAN_MASTERBUS_FX_RACK_VST.md):
@@ -53,4 +55,23 @@ int run_open_fx_gui(const std::string& jobPath);
// --open-fx-gui.
int run_fx_gui_server(const std::string& jobPath);
// Realtime FX chain (T2.4): live VST3 audio effects on the bridge master mix.
// setChain() is async (a worker thread loads the plugins and swaps the chain);
// process() runs ONLY on the audio thread; shutdown() joins the worker and must
// be called before CoUninitialize. v1: master chain only (per-track deferred).
class RealtimeFxChain {
public:
RealtimeFxChain();
~RealtimeFxChain();
// JSON: [{"path":"...","bypass":true|false},...] — chain entries replace
// the previous chain atomically. May be called from any thread.
void setChain(const std::string& json, double sampleRate, int32_t blockSize);
// Audio thread only: run the chain in-place over one stereo block.
void process(float* inL, float* inR, uint32_t n);
void shutdown();
private:
struct Impl;
std::unique_ptr<Impl> impl_;
};
#endif // RENDER_FX_JOB_H