FIX: sửa lỗi không load soundfont trên window, MIDI item không play được qua carla
This commit is contained in:
+59
-37
@@ -278,8 +278,6 @@ class PluginManager:
|
||||
return load_soundfont_cached(path)
|
||||
|
||||
def list_soundfont_instruments(self, sf_id: str):
|
||||
if not ensure_pyfluidsynth():
|
||||
return []
|
||||
if sf_id in _SF_INSTRUMENTS_CACHE:
|
||||
return _SF_INSTRUMENTS_CACHE[sf_id]
|
||||
search_dirs = []
|
||||
@@ -293,12 +291,18 @@ class PluginManager:
|
||||
for d in (self.extra_vst_dirs or []):
|
||||
if d and os.path.isdir(d) and d not in search_dirs:
|
||||
search_dirs.append(d)
|
||||
for d in search_dirs:
|
||||
for f in os.listdir(d):
|
||||
if not (f.endswith(".sf2") or f.endswith(".sf3")):
|
||||
continue
|
||||
base = os.path.splitext(f)[0]
|
||||
if base == sf_id or base == sf_id.replace("sf_", ""):
|
||||
presets = []
|
||||
# ── 1) FluidSynth (nếu có lib) — đọc bank/program/name từ engine ──
|
||||
if ensure_pyfluidsynth():
|
||||
for d in search_dirs:
|
||||
if presets:
|
||||
break
|
||||
for f in os.listdir(d):
|
||||
if not (f.endswith(".sf2") or f.endswith(".sf3")):
|
||||
continue
|
||||
base = os.path.splitext(f)[0]
|
||||
if base != sf_id and base != sf_id.replace("sf_", ""):
|
||||
continue
|
||||
path = os.path.join(d, f)
|
||||
try:
|
||||
import fluidsynth as _fs
|
||||
@@ -308,35 +312,31 @@ class PluginManager:
|
||||
_synth = _fs.new_fluid_synth(_settings)
|
||||
try:
|
||||
fid = _fs.fluid_synth_sfload(_synth, path.encode("utf-8"), 1)
|
||||
if fid < 0:
|
||||
continue
|
||||
sfont = _fs.fluid_synth_get_sfont_by_id(_synth, fid)
|
||||
presets = []
|
||||
if sfont:
|
||||
for bank in range(0, 2):
|
||||
for prog_num in range(0, 128):
|
||||
try:
|
||||
preset = _fs.fluid_sfont_get_preset(sfont, bank, prog_num)
|
||||
except Exception:
|
||||
break
|
||||
if preset:
|
||||
if fid >= 0:
|
||||
sfont = _fs.fluid_synth_get_sfont_by_id(_synth, fid)
|
||||
if sfont:
|
||||
for bank in range(0, 2):
|
||||
for prog_num in range(0, 128):
|
||||
try:
|
||||
name_ptr = _fs.fluid_preset_get_name(preset)
|
||||
if name_ptr:
|
||||
if hasattr(_fs, "ffi"):
|
||||
raw = _fs.ffi.string(name_ptr)
|
||||
else:
|
||||
raw = c_char_p(name_ptr).value
|
||||
if raw:
|
||||
presets.append({
|
||||
"bank": bank,
|
||||
"program": prog_num,
|
||||
"name": raw.decode("utf-8", errors="replace")
|
||||
})
|
||||
preset = _fs.fluid_sfont_get_preset(sfont, bank, prog_num)
|
||||
except Exception:
|
||||
continue
|
||||
_SF_INSTRUMENTS_CACHE[sf_id] = presets[:256]
|
||||
return presets[:256]
|
||||
break
|
||||
if preset:
|
||||
try:
|
||||
name_ptr = _fs.fluid_preset_get_name(preset)
|
||||
if name_ptr:
|
||||
if hasattr(_fs, "ffi"):
|
||||
raw = _fs.ffi.string(name_ptr)
|
||||
else:
|
||||
raw = c_char_p(name_ptr).value
|
||||
if raw:
|
||||
presets.append({
|
||||
"bank": bank,
|
||||
"program": prog_num,
|
||||
"name": raw.decode("utf-8", errors="replace"),
|
||||
})
|
||||
except Exception:
|
||||
continue
|
||||
finally:
|
||||
try:
|
||||
_fs.delete_fluid_synth(_synth)
|
||||
@@ -344,8 +344,30 @@ class PluginManager:
|
||||
pass
|
||||
except Exception:
|
||||
import traceback; traceback.print_exc()
|
||||
_SF_INSTRUMENTS_CACHE[sf_id] = []
|
||||
return []
|
||||
break # đã xử lý file khớp
|
||||
# ── 2) Fallback: sf2utils đọc TRỰC TIẾP file (thuần Python) ──
|
||||
# Không cần libfluidsynth — quan trọng trên Windows khi thiếu DLL.
|
||||
# Đọc preset header (pdta/phdr) → bank/program/name như nhau.
|
||||
if not presets:
|
||||
try:
|
||||
from app.core.soundfont_inspector import SoundFontInspector
|
||||
insp = SoundFontInspector(system_sf_dir=self.sf_dir, upload_sf_dir=self.upload_sf_dir)
|
||||
for d in search_dirs:
|
||||
if presets:
|
||||
break
|
||||
for f in os.listdir(d):
|
||||
if not (f.endswith(".sf2") or f.endswith(".sf3")):
|
||||
continue
|
||||
base = os.path.splitext(f)[0]
|
||||
if base == sf_id or base == sf_id.replace("sf_", ""):
|
||||
info = insp.inspect_sf2_file(os.path.join(d, f))
|
||||
if info and info.get("instruments"):
|
||||
presets = info["instruments"]
|
||||
break
|
||||
except Exception:
|
||||
presets = []
|
||||
_SF_INSTRUMENTS_CACHE[sf_id] = presets[:256]
|
||||
return presets[:256]
|
||||
|
||||
def list_available(self) -> dict:
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user