feat(piano-roll): vào tab lúc main play -> chỉ play MIDI notes track đang edit, các track khác mute
useEffect [activeTab] mới: activeTab là PIANO_ROLL và main/section đang play -> stopAllPlayback + restart play CHỈ track piano roll tại vị trí tương ứng trong item (mainPos - item.startTime). mainResumeRef giữ để quay lại main/section resume đúng vị trí (nhánh resume cũ không đổi).
This commit is contained in:
+27
-4
@@ -16943,6 +16943,29 @@ const App = () => {
|
||||
console.log('[SectionTab] play CHỈ section items tại local', _pt.toFixed(2), '(secStart', _secStart.toFixed(2) + ')');
|
||||
} catch (e) { console.warn('[SectionTab] restart error:', e); }
|
||||
}
|
||||
// Vào PIANO ROLL lúc MAIN/SECTION đang play → CHỈ play MIDI notes CỦA
|
||||
// TRACK đang edit, TẮT âm MỌI track khác (user: vào piano roll phải play
|
||||
// only midi notes đang active). Dừng main → play lại CHỈ track piano roll
|
||||
// tại vị trí TƯƠNG ỨNG trong item (mainPos − item.startTime). Rời tab →
|
||||
// nhánh resume (dưới) về main/section đúng vị trí (mainResumeRef vẫn giữ).
|
||||
const _prTabNew = activeTab && activeTab.startsWith('midi_') ? subTabsRef.current.find(s => s.id === activeTab && s.type === 'PIANO_ROLL') : null;
|
||||
if (_prTabNew && !_prTabNew.isPlaying && isPlaying) {
|
||||
try {
|
||||
const _ctx = getAudioContext();
|
||||
const _mainPos = startOffsetTimeRef.current + (_ctx.currentTime - startAudioTimeRef.current);
|
||||
const _itemInfo = getPianoRollItemInfo(_prTabNew);
|
||||
const _prPos = _itemInfo ? Math.max(0, _mainPos - (_itemInfo.startTime || 0)) : (_prTabNew.currentTime || 0);
|
||||
stopAllPlayback();
|
||||
startOffsetTimeRef.current = _prPos;
|
||||
startAudioTimeRef.current = _ctx.currentTime;
|
||||
startBufferOffsetRef.current = _prPos * (_prTabNew.speed || 1.0);
|
||||
schedulePianoRollMidi(_prTabNew, _prPos);
|
||||
startSubTabPlayback(_prTabNew, _prPos);
|
||||
setSubTabs(prev => prev.map(s => s.id === _prTabNew.id ? { ...s, isPlaying: true, currentTime: _prPos } : s));
|
||||
animationFrameIdRef.current = requestAnimationFrame(updatePlayhead);
|
||||
console.log('[PianoRollTab] play CHỈ track', _prTabNew.trackId, 'tại local', _prPos.toFixed(2), '(mainPos', _mainPos.toFixed(2), 'itemStart', _itemInfo ? _itemInfo.startTime.toFixed(2) : '?', ')');
|
||||
} catch (e) { console.warn('[PianoRollTab] restart error:', e); }
|
||||
}
|
||||
const prevSub = subTabsRef.current.find(s => s.id === prevTab);
|
||||
if (prevSub && prevSub.isPlaying) {
|
||||
// Chuyển sang SUB-TAB KHÁC (piano roll khác/audio tab) → STOP âm tab
|
||||
@@ -18950,10 +18973,10 @@ const App = () => {
|
||||
const midiItem = (track.midiItems || []).find(m => m.id === midiItemId);
|
||||
if (!midiItem) return;
|
||||
|
||||
// Clean stop playback ONLY khi KHÔNG đang play main — nếu main đang play,
|
||||
// mở PIANO ROLL tab KHÔNG được dừng âm (user: dblclick mở tab lúc main
|
||||
// play → âm main phải tiếp tục). Nhánh play sub-tab tự stopAllPlayback
|
||||
// trước khi play nên không xung đột route.
|
||||
// Main đang play → CHỈ lưu điểm resume; useEffect [activeTab] tự
|
||||
// stopAllPlayback + play CHỈ track piano roll khi vào tab (user: piano roll
|
||||
// play only midi notes đang active — mọi track khác mute). mainResumeRef
|
||||
// giữ để quay lại MAIN/SECTION resume đúng vị trí.
|
||||
if (isPlaying) {
|
||||
// Lưu điểm resume: nếu user bấm Space trong piano roll (play piano roll
|
||||
// → stopAllPlayback dừng main) → khi quay lại MAIN/SECTION resume main
|
||||
|
||||
Reference in New Issue
Block a user