docs: design VST2 backward compatibility for standalone-shm-bridge

This commit is contained in:
2026-08-16 21:04:31 +07:00
parent cead8c8c71
commit 4f6e2bc049
+102
View File
@@ -0,0 +1,102 @@
# 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.