spessasynth_core 3.26.16 → 3.26.18

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 (61) hide show
  1. package/index.js +5 -3
  2. package/package.json +1 -1
  3. package/src/externals/README.md +6 -0
  4. package/src/sequencer/README.md +5 -1
  5. package/src/soundfont/README.md +6 -8
  6. package/src/soundfont/basic_soundfont/basic_global_zone.js +16 -0
  7. package/src/soundfont/basic_soundfont/basic_instrument.js +26 -22
  8. package/src/soundfont/basic_soundfont/basic_instrument_zone.js +35 -0
  9. package/src/soundfont/basic_soundfont/basic_preset.js +45 -42
  10. package/src/soundfont/basic_soundfont/basic_preset_zone.js +30 -0
  11. package/src/soundfont/basic_soundfont/{basic_soundfont.js → basic_soundbank.js} +22 -44
  12. package/src/soundfont/basic_soundfont/basic_zone.js +1 -5
  13. package/src/soundfont/basic_soundfont/generator.js +2 -152
  14. package/src/soundfont/basic_soundfont/generator_types.js +151 -0
  15. package/src/soundfont/basic_soundfont/modulator.js +251 -79
  16. package/src/soundfont/basic_soundfont/write_dls/art2.js +3 -2
  17. package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +25 -42
  18. package/src/soundfont/basic_soundfont/write_dls/ins.js +11 -27
  19. package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +2 -2
  20. package/src/soundfont/basic_soundfont/write_dls/rgn2.js +2 -2
  21. package/src/soundfont/basic_soundfont/write_sf2/ibag.js +21 -10
  22. package/src/soundfont/basic_soundfont/write_sf2/igen.js +31 -27
  23. package/src/soundfont/basic_soundfont/write_sf2/imod.js +24 -14
  24. package/src/soundfont/basic_soundfont/write_sf2/inst.js +4 -5
  25. package/src/soundfont/basic_soundfont/write_sf2/pbag.js +20 -9
  26. package/src/soundfont/basic_soundfont/write_sf2/pgen.js +32 -29
  27. package/src/soundfont/basic_soundfont/write_sf2/phdr.js +4 -2
  28. package/src/soundfont/basic_soundfont/write_sf2/pmod.js +25 -15
  29. package/src/soundfont/basic_soundfont/write_sf2/write.js +2 -2
  30. package/src/soundfont/dls/articulator_converter.js +9 -3
  31. package/src/soundfont/dls/dls_preset.js +2 -3
  32. package/src/soundfont/dls/dls_soundfont.js +1 -1
  33. package/src/soundfont/dls/dls_sources.js +7 -6
  34. package/src/soundfont/dls/dls_zone.js +4 -5
  35. package/src/soundfont/dls/read_articulation.js +2 -1
  36. package/src/soundfont/dls/read_instrument.js +3 -6
  37. package/src/soundfont/dls/read_lart.js +1 -1
  38. package/src/soundfont/dls/read_region.js +2 -1
  39. package/src/soundfont/read_sf2/instruments.js +10 -1
  40. package/src/soundfont/read_sf2/modulators.js +10 -23
  41. package/src/soundfont/read_sf2/presets.js +10 -1
  42. package/src/soundfont/read_sf2/soundfont.js +1 -2
  43. package/src/soundfont/read_sf2/zones.js +30 -14
  44. package/src/synthetizer/README.md +3 -3
  45. package/src/synthetizer/audio_engine/README.md +1 -1
  46. package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +1 -1
  47. package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +11 -3
  48. package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +1 -1
  49. package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +1 -1
  50. package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +1 -1
  51. package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +1 -1
  52. package/src/synthetizer/audio_engine/engine_components/voice.js +7 -10
  53. package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +2 -1
  54. package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +1 -1
  55. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +7 -0
  56. package/src/synthetizer/audio_engine/engine_methods/note_on.js +1 -1
  57. package/src/synthetizer/audio_engine/engine_methods/render_voice.js +1 -1
  58. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +1 -1
  59. package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +2 -1
  60. package/src/utils/README.md +5 -2
  61. package/src/soundfont/basic_soundfont/basic_zones.js +0 -43
