59 lines
2.3 KiB
Python
59 lines
2.3 KiB
Python
"""Phase 2: native_render client (thay pedalboard bằng native_bridge --render).
|
|
|
|
Unit: phân loại plugin, tìm bridge, instrument lạ → 404. E2E nhỏ: bridge render
|
|
SF2 thật ra WAV đúng duration (giống native_bridge/tests/test_offline_render.py).
|
|
Skip nếu máy thiếu bridge exe hoặc file SF2 fixture."""
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import tempfile
|
|
|
|
import pytest
|
|
import soundfile as sf
|
|
from fastapi import HTTPException
|
|
|
|
from app.core import native_render
|
|
|
|
|
|
def test_classify_instrument():
|
|
assert native_render.classify_instrument(r"C:\VST\Vital.vst3") == 0
|
|
assert native_render.classify_instrument(r"C:\VST\foo.dll") == 1
|
|
assert native_render.classify_instrument(r"C:\SF\a.sf2") == 2
|
|
assert native_render.classify_instrument(r"C:\SF\a.sf3") == 2
|
|
assert native_render.classify_instrument(r"C:\SF\a.sfz") == 3
|
|
|
|
|
|
def test_find_bridge_exe_dev():
|
|
exe = native_render.find_bridge_exe()
|
|
assert exe, "không tìm thấy bridge exe (install/ hoặc SF_BRIDGE_PATH)"
|
|
assert os.path.isfile(exe)
|
|
|
|
|
|
def test_render_offline_unknown_instrument_404():
|
|
with pytest.raises(HTTPException) as ei:
|
|
native_render.render_offline("__no_such_plugin__", [], bpm=120.0, sample_rate=44100)
|
|
assert ei.value.status_code == 404
|
|
|
|
|
|
def test_bridge_render_sf2_e2e():
|
|
exe = native_render.find_bridge_exe()
|
|
if not exe:
|
|
pytest.skip("bridge exe missing")
|
|
sf2 = r"C:\Users\locpham\SonicForgeStudio\app\storage\soundfonts\518e850f-a5d3-4790-b1f9-0c90c203c524.sf2"
|
|
if not os.path.isfile(sf2):
|
|
pytest.skip("SF2 fixture missing")
|
|
with tempfile.TemporaryDirectory() as td:
|
|
job = {"instrument_type": 2, "plugin_path": sf2, "sample_rate": 44100, "bpm": 120.0,
|
|
"notes": [{"pitch": 60, "velocity": 101, "start_beat": 0.0, "duration_beats": 1.0}]}
|
|
jp = os.path.join(td, "job.json")
|
|
out = os.path.join(td, "out.wav")
|
|
with open(jp, "w", encoding="utf-8") as fh:
|
|
json.dump(job, fh)
|
|
r = subprocess.run([exe, "--render", jp, "--out", out],
|
|
capture_output=True, text=True, timeout=120)
|
|
assert r.returncode == 0, ((r.stdout or "") + (r.stderr or ""))[-500:]
|
|
assert os.path.isfile(out)
|
|
info = sf.info(out)
|
|
assert info.samplerate == 44100
|
|
assert info.frames == 22050
|