fix: VST2 qua jbridge bị tạch tạch — pace child theo consumer-sync + bridge copy full block
Root cause: child plugin_host render ~50x real-time (9323 blocks/s), bridge đọc slot đang bị child ghi đè (torn read) và mỗi segment của 1 DAW block đọc từ nhiều child block khác nhau -> discontinuity -> tạch thay vì âm thật. - SandboxHostIPC: thêm bridgeConsumed[2] cuối struct (append-only, offsets cũ giữ nguyên) — child đếm publish/slot, bridge đếm consume/slot. - plugin_host_main.cpp: sau khi publish 1 block, chờ bridge consume xong block đó mới render block kế (wait-sau-publish, không phải wait-trước- render — wait-trước vẫn cho phép publish 2 block liên tiếp giữa 2 lần consume -> bridge đọc latest sẽ bỏ block). Child giờ publish đúng 1 block/DAW block = real-time; bridge không bao giờ stall (main loop DAW render + pace mọi iteration) nên không deadlock; nếu bridge chết, parent_alive break wait. - SandboxVst2Host: copy full 256 mẫu vào local buffer khi slot đổi, serve mọi segment của 1 DAW block từ 1 child block nhất quán. Verify: child pace 371 blocks/2s (real-time 375, trước 18647); domFreq của waveform = 257.8Hz đúng nốt C4 (note 60) — âm thật, không phải noise; correlation giữa các block liên tiếp âm đều ~-0.4 (waveform tuần hoàn); GUI open path không deadlock (pace vẫn real-time, jBridge dialog + Qin_VST_ Window hiện đủ); GUI đóng -> child idle delta 0; silence_all master peak 0.000016.
This commit is contained in:
@@ -103,6 +103,13 @@ struct SandboxHostIPC {
|
||||
volatile uint32_t presetInLen; // >0: pending; child applies + zeroes
|
||||
char presetOut[PRESET_BLOB_SIZE]; // child -> bridge (base64 text)
|
||||
volatile uint32_t presetOutLen; // 0 = none published yet
|
||||
// G4.7: consumer-sync pacing. The unpaced child renders ~50x real-time and
|
||||
// overwrites the slot the bridge is reading (torn audio -> "tạch tạch").
|
||||
// Child increments a publish count per slot; bridge increments the consume
|
||||
// count when it copies a slot. The child waits after each publish until the
|
||||
// bridge consumed it, so it publishes exactly one block per DAW block.
|
||||
// Append-only: keep at the END, offsets above stay stable.
|
||||
volatile uint32_t bridgeConsumed[2]; // bridge -> child: consume count per slot
|
||||
};
|
||||
|
||||
// Shared-memory helpers (impl in SharedMemoryIPC.cpp).
|
||||
|
||||
Reference in New Issue
Block a user