spessasynth_core 4.1.2 → 4.1.3

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
@@ -519,6 +519,7 @@ declare class ModulationEnvelope {
519
519
  * @param voice the voice this envelope belongs to.
520
520
  */
521
521
  init(voice: Voice): void;
522
+ private tc2Sec;
522
523
  }
523
524
 
524
525
  declare const interpolationTypes: {
@@ -2509,6 +2510,10 @@ declare class SynthesizerCore {
2509
2510
  * Current total amount of voices that are currently playing.
2510
2511
  */
2511
2512
  voiceCount: number;
2513
+ /**
2514
+ * For F5 system exclusive.
2515
+ */
2516
+ channelOffset: number;
2512
2517
  /**
2513
2518
  * Last time the priorities were assigned.
2514
2519
  * Used to prevent assigning priorities multiple times when more than one voice is triggered during a quantum.
package/dist/index.js CHANGED
@@ -7124,7 +7124,7 @@ var ModulationEnvelope = class {
7124
7124
  startRelease(voice) {
7125
7125
  this.releaseStartLevel = this.currentValue;
7126
7126
  this.enteredRelease = true;
7127
- const releaseTime = timecentsToSeconds(
7127
+ const releaseTime = this.tc2Sec(
7128
7128
  Math.max(
7129
7129
  voice.modulatedGenerators[generatorTypes.releaseModEnv],
7130
7130
  -7200
@@ -7139,25 +7139,27 @@ var ModulationEnvelope = class {
7139
7139
  init(voice) {
7140
7140
  this.enteredRelease = false;
7141
7141
  this.sustainLevel = 1 - voice.modulatedGenerators[generatorTypes.sustainModEnv] / 1e3;
7142
- this.attackDuration = timecentsToSeconds(
7142
+ this.attackDuration = this.tc2Sec(
7143
7143
  voice.modulatedGenerators[generatorTypes.attackModEnv]
7144
7144
  );
7145
7145
  const decayKeyExcursionCents = (60 - voice.midiNote) * voice.modulatedGenerators[generatorTypes.keyNumToModEnvDecay];
7146
- const decayTime = timecentsToSeconds(
7146
+ const decayTime = this.tc2Sec(
7147
7147
  voice.modulatedGenerators[generatorTypes.decayModEnv] + decayKeyExcursionCents
7148
7148
  );
7149
7149
  this.decayDuration = decayTime * (1 - this.sustainLevel);
7150
7150
  const holdKeyExcursionCents = (60 - voice.midiNote) * voice.modulatedGenerators[generatorTypes.keyNumToModEnvHold];
7151
- this.holdDuration = timecentsToSeconds(
7151
+ this.holdDuration = this.tc2Sec(
7152
7152
  holdKeyExcursionCents + voice.modulatedGenerators[generatorTypes.holdModEnv]
7153
7153
  );
7154
- this.delayEnd = voice.startTime + timecentsToSeconds(
7155
- voice.modulatedGenerators[generatorTypes.delayModEnv]
7156
- );
7154
+ this.delayEnd = voice.startTime + this.tc2Sec(voice.modulatedGenerators[generatorTypes.delayModEnv]);
7157
7155
  this.attackEnd = this.delayEnd + this.attackDuration;
7158
7156
  this.holdEnd = this.attackEnd + this.holdDuration;
7159
7157
  this.decayEnd = this.holdEnd + this.decayDuration;
7160
7158
  }
7159
+ tc2Sec(timecents) {
7160
+ if (timecents <= -10114) return 0;
7161
+ return timecentsToSeconds(timecents);
7162
+ }
7161
7163
  };
7162
7164
 
7163
7165
  // src/utils/byte_functions/bit_mask.ts
@@ -12437,6 +12439,24 @@ function systemExclusiveInternal(syx, channelOffset) {
12437
12439
  handleXG.call(this, syx, channelOffset);
12438
12440
  break;
12439
12441
  }
12442
+ // Port select (Falcosoft MIDI Player)
12443
+ // https://www.vogons.org/viewtopic.php?p=1404746#p1404746
12444
+ case 245: {
12445
+ if (syx.length < 2) return;
12446
+ this.channelOffset = (syx[1] - 1) * 16;
12447
+ while (this.midiChannels.length <= this.channelOffset) {
12448
+ SpessaSynthInfo(
12449
+ `%cPort select, channel offset %c${this.channelOffset}%c. Creating a new port!`,
12450
+ consoleColors.info,
12451
+ consoleColors.value,
12452
+ consoleColors.info
12453
+ );
12454
+ for (let i = 0; i < 16; i++) {
12455
+ this.createMIDIChannel(true);
12456
+ }
12457
+ }
12458
+ break;
12459
+ }
12440
12460
  }
12441
12461
  }
12442
12462
 
@@ -12560,6 +12580,10 @@ var SynthesizerCore = class {
12560
12580
  * Current total amount of voices that are currently playing.
12561
12581
  */
12562
12582
  voiceCount = 0;
12583
+ /**
12584
+ * For F5 system exclusive.
12585
+ */
12586
+ channelOffset = 0;
12563
12587
  /**
12564
12588
  * Last time the priorities were assigned.
12565
12589
  * Used to prevent assigning priorities multiple times when more than one voice is triggered during a quantum.
@@ -12765,6 +12789,7 @@ var SynthesizerCore = class {
12765
12789
  this.setMIDIVolume(1);
12766
12790
  this.reverbSend = 1;
12767
12791
  this.chorusSend = 1;
12792
+ this.channelOffset = 0;
12768
12793
  if (!this.drumPreset || !this.defaultPreset) {
12769
12794
  return;
12770
12795
  }
@@ -17757,7 +17782,10 @@ var SpessaSynthProcessor = class {
17757
17782
  * @param channelOffset The channel offset to apply (default is 0).
17758
17783
  */
17759
17784
  systemExclusive(syx, channelOffset = 0) {
17760
- this.synthCore.systemExclusive(syx, channelOffset);
17785
+ this.synthCore.systemExclusive(
17786
+ syx,
17787
+ channelOffset + this.synthCore.channelOffset
17788
+ );
17761
17789
  }
17762
17790
  /**
17763
17791
  * Sets a master parameter of the synthesizer.
@@ -17868,10 +17896,7 @@ var SpessaSynthProcessor = class {
17868
17896
  * @param controllerValue The value to set the controller to.
17869
17897
  */
17870
17898
  controllerChange(channel, controllerNumber, controllerValue) {
17871
- this.synthCore.midiChannels[channel].controllerChange(
17872
- controllerNumber,
17873
- controllerValue
17874
- );
17899
+ this.synthCore.midiChannels[channel + this.synthCore.channelOffset].controllerChange(controllerNumber, controllerValue);
17875
17900
  }
17876
17901
  /**
17877
17902
  * Executes a MIDI Note-on message on the specified channel.
@@ -17882,7 +17907,7 @@ var SpessaSynthProcessor = class {
17882
17907
  * If the velocity is 0, it will be treated as a Note-off message.
17883
17908
  */
17884
17909
  noteOn(channel, midiNote, velocity) {
17885
- this.synthCore.midiChannels[channel].noteOn(midiNote, velocity);
17910
+ this.synthCore.midiChannels[channel + this.synthCore.channelOffset].noteOn(midiNote, velocity);
17886
17911
  }
17887
17912
  /**
17888
17913
  * Executes a MIDI Note-off message on the specified channel.
@@ -17890,7 +17915,7 @@ var SpessaSynthProcessor = class {
17890
17915
  * @param midiNote The MIDI note number to stop playing.
17891
17916
  */
17892
17917
  noteOff(channel, midiNote) {
17893
- this.synthCore.midiChannels[channel].noteOff(midiNote);
17918
+ this.synthCore.midiChannels[channel + this.synthCore.channelOffset].noteOff(midiNote);
17894
17919
  }
17895
17920
  /**
17896
17921
  * Executes a MIDI Poly Pressure (Aftertouch) message on the specified channel.
@@ -17899,7 +17924,7 @@ var SpessaSynthProcessor = class {
17899
17924
  * @param pressure The pressure value, from 0 to 127.
17900
17925
  */
17901
17926
  polyPressure(channel, midiNote, pressure) {
17902
- this.synthCore.midiChannels[channel].polyPressure(midiNote, pressure);
17927
+ this.synthCore.midiChannels[channel + this.synthCore.channelOffset].polyPressure(midiNote, pressure);
17903
17928
  }
17904
17929
  /**
17905
17930
  * Executes a MIDI Channel Pressure (Aftertouch) message on the specified channel.
@@ -17907,7 +17932,7 @@ var SpessaSynthProcessor = class {
17907
17932
  * @param pressure The pressure value, from 0 to 127.
17908
17933
  */
17909
17934
  channelPressure(channel, pressure) {
17910
- this.synthCore.midiChannels[channel].channelPressure(pressure);
17935
+ this.synthCore.midiChannels[channel + this.synthCore.channelOffset].channelPressure(pressure);
17911
17936
  }
17912
17937
  /**
17913
17938
  * Executes a MIDI Pitch Wheel message on the specified channel.
@@ -17916,7 +17941,7 @@ var SpessaSynthProcessor = class {
17916
17941
  * @param midiNote The MIDI note number, pass -1 for the regular pitch wheel
17917
17942
  */
17918
17943
  pitchWheel(channel, pitch, midiNote = -1) {
17919
- this.synthCore.midiChannels[channel].pitchWheel(pitch, midiNote);
17944
+ this.synthCore.midiChannels[channel + this.synthCore.channelOffset].pitchWheel(pitch, midiNote);
17920
17945
  }
17921
17946
  /**
17922
17947
  * Executes a MIDI Program Change message on the specified channel.
@@ -17924,7 +17949,7 @@ var SpessaSynthProcessor = class {
17924
17949
  * @param programNumber The program number to change to, from 0 to 127.
17925
17950
  */
17926
17951
  programChange(channel, programNumber) {
17927
- this.synthCore.midiChannels[channel].programChange(programNumber);
17952
+ this.synthCore.midiChannels[channel + this.synthCore.channelOffset].programChange(programNumber);
17928
17953
  }
17929
17954
  // noinspection JSUnusedGlobalSymbols
17930
17955
  /**
@@ -17946,7 +17971,12 @@ var SpessaSynthProcessor = class {
17946
17971
  * @param options Additional options for scheduling the message.
17947
17972
  */
17948
17973
  processMessage(message, channelOffset = 0, force = false, options = DEFAULT_SYNTH_METHOD_OPTIONS) {
17949
- this.synthCore.processMessage(message, channelOffset, force, options);
17974
+ this.synthCore.processMessage(
17975
+ message,
17976
+ channelOffset + this.synthCore.channelOffset,
17977
+ force,
17978
+ options
17979
+ );
17950
17980
  }
17951
17981
  // noinspection JSUnusedGlobalSymbols
17952
17982
  /**