master strip: L/R volume + LINK + MUTE that, bo soloBtn
This commit is contained in:
@@ -303,6 +303,58 @@ def test_55_fader_after_master_chain(monkeypatch, tmp_path, fx_bridge):
|
||||
assert 0.4 < p6 / p0 < 0.6, f"fader -6dB phải ~1/2 đỉnh: {p6:.4f}/{p0:.4f}"
|
||||
assert 0.8 < p6 / base < 1.2, f"fader-6 phải ≈ base: {p6:.4f} vs {base:.4f}"
|
||||
|
||||
# ── 5.8 Master L/R volume + LINK + MUTE ─────────────────────────────────
|
||||
def test_58_master_lr_link_mute(monkeypatch, tmp_path, fx_bridge):
|
||||
"""Master strip L/R: volumeL_db/volumeR_db tách kênh, link_lr → R theo L,
|
||||
muted → zero output. Fallback volume_db (project cũ) vẫn chạy."""
|
||||
monkeypatch.setenv("SF_FX_BRIDGE_PATH", fx_bridge)
|
||||
if not os.path.isfile(DAW_BRIDGE):
|
||||
pytest.skip("daw_vst_bridge.exe chưa build")
|
||||
monkeypatch.setenv("SF_BRIDGE_PATH", DAW_BRIDGE)
|
||||
from app.api.v1 import plugins as pl
|
||||
monkeypatch.setattr(pl.settings, "RENDER_ENGINE", "bridge")
|
||||
from app.core.render_engine import PythonRenderEngine
|
||||
engine = PythonRenderEngine()
|
||||
|
||||
def project(master):
|
||||
track = _midi_track()
|
||||
track["volume_db"] = -20.0 # tránh normalize (>1.0)
|
||||
return {
|
||||
"metadata": {"bpm": 120.0, "time_signature_numerator": 4},
|
||||
"main_session": {
|
||||
"length_bars": 1.0,
|
||||
"tracks": [track],
|
||||
"master": dict({"fx_chain": [], "bypass": False}, **master),
|
||||
},
|
||||
"section_store": {},
|
||||
}
|
||||
|
||||
def render(name, master):
|
||||
out = str(tmp_path / name)
|
||||
engine.render_project(project(master), out)
|
||||
data, _ = _read_wav(out)
|
||||
return data
|
||||
|
||||
base = render("base.wav", {"volumeL_db": 0.0, "volumeR_db": 0.0, "link_lr": True})
|
||||
baseL = float(np.max(np.abs(base[0])))
|
||||
baseR = float(np.max(np.abs(base[1])))
|
||||
assert baseL > 0
|
||||
|
||||
lr = render("lr.wav", {"volumeL_db": -6.0, "volumeR_db": 0.0, "link_lr": False})
|
||||
assert 0.4 < float(np.max(np.abs(lr[0]))) / baseL < 0.6, f"L -6dB phải ~1/2 đỉnh: {float(np.max(np.abs(lr[0]))):.4f}/{baseL:.4f}"
|
||||
assert abs(float(np.max(np.abs(lr[1]))) - baseR) / baseR < 0.15, "R phải giữ nguyên khi link_lr=false"
|
||||
|
||||
link = render("link.wav", {"volumeL_db": -6.0, "volumeR_db": -3.0, "link_lr": True})
|
||||
ratio = float(np.max(np.abs(link[1]))) / float(np.max(np.abs(link[0])))
|
||||
assert 0.9 < ratio < 1.1, f"link_lr: R phải theo L ({ratio:.3f})"
|
||||
|
||||
muted = render("muted.wav", {"volumeL_db": 0.0, "volumeR_db": 0.0,
|
||||
"link_lr": True, "muted": True})
|
||||
assert float(np.max(np.abs(muted))) < 1e-6, "MUTE master phải zero output"
|
||||
|
||||
legacy = render("legacy.wav", {"volume_db": -6.0})
|
||||
assert 0.4 < float(np.max(np.abs(legacy[0]))) / baseL < 0.6 and 0.4 < float(np.max(np.abs(legacy[1]))) / baseR < 0.6, "fallback volume_db (project cũ) phải áp cả 2 kênh"
|
||||
|
||||
|
||||
# ── 5.6 PDC ───────────────────────────────────────────────────────────────
|
||||
def test_56_pdc_aligns_tracks(monkeypatch, tmp_path, fx_bridge):
|
||||
|
||||
Reference in New Issue
Block a user