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
11 KiB
11 KiB
DESKTOP INSTALL PLAN — SonicForge Studio (bản cài trực tiếp trên OS)
Mô hình: server chạy nền trên máy người dùng (localhost), client mở bằng browser. Không cần Electron — tận dụng stack hiện có (FastAPI + static JS precompiled). Soundfonts do người dùng tự tải vào thư mục riêng và khai báo cho ứng dụng.
1. KIẾN TRÚC
┌─────────────────────────── NGƯỜI DÙNG (1 máy) ───────────────────────────┐
│ Browser ──http://127.0.0.1:8000──▶ FastAPI (uvicorn, chạy NỀN) │
│ │ │
│ ~/SonicForgeStudio/ ├─ data/ (DB, uploads, cache) │
│ ├─ data/sonicforge.db ├─ soundfonts/ (user tự bỏ .sf2) │
│ ├─ soundfonts/*.sf2/.sf3 └─ quét nền 30s (scanner có sẵn) │
│ └─ config.json ← khai báo folder soundfont │
└──────────────────────────────────────────────────────────────────────────┘
2. ĐÓNG GÓI CÀI ĐẶT (per-OS) — server nền + browser client
Thành phần đóng gói
| Thành phần | Vai trò |
|---|---|
Python backend (app/, requirements.txt) |
Server — PyInstaller --onedir → binary (không cần Python trên máy user; bảo vệ source tốt hơn so với chạy .py) |
app/static/ (precompiled.js + css + vendor) |
Client — đóng vào package, server phục vụ |
VST3 plugins (vst_plugins/) |
Copy theo platform (win .dll / mac .vst3 / linux .so) |
| Service wrapper | Tự khởi động server nền + mở browser khi login |
Cài đặt + service nền theo OS
| OS | Installer | Service nền | Auto-open browser |
|---|---|---|---|
| Windows | Inno Setup (.exe) |
Windows Service qua NSSM/WinSW hoặc Task Scheduler (logon) |
start http://127.0.0.1:8000 |
| macOS | .dmg + .app (PyInstaller) |
launchd LaunchAgent (~/Library/LaunchAgents) |
open http://127.0.0.1:8000 |
| Linux | .deb / .AppImage |
systemd user service (~/.config/systemd/user/) |
xdg-open http://127.0.0.1:8000 |
- Server bind
127.0.0.1(không lộ mạng), port mặc định 8000 (config được). - App gồm 2 tiến trình nhỏ:
web(uvicorn) +worker(celery) — hoặc gộp worker vào web ở chế độ desktop (đơn giản:--pool=solo, chạy celery trong tiến trình riêng nếu cần render nặng).
3. THƯ MỤC DỮ LIỆU NGƯỜI DÙNG
~/SonicForgeStudio/
├── data/ # DB, uploads, processed (thay app/storage khi chạy desktop)
├── soundfonts/ # USER tự tải .sf2/.sf3 vào đây (mặc định được quét)
└── config.json # cấu hình: soundfont_dirs, port, autostart...
config.py: thêmDATA_DIR(envSFDATA_DIR, mặc định~/SonicForgeStudio/data),SOUNDFONT_DIRS.
4. SOUNDFONT DO NGƯỜI DÙNG QUẢN LÝ (tải + khai báo)
Cơ chế hiện có (tận dụng): app/core/soundfont_scanner.py — SoundFontAutoScanner quét nền 30s
/opt/daw_engine/soundfonts + storage/soundfonts → catalog → API list qua app/api/v1/plugins.py.
Việc cần làm (mở rộng):
- Scanner nhận folder người dùng: constructor nhận thêm
user_dirs(từSOUNDFONT_DIRSenv +config.json) — merge vào catalog (ưu tiên: user > system). - Khai báo folder — 2 cách:
- UI (chính): Settings → "Soundfonts" → nút Add folder… (chọn thư mục chứa .sf2) → lưu vào
config.json→ gọi scanner rescan. - config.json (thủ công):
{ "soundfont_dirs": ["D:/SF", "/Users/me/sf"] }.
- UI (chính): Settings → "Soundfonts" → nút Add folder… (chọn thư mục chứa .sf2) → lưu vào
- API: thêm endpoint
POST /api/v1/plugins/soundfonts/dirs(đăng ký folder) +GET .../dirs(liệt kê) — scanner reload. - UI danh sách: hiển thị catalog (tên SF, kích thước, folder nguồn) — chọn = load vào FluidSynth (luồng có sẵn qua
SonicSF.selectInstrument). - Số hóa: không upload file — server đọc trực tiếp từ đường dẫn user khai báo (không nhân đôi dữ liệu).
5. BUILD + PHÁT HÀNH
code → build.mjs (precompiled + ?v=) → PyInstaller (server binary) → đóng installer theo OS
→ ký số (tùy chọn) → phát hành (GitHub Releases / trang riêng)
- GitHub Actions matrix (windows-latest / macos-latest / ubuntu-latest): test → build → installer artifact.
- Installer gồm: binary server, static/, VST plugins nền tảng, script tạo service + mở browser, mặc định tạo
~/SonicForgeStudio/lần chạy đầu.
5.1 Tối ưu bundle daw_engine (bản 1.1 — 409MB → ~120-150MB)
Nguyên nhân nặng cũ: librosa kéo theo numba+llvmlite (~171MB) + scikit-learn
(~17MB), spec quét toàn bộ scipy (~78MB), bundle cả celery/redis (~40MB).
Đã xử lý:
app/core/audio_features.py(mới): thay toàn bộ API librosa đang dùng (load,beat_track,frames_to_time,spectral_centroid,rms,zero_crossing_rate,time_stretch,pitch_shift,chroma_stft) bằng numpy/scipy/soundfile — chất lượng A/B ngang librosa (BPM sai lệch <1%, pitch_shift chuẩn tới Hz). Các moduleanalyzer.py,dsp_utils.py,sub_tab_dsp.py,ai_dsp_engine.pyđã chuyển sang shim.app/tasks/worker.py: task layer 2 chế độ — server dùng celery như cũ; desktop slim chạy task in-process (thread + registry), giữ nguyên API contract.delay()//tasks/{id}nên frontend KHÔNG phải đổi.engine.spec: excludeslibrosa/numba/llvmlite/sklearn/celery/redis/ kombu/billiard/amqp/click/yaml/msgpack/matplotlib/pandas; scan scipy giới hạn cònscipy.signal(goi duy nhất app còn dùng).src-tauri/tauri.conf.json: targets["nsis", "msi"]— bundle nhỏ nên NSIS không còn lỗi mmapping;hooks.nshcài VC++ Redistributable (MSI không chạy hooks → máy thiếu VC++ → daw_engine.exe không chạy — đây là nguyên nhân "build xong không chạy daw_engine" trên Windows).- Fix layout resources (bản 1.1.1 —
exists=falsetrong spawn.log):bundle.resourcesdạng ARRAY["resources/daw_engine"]copy engine tới$RESOURCE_DIR/resources/daw_engine/...(giữ tiền tốresources/— đọc sourcetauri-utils/src/resources.rs) trong khi lib.rs tìm ở$RESOURCE_DIR/daw_engine/...→exists=false. Đổi sang dạng MAP{"resources/daw_engine": "daw_engine/"}(Walk mode, giữ nguyên cây_internal, đích chuẩndaw_engine/).src-tauri/src/lib.rsđồng thời dò thêm 3 vị trí fallback (legacy/portable/dev) + ghi diagnostic đầy đủ vào%APPDATA%/SonicForgeDAW/logs/spawn.log(liệt kê nội dung resource_dir khi không tìm thấy).
Lệnh build 1 lệnh mỗi OS:
# Windows (PowerShell, ASCII-only)
powershell -ExecutionPolicy Bypass -File build_windows.ps1
# Linux (cần binutils: sudo apt-get install -y binutils)
bash build_linux.sh
# macOS (cần codesign/notarize khi phát hành)
bash build_macos.sh
5.2 KIẾN TRÚC 2 SIDECAR (Native Host Bridge — bản 1.2)
Từ bản 1.2, bản desktop chạy Tauri v2 shell + 2 sidecar (không còn browser):
┌───────────────────────── SonicForgeDAW (Tauri v2) ─────────────────────────┐
│ WebView2 (UI HTML5/JS — app.precompiled.js) │
│ ▲ invoke ▲ bridge-audio (event) │
│ Rust shell (src-tauri) │
│ ├── spawn+watchdog ──► daw_engine.exe (FastAPI sidecar, port 8000) │
│ └── spawn+health ────► daw_vst_bridge.exe (C++ Native Host Bridge) │
│ │ SharedMemory "SonicForge_DAW_IPC" │
│ │ (MidiEventIPC / ControlEventIPC / audio) │
│ └─ FluidSynth / sfizz / VST3 host │
└────────────────────────────────────────────────────────────────────────────┘
- MIDI → âm: Web MIDI/timeline →
push_midi_event(Rust ghi SHM) → bridge render block 256 (FluidSynth/sfizz/VST3) → Rust audio pump emitbridge-audio→ WebView2 ScriptProcessor → track FX → master → loa. - Fallback: bridge chết →
SonicSF(FluidSynth WASM) tự bật, app không crash. - YC runtime: cả
daw_engine.exelẫndaw_vst_bridge.execần VC++ 2015-2022 Redistributable —hooks.nsh(NSIS) càivc_redist.x64.exe; MSI không chạy hooks → máy sạch nên cài NSIS hoặc tự cài redist. - Binaries: engine =
src-tauri/resources/daw_engine/(bundle.resources), bridge =src-tauri/binaries/daw_vst_bridge-x86_64-pc-windows-msvc.exe(bundle.externalBin). - Build bridge:
build/scripts/build_native_bridge.ps1(vcpkg fluidsynth/ sfizz + submodule vst3sdk + CMake MSVC) → copy exe vàosrc-tauri/binaries/. - API mới:
GET /api/v1/bridge/status,POST /api/v1/bridge/load,GET /api/v1/bridge/log(engine giữ trung gian IPC file%APPDATA%/SonicForgeDAW/ipc/). - Logs:
%APPDATA%/SonicForgeDAW/logs/spawn.log(engine+bridge),bridge.log.
6. CẬP NHẬT
- Version check: khi mở app, gọi endpoint version (file
version.jsonđóng kèm + so sánh remote) → thông báo bản mới + link tải installer. - Cập nhật = chạy installer mới (ghi đè, GIỮ NGUYÊN
~/SonicForgeStudio/— data + soundfonts không đụng). ?v=cache-bust JS mỗi bản (cơ chế đã có) — browser không dính cache cũ.
7. CHECKLIST CODE CẦN LÀM
config.py:DATA_DIR,SOUNDFONT_DIRS(env + config.json)soundfont_scanner.py: nhậnuser_dirs, merge catalog, ưu tiên user- API:
POST/GET .../soundfonts/dirs(đăng ký/liệt kê folder) + rescan - UI Settings → Soundfonts (Add folder, Browse, list, load)
soundfontStorage.js: chuyển hướng sang catalog folder-scan (giữ upload path cho dự án cũ)- PyInstaller spec: bundle static/ + vendor (libfluidsynth wasm, vst), bind 127.0.0.1
- Service wrappers: Windows (NSSM/WinSW), macOS (launchd), Linux (systemd user) + auto-open browser
- Installer scripts: Inno Setup (.exe), dmg (macOS), deb/AppImage (Linux)
- CI matrix build 3 OS + release artifacts
version.json+ in-app update check