FIX: sửa lỗi chuyển từ tab PIANO ROLL TAB sang MAIN SESSION và SECTION-TAB thì bị câm
This commit is contained in:
+52
-2
@@ -14840,6 +14840,31 @@ const App = () => {
|
||||
if (prevSub && prevSub.isPlaying) {
|
||||
try { stopAllPlayback(); } catch (e) {}
|
||||
setSubTabs(prev => prev.map(s => s.id === prevTab ? { ...s, isPlaying: false } : s));
|
||||
// Resume main/session play khi rời PIANO ROLL tab đã play (Space):
|
||||
// play piano roll → stopAllPlayback dừng main → quay lại MAIN/SECTION
|
||||
// bị CÂM. Resume startTrackPlayback(offset + elapsed thật) — chỉ khi
|
||||
// trước đó mở tab lúc main đang play (mainResumeRef đã set).
|
||||
const _resume = mainResumeRef.current;
|
||||
mainResumeRef.current = null;
|
||||
if (_resume && prevSub.type === 'PIANO_ROLL' && (activeTab === 'main' || (activeTab && activeTab.startsWith('session_')))) {
|
||||
try {
|
||||
const _elapsed = getAudioContext().currentTime - _resume.audioTime;
|
||||
const _resumeAt = _resume.offset + _elapsed;
|
||||
console.log('[Resume] main play từ', _resumeAt.toFixed(2), 's (offset', _resume.offset.toFixed(2), '+ elapsed', _elapsed.toFixed(2), ')');
|
||||
stopAllPlayback();
|
||||
startOffsetTimeRef.current = _resumeAt;
|
||||
startAudioTimeRef.current = getAudioContext().currentTime;
|
||||
startTrackPlayback(_resumeAt);
|
||||
setIsPlaying(true);
|
||||
} catch (e) { console.warn('[Resume] error:', e); }
|
||||
}
|
||||
} else if (prevSub && prevSub.type === 'PIANO_ROLL') {
|
||||
// Rời PIANO ROLL tab KHÔNG play: main/section play ngầm vẫn chạy (âm
|
||||
// tiếp tục tự nhiên — không cần resume) → clear resume point.
|
||||
// ⚠️ KHÔNG clear khi prevTab = main/session (đang DI CHUYỂN VÀO piano
|
||||
// roll — mainResumeRef vừa set bởi handleEditMidiInTab — clear nhầm ở
|
||||
// đây làm resume chết → quay lại main/section bị CÂM).
|
||||
mainResumeRef.current = null;
|
||||
}
|
||||
}
|
||||
}, [activeTab]);
|
||||
@@ -15562,6 +15587,11 @@ const App = () => {
|
||||
const isDraggingSubTabRef = useRef(false);
|
||||
const handlePlayPauseRef = useRef(null);
|
||||
const currentTimeRef = useRef(currentTime);
|
||||
// Resume main/session play khi rời PIANO ROLL tab: mở piano roll lúc main
|
||||
// đang play → bấm Space (play piano roll) → stopAllPlayback dừng main →
|
||||
// quay lại MAIN/SECTION → CÂM. Lưu {offset, audioTime} lúc mở tab → khi
|
||||
// rời tab resume startTrackPlayback(offset + elapsed thật).
|
||||
const mainResumeRef = useRef(null);
|
||||
currentTimeRef.current = currentTime;
|
||||
|
||||
// ── Keyboard Shortcuts ──
|
||||
@@ -16424,7 +16454,15 @@ const App = () => {
|
||||
// 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.
|
||||
if (!isPlaying) stopAllPlayback();
|
||||
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
|
||||
// từ đúng vị trí âm (offset + elapsed thật) — hết câm.
|
||||
mainResumeRef.current = { offset: startOffsetTimeRef.current, audioTime: getAudioContext().currentTime };
|
||||
} else {
|
||||
mainResumeRef.current = null;
|
||||
stopAllPlayback();
|
||||
}
|
||||
|
||||
const ctx = getAudioContext();
|
||||
const silentBuffer = ctx.createBuffer(1, 128, ctx.sampleRate);
|
||||
@@ -18425,7 +18463,19 @@ const App = () => {
|
||||
const isSubTab = subTabsRef.current.some(sub => sub.id === activeTabRef.current);
|
||||
if (isSubTab) {
|
||||
const st = subTabsRef.current.find(s => s.id === activeTabRef.current);
|
||||
if (!st || !st.isPlaying || !st.buffer) return;
|
||||
if (!st || !st.buffer) return;
|
||||
if (!st.isPlaying) {
|
||||
// PIANO ROLL / sub-tab KHÔNG play (mới mở, đang edit): playhead của
|
||||
// MAIN/SECTION KHÔNG được tiếp tục di chuyển (yêu cầu user) — KHÔNG
|
||||
// setCurrentTime. Loop phải TIẾP TỤC (rAF) để khi quay lại tab playhead
|
||||
// không nhảy vọt sai lệch. ⚠️ KHÔNG check projectEnd ở đây: projectEnd
|
||||
// tính theo activeTab — piano roll tab (sub-tab) → projectEnd = 1s →
|
||||
// updatedTime (elapsed thật) >= 1 → stopAllPlayback NGAY → CÂM + panic
|
||||
// notes. Âm main đã schedule hết từ startTrackPlayback — tự hết đúng
|
||||
// lúc; khi quay lại MAIN nhánh main tự stop tại projectEnd thật.
|
||||
animationFrameIdRef.current = requestAnimationFrame(updatePlayhead);
|
||||
return;
|
||||
}
|
||||
const context = getAudioContext();
|
||||
const speedFactor = st.speed || 1.0;
|
||||
const elapsed = context.currentTime - startAudioTimeRef.current;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -24,7 +24,7 @@
|
||||
<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/undoRedoEngine.js?v=202607290941"></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608070345" defer></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608070405" defer></script>
|
||||
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
|
||||
<style>
|
||||
:root {
|
||||
|
||||
@@ -2361,3 +2361,33 @@
|
||||
- **FIX (app.jsx updateSfRouting nhánh PIANO_ROLL):** khi `_activeSub.parent_tab_id` startsWith `session_` → lookup node ƯU TIÊN SUB-NODE (key `endsWith('_sub_' + trackId)` — route theo ♪ section + thẳng masterBus.input); không có sub-node → null (SF về masterBus.input — qua mastering, KHÔNG bypass). Không bao giờ route vào node MAIN cho piano roll của section.
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608070345), `wiki.md`. Rebuild precompiled.
|
||||
- **Ghi chú/Test:** hard refresh → play MAIN → double-click section (SECTION-TAB) → double-click MIDI item → PIANO ROLL tab → MIDI qua mastering (nghe EQ/limiter); log `[SFRoute]` không còn dest node MAIN (route 0/1) cho piano roll section.
|
||||
|
||||
### [2026-08-07 03:50] Task: Playhead vẫn di chuyển trong PIANO ROLL TAB khi mở MIDI item từ SECTION-TAB
|
||||
- **Báo cáo user:** mở MIDI item từ SECTION-TAB (đang play) → PIANO ROLL TAB → playhead vẫn tiếp tục di chuyển — cần dừng.
|
||||
- **Phân tích:** piano roll view vẽ playhead theo `st.currentTime` (chỉ cập nhật khi tab play) — khi mở tab (chưa play) code cũ `return` ở nhánh sub-tab KHÔNG setCurrentTime → playhead đứng yên — NHƯNG return đó GIẾT CHẾT rAF loop: main/section play chạy ngầm (handleEditMidiInTab 16427 không dừng âm) → watchdog master-silence chết, âm main không dừng đúng projectEnd, và khi quay lại tab playhead NHẢY VỌT theo `elapsed` thật (trông như vẫn di chuyển/sai lệch).
|
||||
- **FIX (app.jsx updatePlayhead nhánh sub-tab):** tách 2 trường hợp — (1) sub-tab KHÔNG play: KHÔNG setCurrentTime (playhead đứng yên) NHƯNG nếu `isPlaying` (main/session chạy ngầm) → vẫn check projectEnd (stop đúng lúc) + TIẾP TỤC requestAnimationFrame (loop sống, watchdog sống, quay lại tab không nhảy); (2) sub-tab play: giữ nguyên hành vi cũ.
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608070350), `wiki.md`. Rebuild precompiled.
|
||||
- **Ghi chú/Test:** hard refresh → play MAIN → double-click section (SECTION-TAB) → double-click MIDI item → PIANO ROLL TAB → playhead KHÔNG di chuyển (đứng yên); âm main tiếp tục + dừng đúng cuối bài; quay lại SECTION-TAB → playhead đúng vị trí âm (không nhảy vọt). Nếu playhead vẫn chạy khi CHƯA bấm play → xác nhận lại: có bấm Space/Play trong piano roll không (bấm play → playhead chạy là đúng hành vi).
|
||||
|
||||
### [2026-08-07 03:55] Task: FIX hồi quy 0350 — CÂM âm khi mở PIANO ROLL từ SECTION-TAB (projectEnd=1s ở sub-tab)
|
||||
- **Báo cáo user (log 0350):** mở MIDI item từ SECTION-TAB → PIANO ROLL → `[SFRoute] activeTab=midi_... midiAudible=1(midi1)` → `setOutputDestination to: masterBus.input` → KHÔNG noteon tiếp theo → CÂM (bản 0345 play tiếp).
|
||||
- **Nguyên nhân (hồi quy fix 0350):** nhánh updatePlayhead sub-tab không-play check `updatedTime >= projectEndRef.current` — nhưng `projectEnd` tính theo activeTab: piano roll tab (sub-tab) KHÔNG main/không session → `tab=undefined → max=0` → **projectEnd = 1s** → updatedTime (elapsed THẬT từ lúc play main — đã >1s) >= 1 → `stopAllPlayback()` NGAY → panic notes + xóa nodes (activeTrackNodesRef={}) → SF về masterBus.input + KHÔNG noteon = CÂM.
|
||||
- **FIX (app.jsx):** bỏ check projectEnd khỏi nhánh sub-tab không-play — chỉ `requestAnimationFrame` tiếp tục (loop sống cho playhead không nhảy khi quay lại). Âm main đã schedule hết từ startTrackPlayback — tự hết đúng lúc; quay lại MAIN → nhánh main tự stop tại projectEnd THẬT.
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608070355), `wiki.md`. Rebuild precompiled.
|
||||
- **Ghi chú/Test:** hard refresh → play MAIN → double-click section (SECTION-TAB) → double-click MIDI item → PIANO ROLL TAB → âm section TIẾP TỤC play (không câm) + playhead piano roll ĐỨNG YÊN; quay lại SECTION-TAB → playhead đúng vị trí âm.
|
||||
|
||||
### [2026-08-07 04:00] Task: Quay lại MAIN/SECTION sau khi Space trong PIANO ROLL → CÂM — resume main play
|
||||
- **Báo cáo user (log 0355):** mở MIDI item từ SECTION-TAB → PIANO ROLL (playhead đứng yên ✓ — fix 0350/0355); bấm Space → playhead piano roll chạy; **quay lại MAIN/SECTION → CÂM** (log: `[SFRoute] activeTab=main midiAudible=` + `setOutputDestination to: masterBus.input` — SF về masterBus nhưng KHÔNG noteon — main play đã chết).
|
||||
- **Nguyên nhân:** Space trong PIANO ROLL → `handlePlayPause` nhánh sub-tab → `stopAllPlayback()` DỪNG main/section play (xóa nodes + panic) → chơi piano roll. Quay lại MAIN/SECTION → không còn gì play → câm.
|
||||
- **FIX (app.jsx):** resume main/section play khi rời piano roll tab đã play:
|
||||
(1) `mainResumeRef` mới — lưu `{offset: startOffsetTimeRef.current, audioTime: ctx.currentTime}` lúc MỞ piano roll tab khi main đang play (handleEditMidiInTab — nhánh isPlaying=true).
|
||||
(2) Effect đổi tab (14814): rời PIANO ROLL tab đã play về MAIN hoặc `session_*` + có `mainResumeRef` → `stopAllPlayback()` + `startTrackPlayback(offset + elapsed thật)` + `setIsPlaying(true)` — âm main/section tiếp tục từ ĐÚNG vị trí (không chơi lại từ đầu, không câm). Các trường hợp khác: clear `mainResumeRef` (không resume trùng).
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608070400), `wiki.md`. Rebuild precompiled.
|
||||
- **Ghi chú/Test:** hard refresh → play MAIN → double-click section (SECTION-TAB) → double-click MIDI item → PIANO ROLL (playhead đứng yên) → Space (playhead piano roll chạy) → quay lại MAIN/SECTION → ÂM TIẾP TỤC từ đúng vị trí (log `[Resume] main play từ X.XX s`); KHÔNG bấm Space → quay lại → âm vẫn tiếp tục (không resume trùng).
|
||||
|
||||
### [2026-08-07 04:05] Task: FIX 0400 — resume không chạy (mainResumeRef bị clear nhầm bởi chính effect đổi tab)
|
||||
- **Báo cáo user (log 0400):** piano roll play (Space) → `dest=sfEntry node 1 ... MASTERING` + noteons ✓ → chuyển về SECTION-TAB → `setOutputDestination to: masterBus.input` (node null) → KHÔNG có log `[Resume]` → CÂM.
|
||||
- **Nguyên nhân:** handleEditMidiInTab set `mainResumeRef` (mở tab lúc main play) → setActiveTab → effect đổi tab (14814) chạy với `prevTab='session_...'` → `prevSub = subTabsRef.find('session_...')` = **undefined** → rơi vào nhánh `else` cũ → **`mainResumeRef.current = null` — XÓA SẠCH resume point NGAY khi VÀO piano roll** → quay lại section: `_resume=null` → không resume → câm.
|
||||
- **FIX (app.jsx effect 14814):** nhánh clear đổi thành `else if (prevSub && prevSub.type === 'PIANO_ROLL')` — chỉ clear khi THỰC SỰ rời khỏi piano roll tab (không play — main ngầm tiếp tục tự nhiên). prevTab = main/session (đang VÀO piano roll) → KHÔNG clear — resume point giữ nguyên.
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608070405), `wiki.md`. Rebuild precompiled.
|
||||
- **Ghi chú/Test:** hard refresh → play MAIN → double-click section → double-click MIDI item → PIANO ROLL (playhead đứng yên) → Space (piano roll play) → quay lại SECTION-TAB → **log `[Resume] main play từ X.XX s` + ÂM TIẾP TỤC từ đúng vị trí** (SF route: `dest=sfEntry node 1 ... MASTERING`); KHÔNG Space → quay lại → âm ngầm tiếp tục (không resume trùng).
|
||||
|
||||
Reference in New Issue
Block a user