// native_bridge/include/RenderFxJob.h #ifndef RENDER_FX_JOB_H #define RENDER_FX_JOB_H #include #include #include // Offline FX render mode (Phase 0 of PLAN_MASTERBUS_FX_RACK_VST.md): // `daw_vst_bridge --render-fx --in --out ` // reads a stereo WAV, runs the input through a chain of VST3 audio effects // (audio-in/audio-out, NO MIDI) plus builtin DSP (gain/normalize), and writes // a 16-bit stereo WAV. Same exit-code contract as --render: 0 ok, 1 job/argument // error, 2 plugin load failure, 3 plugin crashed mid-render (SEH guarded). // // job.json: { sample_rate, block_size?, // fx_chain: [ // { type: "vst3", path, preset_b64?, bypass? }, // { type: "builtin", id: "gain", params: { db } }, // { type: "builtin", id: "normalize", params: { peak } } // ] } // vst3: path = .vst3 module; preset_b64 = base64 of a .vstpreset FILE (raw // SDK chunk format) or of the bridge state blob — both applied via // setState before processing. bypass=true → slot skipped (passthrough). // gain: multiply by 10^(db/20), block-wise. // normalize: post-chain global pass — scale down to peak (0.95) only when // the peak EXCEEDS it (mirrors render_project's clip guard). int run_render_fx_job(const std::string& jobPath, const std::string& inPath, const std::string& outPath); // Plugin scan mode (Phase 1): `daw_vst_bridge --scan ` walks // recursively, loads every .vst3 module and classifies its classes // (kVstAudioEffectClass without "Instrument" subcategory → effect, else // instrument), and prints JSON to stdout: // {"plugins":[{"path":"...","name":"...","is_fx":true,"is_instrument":false,"type":"VST3"}]} // .dll/.so (VST2) cannot be introspected headlessly → classified as instrument. // Returns 0 on success, non-zero on unrecoverable error (a single plugin that // crashes the module loader is skipped, not fatal). int run_scan_dir(const std::string& dirPath); // GUI mode (Mastering/FX Rack → "mở VST GUI"): `daw_vst_bridge --open-fx-gui // ` loads ONE VST3 effect plugin, opens its native editor window and // runs a message loop until the user closes the window (WM_DESTROY), then // detaches the view and exits 0. job.json: { "path": "...", "name": "..." }. // Windows only. Exit codes: 0 ok, 1 job/argument error, 2 plugin load or // editor attach failure. int run_open_fx_gui(const std::string& jobPath); // Embedded GUI server mode (Phase 0 of PLAN_MASTERBUS_VST_GUI_EMBED.md): // `daw_vst_bridge --fx-gui ` — same plugin load + editor attach as // --open-fx-gui but the host window is parked off-screen and a tiny HTTP // server (FxGuiServer.cpp) serves JPEG frames (GET /frame) and relays pointer/ // key input (POST /input) so the web UI can embed the native GUI in a panel. // Prints `SF_FXGUI_PORT=` to stdout. Windows only. Exit codes same as // --open-fx-gui. int run_fx_gui_server(const std::string& jobPath); // Capture the GUI plugin's current state (component + controller) as base64 // of the bridge blob [4B BE compLen][comp][4B BE ctrlLen][ctrl] - the same // format applyPreset accepts. Runs on the GUI pump thread; blocks up to // timeoutMs. outB64 stays empty on timeout or when the plugin has no state. void fxGuiRequestCapture(void* hwnd, std::string& outB64, int timeoutMs); // 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_; }; #endif // RENDER_FX_JOB_H // Realtime SHM FX loop (fx_vst_bridge --realtime-fx): engine (Python) tạo // mapping FxRealtimeIPC, bridge mở, đọc input ring, xử lý qua RealtimeFxChain, // ghi output ring. Thoát khi running==0 hoặc parent chết. int run_realtime_fx_loop(const std::string& jobPath, const std::string& shmName, uint32_t parentPid);