feat: VSTi autosample -> SF2/SF3 (tools/autosample_vsti.py) + bit_depth 16/24/32 render/export WAV (render_engine, plugins API, audio_editor, app.jsx encoders) + tests + task/walkthrough docs (53)
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
"""Tests cho tools/autosample_vsti.py — SF2 writer tự-sinh phải là RIFF/sfbk
|
||||
hợp lệ mà sf2utils parse được (không cần VSTi/pedalboard)."""
|
||||
import os
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from tools.autosample_vsti import write_sf2
|
||||
|
||||
sf2utils = pytest.importorskip("sf2utils.sf2parse")
|
||||
|
||||
|
||||
def _sine(note, sr=44100, dur=0.2):
|
||||
t = np.arange(int(sr * dur)) / sr
|
||||
f = 440.0 * 2 ** ((note - 69) / 12)
|
||||
return (np.sin(2 * np.pi * f * t) * 20000).astype(np.int16)
|
||||
|
||||
|
||||
def test_write_sf2_valid_structure(tmp_path):
|
||||
out = str(tmp_path / "test.sf2")
|
||||
samples = [{"note": n, "frames": _sine(n)} for n in (60, 62, 64)]
|
||||
write_sf2(out, samples, sample_rate=44100, name="Test")
|
||||
assert os.path.getsize(out) > 100
|
||||
with open(out, "rb") as f:
|
||||
head = f.read(12)
|
||||
assert head[:4] == b"RIFF"
|
||||
assert head[8:12] == b"sfbk"
|
||||
with open(out, "rb") as f:
|
||||
sf2 = sf2utils.Sf2File(f)
|
||||
real_samples = [s for s in sf2.samples if s.end > s.start]
|
||||
assert len(real_samples) == 3
|
||||
assert len(sf2.presets) == 2 # preset + terminator
|
||||
assert sf2.presets[0].bank == 0
|
||||
assert sf2.presets[0].preset == 0
|
||||
assert sf2.presets[0].name == "Test"
|
||||
for s in real_samples:
|
||||
assert s.end - s.start == 8820
|
||||
assert s.sample_rate == 44100
|
||||
|
||||
|
||||
def test_write_sf2_rejects_empty(tmp_path):
|
||||
with pytest.raises(ValueError):
|
||||
write_sf2(str(tmp_path / "empty.sf2"), [])
|
||||
|
||||
|
||||
def test_write_sf2_odd_name_no_corruption(tmp_path, caplog):
|
||||
"""INFO text chunk chan — ten le (vd "Nexus") khong duoc lam mat can
|
||||
(sf2utils khong skip pad byte cua odd-size chunk)."""
|
||||
import logging
|
||||
out = str(tmp_path / "odd.sf2")
|
||||
write_sf2(out, [{"note": 60, "frames": _sine(60)}], 44100, name="Nexus")
|
||||
with caplog.at_level(logging.WARNING):
|
||||
with open(out, "rb") as f:
|
||||
sf2 = sf2utils.Sf2File(f)
|
||||
assert len([s for s in sf2.samples if s.end > s.start]) == 1
|
||||
assert not any("corrupted" in r.message for r in caplog.records)
|
||||
Reference in New Issue
Block a user