fix(bridge): đồng đều âm lượng VSTi jbridge, GUI native lên top, modal instrument lọc FX

- calibrate: probe sandbox (jbridge) theo real-time pacing — child render qua SHM
  consumer-sync, probe µs-speed chỉ đo được silence/attack → makeup=1.0 mọi channel.
  Thêm virtual probeNeedsRealtime() (SandboxVst2Host → true), calibrate() Sleep
  ~1 block/5.8ms để child kịp nhận MIDI + render steady-state → makeup đo peak thật
  (3 channel Qin ≈ 2.6, trước đây = 1.0 → âm lượng đồng đều giữa các track/VSTi).
- OPEN_GUI: SetWindowPos(HWND_TOPMOST) + SetForegroundWindow + BringWindowToTop
  → GUI VSTi hiển thị ở top window, tương tác ngay.
- /api/v1/plugins/available: filter vst_instruments + extra theo is_fx của
  fx_vst_bridge --scan (trước merge entry) — modal Select Instrument chỉ còn
  soundfont + VSTi, không hiện VST FX (90 → 33).
This commit is contained in:
2026-08-21 10:18:25 +07:00
parent da7ae02509
commit d7756b08ab
6 changed files with 41 additions and 2 deletions
+15 -1
View File
@@ -166,10 +166,24 @@ async def list_plugins(current_user: dict = Depends(get_current_user)):
d = _effective_dirs()
pm = PluginManager(vst_dir=d["vst_dir"], sf_dir=d["soundfont_dir"], upload_sf_dir=UPLOAD_SF_DIR, extra_vst_dirs=d["plugin_dirs"])
avail = pm.list_available()
# Modal chọn instrument (nút Synth TCP) chỉ hiện soundfont + VSTi — loại
# VST FX (Ozone/Sonible/...) khỏi vst_instruments theo is_fx của bridge scan.
# Filter TRƯỚC merge extra: nếu không, entry FX (path .vst3) chiếm id và
# setdefault chặn entry instrument (path .dll) cùng tên → mất cả hai.
fx_paths = set()
try:
from app.core.vst_engine import get_plugin_manager
fx_paths = {f.get("path", "").lower() for f in get_plugin_manager().list_fx()}
except Exception:
pass
if fx_paths:
avail["vst_instruments"] = [v for v in avail["vst_instruments"]
if (v.get("path") or "").lower() not in fx_paths]
# Gộp VST từ plugin_dirs user đã scan — list_available() CHỈ quét vst_dir
# env (mặc định /opt/daw_engine/vst3) → Synth dropdown không thấy VSTi mà
# Plugin Manager đã scan trong thư mục user chọn (bug: nút Synth rỗng).
extra = _scan_vst_in_dirs(d["plugin_dirs"])
extra = [v for v in _scan_vst_in_dirs(d["plugin_dirs"])
if (v.get("path") or "").lower() not in fx_paths]
by_id = {v["id"]: v for v in avail["vst_instruments"]}
for v in extra:
by_id.setdefault(v["id"], v)