fix(fx-gui): meter VST chạy đúng — bỏ điều kiện inRead chặn peek + chống race lúc load + ẩn cửa sổ native floating
This commit is contained in:
@@ -1433,12 +1433,14 @@ static void fxGuiFeedLoop(Vst3Fx* fx, HWND hwnd, std::shared_ptr<FxGuiShmCtl> ct
|
||||
if (name != curName) {
|
||||
if (v) { fxGuiCloseShm(v); v = nullptr; ipc = nullptr; }
|
||||
curName = name;
|
||||
if (!name.empty()) v = fxGuiOpenShm(name, sizeof(FxRealtimeIPC));
|
||||
ipc = v ? static_cast<FxRealtimeIPC*>(v->view) : nullptr;
|
||||
lastWrite = 0; // session (re)start -> re-anchor
|
||||
}
|
||||
if (!v && !name.empty()) { // retry open each pass: mapping may appear late
|
||||
v = fxGuiOpenShm(name, sizeof(FxRealtimeIPC));
|
||||
ipc = v ? static_cast<FxRealtimeIPC*>(v->view) : nullptr;
|
||||
}
|
||||
if (ipc && ipc->h.magic == FXRT_MAGIC &&
|
||||
ipc->h.inWrite > lastWrite && ipc->h.inWrite > ipc->h.inRead) {
|
||||
ipc->h.inWrite > lastWrite) {
|
||||
if (ipc->h.inSlots == FXRT_IN_SLOTS && ipc->h.blockSize == FXRT_BLOCK) {
|
||||
const uint32_t slot = (ipc->h.inWrite - 1) & (ipc->h.inSlots - 1);
|
||||
float L[FXRT_BLOCK], R[FXRT_BLOCK], oL[FXRT_BLOCK], oR[FXRT_BLOCK];
|
||||
@@ -1453,15 +1455,21 @@ static void fxGuiFeedLoop(Vst3Fx* fx, HWND hwnd, std::shared_ptr<FxGuiShmCtl> ct
|
||||
if (v) fxGuiCloseShm(v);
|
||||
}
|
||||
|
||||
// Detached feeder thread. initialShm may be "" — the frontend pushes the
|
||||
// live session name later via /shm once the realtime session is up.
|
||||
static void fxGuiStartAudioFeeder(Vst3Fx* fx, HWND hwnd, const std::string& initialShm) {
|
||||
// Split feeder setup: fxGuiShmSetName runs EARLY (before the server loop) so
|
||||
// /shm pushes from the frontend are not lost, while the detached thread starts
|
||||
// only AFTER load+attach succeeded — a feeder calling processAudio() mid-load
|
||||
// can crash/corrupt a heavy plugin and break the editor attach.
|
||||
// ponytail: feeder feeds the raw live pre-chain mix; add a separate audio path
|
||||
// if GUI processing of the full insert chain is wanted later.
|
||||
static void fxGuiShmSetName(const std::string& initialShm) {
|
||||
auto p = fxGuiShmCtlRef();
|
||||
if (!p) { p = std::make_shared<FxGuiShmCtl>(); fxGuiShmCtlRef() = p; }
|
||||
std::lock_guard<std::mutex> lk(p->m);
|
||||
p->name = initialShm;
|
||||
}
|
||||
static void fxGuiStartFeederThread(Vst3Fx* fx, HWND hwnd) {
|
||||
auto p = fxGuiShmCtlRef();
|
||||
if (!p) { p = std::make_shared<FxGuiShmCtl>(); fxGuiShmCtlRef() = p; }
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(p->m);
|
||||
p->name = initialShm;
|
||||
}
|
||||
std::thread([fx, hwnd, p]() { fxGuiFeedLoop(fx, hwnd, p); }).detach();
|
||||
}
|
||||
|
||||
@@ -1560,7 +1568,8 @@ int run_open_fx_gui(const std::string& jobPath) {
|
||||
const int rc = fxGuiSetup(jobPath, &fx, &hwnd, /*offscreen=*/false, (LONG_PTR)&ctx, shm);
|
||||
if (rc) return rc;
|
||||
fxGuiStartWatchdog(hwnd, fxGuiParentPid());
|
||||
fxGuiStartAudioFeeder(&fx, hwnd, shm);
|
||||
fxGuiShmSetName(shm);
|
||||
fxGuiStartFeederThread(&fx, hwnd);
|
||||
|
||||
// 5. Pump messages until the window is destroyed.
|
||||
MSG msg;
|
||||
@@ -1598,11 +1607,12 @@ int run_fx_gui_server(const std::string& jobPath) {
|
||||
if (rc) return rc;
|
||||
fxGuiStartWatchdog(hwnd, fxGuiParentPid());
|
||||
SetPropA(hwnd, "FXGUI_FX", &fx); // for WM_FXGUI_RESIZE on the pump thread
|
||||
fxGuiStartAudioFeeder(&fx, hwnd, shm);
|
||||
fxGuiShmSetName(shm); // EARLY — frontend may /shm push before load finishes
|
||||
|
||||
int loadRc = 0;
|
||||
const int srv = fxGuiServerLoop(hwnd, [&]() {
|
||||
loadRc = fxGuiLoadAttach(&fx, path, name, hwnd);
|
||||
if (loadRc == 0) fxGuiStartFeederThread(&fx, hwnd); // after load+attach only
|
||||
if (loadRc != 0) PostMessageA(hwnd, WM_CLOSE, 0, 0); // exit; port already printed
|
||||
});
|
||||
RemovePropA(hwnd, "FXGUI_FX");
|
||||
|
||||
Reference in New Issue
Block a user