spessasynth_core 3.26.17 → 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 (60) 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 +217 -65
  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 +22 -19
  22. package/src/soundfont/basic_soundfont/write_sf2/igen.js +29 -25
  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 +21 -18
  26. package/src/soundfont/basic_soundfont/write_sf2/pgen.js +30 -27
  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/dls/articulator_converter.js +9 -3
  30. package/src/soundfont/dls/dls_preset.js +2 -3
  31. package/src/soundfont/dls/dls_soundfont.js +1 -1
  32. package/src/soundfont/dls/dls_sources.js +7 -6
  33. package/src/soundfont/dls/dls_zone.js +4 -5
  34. package/src/soundfont/dls/read_articulation.js +2 -1
  35. package/src/soundfont/dls/read_instrument.js +3 -6
  36. package/src/soundfont/dls/read_lart.js +1 -1
  37. package/src/soundfont/dls/read_region.js +2 -1
  38. package/src/soundfont/read_sf2/instruments.js +10 -1
  39. package/src/soundfont/read_sf2/modulators.js +10 -23
  40. package/src/soundfont/read_sf2/presets.js +10 -1
  41. package/src/soundfont/read_sf2/soundfont.js +1 -2
  42. package/src/soundfont/read_sf2/zones.js +30 -14
  43. package/src/synthetizer/README.md +3 -3
  44. package/src/synthetizer/audio_engine/README.md +1 -1
  45. package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +1 -1
  46. package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +11 -3
  47. package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +1 -1
  48. package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +1 -1
  49. package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +1 -1
  50. package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +1 -1
  51. package/src/synthetizer/audio_engine/engine_components/voice.js +7 -10
  52. package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +2 -1
  53. package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +1 -1
  54. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +7 -0
  55. package/src/synthetizer/audio_engine/engine_methods/note_on.js +1 -1
  56. package/src/synthetizer/audio_engine/engine_methods/render_voice.js +1 -1
  57. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +1 -1
  58. package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +2 -1
  59. package/src/utils/README.md +5 -2
  60. package/src/soundfont/basic_soundfont/basic_zones.js +0 -43
@@ -2,6 +2,8 @@ import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeWord } from "../../../utils/byte_functions/little_endian.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
+ const BAG_SIZE = 4;
6
+
5
7
  /**
6
8
  * @this {BasicSoundBank}
7
9
  * @returns {IndexedByteArray}
@@ -9,36 +11,37 @@ import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
9
11
  export function getIBAG()
10
12
  {
11
13
  // write all ibag with their start indexes as they were changed in getIGEN() and getIMOD()
12
- const ibagsize = this.instruments.reduce((sum, i) => i.instrumentZones.length * 4 + sum, 4);
14
+ const ibagsize = this.instruments.reduce(
15
+ (sum, i) =>
16
+ // +1 because global zone
17
+ (i.instrumentZones.length + 1) * BAG_SIZE + sum,
18
+ BAG_SIZE
19
+ );
13
20
  const ibagdata = new IndexedByteArray(ibagsize);
14
- let zoneID = 0;
15
21
  let generatorIndex = 0;
16
22
  let modulatorIndex = 0;
23
+ /**
24
+ * @param z {BasicZone}
25
+ */
26
+ const writeZone = z =>
27
+ {
28
+ writeWord(ibagdata, generatorIndex);
29
+ writeWord(ibagdata, modulatorIndex);
30
+ generatorIndex += z.generators.length;
31
+ modulatorIndex += z.modulators.length;
32
+ };
33
+
17
34
  for (const inst of this.instruments)
18
35
  {
19
- // ensure that the first zone is global
20
- const zones = inst.instrumentZones.filter(z => !z.isGlobal);
21
- const global = inst.instrumentZones.filter(z => z.isGlobal);
22
- // only take the first one
23
- if (global?.[0])
36
+ writeZone(inst.globalZone);
37
+ for (const ibag of inst.instrumentZones)
24
38
  {
25
- zones.unshift(global?.[0]);
26
- }
27
- inst.instrumentZoneIndex = zoneID;
28
- for (const ibag of zones)
29
- {
30
- ibag.zoneID = zoneID;
31
- writeWord(ibagdata, generatorIndex);
32
- writeWord(ibagdata, modulatorIndex);
33
- generatorIndex += ibag.generators.length;
34
- modulatorIndex += ibag.modulators.length;
35
- zoneID++;
39
+ writeZone(ibag);
36
40
  }
37
41
  }
