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.
- package/@types/soundfont/basic_soundfont/basic_soundfont.d.ts +1 -1
- package/@types/soundfont/basic_soundfont/write_dls/rgn2.d.ts +2 -1
- package/@types/soundfont/dls/dls_sample.d.ts +1 -1
- package/@types/soundfont/read_sf2/samples.d.ts +2 -2
- package/@types/synthetizer/key_modifier_manager.d.ts +14 -0
- package/@types/synthetizer/worklet_system/worklet_utilities/controller_tables.d.ts +2 -2
- package/@types/utils/indexed_array.d.ts +1 -1
- package/README.md +2 -1
- package/package.json +1 -1
- package/soundfont/basic_soundfont/basic_zone.js +1 -1
- package/soundfont/basic_soundfont/write_dls/ins.js +1 -1
- package/soundfont/basic_soundfont/write_dls/rgn2.js +17 -2
- package/soundfont/basic_soundfont/write_dls/wave.js +22 -8
- package/soundfont/basic_soundfont/write_dls/write_dls.js +1 -1
- package/soundfont/basic_soundfont/write_dls/wsmp.js +12 -8
- package/synthetizer/key_modifier_manager.js +30 -1
- package/synthetizer/worklet_processor.min.js +9 -9
- package/synthetizer/worklet_system/main_processor.js +2 -2
- package/synthetizer/worklet_system/worklet_methods/note_on.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/worklet_key_modifier.js +3 -3
- package/synthetizer/worklet_system/worklet_utilities/volume_envelope.js +20 -13
|
@@ -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 * (
|
|
219
|
-
this.panSmoothingFactor = PAN_SMOOTHING_FACTOR * (
|
|
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.
|
|
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
|
|
35
|
-
deleteMapping: 1, // [channel<number
|
|
36
|
-
clearMappings: 2
|
|
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.
|
|
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
|
|
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.
|
|
285
|
+
env.attenuation += (env.attenuationTargetGain - env.attenuation) * attenuationSmoothing;
|
|
280
286
|
let db = (elapsedRelease / env.releaseDuration) * dbDifference + env.releaseStartDb;
|
|
281
|
-
env.currentReleaseGain = decibelAttenuationToGain(db + decibelOffset
|
|
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.
|
|
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 *
|
|
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.
|
|
347
|
+
env.attenuation += (env.attenuationTargetGain - env.attenuation) * attenuationSmoothing;
|
|
341
348
|
|
|
342
|
-
audioBuffer[filledBuffer] *=
|
|
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.
|
|
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
|
|
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.
|
|
389
|
+
env.attenuation += (env.attenuationTargetGain - env.attenuation) * attenuationSmoothing;
|
|
383
390
|
|
|
384
|
-
audioBuffer[filledBuffer] *= decibelAttenuationToGain(env.sustainDbRelative + decibelOffset
|
|
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)
|