FIX: Đã fix (v202608060430) — tab deactive → stop âm tab đó

This commit is contained in:
2026-08-05 17:29:52 +07:00
parent b3ced7a7b3
commit 289746f187
4 changed files with 26 additions and 2 deletions
+14
View File
@@ -14568,8 +14568,22 @@ const App = () => {
updateSfRouting();
}, [tracks, sessionTabs]);
const prevActiveTabRef = useRef(activeTab);
useEffect(() => {
const prevTab = prevActiveTabRef.current;
prevActiveTabRef.current = activeTab;
updateSfRouting();
// Tab DEACTIVE stop âm ca tab đó (user requirement): ri khi sub-tab
// (PIANO_ROLL/section/audio tab) đang play stop playback ca tab đó.
// Tab mi hot đng bình thưng; MAIN gi hành vi cũ (m piano-roll lúc
// main play main tiếp tc handleEditMidiInTab đã x lý).
if (prevTab !== activeTab) {
const prevSub = subTabsRef.current.find(s => s.id === prevTab);
if (prevSub && prevSub.isPlaying) {
try { stopAllPlayback(); } catch (e) {}
setSubTabs(prev => prev.map(s => s.id === prevTab ? { ...s, isPlaying: false } : s));
}
}
}, [activeTab]);
const [selectionCleared, setSelectionCleared] = useState(false); // LOOP_EDITOR_2.md §4.2
+5 -1
View File
@@ -631,7 +631,11 @@ useEffect(()=>{const all=[...(tracks||[]),...(sessionTabs||[]).reduce((acc,s)=>a
const audioSig=list.map(t=>(t.muted?'1':'0')+(t.solo?'1':'0')+':'+(t.volumeDb??0)+':'+(t.audioBypass?'1':'0')+(t.midiBypass?'1':'0')+':'+(t.midiItems||[]).length+':'+(t.clips||[]).length+':'+(t.sections||[]).length).join('|');if(trackAudioSyncSigRef.current===audioSig)return;trackAudioSyncSigRef.current=audioSig;list.forEach(t=>{// ♪ state → SF mastering route (sfRouteGain/sfDryGain), live on existing nodes
const sn=activeTrackNodesRef.current[t.id];if(sn&&sn.sfRouteGain&&sn.sfDryGain&&sn.sfRouteGain.gain.value>0!==!effMidiBypass(t)){const _b=effMidiBypass(t);sn.sfRouteGain.gain.value=_b?0:1;sn.sfDryGain.gain.value=_b?1:0;}const sig=(t.muted?'1':'0')+(t.solo?'1':'0')+':'+(t.volumeDb??0);if(trackMuteSoloSigRef.current[t.id]===sig)return;trackMuteSoloSigRef.current[t.id]=sig;const audible=computeTrackAudibleGain(list,t)>0;const node=activeTrackNodesRef.current[t.id];const audibleGain=computeTrackAudibleGain(list,t);if(node)setTrackNodeGain(node,audibleGain);if(node&&node.sfEntry){try{const g=typeof audibleGain==='number'&&isFinite(audibleGain)&&!isNaN(audibleGain)?audibleGain:1.0;node.sfEntry.gain.setTargetAtTime(g,getAudioContext().currentTime,0.02);}catch(e){}}// MIDI tracks: mirror the gain decision onto the channel CC7 volume so
// FluidSynth-rendered notes respect mute/solo too.
if(t.midiItems&&t.midiItems.length>0||t.type==='MIDI'){try{if(window.SonicSF&&typeof window.SonicSF.controllerChange==='function'){const ch=ensureTrackMidiChannel(t,list);window.SonicSF.controllerChange(ch,7,audible?100:0);}}catch(e){}}trackAudibleRef.current[t.id]=audible;});updateSfRouting();},[tracks,sessionTabs]);useEffect(()=>{updateSfRouting();},[activeTab]);const[selectionCleared,setSelectionCleared]=useState(false);// LOOP_EDITOR_2.md §4.2
if(t.midiItems&&t.midiItems.length>0||t.type==='MIDI'){try{if(window.SonicSF&&typeof window.SonicSF.controllerChange==='function'){const ch=ensureTrackMidiChannel(t,list);window.SonicSF.controllerChange(ch,7,audible?100:0);}}catch(e){}}trackAudibleRef.current[t.id]=audible;});updateSfRouting();},[tracks,sessionTabs]);const prevActiveTabRef=useRef(activeTab);useEffect(()=>{const prevTab=prevActiveTabRef.current;prevActiveTabRef.current=activeTab;updateSfRouting();// Tab DEACTIVE → stop âm của tab đó (user requirement): rời khỏi sub-tab
// (PIANO_ROLL/section/audio tab) đang play → stop playback của tab đó.
// Tab mới hoạt động bình thường; MAIN giữ hành vi cũ (mở piano-roll lúc
// main play → main tiếp tục — handleEditMidiInTab đã xử lý).
if(prevTab!==activeTab){const prevSub=subTabsRef.current.find(s=>s.id===prevTab);if(prevSub&&prevSub.isPlaying){try{stopAllPlayback();}catch(e){}setSubTabs(prev=>prev.map(s=>s.id===prevTab?{...s,isPlaying:false}:s));}}},[activeTab]);const[selectionCleared,setSelectionCleared]=useState(false);// LOOP_EDITOR_2.md §4.2
const midiVuActivityRef=useRef({});const triggerMidiVuActivity=(trackId,velocity)=>{if(!trackId)return;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;};window.triggerMidiVuActivity=triggerMidiVuActivity;// ── Temp Edit Tab (LOOP_EDITOR_2.md §1.2 Sub Tab) ──
const[tempTabActive,setTempTabActive]=useState(false);const[tempTabBuffer,setTempTabBuffer]=useState(null);const[tempTabTrackId,setTempTabTrackId]=useState(null);const[tempTabOrigStart,setTempTabOrigStart]=useState(0);const[tempTabOrigEnd,setTempTabOrigEnd]=useState(0);const tempTabCanvasRef=useRef(null);// Effect parameters for temp tab
const[tempTabEffects,setTempTabEffects]=useState({reverse:false,gainDb:0,fadeInMs:0,fadeOutMs:0});// ── Auth / User State ──
+1 -1
View File
@@ -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=202608060400" defer></script>
<script src="/static/js/app.precompiled.js?v=202608060430" defer></script>
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
<style>
:root {
+6
View File
@@ -1949,3 +1949,9 @@
- **FIX (dòng 23046):** thêm `midiChannel: undefined` vào clone — `ensureTrackMidiChannel` (đã có guard) cấp channel RIÊNG (loop 0-15 skip 9). Kiểm tra: chỉ 1 chỗ spread srcTrack (23043) — AI composition dùng template sạch ✓.
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608060400), `wiki.md`. Rebuild precompiled.
- **Ghi chú/Test:** `npm run build` → hard refresh → tạo [AI Var] từ track → solo track AI Var → âm PHẢI bình thường (không nhỏ); solo track gốc → AI Var không bị ảnh hưởng.
### [2026-08-06 04:30] Task: Tab deactive → stop âm của tab đó (piano-roll tiếp tục kêu khi quay main)
- **Báo cáo user:** piano roll tab đang play → quay về MAIN/SECTION-TAB → VẪN nghe âm piano roll. Yêu cầu: tab nào deactive → stop âm tab đó.
- **FIX (app.jsx effect [activeTab] ~14571):** `prevActiveTabRef` lưu tab trước; khi đổi tab → nếu tab CŨ là sub-tab (PIANO_ROLL/section/audio) đang `isPlaying``stopAllPlayback()` + set `isPlaying: false` cho tab đó. Tab MỚI không bị ảnh hưởng; MAIN giữ hành vi cũ (mở piano-roll lúc main play → main tiếp tục — handleEditMidiInTab đã xử lý).
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/templates/index.html` (?v=202608060430), `wiki.md`. Rebuild precompiled.
- **Ghi chú/Test:** `npm run build` → hard refresh → piano-roll play → bấm tab MAIN → âm piano-roll phải DỪNG ngay; play main → mở piano-roll → main tiếp tục (hành vi cũ).