spessasynth_lib 3.25.22 → 3.26.0

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 (168) hide show
  1. package/README.md +29 -114
  2. package/index.js +33 -33
  3. package/package.json +16 -6
  4. package/external_midi/README.md +0 -4
  5. package/external_midi/midi_handler.js +0 -130
  6. package/external_midi/web_midi_link.js +0 -43
  7. package/externals/fflate/LICENSE +0 -21
  8. package/externals/fflate/fflate.min.js +0 -1
  9. package/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
  10. package/externals/stbvorbis_sync/LICENSE +0 -202
  11. package/externals/stbvorbis_sync/NOTICE +0 -6
  12. package/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
  13. package/midi/README.md +0 -32
  14. package/midi/basic_midi.js +0 -565
  15. package/midi/midi_builder.js +0 -202
  16. package/midi/midi_data.js +0 -63
  17. package/midi/midi_loader.js +0 -324
  18. package/midi/midi_message.js +0 -254
  19. package/midi/midi_sequence.js +0 -225
  20. package/midi/midi_tools/get_note_times.js +0 -154
  21. package/midi/midi_tools/midi_editor.js +0 -611
  22. package/midi/midi_tools/midi_writer.js +0 -99
  23. package/midi/midi_tools/rmidi_writer.js +0 -567
  24. package/midi/midi_tools/used_keys_loaded.js +0 -238
  25. package/midi/xmf_loader.js +0 -454
  26. package/sequencer/README.md +0 -32
  27. package/sequencer/sequencer_engine/events.js +0 -207
  28. package/sequencer/sequencer_engine/play.js +0 -353
  29. package/sequencer/sequencer_engine/process_event.js +0 -169
  30. package/sequencer/sequencer_engine/process_tick.js +0 -106
  31. package/sequencer/sequencer_engine/sequencer_engine.js +0 -337
  32. package/sequencer/sequencer_engine/song_control.js +0 -229
  33. package/sequencer/worklet_wrapper/default_sequencer_options.js +0 -8
  34. package/sequencer/worklet_wrapper/sequencer.js +0 -807
  35. package/sequencer/worklet_wrapper/sequencer_message.js +0 -53
  36. package/soundfont/README.md +0 -13
  37. package/soundfont/basic_soundfont/basic_instrument.js +0 -77
  38. package/soundfont/basic_soundfont/basic_preset.js +0 -336
  39. package/soundfont/basic_soundfont/basic_sample.js +0 -197
  40. package/soundfont/basic_soundfont/basic_soundfont.js +0 -565
  41. package/soundfont/basic_soundfont/basic_zone.js +0 -64
  42. package/soundfont/basic_soundfont/basic_zones.js +0 -43
  43. package/soundfont/basic_soundfont/generator.js +0 -220
  44. package/soundfont/basic_soundfont/modulator.js +0 -378
  45. package/soundfont/basic_soundfont/riff_chunk.js +0 -149
  46. package/soundfont/basic_soundfont/write_dls/art2.js +0 -173
  47. package/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
  48. package/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -400
  49. package/soundfont/basic_soundfont/write_dls/ins.js +0 -103
  50. package/soundfont/basic_soundfont/write_dls/lins.js +0 -18
  51. package/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
  52. package/soundfont/basic_soundfont/write_dls/rgn2.js +0 -121
  53. package/soundfont/basic_soundfont/write_dls/wave.js +0 -94
  54. package/soundfont/basic_soundfont/write_dls/write_dls.js +0 -119
  55. package/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
  56. package/soundfont/basic_soundfont/write_dls/wvpl.js +0 -32
  57. package/soundfont/basic_soundfont/write_sf2/ibag.js +0 -39
  58. package/soundfont/basic_soundfont/write_sf2/igen.js +0 -80
  59. package/soundfont/basic_soundfont/write_sf2/imod.js +0 -46
  60. package/soundfont/basic_soundfont/write_sf2/inst.js +0 -34
  61. package/soundfont/basic_soundfont/write_sf2/pbag.js +0 -39
  62. package/soundfont/basic_soundfont/write_sf2/pgen.js +0 -82
  63. package/soundfont/basic_soundfont/write_sf2/phdr.js +0 -42
  64. package/soundfont/basic_soundfont/write_sf2/pmod.js +0 -46
  65. package/soundfont/basic_soundfont/write_sf2/sdta.js +0 -80
  66. package/soundfont/basic_soundfont/write_sf2/shdr.js +0 -55
  67. package/soundfont/basic_soundfont/write_sf2/write.js +0 -222
  68. package/soundfont/dls/articulator_converter.js +0 -396
  69. package/soundfont/dls/dls_destinations.js +0 -38
  70. package/soundfont/dls/dls_preset.js +0 -44
  71. package/soundfont/dls/dls_sample.js +0 -75
  72. package/soundfont/dls/dls_soundfont.js +0 -186
  73. package/soundfont/dls/dls_sources.js +0 -62
  74. package/soundfont/dls/dls_zone.js +0 -95
  75. package/soundfont/dls/read_articulation.js +0 -299
  76. package/soundfont/dls/read_instrument.js +0 -121
  77. package/soundfont/dls/read_instrument_list.js +0 -17
  78. package/soundfont/dls/read_lart.js +0 -35
  79. package/soundfont/dls/read_region.js +0 -152
  80. package/soundfont/dls/read_samples.js +0 -270
  81. package/soundfont/load_soundfont.js +0 -21
  82. package/soundfont/read_sf2/generators.js +0 -46
  83. package/soundfont/read_sf2/instruments.js +0 -66
  84. package/soundfont/read_sf2/modulators.js +0 -36
  85. package/soundfont/read_sf2/presets.js +0 -80
  86. package/soundfont/read_sf2/samples.js +0 -304
  87. package/soundfont/read_sf2/soundfont.js +0 -305
  88. package/soundfont/read_sf2/zones.js +0 -263
  89. package/synthetizer/README.md +0 -10
  90. package/synthetizer/audio_effects/effects_config.js +0 -25
  91. package/synthetizer/audio_effects/fancy_chorus.js +0 -162
  92. package/synthetizer/audio_effects/rb_compressed.min.js +0 -1
  93. package/synthetizer/audio_effects/reverb.js +0 -35
  94. package/synthetizer/audio_effects/reverb_as_binary.js +0 -18
  95. package/synthetizer/audio_engine/README.md +0 -25
  96. package/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -266
  97. package/synthetizer/audio_engine/engine_components/controller_tables.js +0 -88
  98. package/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -149
  99. package/synthetizer/audio_engine/engine_components/lfo.js +0 -26
  100. package/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
  101. package/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -471
  102. package/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
  103. package/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
  104. package/synthetizer/audio_engine/engine_components/soundfont_manager/sfman_message.js +0 -9
  105. package/synthetizer/audio_engine/engine_components/soundfont_manager/soundfont_manager.js +0 -254
  106. package/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -120
  107. package/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
  108. package/synthetizer/audio_engine/engine_components/voice.js +0 -519
  109. package/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -401
  110. package/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -263
  111. package/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -132
  112. package/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -48
  113. package/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -241
  114. package/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -27
  115. package/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -253
  116. package/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -66
  117. package/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
  118. package/synthetizer/audio_engine/engine_methods/note_on.js +0 -174
  119. package/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
  120. package/synthetizer/audio_engine/engine_methods/program_change.js +0 -61
  121. package/synthetizer/audio_engine/engine_methods/render_voice.js +0 -196
  122. package/synthetizer/audio_engine/engine_methods/soundfont_management/clear_sound_font.js +0 -30
  123. package/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -22
  124. package/synthetizer/audio_engine/engine_methods/soundfont_management/reload_sound_font.js +0 -40
  125. package/synthetizer/audio_engine/engine_methods/soundfont_management/send_preset_list.js +0 -34
  126. package/synthetizer/audio_engine/engine_methods/soundfont_management/set_embedded_sound_font.js +0 -21
  127. package/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -20
  128. package/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -55
  129. package/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
  130. package/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
  131. package/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
  132. package/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -744
  133. package/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -24
  134. package/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -33
  135. package/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -31
  136. package/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
  137. package/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -27
  138. package/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
  139. package/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
  140. package/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
  141. package/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
  142. package/synthetizer/audio_engine/main_processor.js +0 -765
  143. package/synthetizer/audio_engine/message_protocol/README.md +0 -13
  144. package/synthetizer/audio_engine/message_protocol/message_sending.js +0 -22
  145. package/synthetizer/audio_engine/message_protocol/worklet_message.js +0 -107
  146. package/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -14
  147. package/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
  148. package/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -122
  149. package/synthetizer/synth_constants.js +0 -20
  150. package/synthetizer/worklet_processor.min.js +0 -21
  151. package/synthetizer/worklet_wrapper/key_modifier_manager.js +0 -104
  152. package/synthetizer/worklet_wrapper/synth_event_handler.js +0 -214
  153. package/synthetizer/worklet_wrapper/synth_soundfont_manager.js +0 -111
  154. package/synthetizer/worklet_wrapper/synthetizer.js +0 -1027
  155. package/synthetizer/worklet_wrapper/worklet_processor.js +0 -340
  156. package/synthetizer/worklet_wrapper/worklet_url.js +0 -16
  157. package/utils/README.md +0 -5
  158. package/utils/buffer_to_wav.js +0 -186
  159. package/utils/byte_functions/big_endian.js +0 -32
  160. package/utils/byte_functions/little_endian.js +0 -77
  161. package/utils/byte_functions/string.js +0 -107
  162. package/utils/byte_functions/variable_length_quantity.js +0 -42
  163. package/utils/fill_with_defaults.js +0 -21
  164. package/utils/indexed_array.js +0 -52
  165. package/utils/loggin.js +0 -79
  166. package/utils/other.js +0 -92
  167. package/utils/sysex_detector.js +0 -58
  168. package/utils/xg_hacks.js +0 -193
