FIX: sửa lỗi hiển thị animation của VU meter

This commit is contained in:
2026-08-07 15:40:15 +07:00
parent 58c6ec794d
commit 9e269d3b79
4 changed files with 184 additions and 21 deletions
+94 -9
View File
@@ -13900,6 +13900,12 @@ const App = () => {
selectedItemIdsRef.current = selectedItemIds;
const [currentTime, setCurrentTime] = useState(0);
const [isPlaying, setIsPlaying] = useState(false);
// Ref theo dõi isPlaying setTimeout VU trigger (main-midi delayed + section
// delayed) check ref này trưc khi fire: stop isPlaying=false setTimeout
// sót không fire VU không nhy sau khi âm đã dng (user: VU vn animation
// khi hết âm).
const isPlayingRef = useRef(false);
isPlayingRef.current = isPlaying;
const [selectionStart, setSelectionStart] = useState(null);
const [selectionEnd, setSelectionEnd] = useState(null);
const [selectionFollowsTempo, setSelectionFollowsTempo] = useState(true);
@@ -14988,6 +14994,14 @@ const App = () => {
const velFactor = typeof velocity === 'number' ? (velocity > 1 ? velocity / 127 : velocity) : 0.8;
const peak = Math.min(1.0, Math.max(0.15, velFactor));
midiVuActivityRef.current[trackId] = peak;
// Log ngun trigger (rate-limited 1/20 fire): xác đnh ai còn fire VU khi
// âm đã ngng (user: VU vn animation sau khi hết âm).
try {
const _tf = (window.__trigFrame = (window.__trigFrame || 0) + 1);
if (_tf % 20 === 1) {
console.log('[VUTrig]', trackId, 'vel=', velocity, 'peak=', peak.toFixed(2), 'play=', isPlaying, 'tab=', activeTabRef.current);
}
} catch (e) { }
};
window.triggerMidiVuActivity = triggerMidiVuActivity;
@@ -19349,6 +19363,9 @@ const App = () => {
);
// Trigger VU meter flash when the note starts playing
setTimeout(() => {
// Guard: stop setTimeout sót không đưc fire (VU nhy
// sau khi âm đã dng user bug 05:45).
if (!isPlayingRef.current) return;
if (window.triggerMidiVuActivity) {
window.triggerMidiVuActivity(track.id, note.velocity || 0.8);
}
@@ -19480,6 +19497,20 @@ const App = () => {
subCh,
subTrack.synth_engine
);
// Trigger VU meter flash đúng nhp (c subTrack VU
// section tab + parent track VU MAIN): MIDI section đi
// SF masterBus.input (không qua sub-node analyser)
// VU track ch nhy qua midiVuActivity. (B mt khi
// commit gp khôi phc fix 00:30/02:00.)
setTimeout(() => {
// Guard: stop setTimeout sót không đưc fire (VU
// nhy sau khi âm đã dng user bug 05:45).
if (!isPlayingRef.current) return;
if (window.triggerMidiVuActivity) {
window.triggerMidiVuActivity(subTrack.id, note.velocity || 0.8);
window.triggerMidiVuActivity(track.id, note.velocity || 0.8);
}
}, delay * 1000);
} else {
const remainingDurMs = (notePlayEndMain - offsetTime) * 1000;
window.SonicSF.playNote(
@@ -19492,14 +19523,10 @@ const App = () => {
subCh,
subTrack.synth_engine
);
}
// Trigger VU meter flash đúng nhp (ging main-track midi 19066)
// C subTrack (VU section tab) + parent track (VU MAIN section
// item đang play) midiVuActivity keyed theo track id trigger
// c 2 đ VU main nhy theo section.
if (window.triggerMidiVuActivity) {
window.triggerMidiVuActivity(subTrack.id, note.velocity || 0.8);
window.triggerMidiVuActivity(track.id, note.velocity || 0.8);
if (window.triggerMidiVuActivity) {
window.triggerMidiVuActivity(subTrack.id, note.velocity || 0.8);
window.triggerMidiVuActivity(track.id, note.velocity || 0.8);
}
}
}
});
@@ -24932,8 +24959,17 @@ STRICT CONSTRAINTS:
const v = Math.abs(data[i] - 128) / 128;
if (v > peak) peak = v;
}
// Deadband: b noise nn (log 06:00 master peak 0.008 liên tc dù
// không âm master VU nhy nh mãi)
if (peak < 0.01) peak = 0;
setMasterVU(peak);
setMasterMeterPeak(prev => Math.max(prev * 0.97, peak));
// Log master VU khi đang nhy (chn đoán 06:00 VU nhy ngoài vùng âm)
if (peak > 0.001) {
try {
console.log('[VU-master] peak=', peak.toFixed(3));
} catch (e) { }
}
}
// 2. Track VU Meters
@@ -24989,20 +25025,69 @@ STRICT CONSTRAINTS:
}
}
// MIDI THC: đc t SF output (âm post-FluidSynth) thay velocity
// trigger (GI fire lúc schedule click playhead re-schedule
// VU nhy dù âm không ra log 06:00: midi=0.98 nhưng master=0.008).
// Track MIDI đi SF masterBus (không qua node analyser) tap ti SF
// output gain.
let sfAudioPeak = 0;
let _sfTapped = false;
if (audioPeak <= 0.001) {
try {
if (window.SonicSF && window.SonicSF.getOutputNode) {
const sfNode = window.SonicSF.getOutputNode();
if (sfNode) {
if (!sfNode.__vuAnalyser) {
const _sa = getAudioContext().createAnalyser();
_sa.fftSize = 256;
_sa.smoothingTimeConstant = 0.2;
sfNode.connect(_sa);
sfNode.__vuAnalyser = _sa;
}
_sfTapped = true;
const d3 = new Uint8Array(128);
sfNode.__vuAnalyser.getByteTimeDomainData(d3);
for (let i = 0; i < d3.length; i++) {
const v = Math.abs(d3[i] - 128) / 128;
if (v > sfAudioPeak) sfAudioPeak = v;
}
}
}
} catch (e) { }
}
// midiVuActivityRef đưc set bi triggerMidiVuActivity c khi play
// MIDI item LN khi ARM + nhn phím MIDI keyboard (preview) nên VU
// nhy trong c 2 trưng hp (không chn bi isPlaying).
let midiPeak = isAudible ? (midiVuActivityRef.current[trackId] || 0) : 0;
// SF analyser đã tap CH dùng âm THC (velocity trigger = gi b)
if (_sfTapped) midiPeak = 0;
if (midiPeak > 0) {
midiVuActivityRef.current[trackId] = midiPeak * 0.90;
// Decay nhanh hơn (0.72/frame tt sau ~0.35s) hết note VU
// dng nhanh, không "vn din animation" khi không còn âm.
midiVuActivityRef.current[trackId] = midiPeak * 0.72;
if (midiVuActivityRef.current[trackId] < 0.01) {
midiVuActivityRef.current[trackId] = 0;
}
}
// Gp âm MIDI THC vào audioPeak
if (sfAudioPeak > audioPeak) audioPeak = sfAudioPeak;
// Deadband: b noise nn analyser (log 06:05 audio=0.008 dù không
// âm VU hin th đon nh "v nhưng không animation") hết âm
// VU tt NGAY LP TC (user yêu cu).
if (audioPeak < 0.01) audioPeak = 0;
const peak = Math.max(audioPeak, midiPeak);
const db = peak > 0 ? 20 * Math.log10(peak) : -60;
// Log chn đoán VU: CH in khi peak > 0 (VU đang nhy tht) xác đnh
// ngun nào còn nhy khi playhead ngoài vùng âm (user bug 06:00).
if (peak > 0.001) {
try {
console.log('[VU]', trackId, 'audio=', audioPeak.toFixed(3), 'midi=', midiPeak.toFixed(3), 'key=', key);
} catch (e) { }
}
if (peak > 0.001) {
if (key.endsWith('_mixer')) {
drawMixerVuMeter(canvas, peak);