c3368d0a91
- native_bridge/: InstrumentEngineManager multi-channel, sample-accurate, CC/program/pitchbend, transport, Vst3Instrument stub (HAVE_VST3SDK) - src-tauri: shm.rs, bridge spawn + audio pump + health monitor, open_vst_gui, externalBin, commands - app: UnifiedMidiRouter, NativeBridgeService, bridgeAudioNode, audioRoutingEngine, Plugin Manager UI, Bridge/WASM indicator, set_position sync - build: 3 ps1 (force-added, build/ ignored), verify_bundle --check-bridge, CI workflow - docs: TASKS.md, TEST_NOTES.md (Windows verify checklist), install/report updates
7.4 KiB
7.4 KiB
TEST NOTES — NATIVE BRIDGE (test trên máy native/Windows)
Máy phát triển hiện tại (Linux, không rustc/CMake-MSVC, Python SIGILL khi import
app.core.vst_engine) KHÔNG chạy được pipeline. Danh sách này là "bộ nhớ" —
chạy từng mục trên máy Windows (hoặc OS native có đủ toolchain), đánh dấu ✅ khi pass.
A. C++ bridge (native_bridge/)
- A5+A13: TRANSPORT type=3 (STOP flush / PLAY / SET_POSITION) + log mỗi load — code OK, chưa chạy thật
- A10: InstrumentEngineManager multi-channel (std::map channel→instrument) — code OK, chưa compile Windows
- A11: sample-accurate segment render theo sampleOffset — code OK; JS hiện gửi sampleOffset=0 (best-effort)
- A12: CC/program/pitch bend (MidiEventIPC data2+data3) — code OK
- A6: Vst3Instrument host thật qua vst3sdk — load .vst3 → noteon → PCM ≠ 0
- A7: Vst3Instrument tách class + openGUI(hwnd)
- Windows verify sfizz API names:
SfizzInstrument::controlChangedùngsfizzSynth.cc(cc,val),pitchBenddùngsfizzSynth.pitchWheel(bend14)— nếu bản sfizz vcpkg chỉ cóhdCC/hdPitchWheelthì đổi;programChangeđang no-op (TODO) - Windows verify:
cargo check+ chạyshm_selfcheck.exe(sizeof struct = 11160 bytes)
B. Rust / Tauri (src-tauri/)
- B1-B4:
cargo checkpass trên Windows (windows-sys, shm.rs, lib.rs commands) - B2: SHM struct layout khớp C header (11160 bytes — đã verify C bằng selfcheck Linux; cần Rust)
- B2: signature commands mới —
push_midi_event(..., data2, data3, sample_offset),load_native_instrument(path, type, channel),transport_control(kind, playhead: Option<u32>)— JSnativeBridgeService.js/unifiedMidiRouter.jsđã sync - B5: audio pump thread emit
bridge-audio~5ms — ✅ code: pump thread trong lib.rs (~263-330): đọc bridgeWriteIndex → emitbridge-audio; stall 3s → B10 respawn; cần chạy thật Windows - B8: spawn bridge kèm
SF_SAMPLE_RATE=44100/SF_BLOCK_SIZE=256+ C++ main.cpp đọc env (block cố định 256, SR áp cho init engine) — code OK - B9:
open_vst_guitạo child WebviewWindow + HWND quaraw_window_handle→ control type=4 arg1 — code OK; close_gui khi window đóng chưa làm (chờ A7) - B10: health monitor trong audio pump — stall 3s → respawn 1 lần →
bridge-down; đếm restart vào bridge.log — code OK - B6: tauri.conf.json externalBin chứa daw_vst_bridge — ✅ code:
["binaries/daw_vst_bridge"]đã thêm (chưatauri buildverify) - B7: capabilities — ✅ review: window VST tạo từ Rust (
WebviewWindowBuilder), commands app-level, event listen nằm trongcore:default— không cần permission mới - B9 thật trên Windows: child window hiện + HWND hợp lệ (kiểm tra log bridge nhận type=4)
C. Frontend services
- C1-C7: node --check OK + bundle build OK (Linux)
- C5: ring buffer 8 block chống underrun thật trên Windows (âm nghe được, VU nhảy)
D. app.jsx wiring
- D1: onmidimessage NOTE_ON/OFF → router (code + bundle OK)
- D2: timeline → scheduleMidiNoteDispatch + transport play/stop (code + bundle OK)
- D9: bridgePlayheadSampleRef counter +
transport('set_position', playhead)~mỗi giây trong updatePlayhead (JS là nguồn playhead duy nhất; C++ A13 cập nhật anchor) — code + bundle OK - D1-D2 thật: bấm keyboard + play piano roll → âm qua bridge, Stop hết âm ngân
- D4: Carla không route khi bridge active (code, cần verify thật)
- D5: audio routing vào track FX chain
- D6: panic/Stop →
SonicMidiRouter.panic()(bridge transport panic + fallback SonicSF.stopAll) — 4 call site app.jsx đã đổi - D8: track→channel map + gửi CC0/CC32/PROGRAM trước NOTE_ON khi đổi instrument (scheduleMidiNoteDispatch)
- D7: UI Plugin Manager — badge
● Bridge ON/OFF(queryGET /api/v1/bridge/status), nút "Load Bridge" trên mỗi VST + SoundFont →POST /api/v1/bridge/load(E2 resolve path) →NativeBridgeService.loadInstrument(path, type, 0); code + bundle OK — chưa test thật trên Windows - D10: header indicator Bridge/WASM + nút "Ép WASM" (toggle
SonicMidiRouter.setForceWasm); service thêmonStatusChange(cb)— code + bundle OK
E. Backend Python
- E1-E3: syntax OK (ast.parse)
- E4: desktop_engine.py watchdog — verify: chỉ theo dõi
SF_PARENT_PID(Tauri) để tự thoát; không spawn/kill gì khác → không đụng bridge (bridge do Rust spawn). Không cần sửa. - E5:
GET /api/v1/bridge/log?lines=Ntail bridge.log — thêm Query import; ast.parse OK curl /api/v1/bridge/statustrảconnectedđúng — cần chạy trên máy không SIGILLPOST /api/v1/bridge/loadresolve sf2/vst3 → bridge load → UI nhậnbridge-audio- SIGILL khi import
app.core.vst_enginetrên máy dev (numpy/pedalboard pre-existing) — không phải do code mới
F. Build Windows
- F1-F3: 3 script đã copy vào repo
build/scripts/(ASCII-only, PS5.1-safe) — build_native_bridge (vcpkg+submodule+cmake), build_windows (7 bước), test_standalone (8 bước) - F4:
tools/verify_bundle.py --check-bridge— verify TOC + sidecar tồn tại; fail đúng cách trên Linux (chưa có exe) — test exit 1 OK - F5: hooks.nsh — vc_redist cài toàn máy (ExecWait /quiet) → đủ runtime cho cả daw_engine.exe + daw_vst_bridge.exe; MSI không chạy hooks → cài thủ công
- F6: DESKTOP_INSTALL_PLAN.md §5.2 (kiến trúc 2 sidecar) + DEPLOYMENT_REPORT.md bản 1.2
- F7:
.github/workflows/build-windows.yml— windows-latest: MSVC + Rust + node + python → build_windows.ps1 → upload NSIS/MSI - Chạy thật trên Windows: build_windows.ps1 trọn pipeline ra NSIS+MSI
G. Test end-to-end
- G1: shm_selfcheck pass (đã pass trên Linux: "SHM self-check OK (11160 bytes)" — chạy lại trên Windows)
- G2: SHM Rust tạo → bridge mở → MIDI → audio
- G3: load SGM-V2.01 (SF2) + SalamanderPiano (SFZ) + Vital (VST3)
- G4: live MIDI + timeline cùng lúc, latency <10ms
- G5: Track FX + Master FX tác động âm bridge
- G6: kill bridge → SonicSF fallback, không crash
- G7: test_standalone.ps1 5/5
- G8: đo latency blockTimestamp IPC ≤0.5ms, end-to-end <10ms
- G9: multi-instance 2 track đồng thời (A10 — 2 SF2/SFZ khác nhau, đổi live)
- G10: sustain/CC/pitchbend qua bridge (A12 — CC64 sustain + pitch wheel + CC7 volume)
Ghi chú batch 2026-08-11 (A10-A13 + D5)
- Struct SHM đổi 10872 → 11160: MidiEventIPC +data2/data3(+reserved) = 12B; ControlEventIPC +channel = 1040B.
Sync 3 nơi:
SharedMemoryIPC.h,shm.rs,shm_selfcheck.cpp— đã khớp (selfcheck pass Linux). - Bug pre-existing tìm thấy:
shm.rs push_controlkhông ghi pathlen vào arg1 → bridge cũ đọc path rỗng. Sửa: C++main.cppload path dùng strnlen(arg2); helper Cshm_write_controlchỉ set arg1=pathlen khi type==2. transport_controlRust giờ nhậnplayhead: Option<u32>; JSNativeBridgeService.transport(kind, playhead).loadInstrument(filePath, type, channel);dispatchMidiEvent(cmd,...,data2,data3)hỗ trợ CC/PROGRAM/PITCH_BEND.- Khi D8 (track→channel map) chưa xong: JS loadInstrument mặc định channel=0 — multi-instance chưa kích hoạt từ UI.