@@ -1,11 +1,16 @@
1
- import { generatorTypes, MAX_GENERATOR } from "./generator.js";
2
1
  import { midiControllers } from "../../midi/midi_message.js";
2
+ import { generatorTypes, MAX_GENERATOR } from "./generator_types.js";
3
3
 
4
4
  /**
5
5
  * modulators.js
6
6
  * purpose: parses soundfont modulators and the source enums, also includes the default modulators list
7
7
  **/
8
8
 
9
+ export const MOD_BYTE_SIZE = 10;
10
+
11
+ /**
12
+ * @enum {number}
13
+ */
9
14
  export const modulatorSources = {
10
15
  noController: 0,
11
16
  noteOnVelocity: 2,
@@ -17,6 +22,11 @@ export const modulatorSources = {
17
22
  link: 127
18
23
 
19
24
  };
25
+
26
+ /**
27
+ *
28
+ * @enum {number}
29
+ */
20
30
  export const modulatorCurveTypes = {
21
31
  linear: 0,
22
32
  concave: 1,
@@ -27,23 +37,11 @@ export const modulatorCurveTypes = {
27
37
  export class Modulator
28
38
  {
29
39
  /**
30
- * The current computed value of this modulator
40
+ * The current computed value of this modulator. Only used in the synthesis engine for local voices
31
41
  * @type {number}
32
42
  */
33
43
  currentValue = 0;
34
44
 
35
- /**
36
- * The source enumeration for this modulator
37
- * @type {number}
38
- */
39
- sourceEnum;
40
-
41
- /**
42
- * The secondary source enumeration for this modulator
43
- * @type {number}
44
- */
45
- secondarySourceEnum;
46
-
47
45
  /**
48
46
  * The generator destination of this modulator
49
47
  * @type {generatorTypes}
@@ -63,18 +61,123 @@ export class Modulator
63
61
  transformType;
64
62
 
65
63
  /**
66
- * creates a modulator
67
- * @param srcEnum {number}
68
- * @param secSrcEnum {number}
69
- * @param destination {generatorTypes|number}
64
+ * Indicates if the given modulator is chorus or reverb effects modulator.
65
+ * This is done to simulate BASSMIDI effects behavior:
66
+ * - defaults to 1000 transform amount rather than 200
67
+ * - values can be changed, but anything above 200 is 1000
68
+ * (except for values above 1000, they are copied directly)
69
+ * - all values below are multiplied by 5 (200 * 5 = 1000)
70
+ * - still can be disabled if the soundfont has its own modulator curve
71
+ * - this fixes the very low amount of reverb by default and doesn't break soundfonts
72
+ * @type {boolean}
73
+ */
74
+ isEffectModulator = false;
75
+
76
+ /**
77
+ * 1 if the source is bipolar (min is -1, max is 1)
78
+ * otherwise min is 0 and max is 1
79
+ * @type {0|1}
80
+ */
81
+ sourcePolarity;
82
+
83
+ /**
84
+ * 1 if the source is negative (from 1 to 0)
85
+ * @type {0|1}
86
+ */
87
+ sourceDirection;
88
+
89
+ /**
90
+ * 1 if the source uses a MIDI CC
91
+ * @type {0|1}
92
+ */
93
+ sourceUsesCC;
94
+
95
+ /**
96
+ * source index/CC number
97
+ * @type {modulatorSources|midiControllers}
98
+ */
99
+ sourceIndex;
100
+
101
+ /**
102
+ * source curve type
103
+ * @type {modulatorCurveTypes}
104
+ */
105
+ sourceCurveType;
106
+
107
+ /**
108
+ * 1 if the source is bipolar (min is -1, max is 1)
109
+ * otherwise min is 0 and max is 1
110
+ * @type {0|1}
111
+ */
112
+ secSrcPolarity;
113
+
114
+ /**
115
+ * 1 if the source is negative (from 1 to 0)
116
+ * @type {0|1}
117
+ */
118
+ secSrcDirection;
119
+
120
+ /**
121
+ * 1 if the source uses a MIDI CC
122
+ * @type {0|1}
123
+ */
124
+ secSrcUsesCC;
125
+
126
+ /**
127
+ * source index/CC number
128
+ * @type {modulatorSources|midiControllers}
129
+ */
130
+ secSrcIndex;
131
+
132
+ /**
133
+ * source curve type
134
+ * @type {modulatorCurveTypes}
135
+ */
136
+ secSrcCurveType;
137
+
138
+ /**
139
+ * Creates a new SF2 Modulator
140
+ * @param sourceIndex {modulatorSources|midiControllers}
141
+ * @param sourceCurveType {modulatorCurveTypes}
142
+ * @param sourceUsesCC {0|1}
143
+ * @param sourcePolarity {0|1}
144
+ * @param sourceDirection {0|1}
145
+ * @param secSrcIndex {modulatorSources|midiControllers}
146
+ * @param secSrcCurveType {modulatorCurveTypes}
147
+ * @param secSrcUsesCC {0|1}
148
+ * @param secSrcPolarity {0|1}
149
+ * @param secSrcDirection {0|1}
150
+ * @param destination {generatorTypes}
70
151
  * @param amount {number}
71
- * @param transformType {number}
152
+ * @param transformType {0|2}
72
153
  */
73
- constructor(srcEnum, secSrcEnum, destination, amount, transformType)
154
+ constructor(sourceIndex,
155
+ sourceCurveType,
156
+ sourceUsesCC,
157
+ sourcePolarity,
158
+ sourceDirection,
159
+ secSrcIndex,
160
+ secSrcCurveType,
161
+ secSrcUsesCC,
162
+ secSrcPolarity,
163
+ secSrcDirection,
164
+ destination,
165
+ amount,
166
+ transformType)
74
167
  {
75
- this.sourceEnum = srcEnum;
168
+ this.sourcePolarity = sourcePolarity;
169
+ this.sourceDirection = sourceDirection;
170
+ this.sourceUsesCC = sourceUsesCC;
171
+ this.sourceIndex = sourceIndex;
172
+ this.sourceCurveType = sourceCurveType;
173
+
174
+ this.secSrcPolarity = secSrcPolarity;
175
+ this.secSrcDirection = secSrcDirection;
176
+ this.secSrcUsesCC = secSrcUsesCC;
177
+ this.secSrcIndex = secSrcIndex;
178
+ this.secSrcCurveType = secSrcCurveType;
179
+
76
180
  this.modulatorDestination = destination;
77
- this.secondarySourceEnum = secSrcEnum;
78
181
  this.transformAmount = amount;
79
182
  this.transformType = transformType;
80
183
 
@@ -84,41 +187,6 @@ export class Modulator
84
187
  this.modulatorDestination = generatorTypes.INVALID; // flag as invalid (for linked ones)
85
188
  }
86
189
 
87
- // decode the source
88
- this.sourcePolarity = this.sourceEnum >> 9 & 1;
89
- this.sourceDirection = this.sourceEnum >> 8 & 1;
90
- this.sourceUsesCC = this.sourceEnum >> 7 & 1;
91
- this.sourceIndex = this.sourceEnum & 127;
92
- this.sourceCurveType = this.sourceEnum >> 10 & 3;
93
-
94
- // decode the secondary source
95
- this.secSrcPolarity = this.secondarySourceEnum >> 9 & 1;
96
- this.secSrcDirection = this.secondarySourceEnum >> 8 & 1;
97
- this.secSrcUsesCC = this.secondarySourceEnum >> 7 & 1;
98
- this.secSrcIndex = this.secondarySourceEnum & 127;
99
- this.secSrcCurveType = this.secondarySourceEnum >> 10 & 3;
100
-
101
- /**
102
- * Indicates if the given modulator is chorus or reverb effects modulator.
103
- * This is done to simulate BASSMIDI effects behavior:
104
- * - defaults to 1000 transform amount rather than 200
105
- * - values can be changed, but anything above 200 is 1000
106
- * (except for values above 1000, they are copied directly)
107
- * - all values below are multiplied by 5 (200 * 5 = 1000)
108
- * - still can be disabled if the soundfont has its own modulator curve
109
- * - this fixes the very low amount of reverb by default and doesn't break soundfonts
110
- * @type {boolean}
111
- */
112
- this.isEffectModulator =
113
- (
114
- this.sourceEnum === 0x00DB
115
- || this.sourceEnum === 0x00DD
116
- )
117
- && this.secondarySourceEnum === 0x0
118
- && (
119
- this.modulatorDestination === generatorTypes.reverbEffectsSend
120
- || this.modulatorDestination === generatorTypes.chorusEffectsSend
121
- );
122
190
  }
123
191
 
124
192
  /**
@@ -128,8 +196,16 @@ export class Modulator
128
196
  static copy(modulator)
129
197
  {
130
198
  return new Modulator(
131
- modulator.sourceEnum,
132
- modulator.secondarySourceEnum,
199
+ modulator.sourceIndex,
200
+ modulator.sourceCurveType,
201
+ modulator.sourceUsesCC,
202
+ modulator.sourcePolarity,
203
+ modulator.sourceDirection,
204
+ modulator.secSrcIndex,
205
+ modulator.secSrcCurveType,
206
+ modulator.secSrcUsesCC,
207
+ modulator.secSrcPolarity,
208
+ modulator.secSrcDirection,
133
209
  modulator.modulatorDestination,
134
210
  modulator.transformAmount,
135
211
  modulator.transformType
@@ -144,9 +220,19 @@ export class Modulator
144
220
  */
145
221
  static isIdentical(mod1, mod2, checkAmount = false)
146
222
  {
147
- return (mod1.sourceEnum === mod2.sourceEnum)
223
+ return (mod1.sourceIndex === mod2.sourceIndex)
224
+ && (mod1.sourceUsesCC === mod2.sourceUsesCC)
225
+ && (mod1.sourcePolarity === mod2.sourcePolarity)
226
+ && (mod1.sourceDirection === mod2.sourceDirection)
227
+ && (mod1.sourceCurveType === mod2.sourceCurveType)
228
+
229
+ && (mod1.secSrcIndex === mod2.secSrcIndex)
230
+ && (mod1.secSrcUsesCC === mod2.secSrcUsesCC)
231
+ && (mod1.secSrcPolarity === mod2.secSrcPolarity)
232
+ && (mod1.secSrcDirection === mod2.secSrcDirection)
233
+ && (mod1.secSrcCurveType === mod2.secSrcCurveType)
234
+
148
235
  && (mod1.modulatorDestination === mod2.modulatorDestination)
149
- && (mod1.secondarySourceEnum === mod2.secondarySourceEnum)
150
236
  && (mod1.transformType === mod2.transformType)
151
237
  && (!checkAmount || (mod1.transformAmount === mod2.transformAmount));
152
238
  }
@@ -176,7 +262,7 @@ export class Modulator
176
262
 
177
263
  let secSrcString = getKeyByValue(modulatorCurveTypes, mod.secSrcCurveType);
178
264
  secSrcString += mod.secSrcPolarity === 0 ? " unipolar " : " bipolar ";
179
- secSrcString += mod.secSrcCurveType === 0 ? "forwards " : "backwards ";
265
+ secSrcString += mod.secSrcDirection === 0 ? "forwards " : "backwards ";
180
266
  if (mod.secSrcUsesCC)
181
267
  {
182
268
  secSrcString += getKeyByValue(midiControllers, mod.secSrcIndex);
@@ -194,6 +280,28 @@ export class Modulator
194
280
  \n\n`;
195
281
  }
196
282
 
283
+ getSourceEnum()
284
+ {
285
+ return getModSourceEnum(
286
+ this.sourceCurveType,
287
+ this.sourcePolarity,
288
+ this.sourceDirection,
289
+ this.sourceUsesCC,
290
+ this.sourceIndex
291
+ );
292
+ }
293
+
294
+ getSecSrcEnum()
295
+ {
296
+ return getModSourceEnum(
297
+ this.secSrcCurveType,
298
+ this.secSrcPolarity,
299
+ this.secSrcDirection,
300
+ this.secSrcUsesCC,
301
+ this.secSrcIndex
302
+ );
303
+ }
304
+
197
305
  /**
198
306
  * Sum transform and create a NEW modulator
199
307
  * @param modulator {Modulator}
@@ -202,8 +310,16 @@ export class Modulator
202
310
  sumTransform(modulator)
203
311
  {
204
312
  return new Modulator(
205
- this.sourceEnum,
206
- this.secondarySourceEnum,
313
+ this.sourceIndex,
314
+ this.sourceCurveType,
315
+ this.sourceUsesCC,
316
+ this.sourcePolarity,
317
+ this.sourceDirection,
318
+ this.secSrcIndex,
319
+ this.secSrcCurveType,
320
+ this.secSrcUsesCC,
321
+ this.secSrcPolarity,
322
+ this.secSrcDirection,
207
323
  this.modulatorDestination,
208
324
  this.transformAmount + modulator.transformAmount,
209
325
  this.transformType
@@ -211,6 +327,62 @@ export class Modulator
211
327
  }
212
328
  }
213
329
 
330
+ export class DecodedModulator extends Modulator
331
+ {
332
+ /**
333
+ * reads an SF2 modulator
334
+ * @param sourceEnum {number} SF2 source enum
335
+ * @param secondarySourceEnum {number} SF2 secondary source enum
336
+ * @param destination {generatorTypes|number} destination
337
+ * @param amount {number} amount
338
+ * @param transformType {number} transform type
339
+ */
340
+ constructor(sourceEnum, secondarySourceEnum, destination, amount, transformType)
341
+ {
342
+ // decode the source
343
+ const sourcePolarity = sourceEnum >> 9 & 1;
344
+ const sourceDirection = sourceEnum >> 8 & 1;
345
+ const sourceUsesCC = sourceEnum >> 7 & 1;
346
+ const sourceIndex = /** @type {modulatorSources} **/ sourceEnum & 127;
347
+ const sourceCurveType = /** @type {modulatorCurveTypes} **/ sourceEnum >> 10 & 3;
348
+
349
+ // decode the secondary source
350
+ const secSrcPolarity = secondarySourceEnum >> 9 & 1;
351
+ const secSrcDirection = secondarySourceEnum >> 8 & 1;
352
+ const secSrcUsesCC = secondarySourceEnum >> 7 & 1;
353
+ const secSrcIndex = /** @type {modulatorSources} **/ secondarySourceEnum & 127;
354
+ const secSrcCurveType = /** @type {modulatorCurveTypes} **/ secondarySourceEnum >> 10 & 3;
355
+
356
+ super(
357
+ sourceIndex,
358
+ sourceCurveType,
359
+ sourceUsesCC,
360
+ sourcePolarity,
361
+ sourceDirection,
362
+ secSrcIndex,
363
+ secSrcCurveType,
364
+ secSrcUsesCC,
365
+ secSrcPolarity,
366
+ secSrcDirection,
367
+ destination,
368
+ amount,
369
+ transformType
370
+ );
371
+
372
+
373
+ this.isEffectModulator =
374
+ (
375
+ sourceEnum === 0x00DB
376
+ || sourceEnum === 0x00DD
377
+ )
378
+ && secondarySourceEnum === 0x0
379
+ && (
380
+ this.modulatorDestination === generatorTypes.reverbEffectsSend
381
+ || this.modulatorDestination === generatorTypes.chorusEffectsSend
382
+ );
383
+ }
384
+ }
385
+
214
386
  export const DEFAULT_ATTENUATION_MOD_AMOUNT = 960;
215
387
  export const DEFAULT_ATTENUATION_MOD_CURVE_TYPE = modulatorCurveTypes.concave;
216
388
 
@@ -221,7 +393,7 @@ export function getModSourceEnum(curveType, polarity, direction, isCC, index)
221
393
 
222
394
  const soundFontModulators = [
223
395
  // vel to attenuation
224
- new Modulator(
396
+ new DecodedModulator(
225
397
  getModSourceEnum(
226
398
  DEFAULT_ATTENUATION_MOD_CURVE_TYPE,
227
399
  0,
@@ -236,10 +408,10 @@ const soundFontModulators = [
236
408
  ),
237
409
 
238
410
  // mod wheel to vibrato
239
- new Modulator(0x0081, 0x0, generatorTypes.vibLfoToPitch, 50, 0),
411
+ new DecodedModulator(0x0081, 0x0, generatorTypes.vibLfoToPitch, 50, 0),
240
412
 
241
413
  // vol to attenuation
242
- new Modulator(
414
+ new DecodedModulator(
243
415
  getModSourceEnum(
244
416
  DEFAULT_ATTENUATION_MOD_CURVE_TYPE,
245
417
  0,
@@ -254,17 +426,17 @@ const soundFontModulators = [
254
426
  ),
255
427
 
256
428
  // channel pressure to vibrato
257
- new Modulator(0x000D, 0x0, generatorTypes.vibLfoToPitch, 50, 0),
429
+ new DecodedModulator(0x000D, 0x0, generatorTypes.vibLfoToPitch, 50, 0),
258
430
 
259
431
  // pitch wheel to tuning
260
- new Modulator(0x020E, 0x0010, generatorTypes.fineTune, 12700, 0),
432
+ new DecodedModulator(0x020E, 0x0010, generatorTypes.fineTune, 12700, 0),
261
433
 
262
434
  // pan to uhh, pan
263
435
  // amount is 500 instead of 1000, see #59
264
- new Modulator(0x028A, 0x0, generatorTypes.pan, 500, 0),
436
+ new DecodedModulator(0x028A, 0x0, generatorTypes.pan, 500, 0),
265
437
 
266
438
  // expression to attenuation
267
- new Modulator(
439
+ new DecodedModulator(
268
440
  getModSourceEnum(
269
441
  DEFAULT_ATTENUATION_MOD_CURVE_TYPE,
270
442
  0,
@@ -279,16 +451,16 @@ const soundFontModulators = [
279
451
  ),
280
452
 
281
453
  // reverb effects to send
282
- new Modulator(0x00DB, 0x0, generatorTypes.reverbEffectsSend, 200, 0),
454
+ new DecodedModulator(0x00DB, 0x0, generatorTypes.reverbEffectsSend, 200, 0),
283
455
 
284
456
  // chorus effects to send
285
- new Modulator(0x00DD, 0x0, generatorTypes.chorusEffectsSend, 200, 0)
457
+ new DecodedModulator(0x00DD, 0x0, generatorTypes.chorusEffectsSend, 200, 0)
286
458
  ];
287
459
 
288
460
  const customModulators = [
289
461
  // custom modulators heck yeah
290
462
  // poly pressure to vibrato
291
- new Modulator(
463
+ new DecodedModulator(
292
464
  getModSourceEnum(modulatorCurveTypes.linear, 0, 0, 0, modulatorSources.polyPressure),
293
465
  0x0,
294
466
  generatorTypes.vibLfoToPitch,
@@ -297,7 +469,7 @@ const customModulators = [
297
469
  ),
298
470
 
299
471
  // cc 92 (tremolo) to modLFO volume
300
- new Modulator(
472
+ new DecodedModulator(
301
473
  getModSourceEnum(
302
474
  modulatorCurveTypes.linear,
303
475
  0,
@@ -312,7 +484,7 @@ const customModulators = [
312
484
  ),
313
485
 
314
486
  // cc 73 (attack time) to volEnv attack
315
- new Modulator(
487
+ new DecodedModulator(
316
488
  getModSourceEnum(
317
489
  modulatorCurveTypes.convex,
318
490
  1,
@@ -327,7 +499,7 @@ const customModulators = [
327
499
  ),
328
500
 
329
501
  // cc 72 (release time) to volEnv release
330
- new Modulator(
502
+ new DecodedModulator(
331
503
  getModSourceEnum(
332
504
  modulatorCurveTypes.linear,
333
505
  1,
@@ -342,7 +514,7 @@ const customModulators = [
342
514
  ),
343
515
 
344
516
  // cc 74 (brightness) to filterFc
345
- new Modulator(
517
+ new DecodedModulator(
346
518
  getModSourceEnum(
347
519
  modulatorCurveTypes.linear,
348
520
  1,
@@ -357,7 +529,7 @@ const customModulators = [
357
529
  ),
358
530
 
359
531
  // cc 71 (filter Q) to filter Q
360
- new Modulator(
532
+ new DecodedModulator(
361
533
  getModSourceEnum(
362
534
  modulatorCurveTypes.linear,
363
535
  1,
@@ -1,7 +1,7 @@
1
1
  import { getDLSArticulatorFromSf2Generator, getDLSArticulatorFromSf2Modulator } from "./modulator_converter.js";
2
2
  import { writeRIFFOddSize } from "../riff_chunk.js";
3
3
  import { combineArrays, IndexedByteArray } from "../../../utils/indexed_array.js";
4
- import { Generator, generatorTypes } from "../generator.js";
4
+ import { Generator } from "../generator.js";
5
5
  import { writeDword } from "../../../utils/byte_functions/little_endian.js";
6
6
  import { consoleColors } from "../../../utils/other.js";
7
7
  import { SpessaSynthInfo, SpessaSynthWarn } from "../../../utils/loggin.js";
@@ -12,6 +12,7 @@ import {
12
12
  DLS_1_NO_VIBRATO_MOD,
13
13
  DLS_1_NO_VIBRATO_PRESSURE
14
14
  } from "../../dls/dls_sources.js";
15
+ import { generatorTypes } from "../generator_types.js";
15
16
 
16
17
  const invalidGeneratorTypes = new Set([
17
18
  generatorTypes.sampleModes,
@@ -34,7 +35,7 @@ const invalidGeneratorTypes = new Set([
34
35
  ]);
35
36
 
36
37
  /**
37
- * @param zone {BasicInstrumentZone}
38
+ * @param zone {BasicZone}
38
39
  * @returns {IndexedByteArray}
39
40
  */
40
41
  export function writeArticulator(zone)
@@ -1,6 +1,8 @@
1
1
  import { Modulator } from "../modulator.js";
2
- import { BasicInstrumentZone } from "../basic_zones.js";
3
- import { Generator, generatorLimits, generatorTypes } from "../generator.js";
2
+ import { Generator } from "../generator.js";
3
+ import { generatorLimits, generatorTypes } from "../generator_types.js";
4
+ import { BasicInstrumentZone } from "../basic_instrument_zone.js";
5
+ import { BasicGlobalZone } from "../basic_global_zone.js";
4
6
 
5
7
  const notGlobalizedTypes = new Set([
6
8
  generatorTypes.velRange,
@@ -30,7 +32,7 @@ const notGlobalizedTypes = new Set([
30
32
  * Combines preset zones
31
33
  * @param preset {BasicPreset}
32
34
  * @param globalize {boolean}
33
- * @returns {BasicInstrumentZone[]}
35
+ * @returns {{global: BasicGlobalZone, zones: BasicInstrumentZone[]}}
34
36
  */
35
37
  export function combineZones(preset, globalize = true)
36
38
  {
@@ -75,25 +77,16 @@ export function combineZones(preset, globalize = true)
75
77
  * @type {Modulator[]}
76
78
  */
77
79
  const globalPresetModulators = [];
78
- let globalPresetKeyRange = { min: 0, max: 127 };
79
- let globalPresetVelRange = { min: 0, max: 127 };
80
80
 
81
81
  // find the global zone and apply ranges, generators, and modulators
82
- const globalPresetZone = preset.presetZones.find(z => z.isGlobal);
83
- if (globalPresetZone)
84
- {
85
- globalPresetGenerators.push(...globalPresetZone.generators);
86
- globalPresetModulators.push(...globalPresetZone.modulators);
87
- globalPresetKeyRange = globalPresetZone.keyRange;
88
- globalPresetVelRange = globalPresetZone.velRange;
89
- }
82
+ const globalPresetZone = preset.globalZone;
83
+ globalPresetGenerators.push(...globalPresetZone.generators);
84
+ globalPresetModulators.push(...globalPresetZone.modulators);
85
+ let globalPresetKeyRange = globalPresetZone.keyRange;
86
+ let globalPresetVelRange = globalPresetZone.velRange;
90
87
  // for each non-global preset zone
91
88
  for (const presetZone of preset.presetZones)
92
89
  {
93
- if (presetZone.isGlobal)
94
- {
95
- continue;
96
- }
97
90
  // use global ranges if not provided
98
91
  let presetZoneKeyRange = presetZone.keyRange;
99
92
  if (!presetZone.hasKeyRange)
@@ -110,8 +103,8 @@ export function combineZones(preset, globalize = true)
110
103
  addUnique(presetGenerators, globalPresetGenerators);
111
104
  const presetModulators = [...presetZone.modulators];
112
105
  addUniqueMods(presetModulators, globalPresetModulators);
113
-
114
- const iZones = presetZone.instrument.instrumentZones;
106
+ const instrument = presetZone.instrument;
107
+ const iZones = instrument.instrumentZones;
115
108
  /**
116
109
  * @type {Generator[]}
117
110
  */
@@ -120,23 +113,14 @@ export function combineZones(preset, globalize = true)
120
113
  * @type {Modulator[]}
121
114
  */
122
115
  const globalInstModulators = [];
123
- let globalInstKeyRange = { min: 0, max: 127 };
124
- let globalInstVelRange = { min: 0, max: 127 };
125
- const globalInstZone = iZones.find(z => z.isGlobal);
126
- if (globalInstZone)
127
- {
128
- globalInstGenerators.push(...globalInstZone.generators);
129
- globalInstModulators.push(...globalInstZone.modulators);
130
- globalInstKeyRange = globalInstZone.keyRange;
131
- globalInstVelRange = globalInstZone.velRange;
132
- }
116
+ const globalInstZone = instrument.globalZone;
117
+ globalInstGenerators.push(...globalInstZone.generators);
118
+ globalInstModulators.push(...globalInstZone.modulators);
119
+ let globalInstKeyRange = globalInstZone.keyRange;
120
+ let globalInstVelRange = globalInstZone.velRange;
133
121
  // for each non-global instrument zone
134
122
  for (const instZone of iZones)
135
123
  {
136
- if (instZone.isGlobal)
137
- {
138
- continue;
139
- }
140
124
  // use global ranges if not provided
141
125
  let instZoneKeyRange = instZone.keyRange;
142
126
  if (!instZone.hasKeyRange)
@@ -236,20 +220,17 @@ export function combineZones(preset, globalize = true)
236
220
  {
237
221
  zone.velRange.min = -1;
238
222
  }
239
- zone.isGlobal = false;
240
- zone.sample = instZone.sample;
223
+ zone.setSample(instZone.sample);
241
224
  zone.generators = finalGenList;
242
225
  zone.modulators = finalModList;
243
226
  finalZones.push(zone);
244
227
  }
245
228
  }
246
-
229
+ const globalZone = new BasicGlobalZone();
247
230
  if (globalize)
248
231
  {
249
232
  // create a global zone and add repeating generators to it
250
233
  // also modulators
251
- const globalZone = new BasicInstrumentZone();
252
- globalZone.isGlobal = true;
253
234
  // iterate over every type of generator
254
235
  for (let checkedType = 0; checkedType < 58; checkedType++)
255
236
  {
@@ -356,14 +337,14 @@ export function combineZones(preset, globalize = true)
356
337
  }
357
338
 
358
339
  // globalize only modulators that exist in all zones
359
- const firstZone = finalZones.find(z => !z.isGlobal);
340
+ const firstZone = finalZones[0];
360
341
  const modulators = firstZone.modulators.map(m => Modulator.copy(m));
361
342
  for (const checkedModulator of modulators)
362
343
  {
363
344
  let existsForAllZones = true;
364
345
  for (const zone of finalZones)
365
346
  {
366
- if (zone.isGlobal || !existsForAllZones)
347
+ if (!existsForAllZones)
367
348
  {
368
349
  continue;
369
350
  }
@@ -394,7 +375,9 @@ export function combineZones(preset, globalize = true)
394
375
  }
395
376
  }
396
377
  }
397
- finalZones.splice(0, 0, globalZone);
398
378
  }
399
- return finalZones;
379
+ return {
380
+ zones: finalZones,
381
+ global: globalZone
382
+ };
400
383
  }