FIX: VU meter giữ animation đúng trường độ âm khi ARM + giữ phím MIDI keyboard (heldMidiNotesRef, không decay khi note còn giữ)

This commit is contained in:
2026-08-08 13:12:49 +00:00
parent b490aa9951
commit 3618e3c591
4 changed files with 71 additions and 16 deletions
+39 -6
View File
@@ -14500,6 +14500,11 @@ const App = () => {
if (window.triggerMidiVuActivity) {
window.triggerMidiVuActivity(as.trackId, scaledVel);
}
// Gi VU theo trưng đ: tăng counter note đang gi
// (tick gi peak cho ti khi note-off)
try {
heldMidiNotesRef.current[as.trackId] = (heldMidiNotesRef.current[as.trackId] || 0) + 1;
} catch (err) { }
window.SonicSF.playNote(pitch, scaledVel, 60000, undefined, asProg, null, asCh, asSe);
});
}
@@ -14512,6 +14517,10 @@ const App = () => {
if (window.triggerMidiVuActivity) {
window.triggerMidiVuActivity(at.id, scaledVel);
}
// Gi VU theo trưng đ: tăng counter note đang gi
try {
heldMidiNotesRef.current[at.id] = (heldMidiNotesRef.current[at.id] || 0) + 1;
} catch (err) { }
window.SonicSF.playNote(pitch, scaledVel, 60000, undefined, atProg, atDest, atCh, atSe);
});
}
@@ -14535,6 +14544,16 @@ const App = () => {
if (!st.synth_engine && st.midiChannel === undefined) return;
var stCh = assignTrackMidiChannel(st, stopTracks);
window.SonicSF.stopNote(stCh, pitch);
// Gim counter note đang gi hết note VU đưc phép decay/tt
// (tick s thy counter = 0 và không còn gi peak na)
try {
if (heldMidiNotesRef.current[st.id] !== undefined) {
heldMidiNotesRef.current[st.id] = Math.max(0, heldMidiNotesRef.current[st.id] - 1);
if (heldMidiNotesRef.current[st.id] === 0) {
delete heldMidiNotesRef.current[st.id];
}
}
} catch (err) { }
});
}
}
@@ -15494,6 +15513,11 @@ const App = () => {
}, [isPlaying]);
const midiVuActivityRef = useRef({});
// Đếm s note MIDI đang GI per-track (ARM + MIDI keyboard live input).
// VU tick dùng ref này: còn note gi gi peak (không decay) VU animate
// ĐÚNG trưng đ âm thanh (user bug: nhn phím gi âm còn kêu nhưng VU tt
// sau ~0.5s vì decay 0.75/frame). Hết note (note-off) mi decay/tt.
const heldMidiNotesRef = useRef({});
const triggerMidiVuActivity = (trackId, velocity) => {
if (!trackId) return;
const velFactor = typeof velocity === 'number' ? (velocity > 1 ? velocity / 127 : velocity) : 0.8;
@@ -20595,6 +20619,9 @@ const App = () => {
// âm cũ user 06:45: tt âm MAIN items khi vào SECTION-TAB VU main
// items phi tt theo, không "din" tiếp).
try { midiVuActivityRef.current = {}; } catch (e) { }
// Clear luôn counter note đang gi nếu không, sau stop (âm đã dng)
// tick vn thy heldCnt > 0 gi peak VU dính mãi (user bug 08:08).
try { heldMidiNotesRef.current = {}; } catch (e) { }
stopMidiCapture();
if (window.SonicSF) {
try { window.SonicSF.stopAll(); } catch (e) { console.warn('[Stop] stopAll error:', e); }
@@ -25856,12 +25883,18 @@ STRICT CONSTRAINTS:
// velocity thp (âm SF nh < 0.03) VU không nhy (user bug 07:10).
let midiPeak = isAudible ? (midiVuActivityRef.current[vuKey] || 0) : 0;
if (midiPeak > 0) {
// Decay 0.75 (~0.5s) cân bng: note đơn/velocity thp hin th rõ
// NHƯNG tt nhanh sau hết note (decay 0.85 ~1s quá lâu user:
// "vn din animation" sau khi âm hết bug 07:15).
midiVuActivityRef.current[vuKey] = midiPeak * 0.75;
if (midiVuActivityRef.current[vuKey] < 0.01) {
midiVuActivityRef.current[vuKey] = 0;
// ARM + MIDI keyboard: còn note đang GI gi nguyên peak, KHÔNG
// decay VU animate đúng trưng đ âm thanh (user bug 08:08: âm còn
// kêu nhưng VU tt sau ~0.5s vì decay 0.75/frame). Hết note decay
// 0.75 (~0.5s) tt nhanh như trưc.
const heldCnt = heldMidiNotesRef.current[vuKey] || 0;
if (heldCnt > 0) {
// Gi nguyên peak trong khi âm đang kêu (không decay)
} else {
midiVuActivityRef.current[vuKey] = midiPeak * 0.75;
if (midiVuActivityRef.current[vuKey] < 0.01) {
midiVuActivityRef.current[vuKey] = 0;
}
}
}
// KHÔNG gp sfAudioPeak vào audioPeak: SF là 1 output CHUNG cho mi