From 51d948fdc9bfaa98aa655b818248d49367baae80 Mon Sep 17 00:00:00 2001 From: locphamtran Date: Tue, 25 Aug 2026 09:24:55 +0700 Subject: [PATCH] fix(render): resolve VSTi offline qua plugin_dirs user + plugin_path schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _resolve_instrument dùng PluginManager() chỉ scan VST_DIR mặc định -> VSTi trong thư mục user (vd Steinberg\VSTPlugins\DUNE 3.dll) 404 -> render_engine fallback oscillator synth -> bounce sai tiếng. Dùng get_plugin_manager() (gộp plugin_dirs user) + resolve_plugin_path (lưới an toàn, chặn ext lạ). render_offline nhận plugin_path từ schema synth_engine.plugin_path ưu tiên. --- app/core/native_render.py | 27 +++++++++++++++++++++++---- app/core/render_engine.py | 1 + 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/core/native_render.py b/app/core/native_render.py index 0fdf17e..5cacbc4 100644 --- a/app/core/native_render.py +++ b/app/core/native_render.py @@ -104,9 +104,20 @@ def classify_instrument(path: str) -> int: def _resolve_instrument(instrument_id: str): - from app.core.vst_engine import PluginManager - path = PluginManager()._scan_plugins().get(instrument_id) + from app.core.vst_engine import get_plugin_manager, resolve_plugin_path + # get_plugin_manager gộp plugin_dirs user (Plugin Manager) — bản cũ dùng + # PluginManager() chỉ scan VST_DIR mặc định → VSTi trong thư mục user + # (vd C:\Program Files\Steinberg\VSTPlugins) 404 → render_engine fallback + # oscillator synth → bounce sai tiếng ("synthwave lạ"). resolve_plugin_path + # là lưới an toàn thứ 2 (so tên file case-insensitive, walk cả dir user). + path = get_plugin_manager()._scan_plugins().get(instrument_id) if not path: + path = resolve_plugin_path(instrument_id) + if not path: + return None, None + # resolve_plugin_path so theo stem — chặn false positive (vd Synapse Audio + # → Synapse Audio.nksf, preset file không phải plugin). + if not path.lower().endswith((".vst3", ".dll", ".so", ".sf2", ".sf3", ".sfz")): return None, None return classify_instrument(path), path @@ -187,13 +198,21 @@ def _run_notes_job(job: dict, label: str) -> tuple: def render_offline(instrument_id, notes, bpm, sample_rate, preset_id=None, preset_path=None, preset_data_b64=None, - soundfont_bank=None, soundfont_program=None) -> tuple: + soundfont_bank=None, soundfont_program=None, + plugin_path=None) -> tuple: """Render MIDI notes qua native_bridge --render → (out_path, duration_sec). Giữ response shape của _render_midi_notes_pedalboard. Lỗi → HTTPException (404 instrument lạ, 501 thiếu bridge, 500 lỗi render — file rác bị xóa). """ - itype, path = _resolve_instrument(instrument_id) + itype, path = None, None + # plugin_path (từ schema synth_engine.plugin_path) ưu tiên — không phụ + # thuộc scan; fallback resolve theo tên instrument_id. + if plugin_path and os.path.exists(plugin_path): + path = os.fspath(plugin_path) + itype = classify_instrument(path) + if not path: + itype, path = _resolve_instrument(instrument_id) if not path: raise HTTPException( status_code=404, diff --git a/app/core/render_engine.py b/app/core/render_engine.py index 30d1834..f9f998f 100644 --- a/app/core/render_engine.py +++ b/app/core/render_engine.py @@ -624,6 +624,7 @@ class PythonRenderEngine: preset_data_b64=se2.get("preset_data") or track.get("preset_data"), soundfont_bank=soundfont_bank, soundfont_program=soundfont_program, + plugin_path=se2.get("plugin_path") or track.get("plugin_path"), ) synth_buffer, _ = sf.read(out_path, dtype="float32") if synth_buffer.ndim == 1: