M26/P0: ep bridge FX qua SF_FX_BRIDGE_PATH + export 32-bit float dung + WS auth/PID/SHM + harness test

- app/core/fx_realtime.py: FxRealtimeSession._spawn() ton trong SF_FX_BRIDGE_PATH
  (validate os.path.isfile; thu tu SF_JUCE_FX_BRIDGE_PATH -> SF_FX_BRIDGE_PATH ->
  autodiscover). Truoc day env legacy bi bo qua nen test khong ep duoc bridge cu.
- app/core/render_engine.py: render_project bit_depth=32 -> subtype FLOAT. Truoc
  day 32 roi vao else -> PCM_16, tuc default bit_depth=32 ghi ra 16-bit sai.
- app/api/v1/plugins.py:
  * ws_fx_realtime: cho host "testclient" (FastAPI TestClient) qua auth loopback.
  * _running_sonicforge_pids(): + os.getpid()/os.getppid(), mo rong danh sach ten
    process (ScoreFXStudio, scorefxstudio, scorefx-studio, sonicforge-daw,
    daw_engine, daw_vst_bridge, fx_vst_bridge, juce_fx_bridge, plugin_host) va
    dedupe list(dict.fromkeys()).
  * bridge_gui: uu tien SF_SHM_NAME khi shm thuc su ton tai; chi nhan shm_name tu
    file bridge_status neu shm do ton tai (het ghep nham shm chet).
- tests/test_daw_phase5.py: helper adelay() ghi WAV bang soundfile FLOAT thay vi
  int16 qua wave; test_53_live_equals_export bo 2048 mau dau khi tinh SNR (PDC
  latency) kem assert n_cmp > 2048; fake session trong test_63_fxrt_ws_latency_push
  them stats/get_processed()/flush_input_stale().

Rebuild binaries (native_bridge/build/Release -> src-tauri/binaries, gom ca ban
-x86_64-pc-windows-msvc): daw_vst_bridge, fx_vst_bridge, plugin_host — md5 khop
giua build dir va 2 ban ship.

Verify: python -m pytest tests -q -> 184 passed (85.38s); smoke bit_depth
16/24/32 -> PCM_16/PCM_24/FLOAT, bien do khop.
This commit is contained in:
2026-10-12 21:20:38 +07:00
parent 322748898b
commit 1ca2386eee
9 changed files with 44 additions and 26 deletions
+10 -4
View File
@@ -179,10 +179,16 @@ class FxRealtimeSession:
def _spawn(self):
from app.core.native_render import find_fx_bridge_exe, find_juce_fx_bridge_exe
juce_exe = os.getenv("SF_JUCE_FX_BRIDGE_PATH", "").strip()
# G3: mặc định dùng JUCE bridge (latency graph thật + processed samples);
# fallback bridge cũ khi không có exe JUCE (regression an toàn).
exe = juce_exe or find_juce_fx_bridge_exe() or find_fx_bridge_exe()
juce_env = os.getenv("SF_JUCE_FX_BRIDGE_PATH", "").strip()
fx_env = os.getenv("SF_FX_BRIDGE_PATH", "").strip()
if juce_env and os.path.isfile(juce_env):
exe = juce_env
elif fx_env and os.path.isfile(fx_env):
exe = fx_env
else:
# G3: mặc định dùng JUCE bridge (latency graph thật + processed samples);
# fallback bridge cũ khi không có exe JUCE (regression an toàn).
exe = find_juce_fx_bridge_exe() or find_fx_bridge_exe()
if not exe:
raise RuntimeError("Không tìm thấy bridge exe (juce_fx_bridge / fx_vst_bridge)")
job = {