# 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ị) ```bash # Build và khởi động tất cả services docker compose up --build # Chạy ở background docker compose up -d --build # Xem logs docker compose logs -f # Dừng services docker compose down ``` Truy cập: **http://localhost:8000** ### Option 2: Local Development ```bash # 1. Cài đặt Python dependencies pip install -r requirements.txt # 2. Khởi động Redis (terminal riêng) redis-server # 3. Khởi động FastAPI (terminal riêng) uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 # 4. Khởi động Celery Worker (terminal riêng) celery -A app.tasks.worker.celery_app worker --loglevel=info ``` ## 🧪 Kịch Bản Kiểm Thử ### Test 1: Basic Audio Loading 1. Mở http://localhost:8000 2. Click "Choose File" và chọn file audio (MP3/WAV) 3. File sẽ load và hiển thị waveform 4. Kiểm tra thời gian hiển thị đúng ### Test 2: Playback Controls 1. Load audio file 2. Click Play - audio phát 3. Click Pause - audio tạm dừng 4. Click Play lại - tiếp tục từ vị trí pause 5. Click Stop - reset về đầu ### Test 3: Volume Control 1. Load và play audio 2. Kéo slider Volume từ -20dB đến +20dB 3. Kiểm tra âm lượng thay đổi real-time ### Test 4: Server Upload & Analysis 1. Load audio file 2. Click "Upload to Server" 3. Đợi upload hoàn tất (hiển thị file_id) 4. Click "Analyze Audio" 5. Kiểm tra kết quả BPM, beats, bars ### Test 5: Zero-Crossing Detection 1. Load audio file với waveform hiển thị 2. Click "Add Marker" (tạo marker tại vị trí current time) 3. Click "Snap to Zero-Crossing" 4. Marker sẽ di chuyển đến điểm zero-crossing gần nhất 5. Kiểm tra status log để xem thời gian chính xác ### Test 6: Server-side Editing 1. Upload file lên server 2. Add 2 markers (start/end cut points) 3. Snap markers to zero-crossing 4. Điều chỉnh: - Loop Count: 2 - Fade In: 500ms - Fade Out: 500ms - Volume: +3dB 5. Click "Apply Edit (Server)" 6. Đợi processing complete 7. Download file đã edit ### Test 7: WAV Export (Client-side) 1. Load audio file 2. Chọn bit depth (8/16/24-bit) 3. Click "Export WAV (Client)" 4. File sẽ download tự động 5. 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: ` | | B3 | Kiểm tra Network tab | Request `download/` 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 ```bash # 1. Start server cd /home/locpham/SonicForgeStudio docker compose up -d --build # 2. Clear browser cache trước khi test lần đầu (cache-bust version đã update) # Chrome: DevTools → Network → Disable cache (khi DevTools mở) # 3. Kiểm tra console logs # Mở DevTools Console, filter: [SonicSF] [FluidSynth] # 4. Force re-download SF (xóa IndexedDB cache nếu cần) # Application → IndexedDB → DAW_SoundFont_Cache → Clear ``` ### Checklist - [ ] A1-A5: FluidSynth WASM load + init - [ ] B1-B5: SoundFont load + switch (nhiều SF) - [ ] C1-C5: Piano roll note play - [ ] D1-D8: MIDI keyboard (virtual + hardware) - [ ] E1-E8: Timeline playback - [ ] F1-F8: **Tremolo/Sustain loop stress** — key test - [ ] G1-G5: Multi-SoundFont switching - [ ] H1-H4: Transport controls (stop, seek) - [ ] I1-I3: Fallback oscillator - [ ] J1-J5: Memory & performance - [ ] K1-K4: Audio parity client vs server - [ ] L1-L5: Regression (features không thay đổi) ## 🐛 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 Đủ - [ ] Docker build thành công - [ ] Redis container chạy - [ ] FastAPI web container chạy - [ ] Celery worker container chạy - [ ] Truy cập http://localhost:8000 thành công - [ ] Load audio file và hiển thị waveform - [ ] Play/Pause/Stop hoạt động - [ ] Volume control real-time - [ ] Upload file lên server - [ ] Server analysis trả về BPM/beats - [ ] Zero-crossing detection hoạt động - [ ] Server editing hoàn tất - [ ] Download file processed - [ ] Export WAV client-side - [ ] Kiểm tra không có audio glitch/pop ## 🔍 Debugging ### Kiểm tra logs ```bash # Web server logs docker compose logs web # Celery worker logs docker compose logs worker # Redis logs docker compose logs redis # All services docker compose logs -f ``` ### Kiểm tra containers ```bash # List containers docker compose ps # Enter container shell docker compose exec web bash docker compose exec worker bash ``` ### Kiểm tra storage ```bash # Uploaded files ls -la app/storage/uploads/ # Processed files ls -la app/storage/processed/ ``` ## 📊 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: 1. Stress test với file > 100MB 2. Concurrent user testing 3. Memory leak detection 4. Audio quality testing (THD, SNR) 5. Cross-browser compatibility 6. Mobile responsive testing ## 📞 Support Nếu gặp vấn đề, kiểm tra: 1. Docker daemon đang chạy 2. Port 8000, 6379 không bị chiếm 3. Đủ RAM (tối thiểu 4GB) 4. FFmpeg installed trong container 5. Browser console không có errors