103 lines
5.4 KiB
Markdown
103 lines
5.4 KiB
Markdown
# Thiết kế: tương thích ngược VSTi cũ (VST2, 32-bit) — bridge âm thanh
|
|
|
|
Ngày: 2026-08-15
|
|
Trạng thái: THIẾT KẾ (chưa sửa code sản phẩm). Linux làm thiết kế + spike khả
|
|
thi; code theo thoả thuận triển khai (Windows).
|
|
|
|
## 1. Mục tiêu
|
|
Standalone bridge (`standalone-shm-bridge`) hiện chỉ host VST3. Nhiều VSTi cũ
|
|
(vintage, freeware, 32-bit) chỉ có bản VST2. Mục tiêu: VST2 64-bit phát được qua
|
|
bridge chính (headless, realtime), không phá luồng VST3 hiện tại.
|
|
|
|
## 2. Hiện trạng (đã xác minh trên code)
|
|
|
|
### VST2 không được implement trong bridge
|
|
- `native_bridge/src/NativeInstrumentEngine.cpp:166-180` — `create_instrument()`:
|
|
`case VST2: return nullptr` + comment
|
|
"ponytail: VST2 host (VST2.4 SDK, Steinberg discontinued) not implemented".
|
|
- Enum đã có sẵn: `native_bridge/src/INativeInstrument.h:8-12`
|
|
(VST3=0, VST2=1, SF2/SF3=2, SFZ=3).
|
|
- `StateStore.h:14` — type 1 = VST2.
|
|
|
|
### Backend đã nhận diện VST2 (scan + UI)
|
|
- `app/api/v1/plugins.py:117-130,224-247` — file `.dll` (không phải folder
|
|
`.vst3`) → `"type":"VST2"`.
|
|
- `app/vst_engine.py:282-300` — scan `.vst3/.so/.dll`.
|
|
- JS mapping: `nativeBridgeService.js:7` `INSTRUMENT_TYPE={VST3:0,VST2:1,SF2:2,SF3:2,SFZ:3}`.
|
|
|
|
→ Hệ quả: UI liệt kê plugin VST2 là loại hợp lệ, user assign → bridge
|
|
`create_instrument` trả nullptr → `assign` false → fail **im lặng**, không có
|
|
lỗi nào hiển thị. Đây là bug UX chính cần sửa kèm.
|
|
|
|
### Đường khác không thay thế
|
|
- Carla (Windows) hỗ trợ VST2 nhưng là đường GUI/preset riêng
|
|
(`plugins.py:530-630` carla-midi/carla-play-notes/open-in-carla), KHÔNG phải
|
|
đường audio bridge chính.
|
|
- Preset `.fxp/.fxb` nằm trong `PRESET_EXTENSIONS` (`vst_engine.py:592`) nhưng
|
|
`apply_preset_to_plugin` gọi `load_preset` của VST3Plugin — không chạy VST2.
|
|
|
|
### Hạ tầng tái dùng được
|
|
- `SandboxVst3Host` + `SandboxHostIPC` double-buffer
|
|
(`SharedMemoryIPC.h:33-39`), `plugin_host_main.cpp`, env `SF_SANDBOX_VST3` —
|
|
pattern sẵn cho helper process 32-bit.
|
|
- Build: `native_bridge/vcpkg.json` chỉ fluidsynth+pkgconf; VST3 SDK là git
|
|
submodule `vst3sdk` (không có vestige — cần thêm header nếu làm VST2 host);
|
|
CMake `-EHa`.
|
|
|
|
## 3. Thiết kế đề xuất
|
|
|
|
### 3.1. VST2 64-bit — host `Vst2Instrument` dùng vestige (làm trước)
|
|
- **vestige** (`vestige/aeffect.h`, mã nguồn mở, từ dự án LMMS): header-only,
|
|
tự định nghĩa lại interface + ABI VST2.4 (vtable layout, dispatcher opcode).
|
|
Không cần Steinberg VST2 SDK (đã discontinued, license không cấp mới) →
|
|
sạch pháp lý, zero dependency build, không submodule mới.
|
|
- `Vst2Instrument` implement cùng interface `INativeInstrument`:
|
|
assign / SHM double-buffer / renderAll tái dùng nguyên trạng.
|
|
- Phạm vi audio headless: `processReplacing`, `setSampleRate`, `setBlockSize`,
|
|
`resume`/`suspend`, `getParameter`/`setParameter`, `effGetChunk`/`effSetChunk`
|
|
(preset .fxp/.fxb), `effGetParamLabel` (tên tham số cho UI).
|
|
- GUI editor: **defer** (không window, không thread GUI). Nhiều VSTi cổ vẫn
|
|
phát headless; plugin nào đòi GUI mới ra tiếng thì ghi rõ giới hạn ở UI.
|
|
- Sửa kèm bug im lặng: khi `create_instrument` trả nullptr → trả lỗi rõ ràng
|
|
lên UI thay vì fail câm.
|
|
|
|
### 3.2. VST2 32-bit — helper process (defer, effort cao)
|
|
- Helper `plugin_host.exe` 32-bit, tái dùng pattern `SandboxVst3Host` +
|
|
`SandboxHostIPC` double-buffer + env `SF_SANDBOX_VST3`.
|
|
- Lý do defer: cần bản build 32-bit riêng, xử lý wow64 + marshalling
|
|
(MIDI/sample rate/block size qua IPC), khó debug. Làm sau khi 64-bit ổn định.
|
|
|
|
### 3.3. Quirk plugin cũ (khi test thực tế)
|
|
- Block size: thử 256 / 512 / 1024 (nhiều plugin cũ chỉ nhận bội số cố định).
|
|
- Sample rate: 44.1 kHz là mặc định an toàn nhất.
|
|
- Thread affinity: open + process cùng 1 thread; tránh đổi thread giữa
|
|
`resume` và vòng render.
|
|
- Plugin 32-bit đòi GUI: một số chỉ phát sau khi editor từng mở — ghi rõ
|
|
giới hạn, không cố host GUI trong bridge.
|
|
|
|
### 3.4. Giới hạn docker/server
|
|
- `pedalboard` không hỗ trợ VST2 → pipeline VSTi→SF2 (`DESIGN_DOCKER_VSTI_PLAY.md`)
|
|
chỉ nhận VST3. VST2 không render được asset SF2 trên server. Ghi rõ ở UI.
|
|
|
|
## 4. Kiến trúc thêm mới (tối thiểu)
|
|
```
|
|
native_bridge/
|
|
vestige/aeffect.h # header mã nguồn mở (thêm file)
|
|
src/Vst2Instrument.h/.cpp # host VST2, implement INativeInstrument
|
|
src/NativeInstrumentEngine.cpp # case VST2 -> new Vst2Instrument
|
|
```
|
|
Không đổi ABI, không đổi `SharedMemoryIPC`, không đổi JS service layer.
|
|
|
|
## 5. Rủi ro / giới hạn
|
|
- Vài plugin rất cổ đòi host callback lạ (`effGetPlugCategory`, vendor opcode)
|
|
→ patch nhỏ riêng từng plugin.
|
|
- Vestige không cung cấp editor GUI → plugin phụ thuộc GUI sẽ câm.
|
|
- ABI VST2 ổn định từ 1999 → 64-bit .dll hiện đại + cổ đều theo, rủi ro thấp.
|
|
|
|
## 6. Thứ tự triển khai
|
|
1. `Vst2Instrument` + vestige: load, assign, render thử 1 plugin VST2 64-bit.
|
|
2. Sửa bug fail im lặng khi không host được.
|
|
3. Preset .fxp/.fxb qua `effSetChunk`/param.
|
|
4. Test block size / sample rate / thread affinity với plugin cổ.
|
|
5. (Defer) 32-bit helper process.
|