FIX: Piano roll track 4 phát âm thanh instrument track 3
This commit is contained in:
@@ -7722,14 +7722,16 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, activeTracks, onClos
|
|||||||
try { previewNodesRef.current.gain.disconnect(); } catch(e) {}
|
try { previewNodesRef.current.gain.disconnect(); } catch(e) {}
|
||||||
previewNodesRef.current = null;
|
previewNodesRef.current = null;
|
||||||
}
|
}
|
||||||
if (window.SonicSF && window.SonicSF._playNoteFallback) {
|
if (window.SonicSF && window.SonicSF.playNote) {
|
||||||
const ctx = getAudioContext();
|
const ctx = getAudioContext();
|
||||||
var dwTrk = activeTracks.find(function(t) { return t.id === st.trackId; });
|
var dwTrk = activeTracks.find(function(t) { return t.id === st.trackId; });
|
||||||
var dwCh = dwTrk ? assignTrackMidiChannel(dwTrk, activeTracks) : 0;
|
var dwCh = dwTrk ? assignTrackMidiChannel(dwTrk, activeTracks) : 0;
|
||||||
var dwPitch = snapToScaleRef.current ? snapPitchToScale(pitch, selectedScaleRef.current) : pitch;
|
var dwPitch = snapToScaleRef.current ? snapPitchToScale(pitch, selectedScaleRef.current) : pitch;
|
||||||
var dwDurMs = Math.max(100, Math.round(initialDur * (60 / bpm) * 1000));
|
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);
|
// playNote (FluidSynth — nhạc cụ THẬT của track). _playNoteFallback chỉ
|
||||||
if (dwNodes) previewNodesRef.current = dwNodes;
|
// là oscillator beep (sai âm với percussion/soundfont — user: note vẽ
|
||||||
|
// mới nghe nhạc 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) {
|
function playDrawPreview(p, durMs) {
|
||||||
stopPreviewNote();
|
stopPreviewNote();
|
||||||
if (window.SonicSF && window.SonicSF._playNoteFallback) {
|
if (window.SonicSF && window.SonicSF.playNote) {
|
||||||
var pvCtx = getAudioContext();
|
var pvCtx = getAudioContext();
|
||||||
var pvTrk = activeTracks.find(function(t) { return t.id === st.trackId; });
|
var pvTrk = activeTracks.find(function(t) { return t.id === st.trackId; });
|
||||||
var pvCtxInst = resolveTrackInstrumentCtx(pvTrk, activeTracks);
|
var pvCtxInst = resolveTrackInstrumentCtx(pvTrk, activeTracks);
|
||||||
var pvVel = Math.round(brushVelocityRef.current * 127);
|
var pvVel = Math.round(brushVelocityRef.current * 127);
|
||||||
var pvNodes = window.SonicSF._playNoteFallback(p, pvVel, durMs, pvCtx.currentTime, pvCtxInst.program, null, pvCtxInst.ch, pvCtxInst.synthEngine);
|
// playNote (FluidSynth — nhạc cụ THẬT). _playNoteFallback = oscillator
|
||||||
if (pvNodes) previewNodesRef.current = pvNodes;
|
// beep sai âm (percussion/soundfont).
|
||||||
|
window.SonicSF.playNote(p, pvVel, durMs, pvCtx.currentTime, pvCtxInst.program, null, pvCtxInst.ch, pvCtxInst.synthEngine);
|
||||||
previewPitchRef.current = p;
|
previewPitchRef.current = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -153,7 +153,7 @@
|
|||||||
// expected notice when a soundfont simply has no
|
// expected notice when a soundfont simply has no
|
||||||
// preset for a bank (e.g. bank 128 on a melodic-only
|
// preset for a bank (e.g. bank 128 on a melodic-only
|
||||||
// font) — the note is just silent, not an error.
|
// 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);
|
console.warn('[FluidSynth:err]', msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -562,7 +562,22 @@
|
|||||||
console.log('[SonicSF] selectProgram for channel:', ch, 'sfHandle:', sfHandle, 'bank:', finalBank, 'prog:', finalProg);
|
console.log('[SonicSF] selectProgram for channel:', ch, 'sfHandle:', sfHandle, 'bank:', finalBank, 'prog:', finalProg);
|
||||||
if (sfHandle !== undefined) {
|
if (sfHandle !== undefined) {
|
||||||
try {
|
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) {}
|
} catch (e) {}
|
||||||
} else {
|
} else {
|
||||||
try { _fluidModule._fluid_synth_bank_select(_synthPtr, ch, finalBank); } catch (e) {}
|
try { _fluidModule._fluid_synth_bank_select(_synthPtr, ch, finalBank); } catch (e) {}
|
||||||
@@ -645,7 +660,11 @@
|
|||||||
var oscType = 'triangle';
|
var oscType = 'triangle';
|
||||||
var attackTime = 0.03, decayTime = 0.1, sustainLevel = 0.5, releaseTime = 0.2, volFactor = 0.25;
|
var attackTime = 0.03, decayTime = 0.1, sustainLevel = 0.5, releaseTime = 0.2, volFactor = 0.25;
|
||||||
var prog = program !== undefined ? parseInt(program) : 0;
|
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;
|
prog = _channels[channel].program || prog;
|
||||||
}
|
}
|
||||||
if (prog >= 0 && prog <= 7) { oscType = 'sine'; decayTime = 0.3; sustainLevel = 0.1; releaseTime = 0.2; }
|
if (prog >= 0 && prog <= 7) { oscType = 'sine'; decayTime = 0.3; sustainLevel = 0.1; releaseTime = 0.2; }
|
||||||
|
|||||||
@@ -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=202608038200"></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/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/aiGateway.js?v=202608037200"></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>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<script src="/static/js/services/midiExtractor.js?v=202607281052"></script>
|
<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/promptTemplateManager.js?v=202607281039"></script>
|
||||||
<script src="/static/js/services/undoRedoEngine.js?v=202607290941"></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">
|
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
|
|||||||
@@ -1901,3 +1901,18 @@
|
|||||||
- **Fix (app.jsx updatePlayhead):** `if (masterSilenceFramesRef.current > (nanOut ? 3 : 45) && sinceRebuild > 3000)` — **NaN (chain chết chắc chắn) → rebuild sau 3 frame ≈ 50ms** (gần như tức thì); pk<0.001 (main) giữ 45 frame. Cooldown 3000 giữ nguyên (chống loop nếu collapse deterministic).
|
- **Fix (app.jsx updatePlayhead):** `if (masterSilenceFramesRef.current > (nanOut ? 3 : 45) && sinceRebuild > 3000)` — **NaN (chain chết chắc chắn) → rebuild sau 3 frame ≈ 50ms** (gần như tức thì); pk<0.001 (main) giữ 45 frame. Cooldown 3000 giữ nguyên (chống loop nếu collapse deterministic).
|
||||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608060030), `wiki.md`. Rebuild precompiled.
|
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608060030), `wiki.md`. Rebuild precompiled.
|
||||||
- **Ghi chú/Test:** `npm run build` → hard refresh → play 0:0 → nếu chain chết: âm hồi phục ~150ms (thay vì 1.5s).
|
- **Ghi chú/Test:** `npm run build` → hard refresh → play 0:0 → nếu chain chết: âm hồi phục ~150ms (thay vì 1.5s).
|
||||||
|
|
||||||
|
### [2026-08-06 01:00] Task: Percussion track câm — program_select bank 128 thiếu preset → fallback preset hợp lệ
|
||||||
|
- **Báo cáo user:** track percussion chỉ nghe 1 âm đầu rồi câm; bật channel 10 → `[FluidSynth:err] There is no preset with bank number 128 and preset number 0 in SoundFont 2`.
|
||||||
|
- **Cơ chế:** track "latin hand perc" (sfId) mang bank 128 prog 0; `fluid_synth_program_select` trả -1 (preset không tồn tại trong font) → noteon trên preset rỗng = CÂM; channel cache vẫn ghi (128,0) → noteon sau skip re-select (progAlreadySet) → CÂM tiếp ("1 âm đầu" = note đầu còn preset cũ hợp lệ trước khi cache bị ghi đè).
|
||||||
|
- **FIX (soundfontPlayer.js doNote):** kiểm tra `_selRet !== 0 && finalBank === 128` → **fallback chuỗi preset trống phổ biến [128,48 (GM kit) → 0,0 → 128,1 → 0,48]** — chọn preset đầu tiên select thành công (trả 0) + cập nhật channel cache (finalBank/finalProg) → các note sau dùng preset hợp lệ. Lọc thêm error "There is no preset with bank number" khỏi console (printErr).
|
||||||
|
- **Các file ảnh hưởng:** `soundfontPlayer.js` (?v=202608060100 — chỉ hard refresh, không build precompiled), `wiki.md`.
|
||||||
|
- **Ghi chú/Test:** hard refresh → play track percussion → KỲ VỌNG: mọi note đều kêu (fallback preset), hết error spam.
|
||||||
|
|
||||||
|
### [2026-08-06 01:30] Task: Note vẽ mới trong piano roll nghe nhạc cụ track TRƯỚC — 2 lỗi preview
|
||||||
|
- **Báo cáo user:** track 4 percussion — click note vẽ từ trước = percussion ✓; VẼ note mới = nhạc cụ track 3.
|
||||||
|
- **2 lỗi:**
|
||||||
|
(1) `_playNoteFallback` (soundfontPlayer dòng 664): `prog = _channels[channel].program || prog` — **override program track bằng cache channel** (track 3 cùng channel ghi đè) → oscillator preview mang character track 3. FIX: chỉ override khi `program === undefined`.
|
||||||
|
(2) **Draw/brush preview dùng `_playNoteFallback` (oscillator beep)** thay vì `playNote` (FluidSynth — nhạc cụ thật) — click note cũ dùng playNote nên đúng. FIX app.jsx: cả 2 chỗ (brush ~7725, draw ~7819) → `playNote` với `resolveTrackInstrumentCtx` (ch/synthEngine của track).
|
||||||
|
- **Các file ảnh hưởng:** `soundfontPlayer.js` + `app.jsx` + `index.html` (?v=202608060130 cho cả 2), `wiki.md`. Rebuild precompiled.
|
||||||
|
- **Ghi chú/Test:** `npm run build` → hard refresh → track percussion → VẼ note mới → KỲ VỌNG: percussion thật (không phải nhạc cụ track trước).
|
||||||
|
|||||||
Reference in New Issue
Block a user