fix: stopAll cancels scheduled notes, loop works on all tabs
- Add _scheduledNotes array tracking - stopAll clears all pending setTimeout notes + allNotesOff() - Loop enabled on MAIN SESSION, SECTION-TAB, PIANO_ROLL via isLoopingSelection + selLeft/selRight auto-derivation
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
let _initialized = false;
|
||||
let _initPromise = null;
|
||||
let _currentSfId = null;
|
||||
const _scheduledNotes = [];
|
||||
|
||||
const SonicSF = {
|
||||
loadedFonts: {},
|
||||
@@ -168,16 +169,28 @@
|
||||
const durSec = durationMs / 1000;
|
||||
const now = ctx.currentTime;
|
||||
const delay = (typeof startTime === 'number' && startTime > now) ? (startTime - now) : 0;
|
||||
const noteId = { on: null, off: null };
|
||||
_scheduledNotes.push(noteId);
|
||||
const doNote = () => {
|
||||
try {
|
||||
_synthInstance.noteOn(channel, midiPitch, midiVel);
|
||||
setTimeout(() => { try { _synthInstance.noteOff(channel, midiPitch); } catch (e) {} }, durSec * 1000);
|
||||
noteId.off = setTimeout(() => {
|
||||
try { _synthInstance.noteOff(channel, midiPitch); } catch (e) {}
|
||||
const idx = _scheduledNotes.indexOf(noteId);
|
||||
if (idx >= 0) _scheduledNotes.splice(idx, 1);
|
||||
}, durSec * 1000);
|
||||
} catch (e) {
|
||||
console.warn("[SonicSF] SpessaSynth noteOn error:", e);
|
||||
this._playNoteOsc(note, velocity, durationMs, startTime, program, null, channel, synthEngine);
|
||||
}
|
||||
};
|
||||
if (delay > 0) setTimeout(doNote, delay * 1000); else doNote();
|
||||
if (delay > 0) {
|
||||
noteId.on = setTimeout(doNote, delay * 1000);
|
||||
} else {
|
||||
doNote();
|
||||
const idx = _scheduledNotes.indexOf(noteId);
|
||||
if (idx >= 0) _scheduledNotes.splice(idx, 1);
|
||||
}
|
||||
},
|
||||
|
||||
_playNoteOsc: function (note, velocity, durationMs, startTime, program, destinationNode, channel, synthEngine) {
|
||||
@@ -257,6 +270,12 @@
|
||||
if (_initialized && _synthInstance) {
|
||||
try { for (let ch = 0; ch < 16; ch++) _synthInstance.allNotesOff(ch); } catch (e) {}
|
||||
}
|
||||
// Cancel all scheduled future notes
|
||||
while (_scheduledNotes.length > 0) {
|
||||
const n = _scheduledNotes.pop();
|
||||
if (n.on) { clearTimeout(n.on); n.on = null; }
|
||||
if (n.off) { clearTimeout(n.off); n.off = null; }
|
||||
}
|
||||
const ctx = getCtx();
|
||||
const now = ctx.currentTime;
|
||||
Object.values(activeOscillators).forEach(entry => {
|
||||
|
||||
Reference in New Issue
Block a user