fix: MIDI ARM không phát âm thanh sau khi load instrument - lazy-load soundfont trong playNote + giữ channel khi selectInstrument truyền channel tường minh
This commit is contained in:
@@ -258,16 +258,16 @@
|
||||
if (!ok) return;
|
||||
}
|
||||
var engKey = (sfId || '') + ':' + bank + ':' + program;
|
||||
if (!_engineChMap[engKey]) {
|
||||
if (channel === undefined || channel === null) {
|
||||
if (channel === undefined || channel === null) {
|
||||
if (!_engineChMap[engKey]) {
|
||||
var allocCh = this.allocateChannel(bank);
|
||||
_engineChMap[engKey] = allocCh;
|
||||
channel = allocCh;
|
||||
} else {
|
||||
_engineChMap[engKey] = channel;
|
||||
channel = _engineChMap[engKey];
|
||||
}
|
||||
} else {
|
||||
channel = _engineChMap[engKey];
|
||||
} else if (!_engineChMap[engKey]) {
|
||||
_engineChMap[engKey] = channel;
|
||||
}
|
||||
var sfHandle = _sfHandleMap.get(sfId);
|
||||
if (sfHandle !== undefined) {
|
||||
@@ -423,18 +423,33 @@
|
||||
var finalBank = usedBank;
|
||||
var finalProg = usedProg;
|
||||
var finalSfId = synthEngine ? synthEngine.soundfont_id : undefined;
|
||||
if (_channels[ch] && _channels[ch].program !== undefined) {
|
||||
finalBank = _channels[ch].bank;
|
||||
finalProg = _channels[ch].program;
|
||||
if (_channels[ch].sfId !== undefined) {
|
||||
finalSfId = _channels[ch].sfId;
|
||||
}
|
||||
var cachedCh = _channels[ch];
|
||||
// A channel explicitly configured with a soundfont (via
|
||||
// selectInstrument) is authoritative. But the default channel
|
||||
// state (bank 0, program 0, no soundfont) must NOT mask the
|
||||
// track's synth engine or the note's program — otherwise notes
|
||||
// on a freshly-picked instrument are silently dropped.
|
||||
if (cachedCh && cachedCh.sfId !== undefined) {
|
||||
finalBank = cachedCh.bank;
|
||||
finalProg = cachedCh.program;
|
||||
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.
|
||||
// Quick instrument pick on a track does not pre-load it, so load
|
||||
// lazily here and retry the note once the font is ready.
|
||||
if (finalSfId && !_sfHandleMap.has(finalSfId)) {
|
||||
self.loadSoundFont(finalSfId).then(function (ok) {
|
||||
if (ok) doNote();
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Program change at note time, not call time — ensures correct
|
||||
// instrument for each item regardless of processing order.
|
||||
// Skip if the channel already has this exact instrument (avoids
|
||||
// per-note soundfont reloads that cause audible crackle/glitches).
|
||||
var cachedCh = _channels[ch];
|
||||
var progAlreadySet = cachedCh && cachedCh.program === finalProg && cachedCh.bank === finalBank && cachedCh.sfId === finalSfId;
|
||||
if ((synthEngine || program !== undefined) && !progAlreadySet) {
|
||||
var sfHandle = finalSfId ? _sfHandleMap.get(finalSfId) : undefined;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<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/soundfontStorage.js?v=202607271016"></script>
|
||||
<script src="/static/js/services/soundfontPlayer.js?v=202607311050"></script>
|
||||
<script src="/static/js/services/soundfontPlayer.js?v=202608031015"></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/pianoRollTabService.js?v=202607272044"></script>
|
||||
|
||||
Reference in New Issue
Block a user