bridge: fix Qin VST2 silent playback via per-child SHM sandbox
- out-of-process VST2 sandbox: each Qin track spawns its own plugin_host.exe child with unique SHM (SonicForge_PluginHost2_<bridgePid>_<ch>_<seq>), watchdog <=3 respawns - preset round-trip bridge<->child over SHM (presetIn/presetOut 64KB), stub rejection MIN_PRESET=100 - seed qin_default.b64 default preset into every fresh child; saved patch wins on restore - forward MIDI on channel 0 (Qin_RV only listens on ch0); one instrument per child - controls 4/5/6 = OPEN_GUI/CLOSE_GUI/QUIT - gitignore runtime carla_projects
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "Vst3Instrument.h"
|
||||
#include "Vst2Instrument.h"
|
||||
#include "SandboxVst3Host.h"
|
||||
#include "SandboxVst2Host.h"
|
||||
#endif
|
||||
|
||||
// void* members keep fluid types out of the public header; cast here.
|
||||
@@ -19,6 +20,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
@@ -181,6 +183,24 @@ void SfizzInstrument::processAudioBlock(float* outputL, float* outputR, uint32_t
|
||||
// -----------------------------------------------------------------
|
||||
// 3. MULTI-CHANNEL INSTRUMENT MANAGER (A10)
|
||||
// -----------------------------------------------------------------
|
||||
// jBridge stub detection: jBridge-wrapped VST2s (e.g. Qin_RV_x64.dll) embed
|
||||
// the string "Bridger64.dll". The bundled wrapper allows only ONE instance
|
||||
// of the same plugin per host process (2nd instance loses the shared audio
|
||||
// buffer -> silent), so these MUST run in a sandbox child (one process per
|
||||
// instance). Native VST2s (Nexus) host in-process with an embedded editor.
|
||||
static bool is_jbridge_dll(const std::string& path) {
|
||||
FILE* f = fopen(path.c_str(), "rb");
|
||||
if (!f) return false;
|
||||
std::vector<char> d;
|
||||
char tmp[16384];
|
||||
size_t n;
|
||||
while ((n = fread(tmp, 1, sizeof(tmp), f)) > 0)
|
||||
d.insert(d.end(), tmp, tmp + n);
|
||||
fclose(f);
|
||||
static const char needle[] = "Bridger64.dll";
|
||||
return std::search(d.begin(), d.end(), needle, needle + sizeof(needle) - 1) != d.end();
|
||||
}
|
||||
|
||||
std::unique_ptr<INativeInstrument> InstrumentEngineManager::create_instrument(InstrumentType type) {
|
||||
switch (type) {
|
||||
case InstrumentType::SOUNDFONT_SF2_SF3: return std::make_unique<FluidSynthInstrument>();
|
||||
@@ -211,6 +231,12 @@ bool InstrumentEngineManager::assign(uint32_t channel, InstrumentType type,
|
||||
if (channel >= 16) return false;
|
||||
auto inst = create_instrument(type);
|
||||
if (!inst) return false;
|
||||
#ifdef _WIN32
|
||||
// jBridge VST2 (Qin): sandbox in a child process - one Bridger64
|
||||
// instance per process. Native VST2 stays in-process.
|
||||
if (type == InstrumentType::VST2 && is_jbridge_dll(path))
|
||||
inst = std::make_unique<SandboxVst2Host>();
|
||||
#endif
|
||||
bool loaded = false;
|
||||
if (type == InstrumentType::SOUNDFONT_SF2_SF3)
|
||||
loaded = static_cast<FluidSynthInstrument*>(inst.get())->loadSoundFontFile(path, sampleRate);
|
||||
@@ -227,6 +253,8 @@ bool InstrumentEngineManager::assign(uint32_t channel, InstrumentType type,
|
||||
if (auto* v2 = dynamic_cast<Vst2Instrument*>(inst.get())) {
|
||||
v2->setChannel(channel);
|
||||
loaded = v2->loadPlugin(path, sampleRate);
|
||||
} else if (auto* s2 = dynamic_cast<SandboxVst2Host*>(inst.get())) {
|
||||
loaded = s2->loadPlugin(path, sampleRate, channel);
|
||||
}
|
||||
}
|
||||
if (type == InstrumentType::VST3) {
|
||||
@@ -344,7 +372,8 @@ bool InstrumentEngineManager::snapshot(BridgeStateSnapshot& out) {
|
||||
// here: mu_ is held, so the audio loop cannot be inside
|
||||
// process() on this instance while getState runs.
|
||||
i->captureState();
|
||||
e.presetBase64 = i->serializeState();
|
||||
std::string saved = i->serializeState();
|
||||
e.presetBase64 = saved.size() >= 100 ? saved : std::string();
|
||||
e.bank = i->bankOf(ch);
|
||||
e.program = i->programOf(ch);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user