M3: ctrl ring reader (engine -> bridge) dieu khien editor qua SHM
JuceFxLoop them thread ctrlReader poll 2ms: doc FxCtrlCmd ring (key 'ed.open'/ 'ed.close'/'ed.show'/'ed.hide'/'ed.resize'/'ed.capture', slot = chain index), dispatch qua engine.requestEditor (queue thread-safe; GUI tick 30ms pump). w/h ma hoa trong value: w*4096+h (chinh xac tuyet doi w,h<=4095 — float 24-bit mantissa); value<=0 -> editor preferred size. SET_PARAM cu (key khac) consume + bo qua an toan (JuceFxEngine chua co param API — params di trong chain JSON). ctrl.join() truoc shutdown. E2E test (session SHM that + bridge that, chain purecomp): ed.open -> window native hien, audio pump khi GUI mo (process+editor song song), hide/show/resize/capture 4049 bytes, close -> window bien mat, teardown sach rc=0 — PASS 11/11. Tien de M4 (engine send_editor_cmd + /fx-gui).
This commit is contained in:
@@ -179,6 +179,64 @@ int run_juce_fx_loop(const std::string& jobPath, const std::string& shmName,
|
||||
}
|
||||
});
|
||||
|
||||
// M3: ctrl ring reader (engine → bridge, poll 2ms). Key "ed.*" = editor
|
||||
// command (Reaper-style: engine điều khiển editor của CHÍNH instance DSP
|
||||
// trong graph — không instance 2). Dispatch qua engine.requestEditor
|
||||
// (thread-safe queue); GUI tick 30ms pumpEditorQueue thực thi. Key khác
|
||||
// (SET_PARAM cũ: param name) — JuceFxEngine chưa có param API (params đi
|
||||
// trong chain JSON) → consume + bỏ qua an toàn (ring không đầy, không chặn
|
||||
// producer). w/h mã hoá trong value: w*4096 + h — chính xác tuyệt đối với
|
||||
// w,h <= 4095 (float 24-bit mantissa); value <= 0 → editor preferred size
|
||||
// (engine chỉ setSize khi w,h > 0).
|
||||
std::thread ctrl([&]() {
|
||||
while (ipc->h.running && ipc->h.state == FXRT_STATE_READY) {
|
||||
while (ipc->h.ctrlRead < ipc->h.ctrlWrite) {
|
||||
const uint32_t cs = ipc->h.ctrlRead & (FXRT_CTRL_SLOTS - 1);
|
||||
const FxCtrlCmd& cmd = ipc->ctrl[cs];
|
||||
const uint32_t slot = cmd.slot;
|
||||
char key[17];
|
||||
std::memcpy(key, cmd.key, 16);
|
||||
key[16] = '\0';
|
||||
const float value = cmd.value;
|
||||
MemoryBarrier();
|
||||
ipc->h.ctrlRead++; // consume trước dispatch — không block ring
|
||||
if (std::strncmp(key, "ed.", 3) != 0)
|
||||
continue; // SET_PARAM cũ — no-op (xem comment trên)
|
||||
JuceFxEngine::EditorAction act;
|
||||
bool known = true;
|
||||
if (std::strcmp(key, "ed.open") == 0)
|
||||
act = JuceFxEngine::EditorAction::Open;
|
||||
else if (std::strcmp(key, "ed.close") == 0)
|
||||
act = JuceFxEngine::EditorAction::Close;
|
||||
else if (std::strcmp(key, "ed.show") == 0)
|
||||
act = JuceFxEngine::EditorAction::Show;
|
||||
else if (std::strcmp(key, "ed.hide") == 0)
|
||||
act = JuceFxEngine::EditorAction::Hide;
|
||||
else if (std::strcmp(key, "ed.resize") == 0)
|
||||
act = JuceFxEngine::EditorAction::Resize;
|
||||
else if (std::strcmp(key, "ed.capture") == 0)
|
||||
act = JuceFxEngine::EditorAction::Capture;
|
||||
else
|
||||
known = false;
|
||||
if (!known) {
|
||||
std::cerr << "[JuceFxLoop] ctrl ed.* lạ: " << key
|
||||
<< " slot=" << slot << std::endl;
|
||||
continue;
|
||||
}
|
||||
int w = 0, h = 0;
|
||||
if (value > 0.0f) {
|
||||
const int v = (int)(value + 0.5f);
|
||||
w = v / 4096;
|
||||
h = v % 4096;
|
||||
}
|
||||
engine.requestEditor(slot, act, w, h);
|
||||
std::cerr << "[JuceFxLoop] ctrl " << key << " slot=" << slot
|
||||
<< " w=" << w << " h=" << h << std::endl;
|
||||
}
|
||||
sleepMs(2);
|
||||
}
|
||||
});
|
||||
|
||||
const uint32_t n = curBlock;
|
||||
const uint32_t inMask = ipc->h.inSlots - 1;
|
||||
const uint32_t outMask = ipc->h.outSlots - 1;
|
||||
@@ -286,6 +344,7 @@ int run_juce_fx_loop(const std::string& jobPath, const std::string& shmName,
|
||||
}
|
||||
ipc->h.state = FXRT_STATE_STARTING;
|
||||
hb.join();
|
||||
ctrl.join(); // dừng trước shutdown — không còn lệnh editor mới
|
||||
guiHost.runOnGui([&] { engine.shutdown(); }); // graph clear trên GUI thread
|
||||
guiHost.stop(); // M2: đóng editor (GUI thread) + dừng GUI thread + join
|
||||
fxshm::closeShm(v);
|
||||
|
||||
Reference in New Issue
Block a user