fix(fx): realtime VST ngắt quãng khi mở MASTERING PANEL + PWR master không ảnh hưởng âm; pacing WS input/output, gate fxRt theo masterConnected, worklet cap 32
This commit is contained in:
+14
-8
@@ -9,13 +9,19 @@ router = APIRouter()
|
||||
# WebView2 standalone chặn anchor-download → không thấy save dialog. Giải pháp:
|
||||
# frontend gọi /save-dialog → engine mở NATIVE SaveFileDialog (Windows Explorer)
|
||||
# → trả đường dẫn user chọn → frontend gửi bytes qua /write → ghi file thật.
|
||||
SAVE_DIALOG_TIMEOUT = 120 # user có thể để dialog mở lâu
|
||||
SAVE_DIALOG_TIMEOUT = 120 # fallback native (PowerShell) — user có thể để dialog mở lâu
|
||||
# Bridge timeout phải LỚN HƠN Rust wait (300s trong lib.rs) — nếu không, user
|
||||
# chọn path sau 300s thì engine đã bỏ cuộc → save_file.response bị bỏ lại, file
|
||||
# không được ghi dù user đã chọn nơi lưu (bug "hỏi nơi lưu nhưng không có file").
|
||||
SAVE_BRIDGE_TIMEOUT = 360
|
||||
|
||||
|
||||
def _save_file_via_tauri_bridge(default_name: str) -> Optional[str]:
|
||||
"""Tauri shell (Rust watcher trong lib.rs) mở NATIVE SaveFileDialog qua
|
||||
file IPC: engine ghi save_file.request (chứa tên mặc định) → Rust mở dialog
|
||||
→ ghi save_file.response. Trả None nếu bridge không tồn tại (standalone)."""
|
||||
→ ghi save_file.response. Trả None nếu bridge không tồn tại (standalone) →
|
||||
caller fallback native. Trả "" nếu bridge ĐÃ dùng nhưng user hủy / hết hạn →
|
||||
KHÔNG fallback (tránh 2 dialog cùng lúc + tránh ghi đè path user đã chọn)."""
|
||||
root = os.environ.get("APPDATA") or os.path.expanduser("~")
|
||||
ipc = os.path.join(root, "SonicForgeDAW", "ipc")
|
||||
if not os.path.isdir(ipc):
|
||||
@@ -35,7 +41,7 @@ def _save_file_via_tauri_bridge(default_name: str) -> Optional[str]:
|
||||
os.remove(f)
|
||||
with open(req, "w", encoding="utf-8") as fh:
|
||||
fh.write(default_name or "untitled")
|
||||
deadline = _time.time() + SAVE_DIALOG_TIMEOUT
|
||||
deadline = _time.time() + SAVE_BRIDGE_TIMEOUT
|
||||
while _time.time() < deadline:
|
||||
if os.path.exists(resp):
|
||||
try:
|
||||
@@ -43,11 +49,11 @@ def _save_file_via_tauri_bridge(default_name: str) -> Optional[str]:
|
||||
val = fh.read().strip()
|
||||
finally:
|
||||
os.remove(resp)
|
||||
return val or None
|
||||
return val # "" khi user hủy — KHÔNG fallback PowerShell (tránh 2 dialog)
|
||||
_time.sleep(0.1)
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
return ""
|
||||
return "" # bridge đã dùng nhưng hết hạn — KHÔNG fallback (dialog Rust vẫn có thể đang mở)
|
||||
|
||||
|
||||
def _save_file_native_engine(default_name: str, filter_name: str, filter_ext: str) -> Optional[str]:
|
||||
@@ -107,9 +113,9 @@ def save_file_dialog(req: SaveDialogRequest):
|
||||
Trả {"path": "<đường dẫn user chọn>"} hoặc {"path": None} (hủy/không có
|
||||
dialog). def (sync) → FastAPI chạy threadpool — không block loop."""
|
||||
path = _save_file_via_tauri_bridge(req.default_name)
|
||||
if path is None:
|
||||
if path is None: # không có bridge (standalone thuần) → fallback native
|
||||
path = _save_file_native_engine(req.default_name, req.filter_name, req.filter_ext)
|
||||
return {"path": path}
|
||||
return {"path": path or None}
|
||||
|
||||
|
||||
@router.post("/write")
|
||||
|
||||
Reference in New Issue
Block a user