fix(bridge): VST2 host dung ABI SDK — crash outs>2, NaN input, editOpen(NULL), opcodes; docs A14 MIDI-out + phan tich Ozone -Inf

- aeffect.h: bo sung opcodes 4-22, 53, 55 + audioMaster 15/41-44 + ERect (dung chuan VST2.4 SDK, DUNE load OK khong crash)
- Vst2Instrument: cap du pointer arrays theo numInputs/numOutputs (fix AV 0xC0000005 Qin outs=32), input fill 0.0f (het NaN poison effect), bo probe effEditOpen(NULL) (crash WaveObserver), GetDirectory + SizeWindow hook, canDo sendVstEvents/sendVstTimeInfo
- TASKS.md: A14 MIDI-out tu plugin (Scaler2/Instacomposer/MelodicFlow xuat MIDI khong phai audio)
- PLAN_MASTERBUS_FX_RACK_VST.md: phan tich Ozone -Inf — chain day du, nguyen nhan = audio DAW khong chay qua bridge master ring
This commit is contained in:
2026-08-19 20:57:16 +07:00
parent 927597a822
commit 6efef85e47
9 changed files with 714 additions and 73 deletions
+19 -4
View File
@@ -1,8 +1,9 @@
// native_bridge/src/Vst2Instrument.h
// VST2 (VST 2.4, 64-bit) instrument host. Clean-room ABI header
// (native_bridge/vestige/aeffect.h) — no Steinberg SDK, no LMMS code.
// Headless: no GUI editor (openGUI returns false); preset state is kept via
// effGetChunk/effSetChunk (fxp-style chunks).
// GUI editor: supported for plugins with kEffectFlagsHasEditor (effEditOpen/
// effEditClose/effEditIdle); preset state is kept via effGetChunk/effSetChunk
// (fxp-style chunks).
#ifndef VST2_INSTRUMENT_H
#define VST2_INSTRUMENT_H
@@ -27,9 +28,11 @@ public:
void programChange(uint32_t channel, uint32_t program) override;
void pitchBend(uint32_t channel, uint32_t bend14) override;
bool openGUI(void* parentWindowHandle) override;
bool canOpenGUI() const override { return false; }
bool canOpenGUI() const override;
bool attachView(void* parentWindowHandle) override;
void closeGUI() override;
bool hasAttachedView() const override;
void guiIdle() override;
void captureState() override;
void restoreState() override;
std::string serializeState() const override;
@@ -39,19 +42,31 @@ public:
// Accessors used by the audioMaster callback (same translation unit's
// friend-ish helpers) without exposing AEffect* in the header.
double sampleRate() const { return sampleRate_; }
const std::string& pluginDir() const { return pluginDir_; }
uint32_t maxBlockSize() const { return maxBlockSize_; }
const void* effect() const; // AEffect*; null until loaded
// Host window the editor is attached to (attachView sets, closeGUI
// clears). The audioMaster SizeWindow handler moves it via the hook.
void* editorParent() const { return editorParent_; }
// Register the SizeWindow hook (main.cpp posts the resize to the UI
// worker). Probe builds never set it -> no-op.
static void setResizeHook(void (*fn)(void* hwnd, int w, int h));
private:
void* state_; // Vst2HostState* (pimpl — aeffect.h stays out of the header)
std::string path_;
std::string pluginDir_;
double sampleRate_;
uint32_t maxBlockSize_;
bool loaded_;
bool guiAttached_ = false; // effEditOpen done, not yet effEditClose'd
void* editorParent_ = nullptr; // host window the editor is a child of
uint32_t channel_ = 0;
// scratch buffers for silent plugin inputs
// scratch buffers for silent plugin inputs and extra output channels
// (plugins with numOutputs > 2 need full pointer arrays)
std::vector<float> inL_;
std::vector<float> inR_;
std::vector<float> extraOut_;
};
#endif // VST2_INSTRUMENT_H