38
42
  // write the terminal IBAG
39
43
  writeWord(ibagdata, generatorIndex);
40
44
  writeWord(ibagdata, modulatorIndex);
41
-
42
45
  return writeRIFFChunk(new RiffChunk(
43
46
  "ibag",
44
47
  ibagdata.length,
@@ -1,8 +1,8 @@
1
1
  import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
2
2
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
-
5
- import { Generator, generatorTypes } from "../generator.js";
4
+ import { GEN_BYTE_SIZE, Generator } from "../generator.js";
5
+ import { generatorTypes } from "../generator_types.js";
6
6
 
7
7
  /**
8
8
  * @this {BasicSoundBank}
@@ -11,9 +11,10 @@ import { Generator, generatorTypes } from "../generator.js";
11
11
  export function getIGEN()
12
12
  {
13
13
  // go through all instruments -> zones and write generators sequentially (add 4 for terminal)
14
- let igensize = 4;
14
+ let igensize = GEN_BYTE_SIZE;
15
15
  for (const inst of this.instruments)
16
16
  {
17
+ igensize += inst.globalZone.generators.length * GEN_BYTE_SIZE;
17
18
  igensize += inst.instrumentZones.reduce((sum, z) =>
18
19
  {
19
20
  // clear sample and range generators before determining the size
@@ -23,7 +24,7 @@ export function getIGEN()
23
24
  g.generatorType !== generatorTypes.velRange
24
25
  );
25
26
  // add sample and ranges if necessary
26
- // unshift vel then key (to make key first) and the instrument is last
27
+ // unshift vel then key (to make key first) and the sample is last
27
28
  if (z.hasVelRange)
28
29
  {
29
30
  z.generators.unshift(new Generator(
@@ -40,38 +41,41 @@ export function getIGEN()
40
41
  false
41
42
  ));
42
43
  }
43
- if (!z.isGlobal)
44
- {
45
- // write sample
46
- z.generators.push(new Generator(
47
- generatorTypes.sampleID,
48
- this.samples.indexOf(z.sample),
49
- false
50
- ));
51
- }
52
- return z.generators.length * 4 + sum;
44
+ // add sample id
45
+ z.generators.push(new Generator(
46
+ generatorTypes.sampleID,
47
+ this.samples.indexOf(z.sample),
48
+ false
49
+ ));
50
+ return z.generators.length * GEN_BYTE_SIZE + sum;
53
51
  }, 0);
54
52
  }
55
53
  const igendata = new IndexedByteArray(igensize);
56
- let igenIndex = 0;
54
+
55
+ /**
56
+ * @param z {BasicZone}
57
+ */
58
+ const writeZone = z =>
59
+ {
60
+ for (const gen of z.generators)
61
+ {
62
+ // name is deceptive, it works on negatives
63
+ writeWord(igendata, gen.generatorType);
64
+ writeWord(igendata, gen.generatorValue);
65
+ }
66
+ };
67
+
57
68
  for (const instrument of this.instruments)
58
69
  {
70
+ // global zone
71
+ writeZone(instrument.globalZone);
59
72
  for (const instrumentZone of instrument.instrumentZones)
60
73
  {
61
- // set the start index here
62
- instrumentZone.generatorZoneStartIndex = igenIndex;
63
- for (const gen of instrumentZone.generators)
64
- {
65
- // name is deceptive, it works on negatives
66
- writeWord(igendata, gen.generatorType);
67
- writeWord(igendata, gen.generatorValue);
68
- igenIndex++;
69
- }
74
+ writeZone(instrumentZone);
70
75
  }
71
76
  }
72
77
  // terminal generator, is zero
73
78
  writeDword(igendata, 0);
74
-
75
79
  return writeRIFFChunk(new RiffChunk(
76
80
  "igen",
77
81
  igendata.length,
@@ -1,6 +1,7 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeLittleEndian, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
+ import { MOD_BYTE_SIZE } from "../modulator.js";
4
5
 
5
6
  /**
6
7
  * @this {BasicSoundBank}
@@ -10,28 +11,37 @@ export function getIMOD()
10
11
  {
11
12
  // very similar to igen,
12
13
  // go through all instruments -> zones and write modulators sequentially
13
- let imodsize = 10;
14
+ let imodsize = MOD_BYTE_SIZE; // terminal
14
15
  for (const inst of this.instruments)
15
16
  {
17
+ imodsize += inst.globalZone.modulators.length * MOD_BYTE_SIZE;
18
+ // start with one mod for global
16
19
  imodsize += inst.instrumentZones.reduce((sum, z) => z.modulators.length * 10 + sum, 0);
17
20
  }
18
21
  const imoddata = new IndexedByteArray(imodsize);
19
- let imodIndex = 0;
22
+
23
+ /**
24
+ * @param z {BasicZone}
25
+ */
26
+ const writeZone = z =>
27
+ {
28
+ for (const mod of z.modulators)
29
+ {
30
+ writeWord(imoddata, mod.getSourceEnum());
31
+ writeWord(imoddata, mod.modulatorDestination);
32
+ writeWord(imoddata, mod.transformAmount);
33
+ writeWord(imoddata, mod.getSecSrcEnum());
34
+ writeWord(imoddata, mod.transformType);
35
+ }
36
+ };
37
+
20
38
  for (const inst of this.instruments)
21
39
  {
22
- for (const ibag of inst.instrumentZones)
40
+ // global
41
+ writeZone(inst.globalZone);
42
+ for (const instrumentZone of inst.instrumentZones)
23
43
  {
24
- // set the start index here
25
- ibag.modulatorZoneStartIndex = imodIndex;
26
- for (const mod of ibag.modulators)
27
- {
28
- writeWord(imoddata, mod.getSourceEnum());
29
- writeWord(imoddata, mod.modulatorDestination);
30
- writeWord(imoddata, mod.transformAmount);
31
- writeWord(imoddata, mod.getSecSrcEnum());
32
- writeWord(imoddata, mod.transformType);
33
- imodIndex++;
34
- }
44
+ writeZone(instrumentZone);
35
45
  }
36
46
  }
37
47
 
@@ -3,24 +3,23 @@ import { writeStringAsBytes } from "../../../utils/byte_functions/string.js";
3
3
  import { writeWord } from "../../../utils/byte_functions/little_endian.js";
4
4
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
5
5
 
6
+ const INST_SIZE = 22;
7
+
6
8
  /**
7
9
  * @this {BasicSoundBank}
8
10
  * @returns {IndexedByteArray}
9
11
  */
10
12
  export function getINST()
11
13
  {
12
- const instsize = this.instruments.length * 22 + 22;
14
+ const instsize = this.instruments.length * INST_SIZE + INST_SIZE;
13
15
  const instdata = new IndexedByteArray(instsize);
14
16
  // the instrument start index is adjusted in ibag, write it here
15
17
  let instrumentStart = 0;
16
- let instrumentID = 0;
17
18
  for (const inst of this.instruments)
18
19
  {
19
20
  writeStringAsBytes(instdata, inst.instrumentName, 20);
20
21
  writeWord(instdata, instrumentStart);
21
- instrumentStart += inst.instrumentZones.length;
22
- inst.instrumentID = instrumentID;
23
- instrumentID++;
22
+ instrumentStart += inst.instrumentZones.length + 1; // global
24
23
  }
25
24
  // write EOI
26
25
  writeStringAsBytes(instdata, "EOI", 20);
@@ -2,6 +2,8 @@ import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeWord } from "../../../utils/byte_functions/little_endian.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
+ const BAG_SIZE = 4;
6
+
5
7
  /**
6
8
  * @this {BasicSoundBank}
7
9
  * @returns {IndexedByteArray}
@@ -9,30 +11,31 @@ import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
9
11
  export function getPBAG()
10
12
  {
11
13
  // write all pbag with their start indexes as they were changed in getPGEN() and getPMOD()
12
- const pbagsize = this.presets.reduce((sum, i) => i.presetZones.length * 4 + sum, 4);
14
+ const pbagsize = this.presets.reduce((sum, i) =>
15
+ // +1 because global zone
16
+ (i.presetZones.length + 1) * BAG_SIZE + sum, BAG_SIZE);
13
17
  const pbagdata = new IndexedByteArray(pbagsize);
14
- let zoneID = 0;
15
18
  let generatorIndex = 0;
16
19
  let modulatorIndex = 0;
20
+
21
+ /**
22
+ * @param z {BasicZone}
23
+ */
24
+ const writeZone = z =>
25
+ {
26
+ writeWord(pbagdata, generatorIndex);
27
+ writeWord(pbagdata, modulatorIndex);
28
+ generatorIndex += z.generators.length;
29
+ modulatorIndex += z.modulators.length;
30
+ };
31
+
17
32
  for (const preset of this.presets)
18
33
  {
19
- // ensure that the first zone is global
20
- const zones = preset.presetZones.filter(z => !z.isGlobal);
21
- const global = preset.presetZones.filter(z => z.isGlobal);
22
- // only take the first one
23
- if (global?.[0])
24
- {
25
- zones.unshift(global?.[0]);
26
- }
27
- preset.presetZoneStartIndex = zoneID;
28
- for (const pbag of zones)
34
+ // global
35
+ writeZone(preset.globalZone);
36
+ for (const pbag of preset.presetZones)
29
37
  {
30
- pbag.zoneID = zoneID;
31
- writeWord(pbagdata, generatorIndex);
32
- writeWord(pbagdata, modulatorIndex);
33
- generatorIndex += pbag.generators.length;
34
- modulatorIndex += pbag.modulators.length;
35
- zoneID++;
38
+ writeZone(pbag);
36
39
  }
37
40
  }
38
41
  // write the terminal PBAG
@@ -1,8 +1,9 @@
1
- import { writeWord } from "../../../utils/byte_functions/little_endian.js";
1
+ import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
2
2
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
4
 
5
- import { Generator, generatorTypes } from "../generator.js";
5
+ import { GEN_BYTE_SIZE, Generator } from "../generator.js";
6
+ import { generatorTypes } from "../generator_types.js";
6
7
 
7
8
  /**
8
9
  * @this {BasicSoundBank}
@@ -12,9 +13,10 @@ export function getPGEN()
12
13
  {
13
14
  // almost identical to igen, except the correct instrument instead of sample gen
14
15
  // goes through all preset zones and writes generators sequentially (add 4 for terminal)
15
- let pgensize = 4;
16
+ let pgensize = GEN_BYTE_SIZE;
16
17
  for (const preset of this.presets)
17
18
  {
19
+ pgensize += preset.globalZone.generators.length * GEN_BYTE_SIZE;
18
20
  pgensize += preset.presetZones.reduce((size, z) =>
19
21
  {
20
22
  // clear instrument and range generators before determining the size
@@ -40,39 +42,40 @@ export function getPGEN()
40
42
  false
41
43
  ));
42
44
  }
43
- if (!z.isGlobal)
44
- {
45
- // write the instrument
46
- z.generators.push(new Generator(
47
- generatorTypes.instrument,
48
- this.instruments.indexOf(z.instrument),
49
- false
50
- ));
51
- }
52
- return z.generators.length * 4 + size;
45
+ // write the instrument id
46
+ z.generators.push(new Generator(
47
+ generatorTypes.instrument,
48
+ this.instruments.indexOf(z.instrument),
49
+ false
50
+ ));
51
+ return z.generators.length * GEN_BYTE_SIZE + size;
53
52
  }, 0);
54
53
  }
55
54
  const pgendata = new IndexedByteArray(pgensize);
56
- let pgenIndex = 0;
55
+
56
+ /**
57
+ * @param z {BasicZone}
58
+ */
59
+ const writeZone = z =>
60
+ {
61
+ for (const gen of z.generators)
62
+ {
63
+ // name is deceptive, it works on negatives
64
+ writeWord(pgendata, gen.generatorType);
65
+ writeWord(pgendata, gen.generatorValue);
66
+ }
67
+ };
57
68
  for (const preset of this.presets)
58
69
  {
59
- for (const presetZone of preset.presetZones)
70
+ // global zone
71
+ writeZone(preset.globalZone);
72
+ for (const zone of preset.presetZones)
60
73
  {
61
- // set the start index here
62
- presetZone.generatorZoneStartIndex = pgenIndex;
63
- // write generators
64
- for (const gen of presetZone.generators)
65
- {
66
- // name is deceptive, it works on negatives
67
- writeWord(pgendata, gen.generatorType);
68
- writeWord(pgendata, gen.generatorValue);
69
- }
70
- pgenIndex += presetZone.generators.length;
74
+ writeZone(zone);
71
75
  }
72
76
  }
73
77
  // terminal generator, is zero
74
- writeWord(pgendata, 0);
75
- writeWord(pgendata, 0);
78
+ writeDword(pgendata, 0);
76
79
 
77
80
  return writeRIFFChunk(new RiffChunk(
78
81
  "pgen",
@@ -3,13 +3,15 @@ import { writeStringAsBytes } from "../../../utils/byte_functions/string.js";
3
3
  import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
4
4
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
5
5
 
6
+ const PHDR_SIZE = 38;
7
+
6
8
  /**
7
9
  * @this {BasicSoundBank}
8
10
  * @returns {IndexedByteArray}
9
11
  */
10
12
  export function getPHDR()
11
13
  {
12
- const phdrsize = this.presets.length * 38 + 38;
14
+ const phdrsize = this.presets.length * PHDR_SIZE + PHDR_SIZE;
13
15
  const phdrdata = new IndexedByteArray(phdrsize);
14
16
  // the preset start is adjusted in pbag, this is only for the terminal preset index
15
17
  let presetStart = 0;
@@ -23,7 +25,7 @@ export function getPHDR()
23
25
  writeDword(phdrdata, preset.library);
24
26
  writeDword(phdrdata, preset.genre);
25
27
  writeDword(phdrdata, preset.morphology);
26
- presetStart += preset.presetZones.length;
28
+ presetStart += preset.presetZones.length + 1; // global
27
29
  }
28
30
  // write EOP
29
31
  writeStringAsBytes(phdrdata, "EOP", 20);
@@ -1,6 +1,7 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeLittleEndian, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
3
  import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
+ import { MOD_BYTE_SIZE } from "../modulator.js";
4
5
 
5
6
  /**
6
7
  * @this {BasicSoundBank}
@@ -10,28 +11,37 @@ export function getPMOD()
10
11
  {
11
12
  // very similar to imod,
12
13
  // go through all presets -> zones and write modulators sequentially
13
- let pmodsize = 10;
14
+ let pmodsize = MOD_BYTE_SIZE;
14
15
  for (const preset of this.presets)
15
16
  {
16
- pmodsize += preset.presetZones.reduce((sum, z) => z.modulators.length * 10 + sum, 0);
17
+ pmodsize += preset.globalZone.modulators.length * MOD_BYTE_SIZE;
18
+ pmodsize += preset.presetZones.reduce((sum, z) => z.modulators.length * MOD_BYTE_SIZE + sum, 0);
17
19
  }
18
20
  const pmoddata = new IndexedByteArray(pmodsize);
19
- let pmodIndex = 0;
21
+
22
+ /**
23
+ * @param z {BasicZone}
24
+ */
25
+ const writeZone = z =>
26
+ {
27
+ for (const mod of z.modulators)
28
+ {
29
+ writeWord(pmoddata, mod.getSourceEnum());
30
+ writeWord(pmoddata, mod.modulatorDestination);
31
+ writeWord(pmoddata, mod.transformAmount);
32
+ writeWord(pmoddata, mod.getSecSrcEnum());
33
+ writeWord(pmoddata, mod.transformType);
34
+ }
35
+ };
36
+
37
+
20
38
  for (const preset of this.presets)
21
39
  {
22
- for (const pbag of preset.presetZones)
40
+ // global
41
+ writeZone(preset.globalZone);
42
+ for (const zone of preset.presetZones)
23
43
  {
24
- // set the start index here
25
- pbag.modulatorZoneStartIndex = pmodIndex;
26
- for (const mod of pbag.modulators)
27
- {
28
- writeWord(pmoddata, mod.getSourceEnum());
29
- writeWord(pmoddata, mod.modulatorDestination);
30
- writeWord(pmoddata, mod.transformAmount);
31
- writeWord(pmoddata, mod.getSecSrcEnum());
32
- writeWord(pmoddata, mod.transformType);
33
- pmodIndex++;
34
- }
44
+ writeZone(zone);
35
45
  }
36
46
  }
37
47
 
@@ -1,11 +1,17 @@
1
1
  import { DLSSources } from "./dls_sources.js";
2
- import { getModSourceEnum, Modulator, modulatorCurveTypes, modulatorSources } from "../basic_soundfont/modulator.js";
2
+ import {
3
+ DecodedModulator,
4
+ getModSourceEnum,
5
+ Modulator,
6
+ modulatorCurveTypes,
7
+ modulatorSources
8
+ } from "../basic_soundfont/modulator.js";
3
9
  import { midiControllers } from "../../midi/midi_message.js";
4
10
  import { DLSDestinations } from "./dls_destinations.js";
5
11
 
6
- import { generatorTypes } from "../basic_soundfont/generator.js";
7
12
  import { consoleColors } from "../../utils/other.js";
8
13
  import { SpessaSynthWarn } from "../../utils/loggin.js";
14
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
9
15
 
10
16
  /**
11
17
  * @param source {number}
@@ -385,7 +391,7 @@ export function getSF2ModulatorFromArticulator(
385
391
  }
386
392
 
387
393
  // return the modulator!
388
- return new Modulator(
394
+ return new DecodedModulator(
389
395
  sourceEnumFinal,
390
396
  secSourceEnumFinal,
391
397
  destinationGenerator,
@@ -1,5 +1,5 @@
1
1
  import { BasicPreset } from "../basic_soundfont/basic_preset.js";
2
- import { BasicPresetZone } from "../basic_soundfont/basic_zones.js";
2
+ import { BasicPresetZone } from "../basic_soundfont/basic_preset_zone.js";
3
3
  import { BasicInstrument } from "../basic_soundfont/basic_instrument.js";
4
4
 
5
5
  export class DLSPreset extends BasicPreset
@@ -34,10 +34,9 @@ export class DLSPreset extends BasicPreset
34
34
  }
35
35
 
36
36
  this.DLSInstrument = new BasicInstrument();
37
- this.DLSInstrument.addUseCount();
38
37
 
39
38
  const zone = new BasicPresetZone();
40
- zone.instrument = this.DLSInstrument;
39
+ zone.setInstrument(this.DLSInstrument);
41
40
 
42
41
  this.presetZones = [zone];
43
42
  }
@@ -1,4 +1,4 @@
1
- import { BasicSoundBank } from "../basic_soundfont/basic_soundfont.js";
1
+ import { BasicSoundBank } from "../basic_soundfont/basic_soundbank.js";
2
2
  import { IndexedByteArray } from "../../utils/indexed_array.js";
3
3
  import { SpessaSynthGroup, SpessaSynthGroupEnd, SpessaSynthInfo } from "../../utils/loggin.js";
4
4
  import { consoleColors } from "../../utils/other.js";
@@ -1,5 +1,6 @@
1
- import { Modulator } from "../basic_soundfont/modulator.js";
2
- import { generatorTypes } from "../basic_soundfont/generator.js";
1
+ import { DecodedModulator } from "../basic_soundfont/modulator.js";
2
+
3
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
3
4
 
4
5
  /**
5
6
  * @enum {number}
@@ -29,7 +30,7 @@ export const DLSSources = {
29
30
  coarseTune: 0x102
30
31
  };
31
32
 
32
- export const DEFAULT_DLS_REVERB = new Modulator(
33
+ export const DEFAULT_DLS_REVERB = new DecodedModulator(
33
34
  0x00DB,
34
35
  0x0,
35
36
  generatorTypes.reverbEffectsSend,
@@ -37,7 +38,7 @@ export const DEFAULT_DLS_REVERB = new Modulator(
37
38
  0
38
39
  );
39
40
 
40
- export const DEFAULT_DLS_CHORUS = new Modulator(
41
+ export const DEFAULT_DLS_CHORUS = new DecodedModulator(
41
42
  0x00DD,
42
43
  0x0,
43
44
  generatorTypes.chorusEffectsSend,
@@ -45,7 +46,7 @@ export const DEFAULT_DLS_CHORUS = new Modulator(
45
46
  0
46
47
  );
47
48
 
48
- export const DLS_1_NO_VIBRATO_MOD = new Modulator(
49
+ export const DLS_1_NO_VIBRATO_MOD = new DecodedModulator(
49
50
  0x0081,
50
51
  0x0,
51
52
  generatorTypes.vibLfoToPitch,
@@ -53,7 +54,7 @@ export const DLS_1_NO_VIBRATO_MOD = new Modulator(
53
54
  0
54
55
  );
55
56
 
56
- export const DLS_1_NO_VIBRATO_PRESSURE = new Modulator(
57
+ export const DLS_1_NO_VIBRATO_PRESSURE = new DecodedModulator(
57
58
  0x000D,
58
59
  0x0,
59
60
  generatorTypes.vibLfoToPitch,
@@ -1,5 +1,6 @@
1
- import { BasicInstrumentZone } from "../basic_soundfont/basic_zones.js";
2
- import { Generator, generatorTypes } from "../basic_soundfont/generator.js";
1
+ import { Generator } from "../basic_soundfont/generator.js";
2
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
3
+ import { BasicInstrumentZone } from "../basic_soundfont/basic_instrument_zone.js";
3
4
 
4
5
  export class DLSZone extends BasicInstrumentZone
5
6
  {
@@ -12,7 +13,6 @@ export class DLSZone extends BasicInstrumentZone
12
13
  super();
13
14
  this.keyRange = keyRange;
14
15
  this.velRange = velRange;
15
- this.isGlobal = true;
16
16
  }
17
17
 
18
18
  /**
@@ -89,7 +89,6 @@ export class DLSZone extends BasicInstrumentZone
89
89
  }
90
90
  // add sample ID
91
91
  this.generators.push(new Generator(generatorTypes.sampleID, sampleID));
92
- this.sample = sample;
93
- sample.useCount++;
92
+ this.setSample(sample);
94
93
  }
95
94
  }
@@ -4,8 +4,9 @@ import { DLS_1_NO_VIBRATO_MOD, DLS_1_NO_VIBRATO_PRESSURE, DLSSources } from "./d
4
4
  import { getSF2ModulatorFromArticulator } from "./articulator_converter.js";
5
5
  import { SpessaSynthInfo, SpessaSynthWarn } from "../../utils/loggin.js";
6
6
  import { consoleColors } from "../../utils/other.js";
7
- import { Generator, generatorTypes } from "../basic_soundfont/generator.js";
7
+ import { Generator } from "../basic_soundfont/generator.js";
8
8
  import { Modulator } from "../basic_soundfont/modulator.js";
9
+ import { generatorTypes } from "../basic_soundfont/generator_types.js";
9
10
 
10
11
 
11
12
  /**
@@ -3,11 +3,10 @@ import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
3
3
  import { DLSPreset } from "./dls_preset.js";
4
4
  import { findRIFFListType, readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
5
5
  import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd } from "../../utils/loggin.js";
6
- import { BasicInstrumentZone } from "../basic_soundfont/basic_zones.js";
7
6
  import { consoleColors } from "../../utils/other.js";
8
- import { generatorLimits, generatorTypes } from "../basic_soundfont/generator.js";
9
7
  import { Modulator } from "../basic_soundfont/modulator.js";
10
8
  import { DEFAULT_DLS_CHORUS, DEFAULT_DLS_REVERB } from "./dls_sources.js";
9
+ import { generatorLimits, generatorTypes } from "../basic_soundfont/generator_types.js";
11
10
 
12
11
  /**
13
12
  * @this {DLSSoundFont}
@@ -70,8 +69,7 @@ export function readDLSInstrument(chunk)
70
69
  }
71
70
 
72
71
  // global articulation: essentially global zone
73
- const globalZone = new BasicInstrumentZone();
74
- globalZone.isGlobal = true;
72
+ const globalZone = preset.DLSInstrument.globalZone;
75
73
 
76
74
  // read articulators
77
75
  const globalLart = findRIFFListType(chunks, "lart");
@@ -93,7 +91,6 @@ export function readDLSInstrument(chunk)
93
91
  {
94
92
  globalZone.modulators.push(Modulator.copy(DEFAULT_DLS_CHORUS));
95
93
  }
96
- preset.DLSInstrument.instrumentZones.push(globalZone);
97
94
 
98
95
  // read regions
99
96
  for (let i = 0; i < regions; i++)
@@ -111,7 +108,7 @@ export function readDLSInstrument(chunk)
111
108
  const zone = this.readRegion(chunk);
112
109
  if (zone)
113
110
  {
114
- preset.DLSInstrument.instrumentZones.push(zone);
111
+ preset.DLSInstrument.addZone(zone);
115
112
  }
116
113
  }
117
114
 
@@ -4,7 +4,7 @@ import { readArticulation } from "./read_articulation.js";
4
4
  /**
5
5
  * @param lartChunk {RiffChunk|undefined}
6
6
  * @param lar2Chunk {RiffChunk|undefined}
7
- * @param zone {BasicInstrumentZone}
7
+ * @param zone {BasicZone}
8
8
  * @this {DLSSoundFont}
9
9
  */
10
10
  export function readLart(lartChunk, lar2Chunk, zone)