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
+37 -19
View File
@@ -4483,6 +4483,27 @@ const PluginManagerModal = ({ isOpen, onClose, pluginsData }) => {
)
);
};
// Module-level so both ProfileModal (open project) and App (auto-restore) can
// warm the FluidSynth font cache for each track's instrument. This only loads
// the soundfonts; the per-track channel re-selection happens at note time.
const preloadTrackInstruments = async (tracks) => {
if (!window.SonicSF || !window.SonicSF.selectInstrument) return;
const list = tracks || [];
for (let i = 0; i < list.length; i++) {
const t = list[i];
const se = t.synth_engine;
const sfId = (se && se.soundfont_id) || t.soundfont_id;
if (!sfId) continue;
const bank = se ? (se.soundfont_bank !== undefined ? se.soundfont_bank : 0) : (t.soundfont_bank !== undefined ? t.soundfont_bank : 0);
const prog = se ? (se.soundfont_program !== undefined ? se.soundfont_program : 0) : (t.soundfont_program !== undefined ? t.soundfont_program : 0);
const ch = t.midiChannel !== undefined ? t.midiChannel : (i % 16);
try {
await window.SonicSF.selectInstrument(ch, bank, prog, sfId);
} catch (e) {}
}
};
const ProfileModal = ({
isOpen,
onClose,
@@ -4494,7 +4515,14 @@ const ProfileModal = ({
currentProjectId,
setCurrentProjectId,
showToast,
loadAudioBuffersForTracks
loadAudioBuffersForTracks,
setAppWarningModal,
bpm,
setBpm,
setMasteringSettings,
setSessionTabs,
setSubTabs,
trackMidiChannelsRef
}) => {
if (!isOpen) return null;
const [activeTab, setActiveTab] = useState('account');
@@ -4627,23 +4655,6 @@ const ProfileModal = ({
}
};
const preloadTrackInstruments = async (tracks) => {
// Preload each track's soundfont before the user plays otherwise the first
// MIDI key after reload triggers a lazy font load and the note sounds late.
if (!window.SonicSF || !window.SonicSF.selectInstrument) return;
for (const t of (tracks || [])) {
const se = t.synth_engine;
const sfId = (se && se.soundfont_id) || t.soundfont_id;
if (!sfId) continue;
const bank = se ? (se.soundfont_bank !== undefined ? se.soundfont_bank : 0) : (t.soundfont_bank !== undefined ? t.soundfont_bank : 0);
const prog = se ? (se.soundfont_program !== undefined ? se.soundfont_program : 0) : (t.soundfont_program !== undefined ? t.soundfont_program : 0);
var ch = t && assignTrackMidiChannel(t, tracks);
try {
await window.SonicSF.selectInstrument(ch, bank, prog, sfId);
} catch (e) {}
}
};
const handleOpenProject = async (projectId, projectName) => {
setAppWarningModal({
title: "Mở dự án",
@@ -23816,7 +23827,14 @@ const App = () => {
currentProjectId: currentProjectId,
setCurrentProjectId: setCurrentProjectId,
showToast: showToast,
loadAudioBuffersForTracks: loadAudioBuffersForTracks
loadAudioBuffersForTracks: loadAudioBuffersForTracks,
setAppWarningModal: setAppWarningModal,
bpm: bpm,
setBpm: setBpm,
setMasteringSettings: setMasteringSettings,
setSessionTabs: setSessionTabs,
setSubTabs: setSubTabs,
trackMidiChannelsRef: trackMidiChannelsRef
}), /*#__PURE__*/React.createElement(SaveProjectModal, {
isOpen: saveProjectModalOpen,
onClose: () => setSaveProjectModalOpen(false),
File diff suppressed because one or more lines are too long
+11 -1
View File
@@ -106,6 +106,11 @@
},
TOTAL_MEMORY: TOTAL_MEMORY,
printErr: function (msg) {
// "No preset found on channel" is FluidSynth's
// expected notice when a soundfont simply has no
// preset for a bank (e.g. bank 128 on a melodic-only
// font) — the note is just silent, not an error.
if (msg && msg.indexOf('No preset found on channel') !== -1) return;
console.warn('[FluidSynth:err]', msg);
}
});
@@ -192,7 +197,12 @@
try { _fluidModule.FS.unlink(fname); } catch (e) {}
_fluidModule.FS.writeFile(fname, new Uint8Array(buf));
var cPath = this._allocCStr(fname);
var handle = _fluidModule._fluid_synth_sfload(_synthPtr, cPath, 1);
// reset_presets = 0: loading a NEW soundfont must NOT reset the
// presets already selected on other channels. With 1, FluidSynth
// re-points every channel to the new font's preset 0, so loading a
// second instrument silently changes the first one's sound
// (decay/loop envelope…).
var handle = _fluidModule._fluid_synth_sfload(_synthPtr, cPath, 0);
_fluidModule._free(cPath);
try { _fluidModule.FS.unlink(fname); } catch (e) {}
return handle;