fix: sfload reset_presets=0 giữ nguyên instrument các track khác; preloadTrackInstruments module-level (sửa ReferenceError reload); truyền props cho ProfileModal; lọc warning No preset found channel 9

This commit is contained in:
2026-08-03 11:00:08 +07:00
parent 84ab4ae823
commit 9b6de7f857
5 changed files with 61 additions and 27 deletions
+5
View File
@@ -1214,3 +1214,8 @@
- **Tóm tắt thay đổi:** FluidSynth có 16 channel; nếu 2 track trùng channel thì ARM track này sẽ `program_select` đè instrument của track kia. Thêm cơ chế channel riêng cho từng track trong app.jsx: `trackMidiChannelsRef` + `ensureTrackMidiChannel`/`assignTrackMidiChannel` cấp channel ổn định, duy nhất (0-15, bỏ qua 9 - slot percussion cổ điển), tự sửa khi 2 track trùng channel được lưu. Áp dụng ở mọi nơi tính channel: `setTrackInstrumentWithProgram`, `setTrackInstrument` (dropdown nhanh), `preloadTrackInstruments`, routing ARM note-on (armedTracks + piano-roll sub-tab), note-off/CC/PitchBend (bỏ fallback `index % 16` — tránh dừng nhầm note của track khác). Lưu `midi_channel` khi save project + restore; reset map channel khi mở/khôi phục dự án. Kết hợp doNote cũ (synth_engine quyết định + re-select trước noteon) → mỗi track luôn phát đúng instrument của nó dù ARM nhiều track, chord/hợp âm đồng thời không còn đổi âm sắc nhau.
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/static/js/app.precompiled.js` (build lại), `app/templates/index.html`
- **Ghi chú/Test (nếu có):** `npm run build` OK, bundle chứa `assignTrackMidiChannel` (8 chỗ). Harness `node /tmp/kilo/test_channels.js`: 3 track → channel 0,1,2 duy nhất; gọi lại ổn định; track mới lấy channel trống; track lưu trùng channel được cấp lại; track lưu channel duy nhất được giữ; percussion giữ 9 + track trống khác lấy channel riêng — ALL PASSED. 3 harness cũ (single/multi/dedup) vẫn PASS. Hard refresh.
### [2026-08-03 11:30] Task: Fix instrument sau làm đổi thông số instrument trước + ReferenceError preloadTrackInstruments + warning channel 9
- **Tóm tắt thay đổi:** (1) **sfload reset_presets 1→0** trong `soundfontPlayer._tryLoadSFL`: trước đây mỗi lần load soundfont mới, FluidSynth reset preset của MỌI channel về preset 0 của font mới → load instrument sau làm đổi âm sắc (decay/loop...) của instrument trước dù channel đã `program_select` riêng; giờ channel giữ nguyên instrument, doNote/selectInstrument tự `program_select` rõ ràng. (2) **ReferenceError `preloadTrackInstruments`**: hàm bị đặt nhầm bên trong `ProfileModal` (không cùng scope với `restoreLastSessionProject` trong `App`) → lỗi khi reload. Chuyển `preloadTrackInstruments` lên module-level (self-contained, chỉ warm font cache). Đồng thời sửa lỗi tiềm ẩn của `handleOpenProject` trong ProfileModal: truyền thêm props App-scoped (`setAppWarningModal`, `bpm`, `setBpm`, `setMasteringSettings`, `setSessionTabs`, `setSubTabs`, `trackMidiChannelsRef`) — trước đây click mở dự án trong modal sẽ ReferenceError. (3) **"No preset found on channel 9 [bank=128 prog=0]"**: lọc warning benign trong `printErr` (font không có preset bank 128 thì note chỉ câm, không phải lỗi) + reset=0 giảm nguồn sinh ra nó.
- **Các file ảnh hưởng:** `app/static/js/services/soundfontPlayer.js`, `app/static/js/app.jsx`, `app/static/js/app.precompiled.js` (build lại), `app/templates/index.html`
- **Ghi chú/Test (nếu có):** `npm run build` OK, bundle syntax OK. Harness `node /tmp/kilo/test_reset.js`: sfload reset=0, load B không re-select channel A, noteon ch0/ch1 không kèm program_select thừa — PASSED. 5 harness còn lại (single/multi/dedup/channels) vẫn PASS. Deprecation ScriptProcessorNode giữ nguyên (đổi sang AudioWorklet có rủi ro crackle, cần test audio thật). Hard refresh.