fix: engine->channel map cho multi-track ARM

_engineChMap: key=sfId:bank:prog → allocated MIDI channel.
Mỗi track ARM riêng biệt có engKey khác nhau → allocated channel
riêng (0-8 round-robin). _playNoteFluid lookup channel từ map
thay vì dùng MIDI channel gốc (luôn 0).
This commit is contained in:
2026-07-27 15:40:45 +07:00
parent 3d7bae94f2
commit 638d56ce63
+27 -7
View File
@@ -13,6 +13,7 @@
let _channels = Array.from({ length: 16 }, () => ({ bank: 0, program: 0, isPercussion: false }));
let _nextMelodicChannel = 0;
let _sustainStates = new Array(16).fill(false);
let _engineChMap = {};
let _leftBufPtr = null;
let _rightBufPtr = null;
let _renderTimer = null;
@@ -229,6 +230,14 @@
var ok = await this.loadSoundFont(sfId);
if (!ok) return;
}
var engKey = (sfId || '') + ':' + bank + ':' + program;
if (!_engineChMap[engKey]) {
var allocCh = this.allocateChannel(bank);
_engineChMap[engKey] = allocCh;
channel = allocCh;
} else {
channel = _engineChMap[engKey];
}
try {
_fluidModule._fluid_synth_bank_select(_synthPtr, channel, bank);
} catch (e) {}
@@ -278,9 +287,14 @@
bank = bank !== undefined ? bank : (synthEngine.soundfont_bank || 0);
program = program !== undefined ? program : (synthEngine.soundfont_program || 0);
}
var channel = this.allocateChannel(bank);
this.selectInstrument(channel, bank, program, synthEngine && synthEngine.soundfont_id);
return channel;
var sfId = synthEngine && synthEngine.soundfont_id;
var engKey = (sfId || '') + ':' + bank + ':' + program;
if (!_engineChMap[engKey]) {
var channel = this.allocateChannel(bank);
_engineChMap[engKey] = channel;
}
this.selectInstrument(_engineChMap[engKey], bank, program, sfId);
return _engineChMap[engKey];
},
getChannelState: function (channel) {
@@ -342,11 +356,16 @@
var ch = channel;
var usedBank = 0, usedProg = 0;
if (synthEngine) {
if (ch === undefined) {
ch = synthEngine.soundfont_bank === 128 ? 9 : 0;
}
usedBank = synthEngine.soundfont_bank || 0;
usedProg = synthEngine.soundfont_program || 0;
var engKey = (synthEngine.soundfont_id || '') + ':' + usedBank + ':' + usedProg;
var mappedCh = _engineChMap[engKey];
if (mappedCh !== undefined) {
ch = mappedCh;
} else if (ch === undefined) {
ch = usedBank === 128 ? 9 : 0;
}
if (ch === undefined) ch = (usedBank === 128 ? 9 : 0);
try {
_fluidModule._fluid_synth_bank_select(_synthPtr, ch, usedBank);
} catch (e) {}
@@ -356,8 +375,9 @@
if (channel === undefined) channel = ch;
} else if (program !== undefined) {
usedProg = program;
if (ch === undefined) ch = 0;
try {
_fluidModule._fluid_synth_program_change(_synthPtr, ch || 0, usedProg);
_fluidModule._fluid_synth_program_change(_synthPtr, ch, usedProg);
} catch (e) {}
}
if (ch === undefined) ch = (usedBank === 128 ? 9 : 0);