fix(fx-rt): het crackle master FX - limiter attack smooth + crossfade khi bat/tat chain
- NativeInstrumentEngine: kAttack 0.9->0.1 (het zipper khi sum nhieu track) - app.jsx: crossfade masterFxDryGain/masterFxGain thay hard-rewire graph luc activation/deactivation master chain FX; worklet bao 'started' -> ramp dung luc; PDC tre sau khi dry silent (tranh gap 80ms) - sf-fx-realtime.js: fade-in 512 mau luc FILL xong / resume sau underrun - index.html + addModule: cache-buster v=202608241200 - rebuild app.precompiled.js, copy bundle vao dist/ + src-tauri/resources/ - keo dai fix cac round truoc: FILL 16, FXRT_BURST_MS, REBUFFER, pacing, VST GUI click/focus, solo crackle - them harness + plans/patch scripts
This commit is contained in:
@@ -631,6 +631,11 @@ class FxGuiRequest(BaseModel):
|
||||
# mở mapping này để PEEK input ring và chạy processAudio() trên instance
|
||||
# GUI → meter trong plugin nhảy theo âm thật (GUI không consume ring).
|
||||
shm: str = ""
|
||||
# preset_b64: preset GUI capture mới nhất (bridge state blob hoặc raw
|
||||
# .vstpreset b64) — bridge áp sau fx->load() để mở GUI với ĐÚNG cài đặt
|
||||
# đã chỉnh (trước đây GUI mở lại load default → mất settings khi
|
||||
# hide/show).
|
||||
preset_b64: str = ""
|
||||
|
||||
|
||||
class FxGuiCloseRequest(BaseModel):
|
||||
@@ -682,6 +687,8 @@ async def open_fx_gui(req: FxGuiRequest, current_user: dict = Depends(get_curren
|
||||
job = {"path": plugin_path, "name": req.name or os.path.basename(plugin_path)}
|
||||
if req.shm:
|
||||
job["shm"] = req.shm
|
||||
if req.preset_b64:
|
||||
job["preset_b64"] = req.preset_b64
|
||||
fd, job_path = tempfile.mkstemp(prefix="sf_fx_gui_", suffix=".json", dir=tempfile.gettempdir())
|
||||
try:
|
||||
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
||||
@@ -1003,6 +1010,10 @@ class FxRealtimeStartRequest(BaseModel):
|
||||
class FxRealtimeStopRequest(BaseModel):
|
||||
session_id: str = ""
|
||||
|
||||
class FxRealtimeSetChainRequest(BaseModel):
|
||||
session_id: str = ""
|
||||
fx_chain: list = []
|
||||
|
||||
@router.post("/fx-realtime/start")
|
||||
async def fx_realtime_start(req: FxRealtimeStartRequest,
|
||||
current_user: dict = Depends(get_current_user)):
|
||||
@@ -1033,6 +1044,21 @@ async def fx_realtime_stop(req: FxRealtimeStopRequest,
|
||||
ok = fx_realtime.stop_session(req.session_id or "")
|
||||
return {"success": True, "stopped": ok}
|
||||
|
||||
@router.post("/fx-realtime/set-chain")
|
||||
async def fx_realtime_set_chain(req: FxRealtimeSetChainRequest,
|
||||
current_user: dict = Depends(get_current_user)):
|
||||
"""Cập nhật chain trên session realtime ĐANG CHẠY — KHÔNG restart session.
|
||||
Engine ghi lại job file (seq++); bridge poll seq → RealtimeFxChain::setChain
|
||||
(worker load chain mới, swap atomic dưới mutex — audio thread copy
|
||||
shared_ptr, không dừng) → load/đổi VST FX + đổi preset GUI không ngắt âm/
|
||||
crackle. Session/WS/SHM giữ nguyên."""
|
||||
enforce_password_changed(current_user)
|
||||
sess = fx_realtime.get_session(req.session_id or "")
|
||||
if not sess:
|
||||
raise HTTPException(status_code=404, detail="Session realtime không tồn tại")
|
||||
ok = sess.set_chain(req.fx_chain or [])
|
||||
return {"success": True, "updated": ok}
|
||||
|
||||
@router.websocket("/ws/fx-realtime/{session_id}")
|
||||
async def ws_fx_realtime(websocket: WebSocket, session_id: str):
|
||||
"""Vòng lặp FX realtime: receive block input → SHM → bridge → SHM → send
|
||||
|
||||
Reference in New Issue
Block a user