spessasynth_lib 3.20.30 → 3.20.32

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.
Files changed (124) hide show
  1. package/@types/midi_parser/midi_loader.d.ts +2 -0
  2. package/LICENSE +0 -0
  3. package/README.md +0 -0
  4. package/external_midi/README.md +0 -0
  5. package/external_midi/midi_handler.js +0 -0
  6. package/external_midi/web_midi_link.js +0 -0
  7. package/externals/NOTICE +0 -0
  8. package/externals/libvorbis/@types/OggVorbisEncoder.d.ts +0 -0
  9. package/externals/libvorbis/OggVorbisEncoder.min.js +0 -0
  10. package/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -0
  11. package/externals/stbvorbis_sync/LICENSE +0 -0
  12. package/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -0
  13. package/midi_parser/README.md +0 -0
  14. package/midi_parser/basic_midi.js +0 -0
  15. package/midi_parser/midi_builder.js +0 -0
  16. package/midi_parser/midi_data.js +0 -0
  17. package/midi_parser/midi_editor.js +0 -0
  18. package/midi_parser/midi_loader.js +2 -2
  19. package/midi_parser/midi_message.js +0 -0
  20. package/midi_parser/midi_writer.js +0 -0
  21. package/midi_parser/rmidi_writer.js +0 -0
  22. package/midi_parser/used_keys_loaded.js +0 -0
  23. package/package.json +1 -1
  24. package/sequencer/README.md +0 -0
  25. package/sequencer/sequencer.js +0 -0
  26. package/sequencer/worklet_sequencer/events.js +0 -0
  27. package/sequencer/worklet_sequencer/play.js +1 -1
  28. package/sequencer/worklet_sequencer/process_event.js +1 -0
  29. package/sequencer/worklet_sequencer/process_tick.js +0 -0
  30. package/sequencer/worklet_sequencer/sequencer_message.js +0 -0
  31. package/sequencer/worklet_sequencer/song_control.js +0 -0
  32. package/sequencer/worklet_sequencer/worklet_sequencer.js +0 -0
  33. package/soundfont/README.md +0 -0
  34. package/soundfont/basic_soundfont/basic_instrument.js +0 -0
  35. package/soundfont/basic_soundfont/basic_preset.js +0 -0
  36. package/soundfont/basic_soundfont/basic_sample.js +0 -0
  37. package/soundfont/basic_soundfont/basic_soundfont.js +0 -0
  38. package/soundfont/basic_soundfont/basic_zone.js +0 -0
  39. package/soundfont/basic_soundfont/basic_zones.js +0 -0
  40. package/soundfont/basic_soundfont/riff_chunk.js +0 -0
  41. package/soundfont/basic_soundfont/write_sf2/ibag.js +0 -0
  42. package/soundfont/basic_soundfont/write_sf2/igen.js +0 -0
  43. package/soundfont/basic_soundfont/write_sf2/imod.js +0 -0
  44. package/soundfont/basic_soundfont/write_sf2/inst.js +0 -0
  45. package/soundfont/basic_soundfont/write_sf2/pbag.js +0 -0
  46. package/soundfont/basic_soundfont/write_sf2/pgen.js +0 -0
  47. package/soundfont/basic_soundfont/write_sf2/phdr.js +0 -0
  48. package/soundfont/basic_soundfont/write_sf2/pmod.js +0 -0
  49. package/soundfont/basic_soundfont/write_sf2/sdta.js +0 -0
  50. package/soundfont/basic_soundfont/write_sf2/shdr.js +0 -0
  51. package/soundfont/basic_soundfont/write_sf2/soundfont_trimmer.js +0 -0
  52. package/soundfont/basic_soundfont/write_sf2/write.js +0 -0
  53. package/soundfont/dls/articulator_converter.js +0 -0
  54. package/soundfont/dls/dls_destinations.js +0 -0
  55. package/soundfont/dls/dls_preset.js +0 -0
  56. package/soundfont/dls/dls_sample.js +0 -0
  57. package/soundfont/dls/dls_soundfont.js +0 -0
  58. package/soundfont/dls/dls_sources.js +0 -0
  59. package/soundfont/dls/dls_zone.js +0 -0
  60. package/soundfont/dls/read_articulation.js +0 -0
  61. package/soundfont/dls/read_instrument.js +0 -0
  62. package/soundfont/dls/read_instrument_list.js +0 -0
  63. package/soundfont/dls/read_lart.js +0 -0
  64. package/soundfont/dls/read_region.js +0 -0
  65. package/soundfont/dls/read_samples.js +0 -0
  66. package/soundfont/load_soundfont.js +0 -0
  67. package/soundfont/read_sf2/generators.js +0 -0
  68. package/soundfont/read_sf2/instruments.js +0 -0
  69. package/soundfont/read_sf2/modulators.js +0 -0
  70. package/soundfont/read_sf2/presets.js +0 -0
  71. package/soundfont/read_sf2/samples.js +0 -0
  72. package/soundfont/read_sf2/soundfont.js +0 -0
  73. package/soundfont/read_sf2/zones.js +0 -0
  74. package/synthetizer/README.md +0 -0
  75. package/synthetizer/audio_effects/effects_config.js +0 -0
  76. package/synthetizer/audio_effects/fancy_chorus.js +0 -0
  77. package/synthetizer/audio_effects/impulse_response_2.flac +0 -0
  78. package/synthetizer/audio_effects/reverb.js +0 -0
  79. package/synthetizer/synth_event_handler.js +0 -0
  80. package/synthetizer/synth_soundfont_manager.js +0 -0
  81. package/synthetizer/synthetizer.js +0 -0
  82. package/synthetizer/worklet_processor.min.js +9 -7
  83. package/synthetizer/worklet_system/README.md +0 -0
  84. package/synthetizer/worklet_system/main_processor.js +0 -0
  85. package/synthetizer/worklet_system/message_protocol/handle_message.js +0 -0
  86. package/synthetizer/worklet_system/message_protocol/message_sending.js +0 -0
  87. package/synthetizer/worklet_system/message_protocol/worklet_message.js +0 -0
  88. package/synthetizer/worklet_system/minify_processor.sh +1 -1
  89. package/synthetizer/worklet_system/worklet_methods/controller_control.js +2 -1
  90. package/synthetizer/worklet_system/worklet_methods/data_entry.js +0 -0
  91. package/synthetizer/worklet_system/worklet_methods/note_off.js +0 -0
  92. package/synthetizer/worklet_system/worklet_methods/note_on.js +0 -0
  93. package/synthetizer/worklet_system/worklet_methods/program_control.js +0 -0
  94. package/synthetizer/worklet_system/worklet_methods/reset_controllers.js +1 -0
  95. package/synthetizer/worklet_system/worklet_methods/snapshot.js +0 -0
  96. package/synthetizer/worklet_system/worklet_methods/system_exclusive.js +0 -0
  97. package/synthetizer/worklet_system/worklet_methods/tuning_control.js +0 -0
  98. package/synthetizer/worklet_system/worklet_methods/vibrato_control.js +0 -0
  99. package/synthetizer/worklet_system/worklet_methods/voice_control.js +18 -7
  100. package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/sfman_message.js +0 -0
  101. package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +0 -0
  102. package/synthetizer/worklet_system/worklet_processor.js +0 -0
  103. package/synthetizer/worklet_system/worklet_utilities/lfo.js +0 -0
  104. package/synthetizer/worklet_system/worklet_utilities/lowpass_filter.js +0 -0
  105. package/synthetizer/worklet_system/worklet_utilities/modulation_envelope.js +0 -0
  106. package/synthetizer/worklet_system/worklet_utilities/modulator_curves.js +0 -0
  107. package/synthetizer/worklet_system/worklet_utilities/stereo_panner.js +0 -0
  108. package/synthetizer/worklet_system/worklet_utilities/unit_converter.js +0 -0
  109. package/synthetizer/worklet_system/worklet_utilities/volume_envelope.js +9 -7
  110. package/synthetizer/worklet_system/worklet_utilities/wavetable_oscillator.js +27 -33
  111. package/synthetizer/worklet_system/worklet_utilities/worklet_modulator.js +0 -0
  112. package/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js +0 -1
  113. package/synthetizer/worklet_system/worklet_utilities/worklet_voice.js +11 -0
  114. package/synthetizer/worklet_url.js +0 -0
  115. package/utils/README.md +0 -0
  116. package/utils/buffer_to_wav.js +0 -0
  117. package/utils/byte_functions/big_endian.js +0 -0
  118. package/utils/byte_functions/little_endian.js +0 -0
  119. package/utils/byte_functions/string.js +0 -0
  120. package/utils/byte_functions/variable_length_quantity.js +0 -0
  121. package/utils/encode_vorbis.js +0 -0
  122. package/utils/indexed_array.js +0 -0
  123. package/utils/loggin.js +0 -0
  124. package/utils/other.js +0 -0
