spessasynth_core 3.27.8 → 4.0.1

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 (157) hide show
  1. package/README.md +85 -51
  2. package/dist/index.d.ts +4057 -0
  3. package/dist/index.js +17178 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +24 -6
  6. package/index.js +0 -132
  7. package/src/externals/README.md +0 -6
  8. package/src/externals/fflate/LICENSE +0 -21
  9. package/src/externals/fflate/fflate.min.js +0 -1
  10. package/src/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
  11. package/src/externals/stbvorbis_sync/LICENSE +0 -202
  12. package/src/externals/stbvorbis_sync/NOTICE +0 -6
  13. package/src/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
  14. package/src/midi/README.md +0 -32
  15. package/src/midi/basic_midi.js +0 -587
  16. package/src/midi/midi_builder.js +0 -203
  17. package/src/midi/midi_loader.js +0 -321
  18. package/src/midi/midi_message.js +0 -254
  19. package/src/midi/midi_sequence.js +0 -230
  20. package/src/midi/midi_tools/get_note_times.js +0 -154
  21. package/src/midi/midi_tools/midi_editor.js +0 -611
  22. package/src/midi/midi_tools/midi_writer.js +0 -105
  23. package/src/midi/midi_tools/rmidi_writer.js +0 -566
  24. package/src/midi/midi_tools/used_keys_loaded.js +0 -256
  25. package/src/midi/xmf_loader.js +0 -454
  26. package/src/sequencer/README.md +0 -9
  27. package/src/sequencer/events.js +0 -81
  28. package/src/sequencer/play.js +0 -362
  29. package/src/sequencer/process_event.js +0 -165
  30. package/src/sequencer/process_tick.js +0 -104
  31. package/src/sequencer/sequencer_engine.js +0 -372
  32. package/src/sequencer/song_control.js +0 -196
  33. package/src/soundfont/README.md +0 -11
  34. package/src/soundfont/basic_soundfont/basic_global_zone.js +0 -6
  35. package/src/soundfont/basic_soundfont/basic_instrument.js +0 -115
  36. package/src/soundfont/basic_soundfont/basic_instrument_zone.js +0 -45
  37. package/src/soundfont/basic_soundfont/basic_preset.js +0 -313
  38. package/src/soundfont/basic_soundfont/basic_preset_zone.js +0 -39
  39. package/src/soundfont/basic_soundfont/basic_sample.js +0 -477
  40. package/src/soundfont/basic_soundfont/basic_soundbank.js +0 -740
  41. package/src/soundfont/basic_soundfont/basic_zone.js +0 -145
  42. package/src/soundfont/basic_soundfont/generator.js +0 -76
  43. package/src/soundfont/basic_soundfont/generator_types.js +0 -151
  44. package/src/soundfont/basic_soundfont/modulator.js +0 -581
  45. package/src/soundfont/basic_soundfont/riff_chunk.js +0 -195
  46. package/src/soundfont/basic_soundfont/write_dls/art2.js +0 -174
  47. package/src/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
  48. package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -374
  49. package/src/soundfont/basic_soundfont/write_dls/ins.js +0 -85
  50. package/src/soundfont/basic_soundfont/write_dls/lins.js +0 -15
  51. package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
  52. package/src/soundfont/basic_soundfont/write_dls/rgn2.js +0 -120
  53. package/src/soundfont/basic_soundfont/write_dls/wave.js +0 -71
  54. package/src/soundfont/basic_soundfont/write_dls/write_dls.js +0 -124
  55. package/src/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
  56. package/src/soundfont/basic_soundfont/write_dls/wvpl.js +0 -35
  57. package/src/soundfont/basic_soundfont/write_sf2/ibag.js +0 -60
  58. package/src/soundfont/basic_soundfont/write_sf2/igen.js +0 -91
  59. package/src/soundfont/basic_soundfont/write_sf2/imod.js +0 -62
  60. package/src/soundfont/basic_soundfont/write_sf2/inst.js +0 -42
  61. package/src/soundfont/basic_soundfont/write_sf2/pbag.js +0 -57
  62. package/src/soundfont/basic_soundfont/write_sf2/pgen.js +0 -92
  63. package/src/soundfont/basic_soundfont/write_sf2/phdr.js +0 -61
  64. package/src/soundfont/basic_soundfont/write_sf2/pmod.js +0 -62
  65. package/src/soundfont/basic_soundfont/write_sf2/sdta.js +0 -131
  66. package/src/soundfont/basic_soundfont/write_sf2/shdr.js +0 -77
  67. package/src/soundfont/basic_soundfont/write_sf2/write.js +0 -287
  68. package/src/soundfont/dls/articulator_converter.js +0 -402
  69. package/src/soundfont/dls/dls_destinations.js +0 -38
  70. package/src/soundfont/dls/dls_instrument.js +0 -20
  71. package/src/soundfont/dls/dls_preset.js +0 -43
  72. package/src/soundfont/dls/dls_sample.js +0 -238
  73. package/src/soundfont/dls/dls_soundfont.js +0 -183
  74. package/src/soundfont/dls/dls_sources.js +0 -63
  75. package/src/soundfont/dls/dls_zone.js +0 -89
  76. package/src/soundfont/dls/read_articulation.js +0 -300
  77. package/src/soundfont/dls/read_instrument.js +0 -118
  78. package/src/soundfont/dls/read_instrument_list.js +0 -17
  79. package/src/soundfont/dls/read_lart.js +0 -35
  80. package/src/soundfont/dls/read_region.js +0 -157
  81. package/src/soundfont/dls/read_samples.js +0 -154
  82. package/src/soundfont/load_soundfont.js +0 -21
  83. package/src/soundfont/read_sf2/generators.js +0 -43
  84. package/src/soundfont/read_sf2/instrument_zones.js +0 -75
  85. package/src/soundfont/read_sf2/instruments.js +0 -71
  86. package/src/soundfont/read_sf2/modulators.js +0 -25
  87. package/src/soundfont/read_sf2/preset_zones.js +0 -79
  88. package/src/soundfont/read_sf2/presets.js +0 -80
  89. package/src/soundfont/read_sf2/samples.js +0 -317
  90. package/src/soundfont/read_sf2/soundfont.js +0 -452
  91. package/src/soundfont/read_sf2/zones.js +0 -28
  92. package/src/synthetizer/README.md +0 -7
  93. package/src/synthetizer/audio_engine/README.md +0 -9
  94. package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -289
  95. package/src/synthetizer/audio_engine/engine_components/controller_tables.js +0 -90
  96. package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +0 -95
  97. package/src/synthetizer/audio_engine/engine_components/enums.js +0 -18
  98. package/src/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -151
  99. package/src/synthetizer/audio_engine/engine_components/lfo.js +0 -26
  100. package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
  101. package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -551
  102. package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
  103. package/src/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
  104. package/src/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -265
  105. package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -124
  106. package/src/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
  107. package/src/synthetizer/audio_engine/engine_components/voice.js +0 -525
  108. package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -402
  109. package/src/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -274
  110. package/src/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -159
  111. package/src/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -53
  112. package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -254
  113. package/src/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -20
  114. package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +0 -198
  115. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -281
  116. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -109
  117. package/src/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
  118. package/src/synthetizer/audio_engine/engine_methods/note_on.js +0 -220
  119. package/src/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
  120. package/src/synthetizer/audio_engine/engine_methods/program_change.js +0 -35
  121. package/src/synthetizer/audio_engine/engine_methods/render_voice.js +0 -214
  122. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/embedded_sound_bank.js +0 -42
  123. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -0
  124. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/update_preset_list.js +0 -19
  125. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -23
  126. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -56
  127. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
  128. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
  129. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
  130. package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -1058
  131. package/src/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -23
  132. package/src/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -31
  133. package/src/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -29
  134. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
  135. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -26
  136. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
  137. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
  138. package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
  139. package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
  140. package/src/synthetizer/audio_engine/main_processor.js +0 -817
  141. package/src/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -16
  142. package/src/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
  143. package/src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -116
  144. package/src/synthetizer/audio_engine/synth_processor_options.js +0 -18
  145. package/src/synthetizer/synth_constants.js +0 -26
  146. package/src/utils/README.md +0 -8
  147. package/src/utils/buffer_to_wav.js +0 -197
  148. package/src/utils/byte_functions/big_endian.js +0 -32
  149. package/src/utils/byte_functions/little_endian.js +0 -77
  150. package/src/utils/byte_functions/string.js +0 -92
  151. package/src/utils/byte_functions/variable_length_quantity.js +0 -42
  152. package/src/utils/fill_with_defaults.js +0 -21
  153. package/src/utils/indexed_array.js +0 -34
  154. package/src/utils/loggin.js +0 -71
  155. package/src/utils/other.js +0 -92
  156. package/src/utils/sysex_detector.js +0 -58
  157. package/src/utils/xg_hacks.js +0 -193
