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,300 +0,0 @@
1
- import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
2
- import { DLSDestinations } from "./dls_destinations.js";
3
- import { DLS_1_NO_VIBRATO_MOD, DLS_1_NO_VIBRATO_PRESSURE, DLSSources } from "./dls_sources.js";
4
- import { getSF2ModulatorFromArticulator } from "./articulator_converter.js";
5
- import { SpessaSynthInfo, SpessaSynthWarn } from "../../utils/loggin.js";
6
- import { consoleColors } from "../../utils/other.js";
7
- import { Generator } from "../basic_soundfont/generator.js";
8
- import { Modulator } from "../basic_soundfont/modulator.js";
9
- import { generatorTypes } from "../basic_soundfont/generator_types.js";
10
-
11
-
12
- /**
13
- * Reads the articulator chunk
14
- * @param chunk {RiffChunk}
15
- * @param disableVibrato {boolean} it seems that dls 1 does not have vibrato lfo, so we shall disable it
16
- * @returns {{modulators: Modulator[], generators: Generator[]}}
17
- */
18
- export function readArticulation(chunk, disableVibrato)
19
- {
20
- const artData = chunk.chunkData;
21
- /**
22
- * @type {Generator[]}
23
- */
24
- const generators = [];
25
- /**
26
- * @type {Modulator[]}
27
- */
28
- const modulators = [];
29
-
30
- // cbSize (ignore)
31
- readLittleEndian(artData, 4);
32
- const connectionsAmount = readLittleEndian(artData, 4);
33
- for (let i = 0; i < connectionsAmount; i++)
34
- {
35
- // read the block
36
- const source = readLittleEndian(artData, 2);
37
- const control = readLittleEndian(artData, 2);
38
- const destination = readLittleEndian(artData, 2);
39
- const transform = readLittleEndian(artData, 2);
40
- const scale = readLittleEndian(artData, 4) | 0;
41
- const value = scale >> 16; // convert it to 16 bit as soundfont uses that
42
-
43
- // modulatorConverterDebug(
44
- // source,
45
- // control,
46
- // destination,
47
- // value,
48
- // transform
49
- // );
50
-
51
- // interpret this somehow...
52
- // if source and control are both zero, it's a generator
53
- if (source === 0 && control === 0 && transform === 0)
54
- {
55
- /**
56
- * @type {Generator}
57
- */
58
- let generator;
59
- switch (destination)
60
- {
61
- case DLSDestinations.pan:
62
- generator = new Generator(generatorTypes.pan, value); // turn percent into tenths of percent
63
- break;
64
- case DLSDestinations.gain:
65
- generator = new Generator(generatorTypes.initialAttenuation, -value * 10 / 0.4); // turn to centibels and apply emu correction
66
- break;
67
- case DLSDestinations.filterCutoff:
68
- generator = new Generator(generatorTypes.initialFilterFc, value);
69
- break;
70
- case DLSDestinations.filterQ:
71
- generator = new Generator(generatorTypes.initialFilterQ, value);
72
- break;
73
-
74
- // mod lfo raw values it seems
75
- case DLSDestinations.modLfoFreq:
76
- generator = new Generator(generatorTypes.freqModLFO, value);
77
- break;
78
- case DLSDestinations.modLfoDelay:
79
- generator = new Generator(generatorTypes.delayModLFO, value);
80
- break;
81
- case DLSDestinations.vibLfoFreq:
82
- generator = new Generator(generatorTypes.freqVibLFO, value);
83
- break;
84
- case DLSDestinations.vibLfoDelay:
85
- generator = new Generator(generatorTypes.delayVibLFO, value);
86
- break;
87
-
88
- // vol. env: all times are timecents like sf2
89
- case DLSDestinations.volEnvDelay:
90
- generator = new Generator(generatorTypes.delayVolEnv, value);
91
- break;
92
- case DLSDestinations.volEnvAttack:
93
- generator = new Generator(generatorTypes.attackVolEnv, value);
94
- break;
95
- case DLSDestinations.volEnvHold:
96
- // do not validate because keyNumToSomething
97
- generator = new Generator(generatorTypes.holdVolEnv, value, false);
98
- break;
99
- case DLSDestinations.volEnvDecay:
100
- // do not validate because keyNumToSomething
101
- generator = new Generator(generatorTypes.decayVolEnv, value, false);
102
- break;
103
- case DLSDestinations.volEnvRelease:
104
- generator = new Generator(generatorTypes.releaseVolEnv, value);
105
- break;
106
- case DLSDestinations.volEnvSustain:
107
- // gain seems to be (1000 - value) / 10 = sustain dB
108
- const sustainCb = 1000 - value;
109
- generator = new Generator(generatorTypes.sustainVolEnv, sustainCb);
110
- break;
111
-
112
- // mod env
113
- case DLSDestinations.modEnvDelay:
114
- generator = new Generator(generatorTypes.delayModEnv, value);
115
- break;
116
- case DLSDestinations.modEnvAttack:
117
- generator = new Generator(generatorTypes.attackModEnv, value);
118
- break;
119
- case DLSDestinations.modEnvHold:
120
- // do not validate because keyNumToSomething
121
- generator = new Generator(generatorTypes.holdModEnv, value, false);
122
- break;
123
- case DLSDestinations.modEnvDecay:
124
- // do not validate because keyNumToSomething
125
- generator = new Generator(generatorTypes.decayModEnv, value, false);
126
- break;
127
- case DLSDestinations.modEnvRelease:
128
- generator = new Generator(generatorTypes.releaseModEnv, value);
129
- break;
130
- case DLSDestinations.modEnvSustain:
131
- // dls uses 1%, desfont uses 0.1%
132
- const percentageSustain = 1000 - value;
133
- generator = new Generator(generatorTypes.sustainModEnv, percentageSustain);
134
- break;
135
-
136
- case DLSDestinations.reverbSend:
137
- generator = new Generator(generatorTypes.reverbEffectsSend, value);
138
- break;
139
- case DLSDestinations.chorusSend:
140
- generator = new Generator(generatorTypes.chorusEffectsSend, value);
141
- break;
142
- case DLSDestinations.pitch:
143
- // split it up
144
- const semi = Math.floor(value / 100);
145
- const cents = Math.floor(value - semi * 100);
146
- generator = new Generator(generatorTypes.fineTune, cents);
147
- generators.push(new Generator(generatorTypes.coarseTune, semi));
148
- break;
149
- }
150
- if (generator)
151
- {
152
- generators.push(generator);
153
- }
154
- }
155
- else
156
- // if not, modulator?
157
- {
158
- let isGenerator = true;
159
-
160
- const applyKeyToCorrection = (value, keyToGen, realGen) =>
161
- {
162
- // according to viena and another strange (with modulators) rendition of gm.dls in sf2,
163
- // it shall be divided by -128
164
- // and a strange correction needs to be applied to the real value:
165
- // real + (60 / 128) * scale
166
- const keyToGenValue = value / -128;
167
- generators.push(new Generator(keyToGen, keyToGenValue));
168
- // airfont 340 fix
169
- if (keyToGenValue <= 120)
170
- {
171
- const correction = Math.round((60 / 128) * value);
172
- generators.forEach(g =>
173
- {
174
- if (g.generatorType === realGen)
175
- {
176
- g.generatorValue += correction;
177
- }
178
- });
179
- }
180
- };
181
-
182
- // a few special cases which are generators:
183
- if (control === DLSSources.none)
184
- {
185
- // mod lfo to pitch
186
- if (source === DLSSources.modLfo && destination === DLSDestinations.pitch)
187
- {
188
- generators.push(new Generator(generatorTypes.modLfoToPitch, value));
189
- }
190
- else
191
- // mod lfo to volume
192
- if (source === DLSSources.modLfo && destination === DLSDestinations.gain)
193
- {
194
- generators.push(new Generator(generatorTypes.modLfoToVolume, value));
195
- }
196
- else
197
- // mod lfo to filter
198
- if (source === DLSSources.modLfo && destination === DLSDestinations.filterCutoff)
199
- {
200
- generators.push(new Generator(generatorTypes.modLfoToFilterFc, value));
201
- }
202
- else
203
- // vib lfo to pitch
204
- if (source === DLSSources.vibratoLfo && destination === DLSDestinations.pitch)
205
- {
206
- generators.push(new Generator(generatorTypes.vibLfoToPitch, value));
207
- }
208
- else
209
- // mod env to pitch
210
- if (source === DLSSources.modEnv && destination === DLSDestinations.pitch)
211
- {
212
- generators.push(new Generator(generatorTypes.modEnvToPitch, value));
213
- }
214
- else
215
- // mod env to filter
216
- if (source === DLSSources.modEnv && destination === DLSDestinations.filterCutoff)
217
- {
218
- generators.push(new Generator(generatorTypes.modEnvToFilterFc, value));
219
- }
220
- else
221
- // scale tuning (key number to pitch)
222
- if (source === DLSSources.keyNum && destination === DLSDestinations.pitch)
223
- {
224
- // this is just a soundfont generator, but the amount must be changed
225
- // 12,800 means the regular scale (100)
226
- generators.push(new Generator(generatorTypes.scaleTuning, value / 128));
227
- }
228
- else
229
- // key to vol env hold
230
- if (source === DLSSources.keyNum && destination === DLSDestinations.volEnvHold)
231
- {
232
- applyKeyToCorrection(value, generatorTypes.keyNumToVolEnvHold, generatorTypes.holdVolEnv);
233
- }
234
- else
235
- // key to vol env decay
236
- if (source === DLSSources.keyNum && destination === DLSDestinations.volEnvDecay)
237
- {
238
- applyKeyToCorrection(value, generatorTypes.keyNumToVolEnvDecay, generatorTypes.decayVolEnv);
239
- }
240
- else
241
- // key to mod env hold
242
- if (source === DLSSources.keyNum && destination === DLSDestinations.modEnvHold)
243
- {
244
- applyKeyToCorrection(value, generatorTypes.keyNumToModEnvHold, generatorTypes.holdModEnv);
245
- }
246
- else
247
- // key to mod env decay
248
- if (source === DLSSources.keyNum && destination === DLSDestinations.modEnvDecay)
249
- {
250
- applyKeyToCorrection(value, generatorTypes.keyNumToModEnvDecay, generatorTypes.decayModEnv);
251
- }
252
- else
253
- {
254
- isGenerator = false;
255
- }
256
-
257
- }
258
- else
259
- {
260
- isGenerator = false;
261
- }
262
- if (isGenerator === false)
263
- {
264
- // UNCOMMENT TO ENABLE DEBUG
265
- // modulatorConverterDebug(source, control, destination, value, transform)
266
- // convert it to modulator
267
- const mod = getSF2ModulatorFromArticulator(
268
- source,
269
- control,
270
- destination,
271
- transform,
272
- value
273
- );
274
- if (mod)
275
- {
276
- // some articulators cannot be turned into modulators, that's why this check is a thing
277
- modulators.push(mod);
278
- SpessaSynthInfo("%cSucceeded converting to SF2 Modulator!", consoleColors.recognized);
279
- }
280
- else
281
- {
282
- SpessaSynthWarn("Failed converting to SF2 Modulator!");
283
- }
284
- }
285
- }
286
- }
287
-
288
- // it seems that dls 1 does not have vibrato lfo, so we shall disable it
289
- if (disableVibrato)
290
- {
291
- modulators.push(
292
- // mod to vib
293
- Modulator.copy(DLS_1_NO_VIBRATO_MOD),
294
- // press to vib
295
- Modulator.copy(DLS_1_NO_VIBRATO_PRESSURE)
296
- );
297
- }
298
-
299
- return { modulators: modulators, generators: generators };
300
- }
@@ -1,118 +0,0 @@
1
- import { readBytesAsString } from "../../utils/byte_functions/string.js";
2
- import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
3
- import { DLSPreset } from "./dls_preset.js";
4
- import { findRIFFListType, readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
5
- import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd } from "../../utils/loggin.js";
6
- import { consoleColors } from "../../utils/other.js";
7
- import { Modulator } from "../basic_soundfont/modulator.js";
8
- import { DEFAULT_DLS_CHORUS, DEFAULT_DLS_REVERB } from "./dls_sources.js";
9
- import { generatorLimits, generatorTypes } from "../basic_soundfont/generator_types.js";
10
- import { readRegion } from "./read_region.js";
11
-
12
- /**
13
- * @this {DLSSoundFont}
14
- * @param chunk {RiffChunk}
15
- */
16
- export function readDLSInstrument(chunk)
17
- {
18
- this.verifyHeader(chunk, "LIST");
19
- this.verifyText(readBytesAsString(chunk.chunkData, 4), "ins ");
20
- /**
21
- * @type {RiffChunk[]}
22
- */
23
- const chunks = [];
24
- while (chunk.chunkData.length > chunk.chunkData.currentIndex)
25
- {
26
- chunks.push(readRIFFChunk(chunk.chunkData));
27
- }
28
-
29
-
30
- const instrumentHeader = chunks.find(c => c.header === "insh");
31
- if (!instrumentHeader)
32
- {
33
- SpessaSynthGroupEnd();
34
- throw new Error("No instrument header!");
35
- }
36
-
37
- // read instrument header
38
- const regions = readLittleEndian(instrumentHeader.chunkData, 4);
39
- const ulBank = readLittleEndian(instrumentHeader.chunkData, 4);
40
- const ulInstrument = readLittleEndian(instrumentHeader.chunkData, 4);
41
- const preset = new DLSPreset(this, ulBank, ulInstrument);
42
-
43
- // read preset name in INFO
44
- let presetName = ``;
45
- const infoChunk = findRIFFListType(chunks, "INFO");
46
- if (infoChunk)
47
- {
48
- let info = readRIFFChunk(infoChunk.chunkData);
49
- while (info.header !== "INAM")
50
- {
51
- info = readRIFFChunk(infoChunk.chunkData);
52
- }
53
- presetName = readBytesAsString(info.chunkData, info.chunkData.length).trim();
54
- }
55
- if (presetName.length < 1)
56
- {
57
- presetName = `unnamed ${(ulBank >> 8) & 127}:${ulInstrument & 127}`;
58
- }
59
- preset.presetName = presetName;
60
- preset.dlsInstrument.instrumentName = presetName;
61
- SpessaSynthGroupCollapsed(
62
- `%cParsing %c"${presetName}"%c...`,
63
- consoleColors.info,
64
- consoleColors.recognized,
65
- consoleColors.info
66
- );
67
-
68
- // list of regions
69
- const regionListChunk = findRIFFListType(chunks, "lrgn");
70
- if (!regionListChunk)
71
- {
72
- SpessaSynthGroupEnd();
73
- throw new Error("No region list!");
74
- }
75
-
76
- // global articulation: essentially global zone
77
- const globalZone = preset.dlsInstrument.globalZone;
78
-
79
- // read articulators
80
- const globalLart = findRIFFListType(chunks, "lart");
81
- const globalLar2 = findRIFFListType(chunks, "lar2");
82
- if (globalLar2 !== undefined || globalLart !== undefined)
83
- {
84
- this.readLart(globalLart, globalLar2, globalZone);
85
- }
86
- // remove generators with default values
87
- globalZone.generators = globalZone.generators.filter(g => g.generatorValue !== generatorLimits[g.generatorType].def);
88
- // override reverb and chorus with 1000 instead of 200 (if not override)
89
- // reverb
90
- if (globalZone.modulators.find(m => m.modulatorDestination === generatorTypes.reverbEffectsSend) === undefined)
91
- {
92
- globalZone.addModulators(Modulator.copy(DEFAULT_DLS_REVERB));
93
- }
94
- // chorus
95
- if (globalZone.modulators.find(m => m.modulatorDestination === generatorTypes.chorusEffectsSend) === undefined)
96
- {
97
- globalZone.addModulators(Modulator.copy(DEFAULT_DLS_CHORUS));
98
- }
99
-
100
- // read regions
101
- for (let i = 0; i < regions; i++)
102
- {
103
- const chunk = readRIFFChunk(regionListChunk.chunkData);
104
- this.verifyHeader(chunk, "LIST");
105
- const type = readBytesAsString(chunk.chunkData, 4);
106
- if (type !== "rgn " && type !== "rgn2")
107
- {
108
- SpessaSynthGroupEnd();
109
- this.parsingError(`Invalid DLS region! Expected "rgn " or "rgn2" got "${type}"`);
110
- }
111
-
112
-
113
- readRegion.call(this, chunk, preset.dlsInstrument);
114
- }
115
- this.addPresets(preset);
116
- this.addInstruments(preset.dlsInstrument);
117
- SpessaSynthGroupEnd();
118
- }
@@ -1,17 +0,0 @@
1
- import { readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
2
- import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd } from "../../utils/loggin.js";
3
- import { consoleColors } from "../../utils/other.js";
4
-
5
- /**
6
- * @this {DLSSoundFont}
7
- * @param instrumentListChunk {RiffChunk}
8
- */
9
- export function readDLSInstrumentList(instrumentListChunk)
10
- {
11
- SpessaSynthGroupCollapsed("%cLoading instruments...", consoleColors.info);
12
- for (let i = 0; i < this.instrumentAmount; i++)
13
- {
14
- this.readDLSInstrument(readRIFFChunk(instrumentListChunk.chunkData));
15
- }
16
- SpessaSynthGroupEnd();
17
- }
@@ -1,35 +0,0 @@
1
- import { readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
2
- import { readArticulation } from "./read_articulation.js";
3
-
4
- /**
5
- * @param lartChunk {RiffChunk|undefined}
6
- * @param lar2Chunk {RiffChunk|undefined}
7
- * @param zone {BasicZone}
8
- * @this {DLSSoundFont}
9
- */
10
- export function readLart(lartChunk, lar2Chunk, zone)
11
- {
12
- if (lartChunk)
13
- {
14
- while (lartChunk.chunkData.currentIndex < lartChunk.chunkData.length)
15
- {
16
- const art1 = readRIFFChunk(lartChunk.chunkData);
17
- this.verifyHeader(art1, "art1", "art2");
18
- const modsAndGens = readArticulation(art1, true);
19
- zone.addGenerators(...modsAndGens.generators);
20
- zone.addModulators(...modsAndGens.modulators);
21
- }
22
- }
23
-
24
- if (lar2Chunk)
25
- {
26
- while (lar2Chunk.chunkData.currentIndex < lar2Chunk.chunkData.length)
27
- {
28
- const art2 = readRIFFChunk(lar2Chunk.chunkData);
29
- this.verifyHeader(art2, "art2", "art1");
30
- const modsAndGens = readArticulation(art2, false);
31
- zone.addGenerators(...modsAndGens.generators);
32
- zone.addModulators(...modsAndGens.modulators);
33
- }
34
- }
35
- }
@@ -1,157 +0,0 @@
1
- import { readLittleEndian, signedInt16 } from "../../utils/byte_functions/little_endian.js";
2
- import { findRIFFListType, readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
3
- import { Generator } from "../basic_soundfont/generator.js";
4
- import { generatorTypes } from "../basic_soundfont/generator_types.js";
5
- import { SpessaSynthWarn } from "../../utils/loggin.js";
6
-
7
- /**
8
- * @this {DLSSoundFont}
9
- * @param chunk {RiffChunk}
10
- * @param instrument {DLSInstrument}
11
- */
12
- export function readRegion(chunk, instrument)
13
- {
14
- // regions are essentially instrument zones
15
-
16
- /**
17
- * read chunks in the region
18
- * @type {RiffChunk[]}
19
- */
20
- const regionChunks = [];
21
- while (chunk.chunkData.length > chunk.chunkData.currentIndex)
22
- {
23
- regionChunks.push(readRIFFChunk(chunk.chunkData));
24
- }
25
-
26
- // region header
27
- const regionHeader = regionChunks.find(c => c.header === "rgnh");
28
-
29
- if (!regionHeader)
30
- {
31
- SpessaSynthWarn("Invalid DLS region: missing 'rgnh' chunk! Discarding...");
32
- return;
33
- }
34
- // key range
35
- let keyMin = readLittleEndian(regionHeader.chunkData, 2);
36
- let keyMax = readLittleEndian(regionHeader.chunkData, 2);
37
- // vel range
38
- let velMin = readLittleEndian(regionHeader.chunkData, 2);
39
- let velMax = readLittleEndian(regionHeader.chunkData, 2);
40
-
41
- // a fix for not cool files
42
- if (velMin === 0 && velMax === 0)
43
- {
44
- velMax = 127;
45
- velMin = 0;
46
- }
47
- // cannot do the same to key zones sadly
48
- // create zone
49
- const zone = instrument.createZone();
50
- // apply ranges
51
- zone.keyRange = { min: keyMin, max: keyMax };
52
- zone.velRange = { min: velMin, max: velMax };
53
-
54
- // fusOptions: no idea about that one???
55
- readLittleEndian(regionHeader.chunkData, 2);
56
-
57
- // keyGroup: essentially exclusive class
58
- const exclusive = readLittleEndian(regionHeader.chunkData, 2);
59
- if (exclusive !== 0)
60
- {
61
- zone.addGenerators(new Generator(generatorTypes.exclusiveClass, exclusive));
62
- }
63
-
64
- // lart
65
- const lart = findRIFFListType(regionChunks, "lart");
66
- const lar2 = findRIFFListType(regionChunks, "lar2");
67
- this.readLart(lart, lar2, zone);
68
-
69
- // wsmp: wave sample chunk
70
- const waveSampleChunk = regionChunks.find(c => c.header === "wsmp");
71
- // cbSize
72
- readLittleEndian(waveSampleChunk.chunkData, 4);
73
- let originalKey = readLittleEndian(waveSampleChunk.chunkData, 2);
74
-
75
- // sFineTune
76
- let pitchCorrection = signedInt16(
77
- waveSampleChunk.chunkData[waveSampleChunk.chunkData.currentIndex++],
78
- waveSampleChunk.chunkData[waveSampleChunk.chunkData.currentIndex++]
79
- );
80
-
81
- // gain correction: Each unit of gain represents 1/655360 dB
82
- // it is set after linking the sample
83
- const gainCorrection = readLittleEndian(waveSampleChunk.chunkData, 4);
84
- // convert to signed and turn into attenuation (invert)
85
- const dbCorrection = (gainCorrection | 0) / -655360;
86
-
87
- // skip options
88
- readLittleEndian(waveSampleChunk.chunkData, 4);
89
-
90
- // read loop count (always one or zero)
91
- const loopsAmount = readLittleEndian(waveSampleChunk.chunkData, 4);
92
- let loopingMode;
93
- const loop = { start: 0, end: 0 };
94
- if (loopsAmount === 0)
95
- {
96
- // no loop
97
- loopingMode = 0;
98
- }
99
- else
100
- {
101
- // ignore cbSize
102
- readLittleEndian(waveSampleChunk.chunkData, 4);
103
- // loop type: loop normally or loop until release (like soundfont)
104
- const loopType = readLittleEndian(waveSampleChunk.chunkData, 4); // why is it long?
105
- if (loopType === 0)
106
- {
107
- loopingMode = 1;
108
- }
109
- else
110
- {
111
- loopingMode = 3;
112
- }
113
- loop.start = readLittleEndian(waveSampleChunk.chunkData, 4);
114
- const loopLength = readLittleEndian(waveSampleChunk.chunkData, 4);
115
- loop.end = loop.start + loopLength;
116
- }
117
-
118
- // wave link
119
- const waveLinkChunk = regionChunks.find(c => c.header === "wlnk");
120
- if (waveLinkChunk === undefined)
121
- {
122
- // No wave link means no sample. What? Why is it even here then?
123
- return undefined;
124
- }
125
-
126
- // flags
127
- readLittleEndian(waveLinkChunk.chunkData, 2);
128
- // phase group
129
- readLittleEndian(waveLinkChunk.chunkData, 2);
130
- // channel
131
- readLittleEndian(waveLinkChunk.chunkData, 4);
132
- // sampleID
133
- const sampleID = readLittleEndian(waveLinkChunk.chunkData, 4);
134
- // noinspection JSValidateTypes
135
- /**
136
- * @type {DLSSample}
137
- */
138
- const sample = this.samples[sampleID];
139
- if (sample === undefined)
140
- {
141
- throw new Error("Invalid sample ID!");
142
- }
143
-
144
- // this correction overrides the sample gain correction
145
- const actualDbCorrection = dbCorrection || sample.sampleDbAttenuation;
146
- // convert to centibels
147
- const attenuation = (actualDbCorrection * 10) / 0.4; // make sure to apply EMU correction
148
-
149
- zone.setWavesample(
150
- attenuation, loopingMode,
151
- loop,
152
- originalKey,
153
- sample,
154
- sampleID,
155
- pitchCorrection
156
- );
157
- }