spessasynth_core 4.0.16 → 4.0.18
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 +16 -9
- package/dist/index.js +120 -137
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3822,6 +3822,11 @@ declare class SpessaSynthSequencer {
|
|
|
3822
3822
|
* This is used by spessasynth_lib to pass them over to Web MIDI API.
|
|
3823
3823
|
*/
|
|
3824
3824
|
externalMIDIPlayback: boolean;
|
|
3825
|
+
/**
|
|
3826
|
+
* If the notes that were playing when the sequencer was paused should be re-triggered.
|
|
3827
|
+
* Defaults to true.
|
|
3828
|
+
*/
|
|
3829
|
+
retriggerPausedNotes: boolean;
|
|
3825
3830
|
/**
|
|
3826
3831
|
* The loop count of the sequencer.
|
|
3827
3832
|
* If infinite, it will loop forever.
|
|
@@ -4001,18 +4006,10 @@ declare class SpessaSynthSequencer {
|
|
|
4001
4006
|
*/
|
|
4002
4007
|
protected addNewMIDIPort(): void;
|
|
4003
4008
|
protected sendMIDIMessage(message: number[]): void;
|
|
4009
|
+
protected sendMIDIAllOff(): void;
|
|
4004
4010
|
protected sendMIDIReset(): void;
|
|
4005
4011
|
protected loadCurrentSong(): void;
|
|
4006
4012
|
protected shuffleSongIndexes(): void;
|
|
4007
|
-
protected sendMIDICC(channel: number, type: number, value: number): void;
|
|
4008
|
-
protected sendMIDIProgramChange(channel: number, program: number): void;
|
|
4009
|
-
/**
|
|
4010
|
-
* Sets the pitch of the given channel
|
|
4011
|
-
* @param channel usually 0-15: the channel to change pitch
|
|
4012
|
-
* @param MSB SECOND byte of the MIDI pitchWheel message
|
|
4013
|
-
* @param LSB FIRST byte of the MIDI pitchWheel message
|
|
4014
|
-
*/
|
|
4015
|
-
protected sendMIDIPitchWheel(channel: number, MSB: number, LSB: number): void;
|
|
4016
4013
|
/**
|
|
4017
4014
|
* Sets the time in MIDI ticks.
|
|
4018
4015
|
* @param ticks the MIDI ticks to set the time to.
|
|
@@ -4023,6 +4020,16 @@ declare class SpessaSynthSequencer {
|
|
|
4023
4020
|
* @param time the time in seconds to recalculate the start time for.
|
|
4024
4021
|
*/
|
|
4025
4022
|
protected recalculateStartTime(time: number): void;
|
|
4023
|
+
protected sendMIDINoteOn(channel: number, midiNote: number, velocity: number): void;
|
|
4024
|
+
protected sendMIDINoteOff(channel: number, midiNote: number): void;
|
|
4025
|
+
protected sendMIDICC(channel: number, type: MIDIController, value: number): void;
|
|
4026
|
+
protected sendMIDIProgramChange(channel: number, program: number): void;
|
|
4027
|
+
/**
|
|
4028
|
+
* Sets the pitch of the given channel
|
|
4029
|
+
* @param channel usually 0-15: the channel to change pitch
|
|
4030
|
+
* @param pitch the 14-bit pitch value
|
|
4031
|
+
*/
|
|
4032
|
+
protected sendMIDIPitchWheel(channel: number, pitch: number): void;
|
|
4026
4033
|
}
|
|
4027
4034
|
|
|
4028
4035
|
declare const DEFAULT_MASTER_PARAMETERS: MasterParameterType;
|
package/dist/index.js
CHANGED
|
@@ -4734,12 +4734,7 @@ function setTimeToInternal(time, ticks = void 0) {
|
|
|
4734
4734
|
return false;
|
|
4735
4735
|
}
|
|
4736
4736
|
this.oneTickToSeconds = 60 / (120 * this._midiData.timeDivision);
|
|
4737
|
-
|
|
4738
|
-
this.sendMIDIReset();
|
|
4739
|
-
} else {
|
|
4740
|
-
this.synth.resetAllControllers();
|
|
4741
|
-
this.synth.stopAllChannels(false);
|
|
4742
|
-
}
|
|
4737
|
+
this.sendMIDIReset();
|
|
4743
4738
|
this.playedTime = 0;
|
|
4744
4739
|
this.eventIndexes = Array(this._midiData.tracks.length).fill(0);
|
|
4745
4740
|
const channelsToSave = this.synth.midiChannels.length;
|
|
@@ -4823,15 +4818,7 @@ function setTimeToInternal(time, ticks = void 0) {
|
|
|
4823
4818
|
} else if (controllerNumber === midiControllers.resetAllControllers) {
|
|
4824
4819
|
resetAllControllers(channel);
|
|
4825
4820
|
}
|
|
4826
|
-
|
|
4827
|
-
this.sendMIDICC(channel, controllerNumber, ccV);
|
|
4828
|
-
} else {
|
|
4829
|
-
this.synth.controllerChange(
|
|
4830
|
-
channel,
|
|
4831
|
-
controllerNumber,
|
|
4832
|
-
ccV
|
|
4833
|
-
);
|
|
4834
|
-
}
|
|
4821
|
+
this.sendMIDICC(channel, controllerNumber, ccV);
|
|
4835
4822
|
} else {
|
|
4836
4823
|
savedControllers[channel] ??= Array.from(
|
|
4837
4824
|
defaultControllerArray
|
|
@@ -4859,70 +4846,28 @@ function setTimeToInternal(time, ticks = void 0) {
|
|
|
4859
4846
|
}
|
|
4860
4847
|
this.playedTime += this.oneTickToSeconds * (nextEvent.ticks - event.ticks);
|
|
4861
4848
|
}
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
});
|
|
4877
|
-
}
|
|
4878
|
-
if (programs[channelNumber].program >= 0 && programs[channelNumber].actualBank >= 0) {
|
|
4879
|
-
const bank = programs[channelNumber].actualBank;
|
|
4849
|
+
for (let channel = 0; channel < channelsToSave; channel++) {
|
|
4850
|
+
if (pitchWheels[channel] !== void 0) {
|
|
4851
|
+
this.sendMIDIPitchWheel(channel, pitchWheels[channel]);
|
|
4852
|
+
}
|
|
4853
|
+
if (savedControllers[channel] !== void 0) {
|
|
4854
|
+
savedControllers[channel].forEach((value, index) => {
|
|
4855
|
+
if (value !== defaultControllerArray[index] && !isCCNonSkippable(index)) {
|
|
4856
|
+
this.sendMIDICC(channel, index, value);
|
|
4857
|
+
}
|
|
4858
|
+
});
|
|
4859
|
+
}
|
|
4860
|
+
if (programs[channel].actualBank >= 0) {
|
|
4861
|
+
const p = programs[channel];
|
|
4862
|
+
if (p.program !== -1) {
|
|
4880
4863
|
this.sendMIDICC(
|
|
4881
|
-
|
|
4864
|
+
channel,
|
|
4882
4865
|
midiControllers.bankSelect,
|
|
4883
|
-
|
|
4866
|
+
p.actualBank
|
|
4884
4867
|
);
|
|
4885
|
-
this.sendMIDIProgramChange(
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
);
|
|
4889
|
-
}
|
|
4890
|
-
}
|
|
4891
|
-
} else {
|
|
4892
|
-
for (let channelNumber = 0; channelNumber < channelsToSave; channelNumber++) {
|
|
4893
|
-
if (pitchWheels[channelNumber] !== void 0) {
|
|
4894
|
-
this.synth.pitchWheel(
|
|
4895
|
-
channelNumber,
|
|
4896
|
-
pitchWheels[channelNumber]
|
|
4897
|
-
);
|
|
4898
|
-
}
|
|
4899
|
-
if (savedControllers[channelNumber] !== void 0) {
|
|
4900
|
-
savedControllers[channelNumber].forEach((value, index) => {
|
|
4901
|
-
if (value !== defaultControllerArray[index] && !isCCNonSkippable(index)) {
|
|
4902
|
-
this.synth.controllerChange(
|
|
4903
|
-
channelNumber,
|
|
4904
|
-
index,
|
|
4905
|
-
value
|
|
4906
|
-
);
|
|
4907
|
-
}
|
|
4908
|
-
});
|
|
4909
|
-
}
|
|
4910
|
-
if (programs[channelNumber].actualBank >= 0) {
|
|
4911
|
-
const p = programs[channelNumber];
|
|
4912
|
-
if (p.program !== -1) {
|
|
4913
|
-
this.synth.controllerChange(
|
|
4914
|
-
channelNumber,
|
|
4915
|
-
midiControllers.bankSelect,
|
|
4916
|
-
p.actualBank
|
|
4917
|
-
);
|
|
4918
|
-
this.synth.programChange(channelNumber, p.program);
|
|
4919
|
-
} else {
|
|
4920
|
-
this.synth.controllerChange(
|
|
4921
|
-
channelNumber,
|
|
4922
|
-
midiControllers.bankSelect,
|
|
4923
|
-
p.bank
|
|
4924
|
-
);
|
|
4925
|
-
}
|
|
4868
|
+
this.sendMIDIProgramChange(channel, p.program);
|
|
4869
|
+
} else {
|
|
4870
|
+
this.sendMIDICC(channel, midiControllers.bankSelect, p.bank);
|
|
4926
4871
|
}
|
|
4927
4872
|
}
|
|
4928
4873
|
}
|
|
@@ -4958,6 +4903,11 @@ var SpessaSynthSequencer = class {
|
|
|
4958
4903
|
* This is used by spessasynth_lib to pass them over to Web MIDI API.
|
|
4959
4904
|
*/
|
|
4960
4905
|
externalMIDIPlayback = false;
|
|
4906
|
+
/**
|
|
4907
|
+
* If the notes that were playing when the sequencer was paused should be re-triggered.
|
|
4908
|
+
* Defaults to true.
|
|
4909
|
+
*/
|
|
4910
|
+
retriggerPausedNotes = false;
|
|
4961
4911
|
/**
|
|
4962
4912
|
* The loop count of the sequencer.
|
|
4963
4913
|
* If infinite, it will loop forever.
|
|
@@ -4977,7 +4927,7 @@ var SpessaSynthSequencer = class {
|
|
|
4977
4927
|
* Indicates if the synthesizer should preload the voices for the newly loaded sequence.
|
|
4978
4928
|
* Recommended.
|
|
4979
4929
|
*/
|
|
4980
|
-
preload =
|
|
4930
|
+
preload = true;
|
|
4981
4931
|
/**
|
|
4982
4932
|
* Called when the sequencer calls an event.
|
|
4983
4933
|
* @param event The event
|
|
@@ -5189,9 +5139,9 @@ var SpessaSynthSequencer = class {
|
|
|
5189
5139
|
if (this.paused) {
|
|
5190
5140
|
this.recalculateStartTime(this.pausedTime ?? 0);
|
|
5191
5141
|
}
|
|
5192
|
-
if (
|
|
5142
|
+
if (this.retriggerPausedNotes) {
|
|
5193
5143
|
this.playingNotes.forEach((n) => {
|
|
5194
|
-
this.
|
|
5144
|
+
this.sendMIDINoteOn(n.channel, n.midiNote, n.velocity);
|
|
5195
5145
|
});
|
|
5196
5146
|
}
|
|
5197
5147
|
this.pausedTime = void 0;
|
|
@@ -5248,21 +5198,7 @@ var SpessaSynthSequencer = class {
|
|
|
5248
5198
|
*/
|
|
5249
5199
|
stop() {
|
|
5250
5200
|
this.pausedTime = this.currentTime;
|
|
5251
|
-
|
|
5252
|
-
this.synth.controllerChange(i, midiControllers.sustainPedal, 0);
|
|
5253
|
-
}
|
|
5254
|
-
this.synth.stopAllChannels();
|
|
5255
|
-
if (this.externalMIDIPlayback) {
|
|
5256
|
-
for (const note of this.playingNotes) {
|
|
5257
|
-
this.sendMIDIMessage([
|
|
5258
|
-
midiMessageTypes.noteOff | note.channel % 16,
|
|
5259
|
-
note.midiNote
|
|
5260
|
-
]);
|
|
5261
|
-
}
|
|
5262
|
-
for (let c = 0; c < MIDI_CHANNEL_COUNT; c++) {
|
|
5263
|
-
this.sendMIDICC(c, midiControllers.allNotesOff, 0);
|
|
5264
|
-
}
|
|
5265
|
-
}
|
|
5201
|
+
this.sendMIDIAllOff();
|
|
5266
5202
|
}
|
|
5267
5203
|
/**
|
|
5268
5204
|
* @returns the index of the first to the current played time
|
|
@@ -5292,24 +5228,36 @@ var SpessaSynthSequencer = class {
|
|
|
5292
5228
|
}
|
|
5293
5229
|
sendMIDIMessage(message) {
|
|
5294
5230
|
if (!this.externalMIDIPlayback) {
|
|
5231
|
+
SpessaSynthWarn(
|
|
5232
|
+
`Attempting to send ${arrayToHexString(message)} to the synthesizer via sendMIDIMessage. This shouldn't happen!`
|
|
5233
|
+
);
|
|
5295
5234
|
return;
|
|
5296
5235
|
}
|
|
5297
5236
|
this.callEvent("midiMessage", { message });
|
|
5298
5237
|
}
|
|
5238
|
+
sendMIDIAllOff() {
|
|
5239
|
+
for (let i = 0; i < 16; i++) {
|
|
5240
|
+
this.sendMIDICC(i, midiControllers.sustainPedal, 0);
|
|
5241
|
+
}
|
|
5242
|
+
if (!this.externalMIDIPlayback) {
|
|
5243
|
+
this.synth.stopAllChannels();
|
|
5244
|
+
return;
|
|
5245
|
+
}
|
|
5246
|
+
this.playingNotes.forEach((note) => {
|
|
5247
|
+
this.sendMIDINoteOff(note.channel, note.midiNote);
|
|
5248
|
+
});
|
|
5249
|
+
for (let c = 0; c < MIDI_CHANNEL_COUNT; c++) {
|
|
5250
|
+
this.sendMIDICC(c, midiControllers.allNotesOff, 0);
|
|
5251
|
+
this.sendMIDICC(c, midiControllers.allSoundOff, 0);
|
|
5252
|
+
}
|
|
5253
|
+
}
|
|
5299
5254
|
sendMIDIReset() {
|
|
5300
|
-
this.
|
|
5301
|
-
|
|
5302
|
-
this.
|
|
5303
|
-
|
|
5304
|
-
midiControllers.allSoundOff,
|
|
5305
|
-
0
|
|
5306
|
-
]);
|
|
5307
|
-
this.sendMIDIMessage([
|
|
5308
|
-
midiMessageTypes.controllerChange | ch,
|
|
5309
|
-
midiControllers.resetAllControllers,
|
|
5310
|
-
0
|
|
5311
|
-
]);
|
|
5255
|
+
this.sendMIDIAllOff();
|
|
5256
|
+
if (!this.externalMIDIPlayback) {
|
|
5257
|
+
this.synth.resetAllControllers();
|
|
5258
|
+
return;
|
|
5312
5259
|
}
|
|
5260
|
+
this.sendMIDIMessage([midiMessageTypes.reset]);
|
|
5313
5261
|
}
|
|
5314
5262
|
loadCurrentSong() {
|
|
5315
5263
|
let index = this._songIndex;
|
|
@@ -5327,11 +5275,65 @@ var SpessaSynthSequencer = class {
|
|
|
5327
5275
|
indexes.splice(indexes.indexOf(index), 1);
|
|
5328
5276
|
}
|
|
5329
5277
|
}
|
|
5330
|
-
|
|
5278
|
+
/**
|
|
5279
|
+
* Sets the time in MIDI ticks.
|
|
5280
|
+
* @param ticks the MIDI ticks to set the time to.
|
|
5281
|
+
*/
|
|
5282
|
+
setTimeTicks(ticks) {
|
|
5283
|
+
if (!this._midiData) {
|
|
5284
|
+
return;
|
|
5285
|
+
}
|
|
5286
|
+
this.playingNotes = [];
|
|
5287
|
+
const seconds = this._midiData.midiTicksToSeconds(ticks);
|
|
5288
|
+
this.callEvent("timeChange", { newTime: seconds });
|
|
5289
|
+
const isNotFinished = this.setTimeTo(0, ticks);
|
|
5290
|
+
this.recalculateStartTime(this.playedTime);
|
|
5291
|
+
if (!isNotFinished) {
|
|
5292
|
+
return;
|
|
5293
|
+
}
|
|
5294
|
+
}
|
|
5295
|
+
/**
|
|
5296
|
+
* Recalculates the absolute start time of the sequencer.
|
|
5297
|
+
* @param time the time in seconds to recalculate the start time for.
|
|
5298
|
+
*/
|
|
5299
|
+
recalculateStartTime(time) {
|
|
5300
|
+
this.absoluteStartTime = this.synth.currentSynthTime - time / this._playbackRate;
|
|
5301
|
+
}
|
|
5302
|
+
/*
|
|
5303
|
+
SEND MIDI METHOD ABSTRACTIONS
|
|
5304
|
+
These abstract the difference between spessasynth and external MIDI
|
|
5305
|
+
*/
|
|
5306
|
+
sendMIDINoteOn(channel, midiNote, velocity) {
|
|
5307
|
+
if (!this.externalMIDIPlayback) {
|
|
5308
|
+
this.synth.noteOn(channel, midiNote, velocity);
|
|
5309
|
+
return;
|
|
5310
|
+
}
|
|
5331
5311
|
channel %= 16;
|
|
5312
|
+
this.sendMIDIMessage([
|
|
5313
|
+
midiMessageTypes.noteOn | channel,
|
|
5314
|
+
midiNote,
|
|
5315
|
+
velocity
|
|
5316
|
+
]);
|
|
5317
|
+
}
|
|
5318
|
+
sendMIDINoteOff(channel, midiNote) {
|
|
5332
5319
|
if (!this.externalMIDIPlayback) {
|
|
5320
|
+
this.synth.noteOff(channel, midiNote);
|
|
5333
5321
|
return;
|
|
5334
5322
|
}
|
|
5323
|
+
channel %= 16;
|
|
5324
|
+
this.sendMIDIMessage([
|
|
5325
|
+
midiMessageTypes.noteOff | channel,
|
|
5326
|
+
midiNote,
|
|
5327
|
+
64
|
|
5328
|
+
// Make sure to send velocity as well
|
|
5329
|
+
]);
|
|
5330
|
+
}
|
|
5331
|
+
sendMIDICC(channel, type, value) {
|
|
5332
|
+
if (!this.externalMIDIPlayback) {
|
|
5333
|
+
this.synth.controllerChange(channel, type, value);
|
|
5334
|
+
return;
|
|
5335
|
+
}
|
|
5336
|
+
channel %= 16;
|
|
5335
5337
|
this.sendMIDIMessage([
|
|
5336
5338
|
midiMessageTypes.controllerChange | channel,
|
|
5337
5339
|
type,
|
|
@@ -5339,10 +5341,11 @@ var SpessaSynthSequencer = class {
|
|
|
5339
5341
|
]);
|
|
5340
5342
|
}
|
|
5341
5343
|
sendMIDIProgramChange(channel, program) {
|
|
5342
|
-
channel %= 16;
|
|
5343
5344
|
if (!this.externalMIDIPlayback) {
|
|
5345
|
+
this.synth.programChange(channel, program);
|
|
5344
5346
|
return;
|
|
5345
5347
|
}
|
|
5348
|
+
channel %= 16;
|
|
5346
5349
|
this.sendMIDIMessage([
|
|
5347
5350
|
midiMessageTypes.programChange | channel,
|
|
5348
5351
|
program
|
|
@@ -5351,39 +5354,19 @@ var SpessaSynthSequencer = class {
|
|
|
5351
5354
|
/**
|
|
5352
5355
|
* Sets the pitch of the given channel
|
|
5353
5356
|
* @param channel usually 0-15: the channel to change pitch
|
|
5354
|
-
* @param
|
|
5355
|
-
* @param LSB FIRST byte of the MIDI pitchWheel message
|
|
5357
|
+
* @param pitch the 14-bit pitch value
|
|
5356
5358
|
*/
|
|
5357
|
-
sendMIDIPitchWheel(channel,
|
|
5358
|
-
channel %= 16;
|
|
5359
|
+
sendMIDIPitchWheel(channel, pitch) {
|
|
5359
5360
|
if (!this.externalMIDIPlayback) {
|
|
5361
|
+
this.synth.pitchWheel(channel, pitch);
|
|
5360
5362
|
return;
|
|
5361
5363
|
}
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
setTimeTicks(ticks) {
|
|
5369
|
-
if (!this._midiData) {
|
|
5370
|
-
return;
|
|
5371
|
-
}
|
|
5372
|
-
this.playingNotes = [];
|
|
5373
|
-
const seconds = this._midiData.midiTicksToSeconds(ticks);
|
|
5374
|
-
this.callEvent("timeChange", { newTime: seconds });
|
|
5375
|
-
const isNotFinished = this.setTimeTo(0, ticks);
|
|
5376
|
-
this.recalculateStartTime(this.playedTime);
|
|
5377
|
-
if (!isNotFinished) {
|
|
5378
|
-
return;
|
|
5379
|
-
}
|
|
5380
|
-
}
|
|
5381
|
-
/**
|
|
5382
|
-
* Recalculates the absolute start time of the sequencer.
|
|
5383
|
-
* @param time the time in seconds to recalculate the start time for.
|
|
5384
|
-
*/
|
|
5385
|
-
recalculateStartTime(time) {
|
|
5386
|
-
this.absoluteStartTime = this.synth.currentSynthTime - time / this._playbackRate;
|
|
5364
|
+
channel %= 16;
|
|
5365
|
+
this.sendMIDIMessage([
|
|
5366
|
+
midiMessageTypes.pitchWheel | channel,
|
|
5367
|
+
pitch & 127,
|
|
5368
|
+
pitch >> 7
|
|
5369
|
+
]);
|
|
5387
5370
|
}
|
|
5388
5371
|
};
|
|
5389
5372
|
|