spessasynth_core 4.0.14 → 4.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -3743,6 +3743,7 @@ interface SequencerEventData {
3743
3743
  };
3744
3744
  /**
3745
3745
  * Called when the playback stops.
3746
+ * @deprecated use songEnded instead.
3746
3747
  */
3747
3748
  pause: {
3748
3749
  /**
@@ -3750,6 +3751,10 @@ interface SequencerEventData {
3750
3751
  */
3751
3752
  isFinished: boolean;
3752
3753
  };
3754
+ /**
3755
+ * Called when the playback stops.
3756
+ */
3757
+ songEnded: object;
3753
3758
  /**
3754
3759
  * Called when the song changes.
3755
3760
  */
@@ -3828,6 +3833,15 @@ declare class SpessaSynthSequencer {
3828
3833
  * Defaults to true.
3829
3834
  */
3830
3835
  skipToFirstNoteOn: boolean;
3836
+ /**
3837
+ * Indicates if the sequencer has finished playing.
3838
+ */
3839
+ isFinished: boolean;
3840
+ /**
3841
+ * Indicates if the synthesizer should preload the voices for the newly loaded sequence.
3842
+ * Recommended.
3843
+ */
3844
+ preload: boolean;
3831
3845
  /**
3832
3846
  * Called when the sequencer calls an event.
3833
3847
  * @param event The event
package/dist/index.js CHANGED
@@ -3907,7 +3907,8 @@ function processTick() {
3907
3907
  this.setTimeTicks(this._midiData.loop.start);
3908
3908
  return;
3909
3909
  }
3910
- if (nextTrack.events.length <= this.eventIndexes[nextTrackIndex]) {
3910
+ if (nextTrack.events.length <= this.eventIndexes[nextTrackIndex] || // https://github.com/spessasus/spessasynth_core/issues/21
3911
+ event.ticks >= this._midiData.lastVoiceEventTick) {
3911
3912
  this.songIsFinished();
3912
3913
  return;
3913
3914
  }
@@ -3941,10 +3942,12 @@ function loadNewSequenceInternal(parsedMidi) {
3941
3942
  if (parsedMidi.duration === 0) {
3942
3943
  SpessaSynthWarn("This MIDI file has a duration of exactly 0 seconds.");
3943
3944
  this.pausedTime = 0;
3945
+ this.isFinished = true;
3944
3946
  return;
3945
3947
  }
3946
3948
  this.oneTickToSeconds = 60 / (120 * parsedMidi.timeDivision);
3947
3949
  this._midiData = parsedMidi;
3950
+ this.isFinished = false;
3948
3951
  this.synth.clearEmbeddedBank();
3949
3952
  if (this._midiData.embeddedSoundBank !== void 0) {
3950
3953
  SpessaSynthInfo(
@@ -3956,23 +3959,33 @@ function loadNewSequenceInternal(parsedMidi) {
3956
3959
  this._midiData.bankOffset
3957
3960
  );
3958
3961
  }
3959
- SpessaSynthGroupCollapsed("%cPreloading samples...", consoleColors.info);
3960
- const used = this._midiData.getUsedProgramsAndKeys(
3961
- this.synth.soundBankManager
3962
- );
3963
- used.forEach((combos, preset) => {
3964
- SpessaSynthInfo(
3965
- `%cPreloading used samples on %c${preset.name}%c...`,
3966
- consoleColors.info,
3967
- consoleColors.recognized,
3962
+ if (this.preload) {
3963
+ SpessaSynthGroupCollapsed(
3964
+ "%cPreloading samples...",
3968
3965
  consoleColors.info
3969
3966
  );
3970
- for (const combo of combos) {
3971
- const [midiNote, velocity] = combo.split("-").map(Number);
3972
- this.synth.getVoicesForPreset(preset, midiNote, velocity, midiNote);
3973
- }
3974
- });
3975
- SpessaSynthGroupEnd();
3967
+ const used = this._midiData.getUsedProgramsAndKeys(
3968
+ this.synth.soundBankManager
3969
+ );
3970
+ used.forEach((combos, preset) => {
3971
+ SpessaSynthInfo(
3972
+ `%cPreloading used samples on %c${preset.name}%c...`,
3973
+ consoleColors.info,
3974
+ consoleColors.recognized,
3975
+ consoleColors.info
3976
+ );
3977
+ for (const combo of combos) {
3978
+ const [midiNote, velocity] = combo.split("-").map(Number);
3979
+ this.synth.getVoicesForPreset(
3980
+ preset,
3981
+ midiNote,
3982
+ velocity,
3983
+ midiNote
3984
+ );
3985
+ }
3986
+ });
3987
+ SpessaSynthGroupEnd();
3988
+ }
3976
3989
  this.currentMIDIPorts = this._midiData.tracks.map((t) => t.port);
3977
3990
  this.midiPortChannelOffset = 0;
3978
3991
  this.midiPortChannelOffsets = {};
@@ -4956,6 +4969,15 @@ var SpessaSynthSequencer = class {
4956
4969
  * Defaults to true.
4957
4970
  */
4958
4971
  skipToFirstNoteOn = true;
4972
+ /**
4973
+ * Indicates if the sequencer has finished playing.
4974
+ */
4975
+ isFinished = false;
4976
+ /**
4977
+ * Indicates if the synthesizer should preload the voices for the newly loaded sequence.
4978
+ * Recommended.
4979
+ */
4980
+ preload = false;
4959
4981
  /**
4960
4982
  * Called when the sequencer calls an event.
4961
4983
  * @param event The event
@@ -5207,8 +5229,12 @@ var SpessaSynthSequencer = class {
5207
5229
  }
5208
5230
  this.stop();
5209
5231
  this.callEvent("pause", { isFinished });
5232
+ if (isFinished) {
5233
+ this.callEvent("songEnded", {});
5234
+ }
5210
5235
  }
5211
5236
  songIsFinished() {
5237
+ this.isFinished = true;
5212
5238
  if (this.songs.length === 1) {
5213
5239
  this.pauseInternal(true);
5214
5240
  return;