spessasynth_core 4.2.10 → 4.2.12

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
@@ -429,11 +429,6 @@ declare class VolumeEnvelope {
429
429
  * We can't do that with modulated as it can silence the volume and then raise it again, and the voice must keep playing.
430
430
  */
431
431
  private canEndOnSilentSustain;
432
- /**
433
- * The current peak gain, used for smoothing.
434
- * @private
435
- */
436
- private peakGain;
437
432
  /**
438
433
  * @param sampleRate Hz
439
434
  */
package/dist/index.js CHANGED
@@ -3604,13 +3604,15 @@ function processEventInternal(event, trackIndex) {
3604
3604
  case midiMessageTypes.systemExclusive:
3605
3605
  this.synth.systemExclusive(event.data, offset);
3606
3606
  break;
3607
- case midiMessageTypes.setTempo:
3608
- this.oneTickToSeconds = 60 / (6e7 / readBigEndian(event.data, 3) * this._midiData.timeDivision);
3607
+ case midiMessageTypes.setTempo: {
3608
+ const tempoBPM = 6e7 / readBigEndian(event.data, 3);
3609
+ this.oneTickToSeconds = 60 / (tempoBPM * this._midiData.timeDivision);
3609
3610
  if (this.oneTickToSeconds === 0) {
3610
3611
  this.oneTickToSeconds = 60 / (120 * this._midiData.timeDivision);
3611
3612
  SpessaSynthInfo("invalid tempo! falling back to 120 BPM");
3612
3613
  }
3613
3614
  break;
3615
+ }
3614
3616
  case midiMessageTypes.timeSignature:
3615
3617
  case midiMessageTypes.endOfTrack:
3616
3618
  case midiMessageTypes.midiChannelPrefix:
@@ -4460,11 +4462,13 @@ function setTimeToInternal(time, ticks = void 0) {
4460
4462
  }
4461
4463
  break;
4462
4464
  }
4463
- case midiMessageTypes.setTempo:
4464
- this.oneTickToSeconds = 60 / (6e7 / readBigEndian(event.data, 3) * this._midiData.timeDivision);
4465
+ case midiMessageTypes.setTempo: {
4466
+ const tempoBPM = 6e7 / readBigEndian(event.data, 3);
4467
+ this.oneTickToSeconds = 60 / (tempoBPM * this._midiData.timeDivision);
4465
4468
  savedTempo = event;
4466
4469
  savedTempoTrack = trackIndex;
4467
4470
  break;
4471
+ }
4468
4472
  default:
4469
4473
  this.processEvent(event, trackIndex);
4470
4474
  break;
@@ -4880,7 +4884,8 @@ var SpessaSynthSequencer = class {
4880
4884
  const idx = track.events.findIndex((e) => e.ticks >= targetTicks);
4881
4885
  this.eventIndexes.push(idx === -1 ? track.events.length : idx);
4882
4886
  }
4883
- this.oneTickToSeconds = 60 / (this._midiData.tempoChanges.find((t) => t.ticks <= targetTicks).tempo * this._midiData.timeDivision);
4887
+ const targetTempo = this._midiData.tempoChanges.find((t) => t.ticks <= targetTicks);
4888
+ this.oneTickToSeconds = 60 / (targetTempo.tempo * this._midiData.timeDivision);
4884
4889
  }
