spessasynth_lib 3.23.0 → 3.23.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.
@@ -215,8 +215,8 @@ class SpessaSynthProcessor extends AudioWorkletProcessor
215
215
  this.workletProcessorChannels[DEFAULT_PERCUSSION].drumChannel = true;
216
216
 
217
217
  // these smoothing factors were tested on 44100Hz, adjust them here
218
- this.volumeEnvelopeSmoothingFactor = VOLUME_ENVELOPE_SMOOTHING_FACTOR * (sampleRate / 44100);
219
- this.panSmoothingFactor = PAN_SMOOTHING_FACTOR * (sampleRate / 44100);
218
+ this.volumeEnvelopeSmoothingFactor = VOLUME_ENVELOPE_SMOOTHING_FACTOR * (44100 / sampleRate);
219
+ this.panSmoothingFactor = PAN_SMOOTHING_FACTOR * (44100 / sampleRate);
220
220
 
221
221
  /**
222
222
  * Controls the system
@@ -117,7 +117,7 @@ export function noteOn(channel, midiNote, velocity, enableDebugging = false, sen
117
117
  }
118
118
  // set the current attenuation to target,
119
119
  // as it's interpolated (we don't want 0 attenuation for even a split second)
120
- voice.volumeEnvelope.attenuation = voice.volumeEnvelope.attenuationTarget;
120
+ voice.volumeEnvelope.attenuation = voice.volumeEnvelope.attenuationTargetGain;
121
121
  // set initial pan to avoid split second changing from middle to the correct value
122
122
  voice.currentPan = ((Math.max(
123
123
  -500,
@@ -31,9 +31,9 @@ export class KeyModifier
31
31
  * @enum {number}
32
32
  */
33
33
  export const workletKeyModifierMessageType = {
34
- addMapping: 0, // [channel<number, midiNote<number>, mapping<KeyModifier>]
35
- deleteMapping: 1, // [channel<number, midiNote<number>]
36
- clearMappings: 2 // <no data>
34
+ addMapping: 0, // [channel<number>, midiNote<number>, mapping<KeyModifier>]
35
+ deleteMapping: 1, // [channel<number>, midiNote<number>]
36
+ clearMappings: 2 // <no data>
37
37
  };
38
38
 
39
39
  export class WorkletKeyModifierManager
@@ -7,7 +7,7 @@ import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js"
7
7
  * purpose: applies a volume envelope for a given voice
8
8
  */
9
9
 
10
- export const VOLUME_ENVELOPE_SMOOTHING_FACTOR = 0.001;
10
+ export const VOLUME_ENVELOPE_SMOOTHING_FACTOR = 0.01;
11
11
 
12
12
  const DB_SILENCE = 100;
13
13
  const PERCEIVED_DB_SILENCE = 90;
@@ -77,12 +77,17 @@ export class WorkletVolumeEnvelope
77
77
  */
78
78
  releaseDuration = 0;
79
79
  /**
80
- * The voice's absolute attenuation in dB
80
+ * The voice's absolute attenuation as linear gain
81
81
  * @type {number}
82
82
  */
83
83
  attenuation = 0;
84
84
  /**
85
- * The attenuation target, which the "attenuation" property is linearly interpolated towards
85
+ * The attenuation target, which the "attenuation" property is linearly interpolated towards (gain)
86
+ * @type {number}
87
+ */
88
+ attenuationTargetGain = 0;
89
+ /**
90
+ * The attenuation target, which the "attenuation" property is linearly interpolated towards (dB)
86
91
  * @type {number}
87
92
  */
88
93
  attenuationTarget = 0;
@@ -155,6 +160,7 @@ export class WorkletVolumeEnvelope
155
160
  0,
156
161
  Math.min(voice.modulatedGenerators[generatorTypes.initialAttenuation], 1440)
157
162
  ) / 10; // divide by ten to get decibels
163
+ env.attenuationTargetGain = decibelAttenuationToGain(env.attenuationTarget);
158
164
  env.sustainDbRelative = Math.min(DB_SILENCE, voice.modulatedGenerators[generatorTypes.sustainVolEnv] / 10);
159
165
  const sustainDb = Math.min(DB_SILENCE, env.sustainDbRelative);
160
166
 
@@ -276,9 +282,9 @@ export class WorkletVolumeEnvelope
276
282
  for (let i = 0; i < audioBuffer.length; i++)
