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:
@@ -51,12 +51,8 @@ def adelay():
|
||||
|
||||
|
||||
def _write_wav(path, data, sr):
|
||||
pcm = (np.clip(data, -1.0, 1.0).T * 32767).astype(np.int16)
|
||||
with wave.open(path, "wb") as w:
|
||||
w.setnchannels(2)
|
||||
w.setsampwidth(2)
|
||||
w.setframerate(sr)
|
||||
w.writeframes(pcm.tobytes())
|
||||
import soundfile as sf
|
||||
sf.write(path, data.T, sr, subtype="FLOAT")
|
||||
|
||||
|
||||
def _read_wav(path):
|
||||
@@ -189,8 +185,8 @@ def test_53_live_equals_export(fx_bridge, monkeypatch):
|
||||
else:
|
||||
got = live[:, :offline.shape[1] + lag]
|
||||
n_cmp = min(offline.shape[1], got.shape[1]) - 8
|
||||
assert n_cmp > 1000, "đoạn so sánh quá ngắn"
|
||||
snr = _snr_db(offline[:, :n_cmp], got[:, :n_cmp])
|
||||
assert n_cmp > 2048, "đoạn so sánh quá ngắn"
|
||||
snr = _snr_db(offline[:, 2048:n_cmp], got[:, 2048:n_cmp])
|
||||
assert snr >= 30.0, f"live≠export SNR {snr:.1f} dB (lag {lag})"
|
||||
|
||||
|
||||
@@ -717,6 +713,7 @@ def test_63_fxrt_ws_latency_push(monkeypatch):
|
||||
class _FakeSess:
|
||||
block_size = 256
|
||||
sample_rate = 44100
|
||||
stats = {}
|
||||
|
||||
def alive(self):
|
||||
return True
|
||||
@@ -727,6 +724,12 @@ def test_63_fxrt_ws_latency_push(monkeypatch):
|
||||
def get_latencies(self):
|
||||
return {0: 1024, 1: 0}
|
||||
|
||||
def get_processed(self):
|
||||
return None
|
||||
|
||||
def flush_input_stale(self, *a):
|
||||
pass
|
||||
|
||||
def set_param(self, *a):
|
||||
pass
|
||||
|
||||
|
||||
Reference in New Issue
Block a user