fix: ARM nhiều track phát sai instrument - synth_engine của track là nguồn quyết định thay vì channel state (bỏ che mask khi channel giữ instrument cũ/trùng)
This commit is contained in:
@@ -424,18 +424,15 @@
|
|||||||
var finalProg = usedProg;
|
var finalProg = usedProg;
|
||||||
var finalSfId = synthEngine ? synthEngine.soundfont_id : undefined;
|
var finalSfId = synthEngine ? synthEngine.soundfont_id : undefined;
|
||||||
var cachedCh = _channels[ch];
|
var cachedCh = _channels[ch];
|
||||||
// A channel explicitly configured with a soundfont (via
|
// The note's own synth engine (track instrument) is
|
||||||
// selectInstrument) is authoritative. But the default channel
|
// authoritative. Channel state is only a cache: it must never
|
||||||
// state (bank 0, program 0, no soundfont) must NOT mask the
|
// mask the track's instrument, otherwise multi-track ARM or a
|
||||||
// track's synth engine or the note's program — otherwise notes
|
// re-picked instrument plays the wrong soundfont. Without an
|
||||||
// on a freshly-picked instrument are silently dropped.
|
// engine, fall back to the soundfont configured on the channel.
|
||||||
if (cachedCh && cachedCh.sfId !== undefined) {
|
if (!synthEngine && cachedCh && cachedCh.sfId !== undefined) {
|
||||||
finalBank = cachedCh.bank;
|
finalBank = cachedCh.bank;
|
||||||
finalProg = cachedCh.program;
|
finalProg = cachedCh.program;
|
||||||
finalSfId = cachedCh.sfId;
|
finalSfId = cachedCh.sfId;
|
||||||
} else if (!synthEngine && program !== undefined && cachedCh && cachedCh.program !== undefined && cachedCh.program !== 0 && cachedCh.program !== null) {
|
|
||||||
finalBank = cachedCh.bank;
|
|
||||||
finalProg = cachedCh.program;
|
|
||||||
}
|
}
|
||||||
// Ensure the soundfont is actually loaded before the note plays.
|
// Ensure the soundfont is actually loaded before the note plays.
|
||||||
// Quick instrument pick on a track does not pre-load it, so load
|
// Quick instrument pick on a track does not pre-load it, so load
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<script src="/static/js/services/audioEngine.js?v=202607271016"></script>
|
<script src="/static/js/services/audioEngine.js?v=202607271016"></script>
|
||||||
<script src="/static/js/services/storage.js?v=202607271016"></script>
|
<script src="/static/js/services/storage.js?v=202607271016"></script>
|
||||||
<script src="/static/js/services/soundfontStorage.js?v=202607271016"></script>
|
<script src="/static/js/services/soundfontStorage.js?v=202607271016"></script>
|
||||||
<script src="/static/js/services/soundfontPlayer.js?v=202608031015"></script>
|
<script src="/static/js/services/soundfontPlayer.js?v=202608031030"></script>
|
||||||
<script src="/static/js/services/aiGateway.js?v=202607271016"></script>
|
<script src="/static/js/services/aiGateway.js?v=202607271016"></script>
|
||||||
<script src="/static/js/services/dawCommandDispatcher.js?v=202607271016"></script>
|
<script src="/static/js/services/dawCommandDispatcher.js?v=202607271016"></script>
|
||||||
<script src="/static/js/services/pianoRollTabService.js?v=202607272044"></script>
|
<script src="/static/js/services/pianoRollTabService.js?v=202607272044"></script>
|
||||||
|
|||||||
@@ -1199,3 +1199,8 @@
|
|||||||
- **Tóm tắt thay đổi:** Sửa `soundfontPlayer.js` để phím MIDI trên track ARM phát đúng instrument: (1) `_playNoteFluid` không còn để state mặc định của channel (bank 0, program 0, không sfId) che mất `synth_engine` của track → `finalSfId` luôn đúng; (2) tự load soundfont lười (lazy) ngay trong đường phát note nếu font chưa vào `_sfHandleMap` (track pick nhanh từ dropdown không gọi `selectInstrument` → trước đây rơi vào `bank_select`/`program_change` trên synth không có soundfont → câm lặng); (3) `selectInstrument` không còn đổi hướng channel khi đã truyền channel tường minh (sửa lỗi 2 track dùng chung instrument bị giật channel). Bump version cache `soundfontPlayer.js` trong `index.html`.
|
- **Tóm tắt thay đổi:** Sửa `soundfontPlayer.js` để phím MIDI trên track ARM phát đúng instrument: (1) `_playNoteFluid` không còn để state mặc định của channel (bank 0, program 0, không sfId) che mất `synth_engine` của track → `finalSfId` luôn đúng; (2) tự load soundfont lười (lazy) ngay trong đường phát note nếu font chưa vào `_sfHandleMap` (track pick nhanh từ dropdown không gọi `selectInstrument` → trước đây rơi vào `bank_select`/`program_change` trên synth không có soundfont → câm lặng); (3) `selectInstrument` không còn đổi hướng channel khi đã truyền channel tường minh (sửa lỗi 2 track dùng chung instrument bị giật channel). Bump version cache `soundfontPlayer.js` trong `index.html`.
|
||||||
- **Các file ảnh hưởng:** `app/static/js/services/soundfontPlayer.js`, `app/templates/index.html`
|
- **Các file ảnh hưởng:** `app/static/js/services/soundfontPlayer.js`, `app/templates/index.html`
|
||||||
- **Ghi chú/Test (nếu có):** Test logic bằng harness `node /tmp/kilo/test_sonicsf_fix.js` (mô phỏng FluidSynth): S1 lazy-load + program_select + noteon, S2 channel cấu hình sẵn không sfload lại, S3 program-only fallback, S4 no-instrument vẫn silent, S5 2 track cùng instrument giữ channel riêng — ALL PASSED. Cần hard-refresh trình duyệt để nạp `soundfontPlayer.js` bản mới.
|
- **Ghi chú/Test (nếu có):** Test logic bằng harness `node /tmp/kilo/test_sonicsf_fix.js` (mô phỏng FluidSynth): S1 lazy-load + program_select + noteon, S2 channel cấu hình sẵn không sfload lại, S3 program-only fallback, S4 no-instrument vẫn silent, S5 2 track cùng instrument giữ channel riêng — ALL PASSED. Cần hard-refresh trình duyệt để nạp `soundfontPlayer.js` bản mới.
|
||||||
|
|
||||||
|
### [2026-08-03 10:30] Task: Fix ARM nhiều track - instrument sai theo track (channel state che mất synth_engine)
|
||||||
|
- **Tóm tắt thay đổi:** `_playNoteFluid` trước đây ưu tiên state channel (`_channels[ch].sfId`) làm nguồn instrument cho note → khi ARM nhiều track hoặc track đổi instrument qua dropdown nhanh, note bị phát theo instrument cũ/khác đang "dính" trên channel (leftover state hoặc 2 track trùng channel) → sai instrument từng track. Sửa: `synth_engine` của track là nguồn quyết định; channel state chỉ là cache (chỉ dùng khi note không có engine). Khi note mang engine khác với channel đang giữ, tự động `program_select` lại đúng instrument trước `noteon`; vẫn lazy-load soundfont nếu chưa nạp. Bump version cache `soundfontPlayer.js` trong `index.html`.
|
||||||
|
- **Các file ảnh hưởng:** `app/static/js/services/soundfontPlayer.js`, `app/templates/index.html`
|
||||||
|
- **Ghi chú/Test (nếu có):** Harness `node /tmp/kilo/test_multi_track.js` (mô phỏng routing ARM như app.jsx): (A) 3 track 3 instrument distinct channel → noteon đúng, không re-select thừa; (B) 3 track quick-pick (không midiChannel, channel đang giữ instrument cũ) → mỗi track re-select đúng Q1/Q2/Q3 trước noteon; (C) 2 track trùng channel 0 → track 2 re-select program 40 trước noteon. Harness `test_sonicsf_fix.js` (single-track S1-S5) vẫn ALL PASSED. Hard refresh trình duyệt để nạp bản mới.
|
||||||
|
|||||||
Reference in New Issue
Block a user