5.3 KiB
TASK 53: ALTERNATIVE SOLUTIONS FOR DIRECT VSTi USAGE IN STANDALONE DAW APPLICATIONS
Spec: "ALTERNATIVE SOLUTIONS FOR DIRECT VSTi USAGE IN STANDALONE DAW APPLICATIONS" Thực hiện trên
C:/Users/locpham/SonicForgeStudio(branchstandalone). Tài liệu đi kèm:md/53_VSTI_AUTOSAMPLE_RENDER_WALKTHROUGH.md.
1. Mục tiêu (từ spec)
| Option | Yêu cầu spec | Hiện thực |
|---|---|---|
| Option 1 | Client-side WASM live preview với 0% IPC — cần "a custom Python script" tự động sample các preset VSTi thành .sf3 (~3-8MB) |
tools/autosample_vsti.py — render từng nốt qua pedalboard → SF2 (16-bit mono), tùy chọn convert sang SF3 |
| Option 2 | Offline render/export qua Python backend (pedalboard VST3 + FluidSynth) — WAV chất lượng 24-bit / 32-bit | Thêm bit_depth (16/24/32) vào toàn bộ đường render/export backend + frontend |
2. Thay đổi
2.1 Auto-sampling tool (mới)
File: tools/autosample_vsti.py (mới, untracked)
- CLI:
--instrument <plugin_id> --out out.sf2 [--preset] [--low --high --step] [--sf3] [--duration --release --velocity --sample-rate] - Reuse
PluginManager().load_vst,apply_preset_to_plugin,HAS_PEDALBOARDtừapp/core/vst_engine.py - Render từng nốt bằng pedalboard, MIDI dạng raw tuple
(bytes([0x90,note,vel]), 0.0)/(bytes([0x80,note,0]), dur)— pedalboard 0.9.19 build này không cóNoteOnclasses; khớpPluginManager.midi_events_to_messages(trả(bytes, seconds)tuples) - Trim leading silence + normalize peak 0.9 trước khi cast int16
write_sf2(): SF2 tối giản hợp lệ — 16-bit mono PCM, 1 zone/nốt (keyRange lo=hi),sampleID,overridingRootKey,end=exclusive; preset 0/bank 0--sf3: convert quaSoundFontConverter(app/core/soundfont_converter.py); fallback giữ SF2 nếu thiếu ffmpeg libvorbis- Toàn bộ text ASCII-only (an toàn cp1252 console Windows)
SF2 writer — chi tiết đúng chuẩn (đã verify bằng sf2utils):
- INFO text chunk (INAM) phải chẵn — pad
\x00bên trong data (strict parsers không skip RIFF pad byte của odd chunk) - Records:
phdr38B (name20 +<HHHIII),inst22B,pmod/imod10B,pgen/igen4B (<HH),ibag/pbag4B,shdr46B; bắt buộc terminator records cho từng bảng
Kết quả verify: Nexus.vst3 → 3 nốt (60/62/64) → SF2 207KB, sf2utils parse sạch, audio peak 29490. Kontakt load được nhưng silent (không có .nki — đúng dự kiến).
2.2 bit_depth 16/24/32 WAV export (Option 2)
| File | Thay đổi |
|---|---|
app/core/render_engine.py |
render_project(self, project_json, output_filepath, bit_depth=16) (L453); subtype_map={16:"PCM_16",24:"PCM_24",32:"PCM_32"} → sf.write (L479-481) |
app/api/v1/plugins.py |
bit_depth: int = 16 thêm vào RenderRequest (L493), MidiRenderRequest (L937), SoundfontRenderRequest (L1063); truyền xuống engine.render_project(..., bit_depth=req.bit_depth) (L1200), _render_midi_notes_pedalboard(..., bit_depth=16) (signature L1001, sf.write L1048), soundfont_render sf.write L1100 |
app/core/audio_editor.py |
Cả 2 subtype map {8:"PCM_S8",16:"PCM_16",24:"PCM_24",32:"PCM_32"} (L196, L257) — mix multitrack + export |
app/static/js/app.jsx |
Option 32 thêm vào cả 2 dropdown export (L11355 JSX + compiled); encoder 32-bit (view.setInt32(... s*0x80000000 ...)) thêm vào cả 2 client WAV encoder — realtime bounce (L25044-25045) và offline-session (L25363-25368). Đồng thời sửa bug có sẵn: trước đây chọn 24-bit rơi vào nhánh fallback 8-bit |
2.3 Tests
tests/test_autosampler.py(mới):test_write_sf2_valid_structure(RIFF/sfbk, 3 samples, preset 0/bank 0, 8820 frames),test_write_sf2_rejects_empty,test_write_sf2_odd_name_no_corruption(regression: tên lẻ "Nexus" không làm sf2utils báo corrupted)tests/test_render_engine.py: thêmtest_render_project_bit_depth(16/24/32 → PCM_16/24/32)
3. Kết quả test
python -m pytest tests/ -q
→ 108 passed, 1 skipped, 1 failed
1 fail: tests/test_vst_engine.py::TestPluginManager::test_init — lỗi môi trường có sẵn (machine VST3 override C:\Program Files\Common Files\VST3 vs expected /opt/daw_engine/vst3; đã xác nhận fail cả trên code sạch bằng git stash). Không thuộc task này.
Lưu ý: không chạy
pytestbare từ root repo (collect torch resources dướisrc-tauri/target/release/resources/→ 52 collection errors). Luôn nhắmtests/.
4. Cách dùng
# Option 1 — auto-sample VSTi preset sang SF2 (client WASM preview, 0% IPC)
python tools/autosample_vsti.py --instrument Nexus.vst3 --out app/storage/soundfonts/nexus.sf2 --preset <path.vstpreset> --low 36 --high 96 --step 2
# ... hoặc sang SF3 (cần ffmpeg + libvorbis)
python tools/autosample_vsti.py --instrument Nexus.vst3 --out app/storage/soundfonts/nexus.sf3 --sf3
# Option 2 — render/export 24-bit/32-bit (API)
POST /api/v1/plugins/render { "project_json": {...}, "bit_depth": 24 }
POST /api/v1/plugins/midi-render { ..., "bit_depth": 32 }
POST /api/v1/plugins/soundfont-render { ..., "bit_depth": 24 }
SF2/SF3 đặt vào app/storage/soundfonts/ để client tải qua /soundfonts/download.