From aeec85604f8660ab07ee91cb031b6466ae1faf35 Mon Sep 17 00:00:00 2001 From: locpham Date: Sat, 22 Aug 2026 04:07:19 +0000 Subject: [PATCH] =?UTF-8?q?fix(available):=20loai=20iZotope=20VST2=20legac?= =?UTF-8?q?y=20(Steinberg\VSTPlugins\iZotope\*.dll)=20trung=20ten=20VST3?= =?UTF-8?q?=20FX=20da=20scan=20=E2=80=94=20block=20theo=20ten=20normalized?= =?UTF-8?q?=20(bo=20prefix=20iZ,=20lowercase=20alnum);=20giu=20VST2=20that?= =?UTF-8?q?=20(DSK/Kong)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/v1/plugins.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/app/api/v1/plugins.py b/app/api/v1/plugins.py index 8665cec..1b936f4 100644 --- a/app/api/v1/plugins.py +++ b/app/api/v1/plugins.py @@ -195,25 +195,40 @@ async def list_plugins(current_user: dict = Depends(get_current_user)): # không xác định được loại → KHÔNG hiện trong nút Synth. fx_paths = set() unknown_paths = set() + fx_norm_names = set() try: from app.core.vst_engine import get_plugin_manager for e in get_plugin_manager().list_scan_all(): path = (e.get("path") or "").lower() if e.get("is_fx"): fx_paths.add(path) + fx_norm_names.add(_norm_plugin_name(e.get("name") or "")) elif e.get("is_unknown"): unknown_paths.add(path) except Exception: pass blocked = fx_paths | unknown_paths + + def _is_fx_dupe(v) -> bool: + # iZotope cài VST2 legacy vào Steinberg\VSTPlugins\iZotope\ (iZOzonePro.dll, + # iZNeutronProCompressor.dll...) TRÙNG với VST3 FX đã scan (Ozone Pro Dynamic + # EQ.vst3...) nhưng path .dll ≠ path .vst3 → block theo path KHÔNG trúng. + # Loại theo TÊN normalized (bỏ prefix iZ, lowercase alnum) — VST2 thật + # (DSK Asian DreamZ, Kong Audio...) không trùng tên FX → vẫn giữ. + if not fx_norm_names: + return False + return _norm_plugin_name(v.get("name") or "") in fx_norm_names + if blocked: avail["vst_instruments"] = [v for v in avail["vst_instruments"] - if (v.get("path") or "").lower() not in blocked] + if (v.get("path") or "").lower() not in blocked + and not _is_fx_dupe(v)] # 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 = [v for v in _scan_vst_in_dirs(d["plugin_dirs"]) - if (v.get("path") or "").lower() not in blocked] + if (v.get("path") or "").lower() not in blocked + and not _is_fx_dupe(v)] by_id = {v["id"]: v for v in avail["vst_instruments"]} for v in extra: by_id.setdefault(v["id"], v) @@ -227,6 +242,16 @@ async def list_plugins(current_user: dict = Depends(get_current_user)): return avail +def _norm_plugin_name(name: str) -> str: + """Tên plugin chuẩn hóa để so khớp FX trùng (iZotope VST2 legacy vs VST3): + bỏ prefix 'iZ' (iZOzonePro → OzonePro), lowercase, chỉ giữ alnum + (Ozone Pro Dynamic EQ → ozoneprodynamiceq).""" + s = "".join(ch for ch in (name or "").lower() if ch.isalnum()) + if s.startswith("iz") and len(s) > 2: + s = s[2:] + return s + + def _scan_soundfonts_in_dirs(dirs: list) -> list: """Walk các thư mục (plugin_dirs user) → danh sách soundfont .sf2/.sf3 (id = tên file; name từ .meta nếu có — cùng format PluginManager)."""