File without changes
File without changes
@@ -1,4 +1,4 @@
1
1
  #!/bin/bash
2
- cd "$(dirname "$0")"
2
+ cd "$(dirname "$0")" || exit
3
3
  esbuild worklet_processor.js --bundle --minify --format=esm --outfile=../worklet_processor.min.js --platform=browser
4
4
  echo "Processor minifed succesfully"
@@ -41,7 +41,8 @@ export function controllerChange(channel, controllerNumber, controllerValue, for
41
41
  channelObject.midiControllers[actualCCNum] = (channelObject.midiControllers[actualCCNum] & 0x3F80) | (controllerValue & 0x7F);
42
42
  channelObject.voices.forEach(v => computeModulators(v, channelObject.midiControllers, 1, actualCCNum));
43
43
  }
44
- switch (controllerNumber) {
44
+ switch (controllerNumber)
45
+ {
45
46
  case midiControllers.allNotesOff:
46
47
  this.stopAll(channel);
47
48
  break;
@@ -87,6 +87,7 @@ export function resetAllControllers(log= true)
87
87
  restoreControllerValueEvent(midiControllers.modulationWheel);
88
88
  restoreControllerValueEvent(midiControllers.effects3Depth);
89
89
  restoreControllerValueEvent(midiControllers.effects1Depth);
90
+ restoreControllerValueEvent(midiControllers.brightness);
90
91
 
91
92
  // restore pitch wheel
92
93
  if(this.workletProcessorChannels[channelNumber].lockedControllers[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel])
@@ -3,7 +3,11 @@ import { absCentsToHz, timecentsToSeconds } from '../worklet_utilities/unit_conv
3
3
  import { getLFOValue } from '../worklet_utilities/lfo.js'
4
4
  import { customControllers } from '../worklet_utilities/worklet_processor_channel.js'
5
5
  import { WorkletModulationEnvelope } from '../worklet_utilities/modulation_envelope.js'
6
- import { getSampleLinear, getSampleNearest, interpolationTypes } from '../worklet_utilities/wavetable_oscillator.js'
6
+ import {
7
+ getSampleLinear,
8
+ getSampleNearest,
9
+ interpolationTypes,
10
+ } from '../worklet_utilities/wavetable_oscillator.js'
7
11
  import { panVoice } from '../worklet_utilities/stereo_panner.js'
8
12
  import { WorkletLowpassFilter } from '../worklet_utilities/lowpass_filter.js'
9
13
  import { MIN_NOTE_LENGTH } from '../main_processor.js'
@@ -149,13 +153,16 @@ export function renderVoice(
149
153
  const bufferOut = new Float32Array(outputLeft.length);
150
154
 
151
155
  // wavetable oscillator
152
- if(this.interpolationType === interpolationTypes.linear)
156
+ switch(this.interpolationType)
153
157
  {
154
- getSampleLinear(voice, bufferOut);
155
- }
156
- else
157
- {
158
- getSampleNearest(voice, bufferOut);
158
+ case interpolationTypes.linear:
159
+ default:
160
+ getSampleLinear(voice, bufferOut);
161
+ break;
162
+
163
+ case interpolationTypes.nearestNeighbor:
164
+ getSampleNearest(voice, bufferOut);
165
+ break;
159
166
  }
160
167
 
161
168
  // lowpass filter
@@ -257,4 +264,8 @@ export function releaseVoice(voice)
257
264
  {
258
265
  voice.releaseStartTime = voice.startTime + MIN_NOTE_LENGTH;
259
266
  }
267
+ if(voice.sample.loopingMode === 3)
268
+ {
269
+ voice.sample.isLooping = false;
270
+ }
260
271
  }
File without changes
@@ -10,6 +10,7 @@ export const VOLUME_ENVELOPE_SMOOTHING_FACTOR = 0.001;
10
10
 
11
11
  const DB_SILENCE = 100;
12
12
  const PERCEIVED_DB_SILENCE = 90;
13
+ const PERCEIVED_GAIN_SILENCE = 0.005;
13
14
 
14
15
  /**
15
16
  * VOL ENV STATES:
@@ -257,6 +258,7 @@ export class WorkletVolumeEnvelope
257
258
  {
258
259
  voice.finished = true;
259
260
  }
261
+ env.currentReleaseGain = decibelAttenuationToGain(env.releaseStartDb);
260
262
  }
261
263
  }
262
264
 
@@ -291,18 +293,17 @@ export class WorkletVolumeEnvelope
291
293
  return;
292
294
  }
293
295
  let dbDifference = DB_SILENCE - env.releaseStartDb;
294
- let db = 0;
295
296
  for (let i = 0; i < audioBuffer.length; i++)
296
297
  {
297
- db = (elapsedRelease / env.releaseDuration) * dbDifference + env.releaseStartDb;
298
+ let db = (elapsedRelease / env.releaseDuration) * dbDifference + env.releaseStartDb;
298
299
  let gain = decibelAttenuationToGain(db + decibelOffset);
299
300
  env.currentReleaseGain += (gain - env.currentReleaseGain) * releaseSmoothingFactor;
300
301
  audioBuffer[i] *= env.currentReleaseGain;
301
302
  env.currentSampleTime++;
302
303
  elapsedRelease++;
303
304
  }
304
-
305
- if(db >= PERCEIVED_DB_SILENCE)
305
+
306
+ if(env.currentReleaseGain <= PERCEIVED_GAIN_SILENCE)
306
307
  {
307
308
  voice.finished = true;
308
309
  }
@@ -329,6 +330,7 @@ export class WorkletVolumeEnvelope
329
330
  // fallthrough
330
331
 
331
332
  case 1:
333
+ let gain;
332
334
  // attack phase: ramp from 0 to attenuation
333
335
  while(env.currentSampleTime < env.attackEnd)
334
336
  {
@@ -337,11 +339,11 @@ export class WorkletVolumeEnvelope
337
339
 
338
340
  // Special case: linear gain ramp instead of linear db ramp
339
341
  let linearAttenuation = 1 - (env.attackEnd - env.currentSampleTime) / env.attackDuration; // 0 to 1
340
- audioBuffer[filledBuffer] *= linearAttenuation * decibelAttenuationToGain(env.attenuation + decibelOffset)
341
-
342
+ gain = linearAttenuation * decibelAttenuationToGain(env.attenuation + decibelOffset)
343
+ audioBuffer[filledBuffer] *= gain;
342
344
  // set current attenuation to peak as its invalid during this phase
343
345
  env.currentAttenuationDb = env.attenuation;
344
-
346
+
345
347
  env.currentSampleTime++;
346
348
  if(++filledBuffer >= audioBuffer.length)
347
349
  {
@@ -9,7 +9,8 @@
9
9
  */
10
10
  export const interpolationTypes = {
11
11
  linear: 0,
12
- nearestNeighbor: 1
12
+ nearestNeighbor: 1,
13
+ fourthOrder: 2,
13
14
  }
14
15
 
15
16
 
@@ -20,17 +21,17 @@ export const interpolationTypes = {
20
21
  */
21
22
  export function getSampleLinear(voice, outputBuffer)
22
23
  {
23
- let cur = voice.sample.cursor;
24
- const loop = (voice.sample.loopingMode === 1) || (voice.sample.loopingMode === 3 && !voice.isInRelease);
25
- const sampleData = voice.sample.sampleData;
24
+ const sample = voice.sample;
25
+ let cur = sample.cursor;
26
+ const sampleData = sample.sampleData;
26
27
 
27
- if(loop)
28
+ if(sample.isLooping)
28
29
  {
29
- const loopLength = voice.sample.loopEnd - voice.sample.loopStart;
30
+ const loopLength = sample.loopEnd - sample.loopStart;
30
31
  for (let i = 0; i < outputBuffer.length; i++)
31
32
  {
32
33
  // check for loop
33
- while(cur >= voice.sample.loopEnd)
34
+ while(cur >= sample.loopEnd)
34
35
  {
35
36
  cur -= loopLength;
36
37
  }
@@ -39,7 +40,7 @@ export function getSampleLinear(voice, outputBuffer)
39
40
  const floor = ~~cur;
40
41
  let ceil = floor + 1;
41
42
 
42
- while(ceil >= voice.sample.loopEnd)
43
+ while(ceil >= sample.loopEnd)
43
44
  {
44
45
  ceil -= loopLength;
45
46
  }
@@ -51,22 +52,15 @@ export function getSampleLinear(voice, outputBuffer)
51
52
  const lower = sampleData[floor];
52
53
  outputBuffer[i] = (lower + (upper - lower) * fraction);
53
54
 
54
- // commented code because it's probably gonna come handy... (it did like 6 times already :/)
55
- // if(isNaN(outputBuffer[i]))
56
- // {
57
- // console.error(voice, upper, lower, floor, ceil, cur)
58
- // throw "NAN ALERT";
59
- // }
60
-
61
- cur += voice.sample.playbackStep * voice.currentTuningCalculated;
55
+ cur += sample.playbackStep * voice.currentTuningCalculated;
62
56
  }
63
57
  }
64
58
  else
65
59
  {
66
60
  // check and correct end errors
67
- if(voice.sample.end >= sampleData.length)
61
+ if(sample.end >= sampleData.length)
68
62
  {
69
- voice.sample.end = sampleData.length - 1;
63
+ sample.end = sampleData.length - 1;
70
64
  }
71
65
  for (let i = 0; i < outputBuffer.length; i++)
72
66
  {
@@ -76,7 +70,7 @@ export function getSampleLinear(voice, outputBuffer)
76
70
  const ceil = floor + 1;
77
71
 
78
72
  // flag the voice as finished if needed
79
- if(ceil >= voice.sample.end)
73
+ if(ceil >= sample.end)
80
74
  {
81
75
  voice.finished = true;
82
76
  return;
@@ -89,7 +83,7 @@ export function getSampleLinear(voice, outputBuffer)
89
83
  const lower = sampleData[floor];
90
84
  outputBuffer[i] = (lower + (upper - lower) * fraction);
91
85
 
92
- cur += voice.sample.playbackStep * voice.currentTuningCalculated;
86
+ cur += sample.playbackStep * voice.currentTuningCalculated;
93
87
  }
94
88
  }
95
89
  voice.sample.cursor = cur;
@@ -102,16 +96,16 @@ export function getSampleLinear(voice, outputBuffer)
102
96
  */
103
97
  export function getSampleNearest(voice, outputBuffer)
104
98
  {
105
- let cur = voice.sample.cursor;
106
- const loop = (voice.sample.loopingMode === 1) || (voice.sample.loopingMode === 3 && !voice.isInRelease);
107
- const loopLength = voice.sample.loopEnd - voice.sample.loopStart;
108
- const sampleData = voice.sample.sampleData;
109
- if(loop)
99
+ const sample = voice.sample;
100
+ let cur = sample.cursor;
101
+ const loopLength = sample.loopEnd - sample.loopStart;
102
+ const sampleData = sample.sampleData;
103
+ if(voice.sample.isLooping)
110
104
  {
111
105
  for (let i = 0; i < outputBuffer.length; i++)
112
106
  {
113
107
  // check for loop
114
- while(cur >= voice.sample.loopEnd)
108
+ while(cur >= sample.loopEnd)
115
109
  {
116
110
  cur -= loopLength;
117
111
  }
@@ -119,21 +113,21 @@ export function getSampleNearest(voice, outputBuffer)
119
113
  // grab the nearest neighbor
120
114
  let ceil = ~~cur + 1;
121
115
 
122
- while(ceil >= voice.sample.loopEnd)
116
+ while(ceil >= sample.loopEnd)
123
117
  {
124
118
  ceil -= loopLength;
125
119
  }
126
120
 
127
121
  outputBuffer[i] = sampleData[ceil];
128
- cur += voice.sample.playbackStep * voice.currentTuningCalculated;
122
+ cur += sample.playbackStep * voice.currentTuningCalculated;
129
123
  }
130
124
  }
131
125
  else
132
126
  {
133
127
  // check and correct end errors
134
- if(voice.sample.end >= sampleData.length)
128
+ if(sample.end >= sampleData.length)
135
129
  {
136
- voice.sample.end = sampleData.length - 1;
130
+ sample.end = sampleData.length - 1;
137
131
  }
138
132
  for (let i = 0; i < outputBuffer.length; i++)
139
133
  {
@@ -142,7 +136,7 @@ export function getSampleNearest(voice, outputBuffer)
142
136
  const ceil = ~~cur + 1;
143
137
 
144
138
  // flag the voice as finished if needed
145
- if(ceil >= voice.sample.end)
139
+ if(ceil >= sample.end)
146
140
  {
147
141
  voice.finished = true;
148
142
  return;
@@ -150,8 +144,8 @@ export function getSampleNearest(voice, outputBuffer)
150
144
 
151
145
  //nearest neighbor (uncomment to use)
152
146
  outputBuffer[i] = sampleData[ceil];
153
- cur += voice.sample.playbackStep * voice.currentTuningCalculated;
147
+ cur += sample.playbackStep * voice.currentTuningCalculated;
154
148
  }
155
149
  }
156
- voice.sample.cursor = cur;
150
+ sample.cursor = cur;
157
151
  }
@@ -92,7 +92,6 @@ resetArray[midiControllers.expressionController] = 127 << 7;
92
92
  resetArray[midiControllers.pan] = 64 << 7;
93
93
  resetArray[midiControllers.releaseTime] = 64 << 7;
94
94
  resetArray[midiControllers.brightness] = 64 << 7;
95
- resetArray[midiControllers.effects1Depth] = 40 << 7;
96
95
  resetArray[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel] = 8192;
97
96
  resetArray[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange] = 2 << 7;
98
97
 
@@ -35,7 +35,11 @@ class WorkletSample
35
35
  this.loopEnd = loopEnd;
36
36
  this.end = endIndex;
37
37
  this.loopingMode = loopingMode;
38
+ this.isLooping = this.loopingMode === 1 || this.loopingMode === 3
38
39
  }
40
+
41
+
42
+
39
43
  /**
40
44
  * the sample's audio data
41
45
  * @type {Float32Array}
@@ -86,6 +90,13 @@ class WorkletSample
86
90
  * @type {0|1|2}
87
91
  */
88
92
  loopingMode = 0;
93
+
94
+
95
+ /**
96
+ * Indicates if the sample is currently looping
97
+ * @type {boolean}
98
+ */
99
+ isLooping = false;
89
100
  }
90
101
 
91
102
  import { addAndClampGenerator, generatorTypes } from '../../../soundfont/read_sf2/generators.js'
File without changes
package/utils/README.md CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/utils/loggin.js CHANGED
File without changes
package/utils/other.js CHANGED
File without changes