refactor(bridge): split fx bridge, stabilize VST3 host chain, drop old install engines

- remove diagnostic canaries from audio hot path (crackle fix) and
  stuck C5 note raw-MIDI test (Vst2Instrument::init noteOff)
- split native bridge into daw_vst_bridge (VSTi) + fx_vst_bridge (VST FX)
- VST3: processData prepare before setActive, zero input buses, accept
  both .vstpreset and bridge-state blob in RenderJob presets
- native_render/vst_engine: bridge-exe discovery + render_fx_chain + /fx-gui
- delete old install/ engine binaries (install via sidecar+resources now)
- add BUILD_LAYOUT.md, build_selfcheck, tools/ diagnostics
This commit is contained in:
2026-08-20 09:42:42 +07:00
parent 5df96aef1e
commit 7c22ae1f02
42 changed files with 2363 additions and 210 deletions
+2 -37
View File
@@ -24,7 +24,6 @@
#include <thread>
#include <chrono>
#ifdef _WIN32
#include <malloc.h> // _heapchk (TEMP diag)
#endif
// -----------------------------------------------------------------
@@ -438,9 +437,8 @@ void InstrumentEngineManager::allNotesOff() {
// audio buffers; plain std::vector is only 16B-aligned. Over-allocate and
// align the pointer handed to plugins to 64B.
static float* alignF(std::vector<float>& v, size_t n) {
// 64B-aligned pointer can sit up to 63B into the allocation; TEMP diag:
// huge tail so we can measure how far DUNE writes past n.
const size_t kTail = 2097152 + 64;
// 64B-aligned pointer can sit up to 63B into the allocation.
const size_t kTail = 64;
if (v.size() < n + kTail) v.assign(n + kTail, 0.0f);
uintptr_t a = reinterpret_cast<uintptr_t>(v.data());
return reinterpret_cast<float*>((a + 63) & ~(uintptr_t)63);
@@ -562,17 +560,6 @@ void InstrumentEngineManager::renderAll(float* outputL, float* outputR, uint32_t
if (channelQuiet(ch)) continue; // editor open / crashed: do not process
float* spL = alignF(scratchL_, numSamples);
float* spR = alignF(scratchR_, numSamples);
std::cerr << "[NativeBridge][diag] renderAll ch=" << ch << " n=" << numSamples
<< " spL=0x" << std::hex << (uintptr_t)spL
<< " spR=0x" << (uintptr_t)spR
<< " capL=" << std::dec << scratchL_.size()
<< " capR=" << scratchR_.size() << std::endl;
// TEMP diag: fill canary with a NaN pattern so writes of 0.0 (silence)
// are still detected.
for (uint32_t i = 0; i < numSamples + 2097152; ++i) {
spL[i] = 0x7FC00000u; // quiet NaN
spR[i] = 0x7FC00000u;
}
#ifdef _WIN32
DWORD sehCode = 0;
#else
@@ -617,28 +604,6 @@ void InstrumentEngineManager::renderAll(float* outputL, float* outputR, uint32_t
}
continue;
}
// TEMP diag: plugin output-overrun canary + heap health.
{
static uint64_t diagBlock = 0; ++diagBlock;
int farL = -1, farR = -1;
for (uint32_t i = 0; i < 2097152; ++i) {
uint32_t bL, bR;
std::memcpy(&bL, &spL[numSamples + i], 4);
std::memcpy(&bR, &spR[numSamples + i], 4);
if (bL != 0x7FC00000u) farL = (int)i;
if (bR != 0x7FC00000u) farR = (int)i;
}
if (farL >= 0 || farR >= 0)
std::cerr << "[NativeBridge][diag] block " << diagBlock
<< " OUTPUT OVERRUN past n: L=" << farL
<< " R=" << farR << " (ch=" << ch << ")" << std::endl;
#ifdef _WIN32
int h = _heapchk();
if (h != _HEAPOK)
std::cerr << "[NativeBridge][diag] block " << diagBlock
<< " heap NOT OK code=" << h << std::endl;
#endif
}
// Auto-normalize: makeup calibrated (constant per-channel gain, no steps).
auto mit = makeup_.find(ch);
const float g = (mit != makeup_.end()) ? mit->second : 1.0f;