4885
4890
  sendMIDINoteOn(channel, midiNote, velocity) {
4886
4891
  if (!this.externalMIDIPlayback) {
@@ -6121,11 +6126,6 @@ var VolumeEnvelope = class {
6121
6126
  */
6122
6127
  canEndOnSilentSustain = false;
6123
6128
  /**
6124
- * The current peak gain, used for smoothing.
6125
- * @private
6126
- */
6127
- peakGain = 0;
6128
- /**
6129
6129
  * @param sampleRate Hz
6130
6130
  */
6131
6131
  constructor(sampleRate) {
@@ -6180,9 +6180,8 @@ var VolumeEnvelope = class {
6180
6180
  this.enteredRelease = false;
6181
6181
  this.state = 0;
6182
6182
  this.sampleTime = 0;
6183
+ this.outputGain = 0;
6183
6184
  this.canEndOnSilentSustain = voice.modulatedGenerators[generatorTypes.sustainVolEnv] >= PERCEIVED_CB_SILENCE;
6184
- this.peakGain = CENTIBEL_LOOKUP_TABLE[voice.modulatedGenerators[generatorTypes.initialAttenuation] - MIN_CENTIBELS | 0];
6185
- this.outputGain = this.peakGain;
6186
6185
  this.sustainCb = Math.min(CB_SILENCE, voice.modulatedGenerators[generatorTypes.sustainVolEnv]);
6187
6186
  this.attackDuration = this.timecentsToSamples(voice.modulatedGenerators[generatorTypes.attackVolEnv]);
6188
6187
  const keyNumAddition = (60 - voice.targetKey) * voice.modulatedGenerators[generatorTypes.keyNumToVolEnvDecay];
@@ -6223,7 +6222,8 @@ var VolumeEnvelope = class {
6223
6222
  case 1:
6224
6223
  if (sampleTime < attackEnd) {
6225
6224
  this.attenuationCb = 0;
6226
- this.outputGain = (1 - (attackEnd - sampleTime) / attackDuration) * gainTarget;
6225
+ const linearGain = 1 - (attackEnd - sampleTime) / attackDuration;
6226
+ this.outputGain = linearGain * gainTarget;
6227
6227
  return true;
6228
6228
  }
6229
6229
  this.state++;
@@ -6392,7 +6392,8 @@ var ModulationEnvelope = class {
6392
6392
  startRelease(voice) {
6393
6393
  this.releaseStartLevel = this.currentValue;
6394
6394
  this.enteredRelease = true;
6395
- this.releaseDuration = this.tc2Sec(Math.max(voice.modulatedGenerators[generatorTypes.releaseModEnv], -7200)) * this.releaseStartLevel;
6395
+ const releaseTime = this.tc2Sec(Math.max(voice.modulatedGenerators[generatorTypes.releaseModEnv], -7200));
6396
+ this.releaseDuration = releaseTime * this.releaseStartLevel;
6396
6397
  }
6397
6398
  /**
6398
6399
  * Initializes the modulation envelope.
@@ -6403,7 +6404,8 @@ var ModulationEnvelope = class {
6403
6404
  this.sustainLevel = 1 - voice.modulatedGenerators[generatorTypes.sustainModEnv] / 1e3;
6404
6405
  this.attackDuration = this.tc2Sec(voice.modulatedGenerators[generatorTypes.attackModEnv]);
6405
6406
  const decayKeyExcursionCents = (60 - voice.midiNote) * voice.modulatedGenerators[generatorTypes.keyNumToModEnvDecay];
6406
- this.decayDuration = this.tc2Sec(voice.modulatedGenerators[generatorTypes.decayModEnv] + decayKeyExcursionCents) * (1 - this.sustainLevel);
6407
+ const decayTime = this.tc2Sec(voice.modulatedGenerators[generatorTypes.decayModEnv] + decayKeyExcursionCents);
6408
+ this.decayDuration = decayTime * (1 - this.sustainLevel);
6407
6409
  const holdKeyExcursionCents = (60 - voice.midiNote) * voice.modulatedGenerators[generatorTypes.keyNumToModEnvHold];
6408
6410
  this.holdDuration = this.tc2Sec(holdKeyExcursionCents + voice.modulatedGenerators[generatorTypes.holdModEnv]);
6409
6411
  this.delayEnd = voice.startTime + this.tc2Sec(voice.modulatedGenerators[generatorTypes.delayModEnv]);
@@ -11787,7 +11789,7 @@ function dataEntryFine(dataValue) {
11787
11789
  case dataEntryStates.NRPFine: {
11788
11790
  const paramCoarse = this.midiControllers[midiControllers.nonRegisteredParameterMSB] >> 7;
11789
11791
  const paramFine = this.midiControllers[midiControllers.nonRegisteredParameterLSB] >> 7;
11790
- if (paramCoarse === nonRegisteredMSB.SF2 || paramCoarse >= nonRegisteredMSB.drumPitch && paramFine <= nonRegisteredMSB.drumDelay || paramCoarse === nonRegisteredMSB.partParameter) return;
11792
+ if (paramCoarse === nonRegisteredMSB.SF2 || paramCoarse >= nonRegisteredMSB.drumPitch && paramCoarse <= nonRegisteredMSB.drumDelay || paramCoarse === nonRegisteredMSB.partParameter) return;
11791
11793
  switch (paramCoarse) {
11792
11794
  default:
11793
11795
  SpessaSynthInfo(`%cUnrecognized NRPN LSB for %c${this.channel}%c: %c(0x${paramCoarse.toString(16).toUpperCase()} 0x${paramFine.toString(16).toUpperCase()})%c data value: %c${dataValue}`, consoleColors.warn, consoleColors.recognized, consoleColors.warn, consoleColors.unrecognized, consoleColors.warn, consoleColors.value);
@@ -18059,7 +18061,8 @@ var SpessaSynthReverb = class {
18059
18061
  set preLowpass(value) {
18060
18062
  this._preLowpass = value;
18061
18063
  this.preLPFfc = 8e3 * .63 ** this._preLowpass;
18062
- this.preLPFa = 1 - Math.exp(-2 * Math.PI * this.preLPFfc / this.sampleRate);
18064
+ const decay = Math.exp(-2 * Math.PI * this.preLPFfc / this.sampleRate);
18065
+ this.preLPFa = 1 - decay;
18063
18066
  this.updateLowpass();
18064
18067
  }
18065
18068
  /**
@@ -18220,7 +18223,8 @@ var SpessaSynthChorus = class {
18220
18223
  set preLowpass(value) {
18221
18224
  this._preLowpass = value;
18222
18225
  this.preLPFfc = 8e3 * .63 ** this._preLowpass;
18223
- this.preLPFa = 1 - Math.exp(-2 * Math.PI * this.preLPFfc / this.sampleRate);
18226
+ const decay = Math.exp(-2 * Math.PI * this.preLPFfc / this.sampleRate);
18227
+ this.preLPFa = 1 - decay;
18224
18228
  }
18225
18229
  _depth = 0;
18226
18230
  get depth() {
@@ -18252,7 +18256,8 @@ var SpessaSynthChorus = class {
18252
18256
  }
18253
18257
  set rate(value) {
18254
18258
  this._rate = value;
18255
- this.rateInc = 15.5 * (value / 127) / this.sampleRate;
18259
+ const rate = 15.5 * (value / 127);
18260
+ this.rateInc = rate / this.sampleRate;
18256
18261
  }
18257
18262
  _level = 64;
18258
18263
  get level() {
@@ -18439,7 +18444,8 @@ var SpessaSynthDelay = class {
18439
18444
  set preLowpass(value) {
18440
18445
  this._preLowpass = value;
18441
18446
  this.preLPFfc = 8e3 * .63 ** this._preLowpass;
18442
- this.preLPFa = 1 - Math.exp(-2 * Math.PI * this.preLPFfc / this.sampleRate);
18447
+ const decay = Math.exp(-2 * Math.PI * this.preLPFfc / this.sampleRate);
18448
+ this.preLPFa = 1 - decay;
18443
18449
  }
18444
18450
  _levelRight = 0;
18445
18451
  get levelRight() {
@@ -19156,6 +19162,25 @@ var SynthesizerCore = class {
19156
19162
  rev.preDelayTime = 0;
19157
19163
  rev.character = macro;
19158
19164
  switch (macro) {
19165
+ /**
19166
+ * REVERB MACRO is a macro parameter that allows global setting of reverb parameters.
19167
+ * When you select the reverb type with REVERB MACRO, each reverb parameter will be set to their most
19168
+ * suitable value.
19169
+ *
19170
+ * Room1, Room2, Room3
19171
+ * These reverbs simulate the reverberation of a room. They provide a well-defined
19172
+ * spacious reverberation.
19173
+ * Hall1, Hall2
19174
+ * These reverbs simulate the reverberation of a concert hall. They provide a deeper
19175
+ * reverberation than the Room reverbs.
19176
+ * Plate
19177
+ * This simulates a plate reverb (a studio device using a metal plate).
19178
+ * Delay
19179
+ * This is a conventional delay that produces echo effects.
19180
+ * Panning Delay
19181
+ * This is a special delay in which the delayed sounds move left and right.
19182
+ * It is effective when you are listening in stereo.
19183
+ */
19159
19184
  case 0:
19160
19185
  rev.character = 0;
19161
19186
  rev.preLowpass = 3;
@@ -19217,6 +19242,23 @@ var SynthesizerCore = class {
19217
19242
  chr.sendLevelToDelay = 0;
19218
19243
  chr.sendLevelToReverb = 0;
19219
19244
  switch (macro) {
19245
+ /**
19246
+ * CHORUS MACRO is a macro parameter that allows global setting of chorus parameters.
19247
+ * When you select the chorus type with CHORUS MACRO, each chorus parameter will be set to their
19248
+ * most suitable value.
19249
+ *
19250
+ * Chorus1, Chorus2, Chorus3, Chorus4
19251
+ * These are conventional chorus effects that add spaciousness and depth to the
19252
+ * sound.
19253
+ * Feedback Chorus
19254
+ * This is a chorus with a flanger-like effect and a soft sound.
19255
+ * Flanger
19256
+ * This is an effect sounding somewhat like a jet airplane taking off and landing.
19257
+ * Short Delay
19258
+ * This is a delay with a short delay time.
19259
+ * Short Delay (FB)
19260
+ * This is a short delay with many repeats.
19261
+ */
19220
19262
  case 0:
19221
19263
  chr.feedback = 0;
19222
19264
  chr.delay = 112;
@@ -19284,6 +19326,29 @@ var SynthesizerCore = class {
19284
19326
  dly.levelRight = dly.levelLeft = 0;
19285
19327
  dly.levelCenter = 127;
19286
19328
  switch (macro) {
19329
+ /**
19330
+ * DELAY MACRO is a macro parameter that allows global setting of delay parameters. When you select the delay type with DELAY MACRO, each delay parameter will be set to their most
19331
+ * suitable value.
19332
+ *
19333
+ * Delay1, Delay2, Delay3
19334
+ * These are conventional delays. 1, 2 and 3 have progressively longer delay times.
19335
+ * Delay4
19336
+ * This is a delay with a rather short delay time.
19337
+ * Pan Delay1. Pan Delay2. Pan Delay3
19338
+ * The delay sound moves between left and right. This is effective when listening in
19339
+ * stereo. 1, 2 and 3 have progressively longer delay times.
19340
+ * Pan Delay4
19341
+ * This is a rather short delay with the delayed sound moving between left and
19342
+ * right.
19343
+ * It is effective when listening in stereo.
19344
+ * Dly To Rev
19345
+ * Reverb is added to the delay sound, which moves between left and right.
19346
+ * It is effective when listening in stereo.
19347
+ * PanRepeat
19348
+ * The delay sound moves between left and right,
19349
+ * but the pan positioning is different from the effects listed above.
19350
+ * It is effective when listening in stereo.
19351
+ */
19287
19352
  case 0:
19288
19353
  dly.timeCenter = 97;
19289
19354
  dly.timeRatioRight = dly.timeRatioLeft = 1;