feat: realtime solo toggle during playback

This commit is contained in:
2026-07-31 10:37:52 +07:00
parent 619a2484ce
commit 3380b0e201
2 changed files with 28 additions and 11 deletions
+25 -8
View File
@@ -13321,8 +13321,9 @@ const App = () => {
const startTrackPlayback = offsetTime => {
const context = getAudioContext();
const hasSolo = activeTracks.some(t => t.solo);
activeTracks.forEach(track => {
const allPlayTracks = activeTracksRef.current && activeTracksRef.current.length ? activeTracksRef.current : activeTracks;
const hasSolo = allPlayTracks.some(t => t.solo);
allPlayTracks.forEach(track => {
const isPlayable = hasSolo ? track.solo : !track.muted;
if (!isPlayable) return;
@@ -13358,7 +13359,7 @@ const App = () => {
// MIDI items playback
const midiItems = track.midiItems || [];
if ((track.type === 'MIDI' || midiItems.length > 0) && window.SonicSF) {
var trkCh = window.SonicPianoRoll ? window.SonicPianoRoll.getTrackMidiChannel(track, activeTracks) : (track.midiChannel !== undefined ? track.midiChannel : 0);
var trkCh = window.SonicPianoRoll ? window.SonicPianoRoll.getTrackMidiChannel(track, allPlayTracks) : (track.midiChannel !== undefined ? track.midiChannel : 0);
// Ensure instrument is loaded in FluidSynth
if (track.synth_engine && track.synth_engine.type === 'soundfont' && track.synth_engine.soundfont_id) {
window.SonicSF.selectInstrument(trkCh, track.synth_engine.soundfont_bank || 0, track.synth_engine.soundfont_program || 0, track.synth_engine.soundfont_id);
@@ -15461,17 +15462,33 @@ const App = () => {
// Track Controls
const toggleTrackSoloEvaluate = trackId => {
const wasPlaying = isPlaying;
const playingSubTab = subTabs.find(s => s.isPlaying && s.type === 'PIANO_ROLL');
stopAllPlayback();
setTracks(prev => prev.map(t =>
t.id === trackId ? { ...t, solo: !t.solo, muted: false } : t
));
if (wasPlaying) {
setTimeout(() => {
setTimeout(() => {
const soloCtx = getAudioContext();
if (wasPlaying) {
startOffsetTimeRef.current = currentTime;
startAudioTimeRef.current = getAudioContext().currentTime;
startAudioTimeRef.current = soloCtx.currentTime;
startBufferOffsetRef.current = currentTime;
setIsPlaying(true);
}, 50);
}
startTrackPlayback(currentTime);
}
if (playingSubTab) {
const prSt = subTabs.find(s => s.id === playingSubTab.id);
if (prSt) {
const prOffset = prSt.currentTime || 0;
startOffsetTimeRef.current = prOffset;
startAudioTimeRef.current = soloCtx.currentTime;
startBufferOffsetRef.current = prOffset * (prSt.speed || 1.0);
schedulePianoRollMidi(prSt, prOffset);
startSubTabPlayback(prSt, prOffset);
setSubTabs(prev => prev.map(s => s.id === prSt.id ? Object.assign({}, s, { isPlaying: true, currentTime: prOffset }) : s));
}
}
}, 60);
setTimeout(() => lucide.createIcons(), 50);
};
const toggleTrackMute = trackId => {