@@ -1,330 +0,0 @@
1
- import { midiControllers } from "../../../midi/midi_message.js";
2
- import { DLSSources } from "../../dls/dls_sources.js";
3
- import { modulatorCurveTypes, modulatorSources } from "../modulator.js";
4
- import { DLSDestinations } from "../../dls/dls_destinations.js";
5
- import { Articulator } from "./articulator.js";
6
- import { SpessaSynthWarn } from "../../../utils/loggin.js";
7
- import { generatorTypes } from "../generator_types.js";
8
-
9
-
10
- /**
11
- * @param cc {0|1}
12
- * @param index {number}
13
- * @returns {number|undefined}
14
- */
15
- function getDLSSourceFromSf2Source(cc, index)
16
- {
17
- if (cc)
18
- {
19
- switch (index)
20
- {
21
- default:
22
- // DLS supports limited controllers
23
- return undefined;
24
-
25
- case midiControllers.modulationWheel:
26
- return DLSSources.modulationWheel;
27
- case midiControllers.mainVolume:
28
- return DLSSources.volume;
29
- case midiControllers.pan:
30
- return DLSSources.pan;
31
- case midiControllers.expressionController:
32
- return DLSSources.expression;
33
- case midiControllers.chorusDepth:
34
- return DLSSources.chorus;
35
- case midiControllers.reverbDepth:
36
- return DLSSources.reverb;
37
- }
38
- }
39
- else
40
- {
41
- switch (index)
42
- {
43
- default:
44
- // cannot be a DLS articulator
45
- return undefined;
46
-
47
- case modulatorSources.noteOnKeyNum:
48
- return DLSSources.keyNum;
49
- case modulatorSources.noteOnVelocity:
50
- return DLSSources.velocity;
51
- case modulatorSources.noController:
52
- return DLSSources.none;
53
- case modulatorSources.polyPressure:
54
- return DLSSources.polyPressure;
55
- case modulatorSources.channelPressure:
56
- return DLSSources.channelPressure;
57
- case modulatorSources.pitchWheel:
58
- return DLSSources.pitchWheel;
59
- case modulatorSources.pitchWheelRange:
60
- return DLSSources.pitchWheelRange;
61
- }
62
- }
63
- }
64
-
65
- /**
66
- * @param dest {number}
67
- * @param amount {number}
68
- * @returns {number|undefined|{dest: number, amount: number}}
69
- */
70
- function getDLSDestinationFromSf2(dest, amount)
71
- {
72
- switch (dest)
73
- {
74
- default:
75
- return undefined;
76
-
77
- case generatorTypes.initialAttenuation:
78
- // the amount does not get EMU corrected here, as this only applies to modulator attenuation
79
- // the generator (affected) attenuation is handled in wsmp.
80
- return { dest: DLSDestinations.gain, amount: -amount };
81
- case generatorTypes.fineTune:
82
- return DLSDestinations.pitch;
83
- case generatorTypes.pan:
84
- return DLSDestinations.pan;
85
- case generatorTypes.keyNum:
86
- return DLSDestinations.keyNum;
87
-
88
- case generatorTypes.reverbEffectsSend:
89
- return DLSDestinations.reverbSend;
90
- case generatorTypes.chorusEffectsSend:
91
- return DLSDestinations.chorusSend;
92
-
93
- case generatorTypes.freqModLFO:
94
- return DLSDestinations.modLfoFreq;
95
- case generatorTypes.delayModLFO:
96
- return DLSDestinations.modLfoDelay;
97
-
98
- case generatorTypes.delayVibLFO:
99
- return DLSDestinations.vibLfoDelay;
100
- case generatorTypes.freqVibLFO:
101
- return DLSDestinations.vibLfoFreq;
102
-
103
- case generatorTypes.delayVolEnv:
104
- return DLSDestinations.volEnvDelay;
105
- case generatorTypes.attackVolEnv:
106
- return DLSDestinations.volEnvAttack;
107
- case generatorTypes.holdVolEnv:
108
- return DLSDestinations.volEnvHold;
109
- case generatorTypes.decayVolEnv:
110
- return DLSDestinations.volEnvDecay;
111
- case generatorTypes.sustainVolEnv:
112
- return { dest: DLSDestinations.volEnvSustain, amount: 1000 - amount };
113
- case generatorTypes.releaseVolEnv:
114
- return DLSDestinations.volEnvRelease;
115
-
116
- case generatorTypes.delayModEnv:
117
- return DLSDestinations.modEnvDelay;
118
- case generatorTypes.attackModEnv:
119
- return DLSDestinations.modEnvAttack;
120
- case generatorTypes.holdModEnv:
121
- return DLSDestinations.modEnvHold;
122
- case generatorTypes.decayModEnv:
123
- return DLSDestinations.modEnvDecay;
124
- case generatorTypes.sustainModEnv:
125
- return { dest: DLSDestinations.modEnvSustain, amount: 1000 - amount };
126
- case generatorTypes.releaseModEnv:
127
- return DLSDestinations.modEnvRelease;
128
-
129
- case generatorTypes.initialFilterFc:
130
- return DLSDestinations.filterCutoff;
131
- case generatorTypes.initialFilterQ:
132
- return DLSDestinations.filterQ;
133
- }
134
- }
135
-
136
- /**
137
- * @param dest {number}
138
- * @param amt {number}
139
- * @returns {{source: DLSSources, dest: DLSDestinations, amt: number, isBipolar: boolean}|undefined}
140
- */
141
- function checkSF2SpecialCombos(dest, amt)
142
- {
143
-
144
- switch (dest)
145
- {
146
- default:
147
- return undefined;
148
- // mod env
149
- case generatorTypes.modEnvToFilterFc:
150
- return { source: DLSSources.modEnv, dest: DLSDestinations.filterCutoff, amt: amt, isBipolar: false };
151
- case generatorTypes.modEnvToPitch:
152
- return { source: DLSSources.modEnv, dest: DLSDestinations.pitch, amt: amt, isBipolar: false };
153
-
154
- // mod lfo
155
- case generatorTypes.modLfoToFilterFc:
156
- return { source: DLSSources.modLfo, dest: DLSDestinations.filterCutoff, amt: amt, isBipolar: true };
157
- case generatorTypes.modLfoToVolume:
158
- return { source: DLSSources.modLfo, dest: DLSDestinations.gain, amt: amt, isBipolar: true };
159
- case generatorTypes.modLfoToPitch:
160
- return { source: DLSSources.modLfo, dest: DLSDestinations.pitch, amt: amt, isBipolar: true };
161
-
162
- // vib lfo
163
- case generatorTypes.vibLfoToPitch:
164
- return { source: DLSSources.vibratoLfo, dest: DLSDestinations.pitch, amt: amt, isBipolar: true };
165
-
166
- // key to something
167
- case generatorTypes.keyNumToVolEnvHold:
168
- return {
169
- source: DLSSources.keyNum,
170
- dest: DLSDestinations.volEnvHold,
171
- amt: amt,
172
- isBipolar: true
173
- };
174
- case generatorTypes.keyNumToVolEnvDecay:
175
- return {
176
- source: DLSSources.keyNum,
177
- dest: DLSDestinations.volEnvDecay,
178
- amt: amt,
179
- isBipolar: true
180
- };
181
- case generatorTypes.keyNumToModEnvHold:
182
- return {
183
- source: DLSSources.keyNum,
184
- dest: DLSDestinations.modEnvHold,
185
- amt: amt,
186
- isBipolar: true
187
- };
188
- case generatorTypes.keyNumToModEnvDecay:
189
- return {
190
- source: DLSSources.keyNum,
191
- dest: DLSDestinations.modEnvDecay,
192
- amt: amt,
193
- isBipolar: true
194
- };
195
-
196
- // Scale tuning is implemented in DLS via an articulator:
197
- // keyNum to relative pitch at 12,800 cents.
198
- // Change that to scale tuning * 128.
199
- // Therefore, a regular scale is still 12,800, half is 6400, etc.
200
- case generatorTypes.scaleTuning:
201
- return {
202
- source: DLSSources.keyNum,
203
- dest: DLSDestinations.pitch,
204
- amt: amt * 128,
205
- isBipolar: false // according to table 4, this should be false.
206
- };
207
- }
208
- }
209
-
210
- /**
211
- * @param gen {Generator}
212
- * @returns {Articulator|undefined}
213
- */
214
- export function getDLSArticulatorFromSf2Generator(gen)
215
- {
216
- const dest = getDLSDestinationFromSf2(gen.generatorType, gen.generatorValue);
217
- let destination = dest;
218
- let source = 0;
219
- let amount = gen.generatorValue;
220
- if (dest?.amount !== undefined)
221
- {
222
- amount = dest.amount;
223
- destination = dest.dest;
224
- }
225
- // check for special combo
226
- const combo = checkSF2SpecialCombos(gen.generatorType, gen.generatorValue);
227
- if (combo !== undefined)
228
- {
229
- amount = combo.amt;
230
- destination = combo.dest;
231
- source = combo.source;
232
- }
233
- else if (destination === undefined)
234
- {
235
- SpessaSynthWarn(`Invalid generator type: ${gen.generatorType}`);
236
- return undefined;
237
- }
238
- return new Articulator(
239
- source,
240
- 0,
241
- destination,
242
- amount,
243
- 0
244
- );
245
- }
246
-
247
-
248
- /**
249
- * @param mod {Modulator}
250
- * @returns {Articulator|undefined}
251
- */
252
- export function getDLSArticulatorFromSf2Modulator(mod)
253
- {
254
- if (mod.transformType !== 0)
255
- {
256
- SpessaSynthWarn("Other transform types are not supported.");
257
- return undefined;
258
- }
259
- let source = getDLSSourceFromSf2Source(mod.sourceUsesCC, mod.sourceIndex);
260
- let sourceTransformType = mod.sourceCurveType;
261
- let sourceBipolar = mod.sourcePolarity;
262
- let sourceDirection = mod.sourceDirection;
263
- if (source === undefined)
264
- {
265
- SpessaSynthWarn(`Invalid source: ${mod.sourceIndex}, CC: ${mod.sourceUsesCC}`);
266
- return undefined;
267
- }
268
- // Attenuation is the opposite of gain. Invert.
269
- if (mod.modulatorDestination === generatorTypes.initialAttenuation)
270
- {
271
- sourceDirection = sourceDirection === 1 ? 0 : 1;
272
- }
273
- let control = getDLSSourceFromSf2Source(mod.secSrcUsesCC, mod.secSrcIndex);
274
- let controlTransformType = mod.secSrcCurveType;
275
- let controlBipolar = mod.secSrcPolarity;
276
- let controlDirection = mod.secSrcDirection;
277
- if (control === undefined)
278
- {
279
- SpessaSynthWarn(`Invalid secondary source: ${mod.secSrcIndex}, CC: ${mod.secSrcUsesCC}`);
280
- return undefined;
281
- }
282
- let dlsDestinationFromSf2 = getDLSDestinationFromSf2(mod.modulatorDestination, mod.transformAmount);
283
- let destination = dlsDestinationFromSf2;
284
- let amt = mod.transformAmount;
285
- if (dlsDestinationFromSf2?.dest !== undefined)
286
- {
287
- destination = dlsDestinationFromSf2.dest;
288
- amt = dlsDestinationFromSf2.amount;
289
- }
290
- const specialCombo = checkSF2SpecialCombos(mod.modulatorDestination, mod.transformAmount);
291
- if (specialCombo !== undefined)
292
- {
293
- amt = specialCombo.amt;
294
- // move the source to control
295
- control = source;
296
- controlTransformType = sourceTransformType;
297
- controlBipolar = sourceBipolar;
298
- controlDirection = sourceDirection;
299
-
300
- // set source as static as it's either: env, lfo or key num
301
- sourceTransformType = modulatorCurveTypes.linear;
302
- sourceBipolar = specialCombo.isBipolar ? 1 : 0;
303
- sourceDirection = 0;
304
- source = specialCombo.source;
305
- destination = specialCombo.dest;
306
- }
307
- else if (destination === undefined)
308
- {
309
- SpessaSynthWarn(`Invalid destination: ${mod.modulatorDestination}`);
310
- return undefined;
311
- }
312
-
313
- // source curve type maps to a desfont curve type in section 2.10, table 9
314
- let transform = 0;
315
- transform |= controlTransformType << 4;
316
- transform |= controlBipolar << 8;
317
- transform |= controlDirection << 9;
318
-
319
- // use the source curve in output transform
320
- transform |= sourceTransformType;
321
- transform |= sourceBipolar << 14;
322
- transform |= sourceDirection << 15;
323
- return new Articulator(
324
- source,
325
- control,
326
- destination,
327
- amt,
328
- transform
329
- );
330
- }
@@ -1,120 +0,0 @@
1
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
- import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { writeRIFFChunkParts, writeRIFFChunkRaw } from "../riff_chunk.js";
4
- import { writeWavesample } from "./wsmp.js";
5
- import { writeArticulator } from "./art2.js";
6
- import { generatorTypes } from "../generator_types.js";
7
-
8
- /**
9
- * @param zone {BasicInstrumentZone}
10
- * @param globalZone {BasicGlobalZone}
11
- * @this {BasicSoundBank}
12
- * @returns {IndexedByteArray}
13
- */
14
- export function writeDLSRegion(zone, globalZone)
15
- {
16
- // region header
17
- const rgnhData = new IndexedByteArray(12);
18
- // keyRange
19
- writeWord(rgnhData, Math.max(zone.keyRange.min, 0));
20
- writeWord(rgnhData, zone.keyRange.max);
21
- // velRange
22
- writeWord(rgnhData, Math.max(zone.velRange.min, 0));
23
- writeWord(rgnhData, zone.velRange.max);
24
- // fusOptions: 0 it seems
25
- writeWord(rgnhData, 0);
26
- // keyGroup (exclusive class)
27
- const exclusive = zone.getGeneratorValue(generatorTypes.exclusiveClass, 0);
28
- writeWord(rgnhData, exclusive);
29
- // usLayer
30
- writeWord(rgnhData, 0);
31
- const rgnh = writeRIFFChunkRaw(
32
- "rgnh",
33
- rgnhData
34
- );
35
-
36
- let rootKey = zone.getGeneratorValue(generatorTypes.overridingRootKey, zone.sample.samplePitch);
37
-
38
- // a lot of soundfonts like to set scale tuning to 0 in drums and keep the key at 60
39
- // since we implement scale tuning via a dls articulator and fluid doesn't support these,
40
- // change the root key here
41
- const scaleTuning = zone.getGeneratorValue(
42
- generatorTypes.scaleTuning,
43
- globalZone.getGeneratorValue(generatorTypes.scaleTuning, 100)
44
- );
45
- if (scaleTuning === 0 && zone.keyRange.max - zone.keyRange.min === 0)
46
- {
47
- rootKey = zone.keyRange.min;
48
- }
49
-
50
- // wave sample (Wsmp)
51
- const wsmp = writeWavesample(
52
- zone.sample,
53
- rootKey,
54
- zone.getGeneratorValue(
55
- generatorTypes.fineTune,
56
- 0
57
- ) + zone.getGeneratorValue(generatorTypes.coarseTune, 0) * 100
58
- + zone.sample.samplePitchCorrection,
59
- zone.getGeneratorValue(generatorTypes.initialAttenuation, 0),
60
- // calculate loop with offsets
61
- zone.sample.sampleLoopStartIndex
62
- + zone.getGeneratorValue(generatorTypes.startloopAddrsOffset, 0)
63
- + zone.getGeneratorValue(generatorTypes.startloopAddrsCoarseOffset, 0) * 32768,
64
- zone.sample.sampleLoopEndIndex
65
- + zone.getGeneratorValue(generatorTypes.endloopAddrsOffset, 0)
66
- + zone.getGeneratorValue(generatorTypes.endloopAddrsCoarseOffset, 0) * 32768,
67
- zone.getGeneratorValue(generatorTypes.sampleModes, 0)
68
- );
69
-
70
- // wave link (wlnk)
71
- const wlnkData = new IndexedByteArray(12);
72
- writeWord(wlnkData, 0); // fusOptions
73
- writeWord(wlnkData, 0); // usPhaseGroup
74
- // let sampleType = 0;
75
- // switch (zone.sample.sampleType)
76
- // {
77
- // default:
78
- // case 1:
79
- // case 4:
80
- // // mono/left
81
- // sampleType = 0;
82
- // break;
83
- //
84
- // case 2:
85
- // // right
86
- // sampleType = 1;
87
- // }
88
- // 1 means that the first bit is on so mono/left
89
- writeDword(wlnkData, 1); // ulChannel
90
- writeDword(wlnkData, this.samples.indexOf(zone.sample)); // ulTableIndex
91
- const wlnk = writeRIFFChunkRaw(
92
- "wlnk",
93
- wlnkData
94
- );
95
-
96
- // art
97
- let lar2 = new IndexedByteArray(0);
98
- if (zone.modulators.length + zone.generators.length > 0)
99
- {
100
- const art2 = writeArticulator(zone);
101
-
102
- lar2 = writeRIFFChunkRaw(
103
- "lar2",
104
- art2,
105
- false,
106
- true
107
- );
108
- }
109
-
110
- return writeRIFFChunkParts(
111
- "rgn2",
112
- [
113
- rgnh,
114
- wsmp,
115
- wlnk,
116
- lar2
117
- ],
118
- true
119
- );
120
- }
@@ -1,71 +0,0 @@
1
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
- import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { writeRIFFChunkParts, writeRIFFChunkRaw } from "../riff_chunk.js";
4
- import { writeWavesample } from "./wsmp.js";
5
- import { SpessaSynthInfo } from "../../../utils/loggin.js";
6
- import { consoleColors } from "../../../utils/other.js";
7
- import { getStringBytes } from "../../../utils/byte_functions/string.js";
8
-
9
- /**
10
- * @param sample {BasicSample}
11
- * @returns {IndexedByteArray}
12
- */
13
- export function writeDLSSample(sample)
14
- {
15
- const fmtData = new IndexedByteArray(18);
16
- writeWord(fmtData, 1); // wFormatTag
17
- writeWord(fmtData, 1); // wChannels
18
- writeDword(fmtData, sample.sampleRate);
19
- writeDword(fmtData, sample.sampleRate * 2); // 16-bit samples
20
- writeWord(fmtData, 2); // wBlockAlign
21
- writeWord(fmtData, 16); // wBitsPerSample
22
- const fmt = writeRIFFChunkRaw(
23
- "fmt ",
24
- fmtData
25
- );
26
- let loop = 1;
27
- if (sample.sampleLoopStartIndex + Math.abs(sample.getAudioData().length - sample.sampleLoopEndIndex) < 2)
28
- {
29
- loop = 0;
30
- }
31
- const wsmp = writeWavesample(
32
- sample,
33
- sample.samplePitch,
34
- sample.samplePitchCorrection,
35
- 0,
36
- sample.sampleLoopStartIndex,
37
- sample.sampleLoopEndIndex,
38
- loop
39
- );
40
- let data = writeRIFFChunkRaw(
41
- "data",
42
- sample.getRawData(false) // no vorbis allowed
43
- );
44
-
45
- const inam = writeRIFFChunkRaw(
46
- "INAM",
47
- getStringBytes(sample.sampleName, true)
48
- );
49
- const info = writeRIFFChunkRaw(
50
- "INFO",
51
- inam,
52
- false,
53
- true
54
- );
55
- SpessaSynthInfo(
56
- `%cSaved %c${sample.sampleName}%c succesfully!`,
57
- consoleColors.recognized,
58
- consoleColors.value,
59
- consoleColors.recognized
60
- );
61
- return writeRIFFChunkParts(
62
- "wave",
63
- [
64
- fmt,
65
- wsmp,
66
- data,
67
- info
68
- ],
69
- true
70
- );
71
- }
@@ -1,124 +0,0 @@
1
- import { writeRIFFChunkParts, writeRIFFChunkRaw } from "../riff_chunk.js";
2
- import { writeDword } from "../../../utils/byte_functions/little_endian.js";
3
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
4
- import { writeLins } from "./lins.js";
5
- import { getStringBytes } from "../../../utils/byte_functions/string.js";
6
- import { writeWavePool } from "./wvpl.js";
7
- import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from "../../../utils/loggin.js";
8
- import { consoleColors } from "../../../utils/other.js";
9
- import { fillWithDefaults } from "../../../utils/fill_with_defaults.js";
10
-
11
- /**
12
- * @typedef {Object} DLSWriteOptions
13
- * @property {ProgressFunction} progressFunction - a function to show progress for writing large banks. It can be undefined.
14
- */
15
-
16
-
17
- /**
18
- * @type {DLSWriteOptions}
19
- */
20
- const DEFAULT_DLS_OPTIONS = {
21
- progressFunction: undefined
22
- };
23
-
24
- /**
25
- * Write the soundfont as a .dls file. Experimental
26
- * @this {BasicSoundBank}
27
- * @param {Partial<DLSWriteOptions>} options - options for writing the file.
28
- * @returns {Uint8Array}
29
- */
30
- export async function writeDLS(options = DEFAULT_DLS_OPTIONS)
31
- {
32
- options = fillWithDefaults(options, DEFAULT_DLS_OPTIONS);
33
- SpessaSynthGroupCollapsed(
34
- "%cSaving DLS...",
35
- consoleColors.info
36
- );
37
- // write colh
38
- const colhNum = new IndexedByteArray(4);
39
- writeDword(colhNum, this.presets.length);
40
- const colh = writeRIFFChunkRaw(
41
- "colh",
42
- colhNum
43
- );
44
- SpessaSynthGroupCollapsed(
45
- "%cWriting instruments...",
46
- consoleColors.info
47
- );
48
- const lins = writeLins.apply(this);
49
- SpessaSynthInfo(
50
- "%cSuccess!",
51
- consoleColors.recognized
52
- );
53
- SpessaSynthGroupEnd();
54
-
55
- SpessaSynthGroupCollapsed(
56
- "%cWriting WAVE samples...",
57
- consoleColors.info
58
- );
59
- const wavepool = await writeWavePool.call(this, options.progressFunction);
60
- const wvpl = wavepool.data;
61
- const ptblOffsets = wavepool.indexes;
62
- SpessaSynthInfo("%cSucceeded!", consoleColors.recognized);
63
- SpessaSynthGroupEnd();
64
-
65
- // write ptbl
66
- const ptblData = new IndexedByteArray(8 + 4 * ptblOffsets.length);
67
- writeDword(ptblData, 8);
68
- writeDword(ptblData, ptblOffsets.length);
69
- for (const offset of ptblOffsets)
70
- {
71
- writeDword(ptblData, offset);
72
- }
73
- const ptbl = writeRIFFChunkRaw(
74
- "ptbl",
75
- ptblData
76
- );
77
-
78
- this.soundFontInfo["ICMT"] = (this.soundFontInfo["ICMT"] || "Soundfont") + "\nConverted from SF2 to DLS using SpessaSynth";
79
- this.soundFontInfo["ISFT"] = "SpessaSynth";
80
- // write INFO
81
- const infos = [];
82
- for (const [info, data] of Object.entries(this.soundFontInfo))
83
- {
84
- if (
85
- info !== "ICMT" &&
86
- info !== "INAM" &&
87
- info !== "ICRD" &&
88
- info !== "IENG" &&
89
- info !== "ICOP" &&
90
- info !== "ISFT" &&
91
- info !== "ISBJ"
92
- )
93
- {
94
- continue;
95
- }
96
- infos.push(
97
- writeRIFFChunkRaw(
98
- info,
99
- getStringBytes(data, true)
100
- )
101
- );
102
- }
103
- const info = writeRIFFChunkParts(
104
- "INFO",
105
- infos,
106
- true
107
- );
108
- SpessaSynthInfo(
109
- "%cSaved succesfully!",
110
- consoleColors.recognized
111
- );
112
- SpessaSynthGroupEnd();
113
- return writeRIFFChunkParts(
114
- "RIFF",
115
- [
116
- getStringBytes("DLS "),
117
- colh,
118
- lins,
119
- ptbl,
120
- wvpl,
121
- info
122
- ]
123
- );
124
- }