Gap 7: master volume automation lane — render_engine automation.volume_db (dB interp -30..+3 sau fader truoc normalize), schema master.automation, UI AUTOM panel MasterStripConsole + realtime scheduling tren masterBus.output.gain (play/seek/stop), serialize/parse, test_65 (177 passed)

This commit is contained in:
2026-08-23 09:05:39 +07:00
parent 2b5f396133
commit 94a0bc7401
6 changed files with 233 additions and 19 deletions
+24
View File
@@ -63,6 +63,22 @@ def _find_default_sf2() -> str:
return p
return ""
def _apply_master_volume_automation(buf, sr, nodes):
"""Gap 7: master volume automation lane (master.automation.volume_db).
nodes: [{time: giây, db}] — envelope tuyến tính dB, clamp -30..+3 dB như
track automation (sub_tab_dsp). Áp TRÊN master_buffer (2, N) — trả copy."""
nodes = [n for n in (nodes or []) if n.get("time") is not None and n.get("db") is not None]
if not nodes:
return buf
nodes = sorted(nodes, key=lambda x: float(x["time"]))
n_samples = buf.shape[1]
times = np.array([float(n["time"]) for n in nodes])
dbs = np.clip(np.array([float(n["db"]) for n in nodes]), -30.0, 3.0)
sample_times = np.arange(n_samples) / sr
interp = np.interp(sample_times, times, dbs, left=dbs[0], right=dbs[-1])
return buf * (10.0 ** (interp / 20.0))
# ── Builtin custom FX (spec fx_chain_architecture §2 Step 2: Custom FX) ─────
# Track FX chain slots: eq / eqpro / compressor / limiter / exciter / rebalance
# (khớp tham số WebAudio track FX modules + EQ Pro bands) + legacy chorus/reverb
@@ -907,6 +923,14 @@ class PythonRenderEngine:
if vol_l:
master_buffer *= 10 ** (vol_l / 20.0)
# Gap 7: master volume automation — envelope áp SAU fader, TRƯỚC
# normalize (fader cuối; automation = lớp âm lượng trên fader).
_auto = master.get("automation") or {}
_auto_vol = _auto.get("volume_db") or []
if _auto_vol:
master_buffer = _apply_master_volume_automation(
master_buffer, self.sample_rate, _auto_vol)
# Normalization to prevent clipping
max_peak = np.max(np.abs(master_buffer))
if max_peak > 1.0: