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:
+39
-6
@@ -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 tới 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);
|
||||
// Giảm counter note đang giữ — hết note → VU được phép decay/tắt
|
||||
// (tick sẽ thấy counter = 0 và không còn giữ peak nữa)
|
||||
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: nhấn phím giữ âm còn kêu nhưng VU tắt
|
||||
// sau ~0.5s vì decay 0.75/frame). Hết note (note-off) → mới decay/tắt.
|
||||
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: tắt âm MAIN items khi vào SECTION-TAB → VU main
|
||||
// items phải tắt theo, không "diễn" tiếp).
|
||||
try { midiVuActivityRef.current = {}; } catch (e) { }
|
||||
// Clear luôn counter note đang giữ — nếu không, sau stop (âm đã dừng)
|
||||
// tick vẫn thấy 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 thấp (âm SF nhỏ < 0.03) → VU không nhảy (user bug 07:10).
|
||||
let midiPeak = isAudible ? (midiVuActivityRef.current[vuKey] || 0) : 0;
|
||||
if (midiPeak > 0) {
|
||||
// Decay 0.75 (~0.5s) — cân bằng: note đơn/velocity thấp hiển thị rõ
|
||||
// NHƯNG tắt nhanh sau hết note (decay 0.85 ~1s quá lâu — user:
|
||||
// "vẫn diễn 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 tắt sau ~0.5s vì decay 0.75/frame). Hết note → decay
|
||||
// 0.75 (~0.5s) tắt 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 gộp sfAudioPeak vào audioPeak: SF là 1 output CHUNG cho mọi
|
||||
|
||||
Reference in New Issue
Block a user