fix(bridge): đồng đều âm lượng VSTi jbridge, GUI native lên top, modal instrument lọc FX

- calibrate: probe sandbox (jbridge) theo real-time pacing — child render qua SHM
  consumer-sync, probe µs-speed chỉ đo được silence/attack → makeup=1.0 mọi channel.
  Thêm virtual probeNeedsRealtime() (SandboxVst2Host → true), calibrate() Sleep
  ~1 block/5.8ms để child kịp nhận MIDI + render steady-state → makeup đo peak thật
  (3 channel Qin ≈ 2.6, trước đây = 1.0 → âm lượng đồng đều giữa các track/VSTi).
- OPEN_GUI: SetWindowPos(HWND_TOPMOST) + SetForegroundWindow + BringWindowToTop
  → GUI VSTi hiển thị ở top window, tương tác ngay.
- /api/v1/plugins/available: filter vst_instruments + extra theo is_fx của
  fx_vst_bridge --scan (trước merge entry) — modal Select Instrument chỉ còn
  soundfont + VSTi, không hiện VST FX (90 → 33).
This commit is contained in:
2026-08-21 10:18:25 +07:00
parent da7ae02509
commit d7756b08ab
6 changed files with 41 additions and 2 deletions
@@ -556,6 +556,11 @@ float InstrumentEngineManager::calibrate(INativeInstrument* inst, double sampleR
const uint32_t bs = blockSize ? blockSize : 512;
const uint32_t body = (uint32_t)(sampleRate * 0.6);
const uint32_t tail = (uint32_t)(sampleRate * 0.25);
// Sandbox hosts render through a child process at consumer pace: consume
// one block per real-time block (~5.8ms @256/44.1k) so the child wakes
// from its idle Sleep(15), picks up the probe notes and renders steady
// state. Direct engines: no pacing (probe finishes in µs).
const bool realtime = inst->probeNeedsRealtime();
std::vector<float> L(bs + 64, 0.0f), R(bs + 64, 0.0f);
const int pitches[3] = { 60, 64, 67 };
float peak = 0.0f;
@@ -578,6 +583,7 @@ float InstrumentEngineManager::calibrate(INativeInstrument* inst, double sampleR
while (off < body) {
uint32_t n = bs; if (off + n > body) n = body - off;
if (!renderProbe(n)) { inst->noteOff(0, (uint32_t)p, 0); return 1.0f; }
if (realtime) Sleep((DWORD)(n * 1000.0 / sampleRate + 0.5));
off += n;
}
inst->noteOff(0, (uint32_t)p, 0);
@@ -585,6 +591,7 @@ float InstrumentEngineManager::calibrate(INativeInstrument* inst, double sampleR
while (off < tail) {
uint32_t n = bs; if (off + n > tail) n = tail - off;
if (!renderProbe(n)) return 1.0f;
if (realtime) Sleep((DWORD)(n * 1000.0 / sampleRate + 0.5));
off += n;
}
}