FIX: Piano roll track 4 phát âm thanh instrument track 3

This commit is contained in:
2026-08-05 15:17:13 +07:00
parent 35f7c3822f
commit 4233c1eeda
5 changed files with 59 additions and 14 deletions
+9 -6
View File
@@ -7722,14 +7722,16 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
try { previewNodesRef.current.gain.disconnect(); } catch(e) {}
previewNodesRef.current = null;
}
if (window.SonicSF && window.SonicSF._playNoteFallback) {
if (window.SonicSF && window.SonicSF.playNote) {
const ctx = getAudioContext();
var dwTrk = activeTracks.find(function(t) { return t.id === st.trackId; });
var dwCh = dwTrk ? assignTrackMidiChannel(dwTrk, activeTracks) : 0;
var dwPitch = snapToScaleRef.current ? snapPitchToScale(pitch, selectedScaleRef.current) : pitch;
var dwDurMs = Math.max(100, Math.round(initialDur * (60 / bpm) * 1000));
var dwNodes = window.SonicSF._playNoteFallback(dwPitch, Math.round(brushVelocityRef.current * 127), dwDurMs, ctx.currentTime, dwTrk ? dwTrk.instrumentProgram : undefined, null, dwCh, dwTrk ? dwTrk.synth_engine : undefined);
if (dwNodes) previewNodesRef.current = dwNodes;
// playNote (FluidSynth nhc c THT ca track). _playNoteFallback ch
// là oscillator beep (sai âm vi percussion/soundfont user: note v
// mi nghe nhc c track trưc).
window.SonicSF.playNote(dwPitch, Math.round(brushVelocityRef.current * 127), dwDurMs, ctx.currentTime, dwTrk ? dwTrk.instrumentProgram : undefined, null, dwCh, dwTrk ? dwTrk.synth_engine : undefined);
}
}
};
@@ -7818,13 +7820,14 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
function playDrawPreview(p, durMs) {
stopPreviewNote();
if (window.SonicSF && window.SonicSF._playNoteFallback) {
if (window.SonicSF && window.SonicSF.playNote) {
var pvCtx = getAudioContext();
var pvTrk = activeTracks.find(function(t) { return t.id === st.trackId; });
var pvCtxInst = resolveTrackInstrumentCtx(pvTrk, activeTracks);
var pvVel = Math.round(brushVelocityRef.current * 127);
var pvNodes = window.SonicSF._playNoteFallback(p, pvVel, durMs, pvCtx.currentTime, pvCtxInst.program, null, pvCtxInst.ch, pvCtxInst.synthEngine);
if (pvNodes) previewNodesRef.current = pvNodes;
// playNote (FluidSynth nhc c THT). _playNoteFallback = oscillator
// beep sai âm (percussion/soundfont).
window.SonicSF.playNote(p, pvVel, durMs, pvCtx.currentTime, pvCtxInst.program, null, pvCtxInst.ch, pvCtxInst.synthEngine);
previewPitchRef.current = p;
}
}
File diff suppressed because one or more lines are too long
+22 -3
View File
@@ -153,7 +153,7 @@
// 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;
if (msg && (msg.indexOf('No preset found on channel') !== -1 || msg.indexOf('There is no preset with bank number') !== -1)) return;
console.warn('[FluidSynth:err]', msg);
}
});
@@ -562,7 +562,22 @@
console.log('[SonicSF] selectProgram for channel:', ch, 'sfHandle:', sfHandle, 'bank:', finalBank, 'prog:', finalProg);
if (sfHandle !== undefined) {
try {
_fluidModule._fluid_synth_program_select(_synthPtr, ch, sfHandle, finalBank, finalProg);
var _selRet = _fluidModule._fluid_synth_program_select(_synthPtr, ch, sfHandle, finalBank, finalProg);
// Percussion (bank 128) preset không tồn tại trong
// font → fallback preset trống hợp lệ (GM kit 48 →
// preset đầu font) — nếu không, noteon trên preset
// rỗng = CÂM (track percussion "1 âm đầu rồi câm").
if (_selRet !== 0 && finalBank === 128) {
var _cands = [[128, 48], [0, 0], [128, 1], [0, 48]];
for (var _ci = 0; _ci < _cands.length; _ci++) {
try {
if (_fluidModule._fluid_synth_program_select(_synthPtr, ch, sfHandle, _cands[_ci][0], _cands[_ci][1]) === 0) {
finalBank = _cands[_ci][0]; finalProg = _cands[_ci][1];
break;
}
} catch (e) {}
}
}
} catch (e) {}
} else {
try { _fluidModule._fluid_synth_bank_select(_synthPtr, ch, finalBank); } catch (e) {}
@@ -645,7 +660,11 @@
var oscType = 'triangle';
var attackTime = 0.03, decayTime = 0.1, sustainLevel = 0.5, releaseTime = 0.2, volFactor = 0.25;
var prog = program !== undefined ? parseInt(program) : 0;
if (channel !== undefined && channel >= 0 && channel < 16) {
// CHỈ dùng cache channel khi KHÔNG có program/synthEngine được
// truyền — trước đây override program của track bằng cache channel
// (bị track khác cùng channel ghi đè → preview note vẽ mới mang
// nhạc cụ của track TRƯỚC).
if (program === undefined && channel !== undefined && channel >= 0 && channel < 16) {
prog = _channels[channel].program || prog;
}
if (prog >= 0 && prog <= 7) { oscType = 'sine'; decayTime = 0.3; sustainLevel = 0.1; releaseTime = 0.2; }
+2 -2
View File
@@ -16,7 +16,7 @@
<script src="/static/js/services/audioEngine.js?v=202607271016"></script>
<script src="/static/js/services/storage.js?v=202608038200"></script>
<script src="/static/js/services/soundfontStorage.js?v=202607271016"></script>
<script src="/static/js/services/soundfontPlayer.js?v=202608052355"></script>
<script src="/static/js/services/soundfontPlayer.js?v=202608060130"></script>
<script src="/static/js/services/aiGateway.js?v=202608037200"></script>
<script src="/static/js/services/dawCommandDispatcher.js?v=202607271016"></script>
<script src="/static/js/services/pianoRollTabService.js?v=202607272044"></script>
@@ -24,7 +24,7 @@
<script src="/static/js/services/midiExtractor.js?v=202607281052"></script>
<script src="/static/js/services/promptTemplateManager.js?v=202607281039"></script>
<script src="/static/js/services/undoRedoEngine.js?v=202607290941"></script>
<script src="/static/js/app.precompiled.js?v=202608060030" defer></script>
<script src="/static/js/app.precompiled.js?v=202608060130" defer></script>
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
<style>
:root {