fix: nhãn của soundfont hiển thị sai và không load được instrument

This commit is contained in:
2026-07-23 22:32:19 +07:00
parent 1a28ebabee
commit 6a17e7036c
14 changed files with 259 additions and 111 deletions
+45 -16
View File
@@ -1,6 +1,7 @@
# SonicForge Studio VST / VSTi Engine Service
import os
import numpy as np
from ctypes import c_int, c_char_p, c_void_p
def midi_note_to_freq(note_number: int) -> float:
return 440.0 * (2.0 ** ((note_number - 69) / 12.0))
@@ -72,6 +73,12 @@ def check_pyfluidsynth_safe():
HAS_PEDALBOARD = check_pedalboard_safe()
HAS_PYFLUIDSYNTH = check_pyfluidsynth_safe()
def ensure_pyfluidsynth():
global HAS_PYFLUIDSYNTH
if not HAS_PYFLUIDSYNTH:
HAS_PYFLUIDSYNTH = check_pyfluidsynth_safe()
return HAS_PYFLUIDSYNTH
if HAS_PEDALBOARD:
try:
from pedalboard import VST3Plugin, Pedalboard, Gain, MidiMessage
@@ -165,32 +172,54 @@ class PluginManager:
return None
def list_soundfont_instruments(self, sf_id: str):
if not HAS_PYFLUIDSYNTH:
if not ensure_pyfluidsynth():
return []
dirs = [self.sf_dir]
if self.upload_sf_dir:
dirs.append(self.upload_sf_dir)
for d in dirs:
search_dirs = []
if os.path.isdir(self.sf_dir):
search_dirs.append(self.sf_dir)
if self.upload_sf_dir and os.path.isdir(self.upload_sf_dir) and self.upload_sf_dir != self.sf_dir:
search_dirs.append(self.upload_sf_dir)
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_", ""):
path = os.path.join(d, f)
try:
fl = fluidsynth.FluidSynth(sample_rate=44100, gain=0.2)
fl = fluidsynth.Synth()
fid = fl.sfload(path)
count = fl.sfont_get_preset_count(fid)
if fid < 0:
fl.delete()
continue
presets = []
for pi in range(count):
try:
name = fl.sfont_get_preset_name(fid, pi)
bank, prog = fl.sfont_get_preset_bank_num(fid, pi), fl.sfont_get_preset_prog_num(fid, pi)
presets.append({"bank": bank, "program": prog, "name": name})
except Exception:
pass
# Use fluid_sfont_get_preset + fluid_preset_get_name C API
_fl = fluidsynth._fl
_fl.fluid_synth_get_sfont_by_id.restype = c_void_p
_fl.fluid_preset_get_name.restype = c_char_p
_fl.fluid_sfont_get_preset.restype = c_void_p
sfont_ptr = _fl.fluid_synth_get_sfont_by_id(c_void_p(fl.synth), c_int(fid))
if sfont_ptr:
for bank in range(0, 2):
for prog_num in range(0, 128):
try:
preset = fluidsynth.fluid_sfont_get_preset(sfont_ptr, c_int(bank), c_int(prog_num))
except Exception:
break
if preset:
name_ptr = fluidsynth.fluid_preset_get_name(preset)
if name_ptr:
name_val = c_char_p(name_ptr).value
if name_val:
presets.append({
"bank": bank,
"program": prog_num,
"name": name_val.decode("utf-8", errors="replace")
})
fl.delete()
return presets
return presets[:256]
except Exception:
pass
import traceback; traceback.print_exc()
return []
def list_available(self) -> dict: