fix(render): resolve VSTi offline qua plugin_dirs user + plugin_path schema

_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.
This commit is contained in:
2026-08-25 09:24:55 +07:00
parent dd17f87e4e
commit 51d948fdc9
2 changed files with 24 additions and 4 deletions
+23 -4
View File
@@ -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,
+1
View File
@@ -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: