import os import json import pytest from app.core.render_engine import PythonRenderEngine def test_render_engine_init(): engine = PythonRenderEngine() assert engine.sample_rate == 44100 def test_bars_to_samples(): engine = PythonRenderEngine() samples = engine.bars_to_samples(4.0, 120.0, 4) assert samples == 352800 def test_render_session_container_empty(): engine = PythonRenderEngine() session = {"tracks": []} buf = engine.render_session_container(session, {}, 120.0, 4, 1000) assert buf.shape == (2, 1000) assert (buf == 0.0).all() def _midi_track(instrument_id, fx_type=None): return { "id": "t1", "type": "MIDI", "instrument_id": instrument_id, "instrument_source": "vsti", "fx_type": fx_type, "volume_db": 0.0, "pan": 0.0, "mute": False, "items": [{ "type": "MIDI_ITEM", "start_bar": 0.0, "duration_bars": 1.0, "clip_start_offset_bars": 0.0, "source_data": { "notes": [ {"pitch": 60, "velocity": 0.8, "start_beat": 0.0, "duration_beats": 1.0} ] }, }], } def test_render_session_vsti_bridge_unknown_instrument_falls_back(monkeypatch): """SF_RENDER_ENGINE=bridge: track VSTi đi vào native_render; instrument lạ (404) → fallback oscillator, không crash, không cần pedalboard.""" from app.api.v1 import plugins as pl monkeypatch.setattr(pl.settings, "RENDER_ENGINE", "bridge") engine = PythonRenderEngine() session = {"tracks": [_midi_track("__no_such_plugin__")]} buf = engine.render_session_container(session, {}, 120.0, 4, 44100) assert buf.shape == (2, 44100) # oscillator sinh âm thật (non-silent) assert (buf != 0.0).any() def test_render_session_vsti_pedalboard_default_falls_back(monkeypatch): """Mặc định pedalboard: không có plugin load được → oscillator (không crash).""" from app.api.v1 import plugins as pl monkeypatch.setattr(pl.settings, "RENDER_ENGINE", "pedalboard") engine = PythonRenderEngine() session = {"tracks": [_midi_track("__no_such_plugin__")]} buf = engine.render_session_container(session, {}, 120.0, 4, 44100) assert buf.shape == (2, 44100) def test_render_session_fx_chorus_scipy_fallback(): """FX chorus: fallback scipy (không pedalboard) không crash, thay đổi âm.""" from app.api.v1 import plugins as pl pl.settings.RENDER_ENGINE = "pedalboard" engine = PythonRenderEngine() session = {"tracks": [_midi_track("__no_such_plugin__", fx_type="chorus")]} buf = engine.render_session_container(session, {}, 120.0, 4, 44100) assert buf.shape == (2, 44100) assert (buf != 0.0).any() def test_render_session_fx_reverb_scipy_fallback(): """FX reverb: fallback scipy (không pedalboard) không crash, thay đổi âm.""" from app.api.v1 import plugins as pl pl.settings.RENDER_ENGINE = "pedalboard" engine = PythonRenderEngine() session = {"tracks": [_midi_track("__no_such_plugin__", fx_type="reverb")]} buf = engine.render_session_container(session, {}, 120.0, 4, 44100) assert buf.shape == (2, 44100) assert (buf != 0.0).any()