@@ -1,35 +0,0 @@
1
- import { reverbBufferBinary } from "./reverb_as_binary.js";
2
-
3
- /**
4
- * Creates a reverb processor
5
- * @param context {BaseAudioContext}
6
- * @param reverbBuffer {AudioBuffer}
7
- * @returns {{conv: ConvolverNode, promise: Promise<AudioBuffer>}}
8
- */
9
- export function getReverbProcessor(context, reverbBuffer = undefined)
10
- {
11
- let solve;
12
- /**
13
- * @type {Promise<AudioBuffer>}
14
- */
15
- let promise = new Promise(r => solve = r);
16
- const convolver = context.createConvolver();
17
- if (reverbBuffer)
18
- {
19
- convolver.buffer = reverbBuffer;
20
- solve();
21
- }
22
- else
23
- {
24
- // decode
25
- promise = context.decodeAudioData(reverbBufferBinary.slice(0));
26
- promise.then(b =>
27
- {
28
- convolver.buffer = b;
29
- });
30
- }
31
- return {
32
- conv: convolver,
33
- promise: promise
34
- };
35
- }
@@ -1,18 +0,0 @@
1
- import { rbCompressed } from "./rb_compressed.min.js";
2
- import { inflateSync } from "../../externals/fflate/fflate.min.js";
3
-
4
- // convert the base64 string to array buffer
5
- const binaryString = atob(rbCompressed);
6
- const binary = new Uint8Array(binaryString.length);
7
- for (let i = 0; i < binaryString.length; i++)
8
- {
9
- binary[i] = binaryString.charCodeAt(i);
10
- }
11
-
12
-
13
- /**
14
- * the reverb is zlib compressed, decompress here
15
- * @type {ArrayBuffer}
16
- */
17
- const reverbBufferBinary = inflateSync(binary).buffer;
18
- export { reverbBufferBinary };
@@ -1,25 +0,0 @@
1
- ## This is the synthesis engine folder.
2
-
3
- The code here is responsible for a single midi channel, synthesizing the sound to it.
4
-
5
- - `engine_methods` contains the methods for the `main_processor.js`
6
- - `engine_components` contains the various digital signal processing functions such as the wavetable oscillator, low
7
- pass filter, etc.
8
-
9
- For those interested, `render_voice.js` file contains the actual DSP synthesis code.
10
-
11
- `minify_processor.js` uses esbuild to minify the processor code. Importing this instead of `worklet_processor.js` is
12
- recommended.
13
-
14
- ## How it works in spessasynth_lib
15
- Both `Synthetizer` and `Sequencer` are essentially "remote control"
16
- for the actual sequencer and synthesizer in the audio worklet thread (here)
17
- These core components are wrapped in the AudioWorkletProcessor, which is receiving both commands and data (MIDIs, sound banks)
18
- through the message port, and sends data back (events, time changes, status changes, etc.).
19
-
20
- For example,
21
- the playback to WebMIDIAPI is actually the sequencer in the worklet thread
22
- playing back the sequence and then postMessaging the commands through the synthesizer to the sequencer
23
- which actually sends them to the specified output.
24
-
25
- The wonders of separate audio thread...
@@ -1,266 +0,0 @@
1
- import { getModulatorCurveValue, MOD_PRECOMPUTED_LENGTH } from "./modulator_curves.js";
2
- import { VolumeEnvelope } from "./volume_envelope.js";
3
- import { ModulationEnvelope } from "./modulation_envelope.js";
4
- import { generatorLimits, generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
5
- import { Modulator, modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
6
- import { NON_CC_INDEX_OFFSET } from "./controller_tables.js";
7
-
8
- /**
9
- * compute_modulator.js
10
- * purpose: precomputes all curve types and computes modulators
11
- */
12
-
13
- const EFFECT_MODULATOR_TRANSFORM_MULTIPLIER = 1000 / 200;
14
-
15
- /**
16
- * Computes a given modulator
17
- * @param controllerTable {Int16Array} all midi controllers as 14bit values + the non-controller indexes, starting at 128
18
- * @param modulator {Modulator} the modulator to compute
19
- * @param voice {Voice} the voice belonging to the modulator
20
- * @returns {number} the computed value
21
- */
22
- export function computeModulator(controllerTable, modulator, voice)
23
- {
24
- if (modulator.transformAmount === 0)
25
- {
26
- modulator.currentValue = 0;
27
- return 0;
28
- }
29
- // mapped to 0-16384
30
- let rawSourceValue;
31
- if (modulator.sourceUsesCC)
32
- {
33
- rawSourceValue = controllerTable[modulator.sourceIndex];
34
- }
35
- else
36
- {
37
- const index = modulator.sourceIndex + NON_CC_INDEX_OFFSET;
38
- switch (modulator.sourceIndex)
39
- {
40
- case modulatorSources.noController:
41
- rawSourceValue = 16383; // equals to 1
42
- break;
43
-
44
- case modulatorSources.noteOnKeyNum:
45
- rawSourceValue = voice.midiNote << 7;
46
- break;
47
-
48
- case modulatorSources.noteOnVelocity:
49
- rawSourceValue = voice.velocity << 7;
50
- break;
51
-
52
- case modulatorSources.polyPressure:
53
- rawSourceValue = voice.pressure << 7;
54
- break;
55
-
56
- default:
57
- rawSourceValue = controllerTable[index]; // pitch bend and range are stored in the cc table
58
- break;
59
- }
60
-
61
- }
62
-
63
- const sourceValue = transforms[modulator.sourceCurveType][modulator.sourcePolarity][modulator.sourceDirection][rawSourceValue];
64
-
65
- // mapped to 0-127
66
- let rawSecondSrcValue;
67
- if (modulator.secSrcUsesCC)
68
- {
69
- rawSecondSrcValue = controllerTable[modulator.secSrcIndex];
70
- }
71
- else
72
- {
73
- const index = modulator.secSrcIndex + NON_CC_INDEX_OFFSET;
74
- switch (modulator.secSrcIndex)
75
- {
76
- case modulatorSources.noController:
77
- rawSecondSrcValue = 16383; // equals to 1
78
- break;
79
-
80
- case modulatorSources.noteOnKeyNum:
81
- rawSecondSrcValue = voice.midiNote << 7;
82
- break;
83
-
84
- case modulatorSources.noteOnVelocity:
85
- rawSecondSrcValue = voice.velocity << 7;
86
- break;
87
-
88
- case modulatorSources.polyPressure:
89
- rawSecondSrcValue = voice.pressure << 7;
90
- break;
91
-
92
- default:
93
- rawSecondSrcValue = controllerTable[index]; // pitch bend and range are stored in the cc table
94
- }
95
-
96
- }
97
- const secondSrcValue = transforms[modulator.secSrcCurveType][modulator.secSrcPolarity][modulator.secSrcDirection][rawSecondSrcValue];
98
-
99
- // see the comment for isEffectModulator (modulator.js in basic_soundfont) for explanation
100
- let transformAmount = modulator.transformAmount;
101
- if (modulator.isEffectModulator && transformAmount <= 1000)
102
- {
103
- transformAmount *= EFFECT_MODULATOR_TRANSFORM_MULTIPLIER;
104
- transformAmount = Math.min(transformAmount, 1000);
105
- }
106
-
107
- // compute the modulator
108
- let computedValue = sourceValue * secondSrcValue * transformAmount;
109
-
110
- if (modulator.transformType === 2)
111
- {
112
- // abs value
113
- computedValue = Math.abs(computedValue);
114
- }
115
-
116
- modulator.currentValue = computedValue;
117
- return computedValue;
118
- }
119
-
120
- /**
121
- * Computes modulators of a given voice. Source and index indicate what modulators shall be computed
122
- * @param voice {Voice} the voice to compute modulators for
123
- * @param controllerTable {Int16Array} all midi controllers as 14bit values + the non-controller indexes, starting at 128
124
- * @param sourceUsesCC {number} what modulators should be computed, -1 means all, 0 means modulator source enum 1 means midi controller
125
- * @param sourceIndex {number} enum for the source
126
- */
127
- export function computeModulators(voice, controllerTable, sourceUsesCC = -1, sourceIndex = 0)
128
- {
129
- const modulators = voice.modulators;
130
- const generators = voice.generators;
131
- const modulatedGenerators = voice.modulatedGenerators;
132
-
133
- if (sourceUsesCC === -1)
134
- {
135
- // All modulators mode: compute all modulators
136
- modulatedGenerators.set(generators);
137
- modulators.forEach(mod =>
138
- {
139
- const limits = generatorLimits[mod.modulatorDestination];
140
- const newValue = modulatedGenerators[mod.modulatorDestination] + computeModulator(
141
- controllerTable,
142
- mod,
143
- voice
144
- );
145
- modulatedGenerators[mod.modulatorDestination] = Math.max(
146
- limits.min,
147
- Math.min(newValue, limits.max)
148
- );
149
- });
150
- VolumeEnvelope.recalculate(voice);
151
- ModulationEnvelope.recalculate(voice);
152
- return;
153
- }
154
-
155
- // Optimized mode: calculate only modulators that use the given source
156
- const volenvNeedsRecalculation = new Set([
157
- generatorTypes.initialAttenuation,
158
- generatorTypes.delayVolEnv,
159
- generatorTypes.attackVolEnv,
160
- generatorTypes.holdVolEnv,
161
- generatorTypes.decayVolEnv,
162
- generatorTypes.sustainVolEnv,
163
- generatorTypes.releaseVolEnv,
164
- generatorTypes.keyNumToVolEnvHold,
165
- generatorTypes.keyNumToVolEnvDecay
166
- ]);
167
-
168
- const computedDestinations = new Set();
169
-
170
- modulators.forEach(mod =>
171
- {
172
- if (
173
- (mod.sourceUsesCC === sourceUsesCC && mod.sourceIndex === sourceIndex) ||
174
- (mod.secSrcUsesCC === sourceUsesCC && mod.secSrcIndex === sourceIndex)
175
- )
176
- {
177
- const destination = mod.modulatorDestination;
178
- if (!computedDestinations.has(destination))
179
- {
180
- // Reset this destination
181
- modulatedGenerators[destination] = generators[destination];
182
- // compute our modulator
183
- computeModulator(controllerTable, mod, voice);
184
- // sum the values of all modulators for this destination
185
- modulators.forEach(m =>
186
- {
187
- if (m.modulatorDestination === destination)
188
- {
189
- const limits = generatorLimits[mod.modulatorDestination];
190
- const newValue = modulatedGenerators[mod.modulatorDestination] + m.currentValue;
191
- modulatedGenerators[mod.modulatorDestination] = Math.max(
192
- limits.min,
193
- Math.min(newValue, limits.max)
194
- );
195
- }
196
- });
197
- computedDestinations.add(destination);
198
- }
199
- }
200
- });
201
-
202
- // Recalculate volume envelope if necessary
203
- if ([...computedDestinations].some(dest => volenvNeedsRecalculation.has(dest)))
204
- {
205
- VolumeEnvelope.recalculate(voice);
206
- }
207
-
208
- ModulationEnvelope.recalculate(voice);
209
- }
210
-
211
-
212
- /**
213
- * as follows: transforms[curveType][polarity][direction] is an array
214
- * @type {Float32Array[][][]}
215
- */
216
- const transforms = [];
217
-
218
- for (let curve = 0; curve < 4; curve++)
219
- {
220
- transforms[curve] =
221
- [
222
- [
223
- new Float32Array(MOD_PRECOMPUTED_LENGTH),
224
- new Float32Array(MOD_PRECOMPUTED_LENGTH)
225
- ],
226
- [
227
- new Float32Array(MOD_PRECOMPUTED_LENGTH),
228
- new Float32Array(MOD_PRECOMPUTED_LENGTH)
229
- ]
230
- ];
231
- for (let i = 0; i < MOD_PRECOMPUTED_LENGTH; i++)
232
- {
233
-
234
- // polarity 0 dir 0
235
- transforms[curve][0][0][i] = getModulatorCurveValue(
236
- 0,
237
- curve,
238
- i / MOD_PRECOMPUTED_LENGTH,
239
- 0
240
- );
241
-
242
- // polarity 1 dir 0
243
- transforms[curve][1][0][i] = getModulatorCurveValue(
244
- 0,
245
- curve,
246
- i / MOD_PRECOMPUTED_LENGTH,
247
- 1
248
- );
249
-
250
- // polarity 0 dir 1
251
- transforms[curve][0][1][i] = getModulatorCurveValue(
252
- 1,
253
- curve,
254
- i / MOD_PRECOMPUTED_LENGTH,
255
- 0
256
- );
257
-
258
- // polarity 1 dir 1
259
- transforms[curve][1][1][i] = getModulatorCurveValue(
260
- 1,
261
- curve,
262
- i / MOD_PRECOMPUTED_LENGTH,
263
- 1
264
- );
265
- }
266
- }
@@ -1,88 +0,0 @@
1
- import { midiControllers } from "../../../midi/midi_message.js";
2
- import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
3
-
4
- /*
5
- * A bit of explanation:
6
- * The controller table is stored as an int16 array, it stores 14-bit values.
7
- * This controller table is then extended with the modulatorSources section,
8
- * for example, pitch range and pitch range depth.
9
- * This allows us for precise control range and supports full pitch-wheel resolution.
10
- */
11
- export const NON_CC_INDEX_OFFSET = 128;
12
- export const CONTROLLER_TABLE_SIZE = 147;
13
-
14
-
15
- // an array with preset default values, so we can quickly use set() to reset the controllers
16
- export const resetArray = new Int16Array(CONTROLLER_TABLE_SIZE).fill(0);
17
- export const setResetValue = (i, v) => resetArray[i] = v << 7;
18
-
19
- // values come from Falcosoft MidiPlayer 6
20
- setResetValue(midiControllers.mainVolume, 100);
21
- setResetValue(midiControllers.balance, 64);
22
- setResetValue(midiControllers.expressionController, 127);
23
- setResetValue(midiControllers.pan, 64);
24
-
25
- setResetValue(midiControllers.portamentoOnOff, 127);
26
-
27
- setResetValue(midiControllers.filterResonance, 64);
28
- setResetValue(midiControllers.releaseTime, 64);
29
- setResetValue(midiControllers.attackTime, 64);
30
- setResetValue(midiControllers.brightness, 64);
31
-
32
- setResetValue(midiControllers.decayTime, 64);
33
- setResetValue(midiControllers.vibratoRate, 64);
34
- setResetValue(midiControllers.vibratoDepth, 64);
35
- setResetValue(midiControllers.vibratoDelay, 64);
36
- setResetValue(midiControllers.generalPurposeController6, 64);
37
- setResetValue(midiControllers.generalPurposeController8, 64);
38
-
39
- setResetValue(midiControllers.RPNLsb, 127);
40
- setResetValue(midiControllers.RPNMsb, 127);
41
- setResetValue(midiControllers.NRPNLsb, 127);
42
- setResetValue(midiControllers.NRPNMsb, 127);
43
-
44
-
45
- export const PORTAMENTO_CONTROL_UNSET = 1;
46
- // special case: portamento control
47
- // since it is only 7-bit, only the values at multiple of 128 are allowed.
48
- // a value of just 1 indicates no key set, hence no portamento.
49
- // this is the "initial unset portamento key" flag.
50
- resetArray[midiControllers.portamentoControl] = PORTAMENTO_CONTROL_UNSET;
51
-
52
- // pitch wheel
53
- setResetValue(NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel, 64);
54
- setResetValue(NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange, 2);
55
-
56
- /**
57
- * @enum {number}
58
- */
59
- export const customControllers = {
60
- channelTuning: 0, // cents, RPN for fine tuning
61
- channelTransposeFine: 1, // cents, only the decimal tuning, (e.g., transpose is 4.5,
62
- // then shift by 4 keys + tune by 50 cents)
63
- modulationMultiplier: 2, // cents, set by modulation depth RPN
64
- masterTuning: 3, // cents, set by system exclusive
65
- channelTuningSemitones: 4 // semitones, for RPN coarse tuning
66
- };
67
- export const CUSTOM_CONTROLLER_TABLE_SIZE = Object.keys(customControllers).length;
68
- export const customResetArray = new Float32Array(CUSTOM_CONTROLLER_TABLE_SIZE);
69
- customResetArray[customControllers.modulationMultiplier] = 1;
70
- /**
71
- * @enum {number}
72
- */
73
- export const dataEntryStates = {
74
- Idle: 0,
75
- RPCoarse: 1,
76
- RPFine: 2,
77
- NRPCoarse: 3,
78
- NRPFine: 4,
79
- DataCoarse: 5,
80
- DataFine: 6
81
- };
82
- /**
83
- * This is a channel configuration enum, it is internally sent from Synthetizer via controller change
84
- * @enum {number}
85
- */
86
- export const channelConfiguration = {
87
- velocityOverride: 128 // overrides velocity for the given channel
88
- };
@@ -1,149 +0,0 @@
1
- /**
2
- * A manager for custom key overrides for channels
3
- */
4
-
5
- export class KeyModifier
6
- {
7
-
8
- /**
9
- * The new override velocity. -1 means unchanged
10
- * @type {number}
11
- */
12
- velocity = -1;
13
- /**
14
- * The patch this key uses. -1 on either means default
15
- * @type {{bank: number, program: number}}
16
- */
17
- patch = { bank: -1, program: -1 };
18
-
19
- /**
20
- * Linear gain override for the voice
21
- */
22
- gain = 1;
23
-
24
- /**
25
- * @param velocity {number}
26
- * @param bank {number}
27
- * @param program {number}
28
- * @param gain {number}
29
- */
30
- constructor(velocity = -1, bank = -1, program = -1, gain = 1)
31
- {
32
- this.velocity = velocity;
33
- this.patch = {
34
- bank: bank,
35
- program: program
36
- };
37
- this.gain = gain;
38
- }
39
- }
40
-
41
- /**
42
- * @enum {number}
43
- */
44
- export const workletKeyModifierMessageType = {
45
- addMapping: 0, // [channel<number>, midiNote<number>, mapping<KeyModifier>]
46
- deleteMapping: 1, // [channel<number>, midiNote<number>]
47
- clearMappings: 2 // <no data>
48
- };
49
-
50
- export class KeyModifierManager
51
- {
52
- /**
53
- * The velocity override mappings for MIDI keys
54
- * @type {KeyModifier[][]}
55
- * @private
56
- */
57
- _keyMappings = [];
58
-
59
- /**
60
- * @param channel {number}
61
- * @param midiNote {number}
62
- * @param mapping {KeyModifier}
63
- */
64
- addMapping(channel, midiNote, mapping)
65
- {
66
- if (this._keyMappings[channel] === undefined)
67
- {
68
- this._keyMappings[channel] = [];
69
- }
70
- this._keyMappings[channel][midiNote] = mapping;
71
- }
72
-
73
- deleteMapping(channel, midiNote)
74
- {
75
- if (this._keyMappings[channel]?.[midiNote] === undefined)
76
- {
77
- return;
78
- }
79
- this._keyMappings[channel][midiNote] = undefined;
80
- }
81
-
82
- clearMappings()
83
- {
84
- this._keyMappings = [];
85
- }
86
-
87
- /**
88
- * @param mappings {KeyModifier[][]}
89
- */
90
- setMappings(mappings)
91
- {
92
- this._keyMappings = mappings;
93
- }
94
-
95
- /**
96
- * @returns {KeyModifier[][]}
97
- */
98
- getMappings()
99
- {
100
- return this._keyMappings;
101
- }
102
-
103
- /**
104
- * @param channel {number}
105
- * @param midiNote {number}
106
- * @returns {number} velocity, -1 if unchanged
107
- */
108
- getVelocity(channel, midiNote)
109
- {
110
- return this._keyMappings[channel]?.[midiNote]?.velocity ?? -1;
111
- }
112
-
113
- /**
114
- * @param channel {number}
115
- * @param midiNote {number}
116
- * @returns {number} linear gain
117
- */
118
- getGain(channel, midiNote)
119
- {
120
- return this._keyMappings[channel]?.[midiNote]?.gain ?? 1;
121
- }
122
-
123
- /**
124
- * @param channel {number}
125
- * @param midiNote {number}
126
- * @returns {boolean}
127
- */
128
- hasOverridePatch(channel, midiNote)
129
- {
130
- const bank = this._keyMappings[channel]?.[midiNote]?.patch?.bank;
131
- return bank !== undefined && bank >= 0;
132
- }
133
-
134
- /**
135
- * @param channel {number}
136
- * @param midiNote {number}
137
- * @returns {{bank: number, program: number}} -1 if unchanged
138
- */
139
- getPatch(channel, midiNote)
140
- {
141
- const modifier = this._keyMappings[channel]?.[midiNote];
142
- if (modifier)
143
- {
144
- return modifier.patch;
145
- }
146
- throw new Error("No modifier.");
147
- }
148
-
149
- }
@@ -1,26 +0,0 @@
1
- /**
2
- * lfo.js
3
- * purpose: low frequency triangel oscillator
4
- */
5
-
6
- /**
7
- * Calculates a triangular wave value for the given time
8
- * @param startTime {number} seconds
9
- * @param frequency {number} Hz
10
- * @param currentTime {number} seconds
11
- * @return {number} the value from -1 to 1
12
- */
13
- export function getLFOValue(startTime, frequency, currentTime)
14
- {
15
- if (currentTime < startTime)
16
- {
17
- return 0;
18
- }
19
-
20
- const xVal = (currentTime - startTime) / (1 / frequency) + 0.25;
21
- // offset by -0.25, otherwise we start at -1 and can have unexpected jump in pitch or low-pass
22
- // (happened with Synth Strings 2)
23
-
24
- // triangle, not sine
25
- return Math.abs(xVal - (~~(xVal + 0.5))) * 4 - 1;
26
- }