diff --git a/app/static/js/app.jsx b/app/static/js/app.jsx index 433249b..0c5ac7c 100644 --- a/app/static/js/app.jsx +++ b/app/static/js/app.jsx @@ -10331,7 +10331,8 @@ const App = () => { const secStart = sec.start || 0; const secEnd = secStart + (sec.duration || 0); - const secTracks = sec.tracks || []; + const openTab = sessionTabsRef.current ? sessionTabsRef.current.find(st => st.sectionId === sec.sectionId || st.sectionId === sec.id) : null; + const secTracks = openTab ? openTab.tracks : (sec.tracks || []); const hasSubSolo = secTracks.some(st => st.solo); secTracks.forEach((subTrack, subIdx) => { diff --git a/app/static/js/app.precompiled.js b/app/static/js/app.precompiled.js index 0ec78a2..a3530e8 100644 --- a/app/static/js/app.precompiled.js +++ b/app/static/js/app.precompiled.js @@ -303,7 +303,7 @@ const noteDurSec=(note.duration_beats||1)*secondsPerBeat;const noteEndSec=noteSt if(track.instrumentId&&midiItems.length===0&&track.buffer){// Play audio normally (the buffer has the audio data) // This block is intentionally empty - audio clips already play above }// SECTION items playback -const sections=track.sections||[];if(activeTab==='main'&§ions.length>0){const bpmVal=parseInt(bpm)||120;const secondsPerBeat=60.0/bpmVal;const secondsPerBar=secondsPerBeat*4;sections.forEach(sec=>{const secStart=sec.start||0;const secEnd=secStart+(sec.duration||0);const secTracks=sec.tracks||[];const hasSubSolo=secTracks.some(st=>st.solo);secTracks.forEach((subTrack,subIdx)=>{const isSubPlayable=hasSubSolo?subTrack.solo:!subTrack.muted;if(!isSubPlayable)return;const subNode=getOrCreateSubTrackNode(track,subTrack,context);if(!subNode)return;// 1. Play clips in subTrack +const sections=track.sections||[];if(activeTab==='main'&§ions.length>0){const bpmVal=parseInt(bpm)||120;const secondsPerBeat=60.0/bpmVal;const secondsPerBar=secondsPerBeat*4;sections.forEach(sec=>{const secStart=sec.start||0;const secEnd=secStart+(sec.duration||0);const openTab=sessionTabsRef.current?sessionTabsRef.current.find(st=>st.sectionId===sec.sectionId||st.sectionId===sec.id):null;const secTracks=openTab?openTab.tracks:sec.tracks||[];const hasSubSolo=secTracks.some(st=>st.solo);secTracks.forEach((subTrack,subIdx)=>{const isSubPlayable=hasSubSolo?subTrack.solo:!subTrack.muted;if(!isSubPlayable)return;const subNode=getOrCreateSubTrackNode(track,subTrack,context);if(!subNode)return;// 1. Play clips in subTrack const subClips=subTrack.clips||[];subClips.forEach(clip=>{if(!clip.buffer)return;const clipStartLocal=clip.startTime||0;const clipDurLocal=clip.buffer.duration/(clip.speed||1.0);const clipStartMain=secStart+clipStartLocal;const clipEndMain=clipStartMain+clipDurLocal;// Only play within the bounds of [secStart, secEnd] const activeStart=Math.max(clipStartMain,secStart);const activeEnd=Math.min(clipEndMain,secEnd);if(activeStart0){subMidiItems.forEach(item=>{const notes=item.notes||[];notes.forEach(note=>{const noteStartSecLocal=item.startTime+(note.start_beat||0)*secondsPerBeat;const noteDurSec=(note.duration_beats||1)*secondsPerBeat;const noteStartMain=secStart+noteStartSecLocal;const noteEndMain=noteStartMain+noteDurSec;// Only play if the note starts inside the Section item bounds and hasn't finished yet diff --git a/app/storage/sonicforge.db b/app/storage/sonicforge.db index 98fec64..8671c89 100644 Binary files a/app/storage/sonicforge.db and b/app/storage/sonicforge.db differ