Files
SonicForgeStudio/native_bridge/include/INativeInstrument.h
T
admin 6efef85e47 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
2026-08-19 20:57:16 +07:00

87 lines
4.2 KiB
C++

// native_bridge/include/INativeInstrument.h
#ifndef I_NATIVE_INSTRUMENT_H
#define I_NATIVE_INSTRUMENT_H
#include <cstdint>
#include <string>
enum class InstrumentType {
VST3,
VST2,
SOUNDFONT_SF2_SF3,
SFZ
};
class INativeInstrument {
public:
virtual ~INativeInstrument() = default;
// Initialize Engine with Sample Rate and Buffer Size
virtual bool init(double sampleRate, uint32_t maxBlockSize) = 0;
// Select Bank and Program Change
virtual void selectProgram(uint32_t channel, uint32_t bank, uint32_t program) = 0;
// Dispatch MIDI Note On / Note Off events
virtual void noteOn(uint32_t channel, uint32_t pitch, float velocity, uint32_t sampleOffset) = 0;
virtual void noteOff(uint32_t channel, uint32_t pitch, uint32_t sampleOffset) = 0;
// MIDI continuous controllers (A12): CC value, program change, 14-bit pitch bend
virtual void controlChange(uint32_t channel, uint32_t cc, uint32_t value) = 0;
virtual void programChange(uint32_t channel, uint32_t program) = 0;
virtual void pitchBend(uint32_t channel, uint32_t bend14) = 0;
// Open/close Native GUI window
virtual bool openGUI(void* parentWindowHandle) = 0;
// Headless engines (VST2 without an editor, SF2/SFZ): the bridge must
// not create/reuse a window for them.
virtual bool canOpenGUI() const { return true; }
virtual void closeGUI() = 0;
// VST3 reopen-after-close: the bridge checks before openGUI whether the
// instance must be rebuilt; while it is, the engine sets reloading=true
// and the real-time loop skips processAudioBlock (teardown must not race
// the audio thread — a reload terminates the VST while renderAll may be
// inside processAudioBlock on the same instance).
virtual bool needsReload() const { return false; }
virtual void setReloading(bool /*on*/) {}
// VST3: rebuild the plugin instance (terminate + loadPlugin) on the owning
// apartment thread. The bridge calls it after tearing an editor down so the
// audio loop never processes an instance whose editor was dropped without
// view->removed(). Non-VST engines: no-op.
virtual bool reload() { return true; }
// VST3: split openGUI so instance teardown/reload runs on the owning
// apartment thread while view->attached() may run on a temporary thread
// with the channel worker pumping messages (see bridge main.cpp).
virtual bool reloadForGUI() { return true; }
virtual bool attachView(void* /*parentWindowHandle*/) { return false; }
virtual void resizeView(int /*w*/, int /*h*/) {}
// Periodic idle tick for attached editors (VST2 effEditIdle repaints;
// others: no-op). Called on the UI worker's pump loop.
virtual void guiIdle() {}
// True while the editor view is attached (GUI window open). The bridge uses
// it to dedupe repeated OPEN_GUI (frontend retry spam) — re-attaching a
// view that is already attached corrupts plugins (Nexus createView→null).
virtual bool hasAttachedView() const { return false; }
// G0.4: serialize/restore the plugin preset across instance reloads
// (GUI close/reopen). Non-VST engines: no-op (nothing to save).
virtual void captureState() {}
virtual void restoreState() {}
// G2.1: serialize the current preset to a portable string for the state
// file (VST3: base64 of captured component+controller state). Caller must
// call captureState() first (VST3 buffers are refreshed there). Non-VST
// engines: empty.
virtual std::string serializeState() const { return std::string(); }
// G2.3: replace the preset with a previously serialized one (VST3:
// base64 of [4B BE compLen][component][4B BE ctrlLen][controller]).
// Must be called after the instrument is loaded. Non-VST: no-op.
virtual void loadSerializedState(const std::string& /*base64*/) {}
// G2.1: last bank/program for a MIDI channel (SF2/SF3). Others: 0.
virtual uint32_t bankOf(uint32_t channel) const { return 0; }
virtual uint32_t programOf(uint32_t channel) const { return 0; }
// Real-time Audio PCM Float32 rendering loop
virtual void processAudioBlock(float* outputL, float* outputR, uint32_t numSamples) = 0;
};
#endif // I_NATIVE_INSTRUMENT_H