feat: realtime solo toggle during playback
This commit is contained in:
+25
-8
@@ -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 => {
|
||||
|
||||
Reference in New Issue
Block a user