Gap 12: soundfont render qua native bridge — render_soundfont_offline (FluidSynth C API) thay pyfluidsynth khi thiếu lib; render_engine soundfont branch fallback bridge (test_64, 176 passed)
This commit is contained in:
@@ -603,11 +603,11 @@ class PythonRenderEngine:
|
||||
)
|
||||
elif soundfont_id or (instrument_id and instrument_id.startswith("sf_")):
|
||||
sf_path = _find_sf2_path(soundfont_id or instrument_id)
|
||||
# 3-level fallback: selected SF → default SF → oscillator synth
|
||||
if not sf_path or not os.path.exists(sf_path) or not HAS_PYFLUIDSYNTH:
|
||||
if not sf_path or not os.path.exists(sf_path):
|
||||
logger.warning(f"[RenderEngine] SoundFont not found for {soundfont_id or instrument_id}, trying default")
|
||||
sf_path = _find_default_sf2() if HAS_PYFLUIDSYNTH else ""
|
||||
# 4-level fallback: selected SF → default SF → native bridge → oscillator synth.
|
||||
# Gap 12: pyfluidsynth thiếu FluidSynth lib → bridge render SF2 thật thay vì oscillator.
|
||||
if not sf_path or not os.path.exists(sf_path):
|
||||
logger.warning(f"[RenderEngine] SoundFont not found for {soundfont_id or instrument_id}, trying default")
|
||||
sf_path = _find_default_sf2()
|
||||
|
||||
if sf_path and os.path.exists(sf_path) and HAS_PYFLUIDSYNTH:
|
||||
import fluidsynth as _fs
|
||||
@@ -651,9 +651,39 @@ class PythonRenderEngine:
|
||||
_cursor = end_s
|
||||
synth_buffer = midi_data
|
||||
_fs.delete_fluid_synth(_fl)
|
||||
elif sf_path and os.path.exists(sf_path) and settings.RENDER_ENGINE == "bridge":
|
||||
# Gap 12: native bridge nhúng FluidSynth C API — render SF2/SF3 thật
|
||||
# khi pyfluidsynth thiếu (RENDER_ENGINE=bridge mặc định).
|
||||
try:
|
||||
from app.core import native_render
|
||||
out_path, _dur = native_render.render_soundfont_offline(
|
||||
sf_path=sf_path,
|
||||
notes=[{
|
||||
"pitch": ev["note"],
|
||||
"velocity": float(ev["velocity"]) / 127.0,
|
||||
"start_beat": ev["start_beat"],
|
||||
"duration_beats": ev["duration_beats"],
|
||||
} for ev in midi_events],
|
||||
bpm=bpm,
|
||||
sample_rate=self.sample_rate,
|
||||
bank=soundfont_bank,
|
||||
program=soundfont_program,
|
||||
)
|
||||
synth_buffer, _ = sf.read(out_path, dtype="float32")
|
||||
if synth_buffer.ndim == 1:
|
||||
synth_buffer = np.vstack([synth_buffer, synth_buffer])
|
||||
else:
|
||||
synth_buffer = synth_buffer.T
|
||||
try:
|
||||
os.remove(out_path)
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.warning("[RenderEngine] native soundfont render failed: %s", e)
|
||||
synth_buffer = render_midi_events_to_audio(
|
||||
midi_events=midi_events, sr=self.sample_rate, bpm=bpm, instrument='synth'
|
||||
)
|
||||
else:
|
||||
if not HAS_PYFLUIDSYNTH:
|
||||
logger.warning("[RenderEngine] pyfluidsynth not available, falling back to oscillator synth")
|
||||
synth_buffer = render_midi_events_to_audio(
|
||||
midi_events=midi_events, sr=self.sample_rate, bpm=bpm, instrument='synth'
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user