fix: remove range auto-loop + gain fade-out for reschedule crackling

This commit is contained in:
2026-07-26 11:34:02 +07:00
parent 724b42d506
commit 5e096b5594
2 changed files with 34 additions and 11 deletions
+31 -8
View File
@@ -5908,12 +5908,10 @@ const beatSec = 60.0 / (parseInt(bpm) || 120);
const eBeat = Math.max(sBeat + 1, Math.max(rulerDragRef.current.startBeat, beat)); const eBeat = Math.max(sBeat + 1, Math.max(rulerDragRef.current.startBeat, beat));
setLoopStartBeat(sBeat); setLoopStartBeat(sBeat);
setLoopEndBeat(eBeat); setLoopEndBeat(eBeat);
setIsLooping(true);
setSubTabs(prev => prev.map(s => s.id === st.id ? { setSubTabs(prev => prev.map(s => s.id === st.id ? {
...s, ...s,
selectionStart: sBeat * beatSec, selectionStart: sBeat * beatSec,
selectionEnd: eBeat * beatSec, selectionEnd: eBeat * beatSec
isLooping: true
} : s)); } : s));
} }
}; };
@@ -6523,8 +6521,21 @@ const App = () => {
const playingSub = subTabs.find(s => s.trackId === trackId && s.type === 'PIANO_ROLL' && s.isPlaying); const playingSub = subTabs.find(s => s.trackId === trackId && s.type === 'PIANO_ROLL' && s.isPlaying);
if (playingSub) { if (playingSub) {
const pid = playingSub.id; const pid = playingSub.id;
stopAllPlayback(); const ctx = getAudioContext();
const tNode = activeTrackNodesRef.current[trackId];
if (tNode && tNode.gainNode) {
tNode.gainNode.gain.setValueAtTime(tNode.gainNode.gain.value || 1, ctx.currentTime);
tNode.gainNode.gain.linearRampToValueAtTime(0.001, ctx.currentTime + 0.04);
}
setTimeout(() => { setTimeout(() => {
stopAllPlayback();
if (tNode && tNode.gainNode) {
const trackData = activeTracksRef.current ? activeTracksRef.current.find(t => t.id === trackId) : null;
const volDb = trackData ? (trackData.volumeDb ?? 0) : 0;
const volLinear = volDb <= -50 ? 0 : Math.pow(10, volDb / 20);
tNode.gainNode.gain.setValueAtTime(0.001, ctx.currentTime);
tNode.gainNode.gain.linearRampToValueAtTime(volLinear || 0.8, ctx.currentTime + 0.015);
}
const context = getAudioContext(); const context = getAudioContext();
const offset = playingSub.currentTime || 0; const offset = playingSub.currentTime || 0;
startOffsetTimeRef.current = offset; startOffsetTimeRef.current = offset;
@@ -6537,7 +6548,7 @@ const App = () => {
subTabsRef.current = subTabsRef.current.map(s => s.id === pid ? { ...s, isPlaying: true } : s); subTabsRef.current = subTabsRef.current.map(s => s.id === pid ? { ...s, isPlaying: true } : s);
} }
animationFrameIdRef.current = requestAnimationFrame(updatePlayhead); animationFrameIdRef.current = requestAnimationFrame(updatePlayhead);
}, 50); }, 60);
} }
setTimeout(() => lucide.createIcons(), 50); setTimeout(() => lucide.createIcons(), 50);
}; };
@@ -15833,14 +15844,26 @@ const App = () => {
const playingSub = subTabs.find(s => s.id === activeTab && s.type === 'PIANO_ROLL' && s.isPlaying); const playingSub = subTabs.find(s => s.id === activeTab && s.type === 'PIANO_ROLL' && s.isPlaying);
if (playingSub) { if (playingSub) {
const offset = playingSub.currentTime || 0; const offset = playingSub.currentTime || 0;
window.SonicSF.stopAll(); const ctx = getAudioContext();
const tNode = activeTrackNodesRef.current[playingSub.trackId];
if (tNode && tNode.gainNode) {
tNode.gainNode.gain.setValueAtTime(tNode.gainNode.gain.value || 1, ctx.currentTime);
tNode.gainNode.gain.linearRampToValueAtTime(0.001, ctx.currentTime + 0.04);
}
setTimeout(() => { setTimeout(() => {
const ctx = getAudioContext(); window.SonicSF.stopAll();
if (tNode && tNode.gainNode) {
const trackData = activeTracksRef.current ? activeTracksRef.current.find(t => t.id === playingSub.trackId) : null;
const volDb = trackData ? (trackData.volumeDb ?? 0) : 0;
const volLinear = volDb <= -50 ? 0 : Math.pow(10, volDb / 20);
tNode.gainNode.gain.setValueAtTime(0.001, ctx.currentTime);
tNode.gainNode.gain.linearRampToValueAtTime(volLinear || 0.8, ctx.currentTime + 0.015);
}
startOffsetTimeRef.current = offset; startOffsetTimeRef.current = offset;
startAudioTimeRef.current = ctx.currentTime; startAudioTimeRef.current = ctx.currentTime;
startBufferOffsetRef.current = offset * (playingSub.speed || 1.0); startBufferOffsetRef.current = offset * (playingSub.speed || 1.0);
schedulePianoRollMidi(playingSub, offset, updatedNotes); schedulePianoRollMidi(playingSub, offset, updatedNotes);
}, 20); }, 50);
} }
} }
}); });
File diff suppressed because one or more lines are too long