Files

59 lines
2.1 KiB
C++

// native_bridge/include/SandboxVst3Host.h
// G4.2: VST3 instrument hosted in a CHILD PROCESS (plugin_host.exe). The
// plugin's crash kills only the child; this host mutes the channel, respawns
// the child, and the bridge + other channels keep running. MIDI flows bridge
// -> child SHM (midiQueue), audio flows child -> bridge (masterLeft/Right).
#ifndef SANDBOX_VST3_HOST_H
#define SANDBOX_VST3_HOST_H
#include "INativeInstrument.h"
#include "SharedMemoryIPC.h"
#include <atomic>
#include <string>
#include <thread>
#ifdef _WIN32
#include <windows.h>
#endif
class SandboxVst3Host : public INativeInstrument {
public:
SandboxVst3Host();
~SandboxVst3Host() override;
bool loadPlugin(const std::string& path, double sampleRate, uint32_t channel);
bool init(double sampleRate, uint32_t maxBlockSize) override;
void selectProgram(uint32_t channel, uint32_t bank, uint32_t program) override {}
void noteOn(uint32_t channel, uint32_t pitch, float velocity, uint32_t sampleOffset) override;
void noteOff(uint32_t channel, uint32_t pitch, uint32_t sampleOffset) override;
void controlChange(uint32_t channel, uint32_t cc, uint32_t value) override;
void programChange(uint32_t channel, uint32_t program) override;
void pitchBend(uint32_t channel, uint32_t bend14) override;
// The child owns its GUI window (plugin_host opens it on its main thread).
bool openGUI(void* parentWindowHandle) override { (void)parentWindowHandle; return true; }
void closeGUI() override {} // child window dies with the child process
void processAudioBlock(float* outputL, float* outputR, uint32_t numSamples) override;
private:
bool spawnChild();
void watchdogLoop();
std::string path_;
std::string shmName_;
double sampleRate_ = 44100.0;
uint32_t block_ = AUDIO_BLOCK_SIZE;
uint32_t channel_ = 0;
ShmHandle* shm_ = nullptr;
SandboxHostIPC* ipc_ = nullptr;
std::atomic<bool> alive_{false};
std::atomic<bool> stop_{false};
std::thread watchdog_;
#ifdef _WIN32
HANDLE childProc_ = nullptr;
#endif
};
#endif // SANDBOX_VST3_HOST_H