KEXEL's picture
1.1
b0bfea8 verified
import { WorkletSequencerReturnMessageType } from "./sequencer_message.js";
/**
* Processes a single tick
* @this {WorkletSequencer}
*/
export function processTick()
{
if (!this.isActive)
{
return;
}
let current = this.currentTime;
while (this.playedTime < current)
{
// find the next event
let trackIndex = this._findFirstEventIndex();
let event = this.tracks[trackIndex][this.eventIndex[trackIndex]];
this._processEvent(event, trackIndex);
this.eventIndex[trackIndex]++;
// find the next event
trackIndex = this._findFirstEventIndex();
if (this.tracks[trackIndex].length <= this.eventIndex[trackIndex])
{
// the song has ended
if (this.loop)
{
this.setTimeTicks(this.midiData.loop.start);
return;
}
this.eventIndex[trackIndex]--;
this.pause(true);
if (this.songs.length > 1)
{
this.nextSong();
}
return;
}
let eventNext = this.tracks[trackIndex][this.eventIndex[trackIndex]];
this.playedTime += this.oneTickToSeconds * (eventNext.ticks - event.ticks);
const canLoop = this.loop && (this.loopCount > 0 || this.loopCount === -1);
// if we reached loop.end
if ((this.midiData.loop.end <= event.ticks) && canLoop)
{
// loop
if (this.loopCount !== Infinity)
{
this.loopCount--;
this.post(WorkletSequencerReturnMessageType.loopCountChange, this.loopCount);
}
this.setTimeTicks(this.midiData.loop.start);
return;
}
// if the song has ended
else if (current >= this.duration)
{
if (canLoop)
{
// loop
if (this.loopCount !== Infinity)
{
this.loopCount--;
this.post(WorkletSequencerReturnMessageType.loopCountChange, this.loopCount);
}
this.setTimeTicks(this.midiData.loop.start);
return;
}
// stop the playback
this.eventIndex[trackIndex]--;
this.pause(true);
if (this.songs.length > 1)
{
this.nextSong();
}
return;
}
}
}
/**
* @returns {number} the index of the first to the current played time
* @this {WorkletSequencer}
*/
export function _findFirstEventIndex()
{
let index = 0;
let ticks = Infinity;
this.tracks.forEach((track, i) =>
{
if (this.eventIndex[i] >= track.length)
{
return;
}
if (track[this.eventIndex[i]].ticks < ticks)
{
index = i;
ticks = track[this.eventIndex[i]].ticks;
}
});
return index;
}