Hướng Dẫn Kiểm Thử SonicForge Studio
✅ Trạng Thái Hoàn Thành
Đã Hoàn Thành
- ✅ Cấu trúc thư mục - Toàn bộ kiến trúc app/
- ✅ Docker Configuration - Dockerfile + docker-compose.yml
- ✅ FastAPI Gateway - main.py, config.py, API endpoints
- ✅ Core DSP Engine - analyzer.py, dsp_utils.py, audio_editor.py
- ✅ Celery Workers - worker.py với task definitions
- ✅ Frontend UI - index.html với đầy đủ Web Audio API
- ✅ Python Syntax - Tất cả files đã validate
Tính Năng Đã Triển Khai
Frontend (index.html)
- 🌊 Waveform visualization với HTML5 Canvas
- ⏯️ Audio playback controls (Play/Pause/Stop)
- 🔊 Real-time volume control với gain node
- 📍 Marker system với drag & drop
- 🎯 Client-side Zero-Crossing detection
- 💾 WAV Encoder (8/16/24-bit PCM)
- 📤 File upload với progress tracking
- 📊 Real-time status logging
Backend API
POST /api/v1/audio/upload - Upload audio files
GET /api/v1/audio/tasks/{task_id} - Check task status
POST /api/v1/audio/edit - Apply server-side editing
GET /api/v1/audio/download/{file_id} - Download processed files
Core DSP Modules
- analyzer.py - Librosa BPM/Beat tracking với Dynamic Programming
- dsp_utils.py - Zero-crossing detection, Micro-fading
- audio_editor.py - Cut, Loop, Fade, Volume operations
🚀 Cách Chạy Hệ Thống
Option 1: Docker (Khuyến Nghị)
Truy cập: http://localhost:8000
Option 2: Local Development
🧪 Kịch Bản Kiểm Thử
Test 1: Basic Audio Loading
- Mở http://localhost:8000
- Click "Choose File" và chọn file audio (MP3/WAV)
- File sẽ load và hiển thị waveform
- Kiểm tra thời gian hiển thị đúng
Test 2: Playback Controls
- Load audio file
- Click Play - audio phát
- Click Pause - audio tạm dừng
- Click Play lại - tiếp tục từ vị trí pause
- Click Stop - reset về đầu
Test 3: Volume Control
- Load và play audio
- Kéo slider Volume từ -20dB đến +20dB
- Kiểm tra âm lượng thay đổi real-time
Test 4: Server Upload & Analysis
- Load audio file
- Click "Upload to Server"
- Đợi upload hoàn tất (hiển thị file_id)
- Click "Analyze Audio"
- Kiểm tra kết quả BPM, beats, bars
Test 5: Zero-Crossing Detection
- Load audio file với waveform hiển thị
- Click "Add Marker" (tạo marker tại vị trí current time)
- Click "Snap to Zero-Crossing"
- Marker sẽ di chuyển đến điểm zero-crossing gần nhất
- Kiểm tra status log để xem thời gian chính xác
Test 6: Server-side Editing
- Upload file lên server
- Add 2 markers (start/end cut points)
- Snap markers to zero-crossing
- Điều chỉnh:
- Loop Count: 2
- Fade In: 500ms
- Fade Out: 500ms
- Volume: +3dB
- Click "Apply Edit (Server)"
- Đợi processing complete
- Download file đã edit
Test 7: WAV Export (Client-side)
- Load audio file
- Chọn bit depth (8/16/24-bit)
- Click "Export WAV (Client)"
- File sẽ download tự động
- Mở file bằng audio player để kiểm tra
🎹 FluidSynth WASM Migration — Manual Test Plan
Môi trường
- Mở DevTools Console (F12) → Tab Console (bật
Verbose để thấy [SonicSF] logs)
- Tab Network: filter
fluidsynth, sf3, .wasm
Test A: FluidSynth WASM Load & Init
| Step |
Action |
Expected Result |
| A1 |
Mở http://localhost:8000 |
Console: [FluidSynth] Loaded from: https://cdn.jsdelivr.net/... |
| A2 |
Kiểm tra Network tab |
.wasm file tải thành công (status 200) |
| A3 |
Check window.__FluidSynthModuleFactory |
typeof window.__FluidSynthModuleFactory === 'function' |
| A4 |
Tương tác với app (click vào DAW) |
Console: [SonicSF] FluidSynth WASM Engine initialized. |
| A5 |
Kiểm tra AudioWorklet |
Console: Worklet reg success hoặc check audioWorklet trong Application tab |
Test B: SoundFont Loading
| Step |
Action |
Expected Result |
| B1 |
Mở Plugin Manager → tab SoundFont |
Danh sách SoundFont hiển thị |
| B2 |
Chọn 1 SoundFont instrument (vd: Piano) |
Console: [SonicSF] SoundFont loaded: <sfId> |
| B3 |
Kiểm tra Network tab |
Request download/<sfId> status 200 |
| B4 |
Chuyển đổi instrument khác (vd: Violin) |
Console: Bank Select + Program Change (nếu cùng SF, không tải lại) |
| B5 |
Load SoundFont có loop samples (vd: Tremolo Strings, Pad, Synth) |
loadSoundFont success, không lỗi |
Test C: Piano Roll Playback
| Step |
Action |
Expected Result |
| C1 |
Mở Piano Roll tab |
Grid hiển thị notes |
| C2 |
Click vào 1 note trên grid |
Note phát ra → âm thanh giống nhạc cụ thật (không phải oscillator beep) |
| C3 |
Click và kéo thả chuột trên grid → draw note mới |
Âm thanh phát ngay lập tức |
| C4 |
Scroll wheel trên piano roll notes |
Các note scroll qua phát âm thanh preview |
| C5 |
Vẽ note dài (full measure) |
Note kéo dài đúng độ dài, không bị tắt giữa chừng |
Test D: MIDI Keyboard (Virtual & Hardware)
| Step |
Action |
Expected Result |
| D1 |
Click vào phím đàn virtual (piano keybed) |
Note phát ra = âm thanh instrument đúng |
| D2 |
Kéo chuột ngang trên keybed |
Các note phát liên tục, glide không bị stuck |
| D3 |
Kết nối MIDI keyboard qua WebMIDI |
Console: MIDI access granted |
| D4 |
Nhấn phím trên MIDI keyboard |
Note phát ra ngay, không delay |
| D5 |
Nhả phím MIDI |
Note tắt ngay (không stuck, không sustain dài) |
| D6 |
Sustain pedal (CC 64) |
Nhấn pedal → notes sustain; nhả → notes release |
| D7 |
Pitch bend wheel |
Cao độ thay đổi real-time |
| D8 |
Modulation wheel (CC 1) |
Âm thanh thay đổi (nếu instrument hỗ trợ) |
Test E: Timeline Playback (MIDI Tracks)
| Step |
Action |
Expected Result |
| E1 |
Tạo track MIDI mới |
Track được tạo |
| E2 |
Gán SoundFont instrument cho track |
Console log bank/program change |
| E3 |
Thêm MIDI notes vào track, click Play |
Notes phát đúng pitch, đúng thời điểm, đúng instrument |
| E4 |
Click Pause → Play |
Nhạc tiếp tục từ vị trí pause |
| E5 |
Click Stop |
Tất cả notes tắt ngay lập tức |
| E6 |
Seek playhead → Play |
Play từ vị trí mới, notes cũ tắt |
| E7 |
Set loop region → Play |
Loop playback hoạt động |
| E8 |
Chuyển track instrument khác → Play |
Âm thanh thay đổi theo instrument mới |
Test F: Tremolo/Sustain/Loop Instrument Stress Test
| Step |
Action |
Expected Result |
| F1 |
Chọn Tremolo Strings (GM#44) |
Load SF thành công |
| F2 |
Play note → nhanh chóng NoteOff |
QUAN TRỌNG: Note tắt ngay, không bị stuck loop |
| F3 |
Play nhiều note liên tiếp (staccato) |
Mỗi note tắt hẳn trước khi note kế phát |
| F4 |
Chọn Saxophone (GM#65-67) |
Load SF thành công |
| F5 |
Play note giữ 3s → NoteOff |
Saxophone release envelope chạy đúng, không stuck |
| F6 |
Chọn Pad/Synth (GM#88-95) |
Các instrument loop dài không bị stuck |
| F7 |
Play 10+ notes cùng lúc → Stop All |
Tất cả notes tắt ngay |
| F8 |
So sánh: Test F1-F7 cũ: SpessaSynth bị stuck notes cần CC120+noteOn+post. FluidSynth WASM: chỉ cần noteOff thường. |
FluidSynth handle loop Gen 54 đúng spec |
Test G: Multi-SoundFont Switching
| Step |
Action |
Expected Result |
| G1 |
Load SoundFont A (vd: GeneralUser) |
Handle ID log |
| G2 |
Chuyển track sang instrument từ SF A |
SF A active |
| G3 |
Tạo track 2, load SoundFont B (vd: SGM) |
SF B load vào MEMFS |
| G4 |
Play track 1 (SF A) + track 2 (SF B) |
Cả 2 soundfont phát đồng thời, mỗi track instrument đúng |
| G5 |
Unload SF A, load SF C |
SF A đã unload, SF C active |
Test H: Transport Controls
| Step |
Action |
Expected Result |
| H1 |
Đang play → click Stop |
Console: FluidSynth: All notes stopped. |
| H2 |
Play với nhiều notes đang vang → Stop |
Âm thanh tắt ngay lập tức (CC 120 all sound off) |
| H3 |
Play → Pause → Seek → Play |
Seek không bị stuck notes |
| H4 |
Play → Reload trang |
Audio context mới, FluidSynth init lại |
Test I: Fallback Behavior
| Step |
Action |
Expected Result |
| I1 |
Chặn CDN request (DevTools → Network → Offline) |
fluidsynthLoader.js detect localhost → vẫn dùng CDN? Set window.__FLUIDSYNTH_CDN = null |
| I2 |
Nếu FluidSynth init fail |
Console: FluidSynth init failed. Fallback oscillator hoạt động (âm beep) |
| I3 |
Nếu loadSoundFont fail (network down) |
Console: SoundFont not found. Fallback oscillator cho note preview |
Test J: Memory & Performance
| Step |
Action |
Expected Result |
| J1 |
Load SF lần đầu |
Network download + MEMFS write + sfload |
| J2 |
Load lại SF lần 2 (đã cache IndexedDB) |
_sfHandleMap.has(sfId) → true, skip download |
| J3 |
Check Performance tab (DevTools) |
_fluid_synth_write_float không block main thread > 5ms |
| J4 |
Play liên tục 5 phút |
Không memory leak, không audio glitch |
| J5 |
Load SF 3-4MB (SGM v2.01) |
MEMFS write + sfload < 500ms |
Test K: Audio Parity (Client vs Server)
| Step |
Action |
Expected Result |
| K1 |
Tạo project với MIDI notes + SoundFont |
Client preview âm thanh |
| K2 |
Export WAV server-side (Render) |
Server dùng pyfluidsynth (C++ core) |
| K3 |
So sánh WAV export vs Client preview |
Giống nhau 100% (cùng FluidSynth engine) |
| K4 |
Test với SF3 files |
Cả client (FluidSynth WASM) và server (pyfluidsynth) đều xử lý SF3 |
Test L: Regression — Tính năng không thay đổi
| Step |
Action |
Expected Result |
| L1 |
AI track generation |
applyAITrackInstrument works → bank/program change |
| L2 |
Audio file playback |
Không ảnh hưởng (vẫn dùng AudioEngine cũ) |
| L3 |
VST instrument tracks |
Không ảnh hưởng (dùng VST engine riêng) |
| L4 |
Upload/download file |
Không thay đổi |
| L5 |
Multi-track mix |
Không thay đổi |
Test Environment Setup
Checklist
🐛 Known Issues
Docker Environment
- Module
celery, redis, librosa, pydub, soundfile chưa được cài trong môi trường hiện tại
- Giải pháp: Sử dụng Docker để chạy (tất cả dependencies đã có trong Dockerfile)
Browser Compatibility
- Web Audio API yêu cầu user interaction trước khi play
- Safari có thể cần format audio khác
- Giải pháp: Test trên Chrome/Firefox
📋 Checklist Kiểm Thử Đầy Đủ
🔍 Debugging
Kiểm tra logs
Kiểm tra containers
Kiểm tra storage
📊 Performance Metrics
Mục Tiêu
- Upload file 10MB: < 5s
- BPM Analysis: < 10s
- Zero-crossing detection: < 100ms
- Waveform rendering: < 500ms
- Audio playback latency: < 50ms
🎯 Next Steps
Sau khi test cơ bản hoạt động:
- Stress test với file > 100MB
- Concurrent user testing
- Memory leak detection
- Audio quality testing (THD, SNR)
- Cross-browser compatibility
- Mobile responsive testing
📞 Support
Nếu gặp vấn đề, kiểm tra:
- Docker daemon đang chạy
- Port 8000, 6379 không bị chiếm
- Đủ RAM (tối thiểu 4GB)
- FFmpeg installed trong container
- Browser console không có errors