277
283
  {
278
284
  // attenuation interpolation
279
- env.attenuation += (env.attenuationTarget - env.attenuation) * attenuationSmoothing;
285
+ env.attenuation += (env.attenuationTargetGain - env.attenuation) * attenuationSmoothing;
280
286
  let db = (elapsedRelease / env.releaseDuration) * dbDifference + env.releaseStartDb;
281
- env.currentReleaseGain = decibelAttenuationToGain(db + decibelOffset + env.attenuation);
287
+ env.currentReleaseGain = env.attenuation * decibelAttenuationToGain(db + decibelOffset);
282
288
  audioBuffer[i] *= env.currentReleaseGain;
283
289
  env.currentSampleTime++;
284
290
  elapsedRelease++;
@@ -315,11 +321,12 @@ export class WorkletVolumeEnvelope
315
321
  while (env.currentSampleTime < env.attackEnd)
316
322
  {
317
323
  // attenuation interpolation
318
- env.attenuation += (env.attenuationTarget - env.attenuation) * attenuationSmoothing;
324
+ env.attenuation += (env.attenuationTargetGain - env.attenuation) * attenuationSmoothing;
319
325
 
320
326
  // Special case: linear gain ramp instead of linear db ramp
321
327
  let linearAttenuation = 1 - (env.attackEnd - env.currentSampleTime) / env.attackDuration; // 0 to 1
322
- audioBuffer[filledBuffer] *= linearAttenuation * decibelAttenuationToGain(env.attenuation + decibelOffset);
328
+ audioBuffer[filledBuffer] *= linearAttenuation * env.attenuation * decibelAttenuationToGain(
329
+ decibelOffset);
323
330
  // set current attenuation to peak as its invalid during this phase
324
331
  env.currentAttenuationDb = 0;
325
332
 
@@ -337,9 +344,9 @@ export class WorkletVolumeEnvelope
337
344
  while (env.currentSampleTime < env.holdEnd)
338
345
  {
339
346
  // attenuation interpolation
340
- env.attenuation += (env.attenuationTarget - env.attenuation) * attenuationSmoothing;
347
+ env.attenuation += (env.attenuationTargetGain - env.attenuation) * attenuationSmoothing;
341
348
 
342
- audioBuffer[filledBuffer] *= decibelAttenuationToGain(env.attenuation + decibelOffset);
349
+ audioBuffer[filledBuffer] *= env.attenuation * decibelAttenuationToGain(decibelOffset);
343
350
  env.currentAttenuationDb = 0;
344
351
 
345
352
  env.currentSampleTime++;
@@ -356,10 +363,10 @@ export class WorkletVolumeEnvelope
356
363
  while (env.currentSampleTime < env.decayEnd)
357
364
  {
358
365
  // attenuation interpolation
359
- env.attenuation += (env.attenuationTarget - env.attenuation) * attenuationSmoothing;
366
+ env.attenuation += (env.attenuationTargetGain - env.attenuation) * attenuationSmoothing;
360
367
 
361
368
  env.currentAttenuationDb = (1 - (env.decayEnd - env.currentSampleTime) / env.decayDuration) * env.sustainDbRelative;
362
- audioBuffer[filledBuffer] *= decibelAttenuationToGain(env.currentAttenuationDb + decibelOffset + env.attenuation);
369
+ audioBuffer[filledBuffer] *= env.attenuation * decibelAttenuationToGain(env.currentAttenuationDb + decibelOffset);
363
370
 
364
371
  env.currentSampleTime++;
365
372
  if (++filledBuffer >= audioBuffer.length)
@@ -379,9 +386,9 @@ export class WorkletVolumeEnvelope
379
386
  while (true)
380
387
  {
381
388
  // attenuation interpolation
382
- env.attenuation += (env.attenuationTarget - env.attenuation) * attenuationSmoothing;
389
+ env.attenuation += (env.attenuationTargetGain - env.attenuation) * attenuationSmoothing;
383
390
 
384
- audioBuffer[filledBuffer] *= decibelAttenuationToGain(env.sustainDbRelative + decibelOffset + env.attenuation);
391
+ audioBuffer[filledBuffer] *= env.attenuation * decibelAttenuationToGain(env.sustainDbRelative + decibelOffset);
385
392
  env.currentAttenuationDb = env.sustainDbRelative;
386
393
  env.currentSampleTime++;
387
394
  if (++filledBuffer >= audioBuffer.length)