spessasynth_lib 3.16.1 → 3.16.3

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 (89) hide show
  1. package/@types/index.d.ts +0 -2
  2. package/@types/soundfont/basic_soundfont/basic_instrument.d.ts +29 -0
  3. package/@types/soundfont/basic_soundfont/basic_preset.d.ts +76 -0
  4. package/@types/soundfont/basic_soundfont/basic_sample.d.ts +82 -0
  5. package/@types/soundfont/basic_soundfont/basic_soundfont.d.ts +80 -0
  6. package/@types/soundfont/basic_soundfont/basic_zone.d.ts +42 -0
  7. package/@types/soundfont/basic_soundfont/basic_zones.d.ts +18 -0
  8. package/@types/soundfont/{read → basic_soundfont}/riff_chunk.d.ts +2 -1
  9. package/@types/soundfont/basic_soundfont/write_sf2/ibag.d.ts +6 -0
  10. package/@types/soundfont/basic_soundfont/write_sf2/igen.d.ts +6 -0
  11. package/@types/soundfont/basic_soundfont/write_sf2/imod.d.ts +6 -0
  12. package/@types/soundfont/basic_soundfont/write_sf2/inst.d.ts +6 -0
  13. package/@types/soundfont/basic_soundfont/write_sf2/pbag.d.ts +6 -0
  14. package/@types/soundfont/basic_soundfont/write_sf2/pgen.d.ts +6 -0
  15. package/@types/soundfont/basic_soundfont/write_sf2/phdr.d.ts +6 -0
  16. package/@types/soundfont/basic_soundfont/write_sf2/pmod.d.ts +6 -0
  17. package/@types/soundfont/basic_soundfont/write_sf2/sdta.d.ts +11 -0
  18. package/@types/soundfont/basic_soundfont/write_sf2/shdr.d.ts +8 -0
  19. package/@types/soundfont/{write → basic_soundfont/write_sf2}/write.d.ts +2 -2
  20. package/@types/soundfont/{read → read_sf2}/generators.d.ts +2 -1
  21. package/@types/soundfont/{read → read_sf2}/instruments.d.ts +3 -24
  22. package/@types/soundfont/read_sf2/presets.d.ts +28 -0
  23. package/@types/soundfont/read_sf2/samples.d.ts +56 -0
  24. package/@types/soundfont/{read → read_sf2}/zones.d.ts +11 -53
  25. package/@types/soundfont/soundfont.d.ts +6 -67
  26. package/midi_parser/midi_loader.js +1 -1
  27. package/midi_parser/rmidi_writer.js +11 -11
  28. package/midi_parser/used_keys_loaded.js +1 -1
  29. package/package.json +1 -1
  30. package/sequencer/worklet_sequencer/song_control.js +1 -1
  31. package/soundfont/basic_soundfont/basic_instrument.js +73 -0
  32. package/soundfont/{read/presets.js → basic_soundfont/basic_preset.js} +54 -87
  33. package/soundfont/basic_soundfont/basic_sample.js +132 -0
  34. package/soundfont/basic_soundfont/basic_soundfont.js +193 -0
  35. package/soundfont/basic_soundfont/basic_zone.js +39 -0
  36. package/soundfont/basic_soundfont/basic_zones.js +47 -0
  37. package/soundfont/{read → basic_soundfont}/riff_chunk.js +8 -1
  38. package/soundfont/{write → basic_soundfont/write_sf2}/ibag.js +4 -4
  39. package/soundfont/{write → basic_soundfont/write_sf2}/igen.js +5 -5
  40. package/soundfont/{write → basic_soundfont/write_sf2}/imod.js +4 -4
  41. package/soundfont/{write → basic_soundfont/write_sf2}/inst.js +5 -5
  42. package/soundfont/{write → basic_soundfont/write_sf2}/pbag.js +4 -4
  43. package/soundfont/{write → basic_soundfont/write_sf2}/pgen.js +5 -5
  44. package/soundfont/{write → basic_soundfont/write_sf2}/phdr.js +5 -5
  45. package/soundfont/{write → basic_soundfont/write_sf2}/pmod.js +4 -4
  46. package/soundfont/{write → basic_soundfont/write_sf2}/sdta.js +5 -5
  47. package/soundfont/{write → basic_soundfont/write_sf2}/shdr.js +5 -5
  48. package/soundfont/{write → basic_soundfont/write_sf2}/soundfont_trimmer.js +5 -5
  49. package/soundfont/{write → basic_soundfont/write_sf2}/write.js +8 -9
  50. package/soundfont/{read → read_sf2}/generators.js +2 -1
  51. package/soundfont/{read → read_sf2}/instruments.js +4 -63
  52. package/soundfont/{read → read_sf2}/modulators.js +1 -1
  53. package/soundfont/read_sf2/presets.js +78 -0
  54. package/soundfont/{read → read_sf2}/samples.js +4 -138
  55. package/soundfont/{read → read_sf2}/zones.js +14 -60
  56. package/soundfont/soundfont.js +21 -188
  57. package/synthetizer/worklet_processor.min.js +6 -6
  58. package/synthetizer/worklet_system/message_protocol/message_sending.js +1 -1
  59. package/synthetizer/worklet_system/worklet_methods/data_entry.js +1 -1
  60. package/synthetizer/worklet_system/worklet_methods/note_off.js +1 -1
  61. package/synthetizer/worklet_system/worklet_methods/note_on.js +1 -1
  62. package/synthetizer/worklet_system/worklet_methods/program_control.js +1 -1
  63. package/synthetizer/worklet_system/worklet_methods/reset_controllers.js +1 -1
  64. package/synthetizer/worklet_system/worklet_methods/tuning_control.js +1 -1
  65. package/synthetizer/worklet_system/worklet_methods/voice_control.js +1 -1
  66. package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +1 -1
  67. package/synthetizer/worklet_system/worklet_utilities/lowpass_filter.js +1 -1
  68. package/synthetizer/worklet_system/worklet_utilities/modulation_envelope.js +2 -2
  69. package/synthetizer/worklet_system/worklet_utilities/modulator_curves.js +1 -1
  70. package/synthetizer/worklet_system/worklet_utilities/volume_envelope.js +4 -4
  71. package/synthetizer/worklet_system/worklet_utilities/worklet_modulator.js +2 -2
  72. package/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js +1 -1
  73. package/synthetizer/worklet_system/worklet_utilities/worklet_voice.js +1 -1
  74. package/utils/buffer_to_wav.js +6 -6
  75. package/@types/midi_parser/used_keys_loaded.d.ts +0 -10
  76. package/@types/soundfont/read/presets.d.ts +0 -88
  77. package/@types/soundfont/read/samples.d.ts +0 -138
  78. package/@types/soundfont/write/ibag.d.ts +0 -6
  79. package/@types/soundfont/write/igen.d.ts +0 -6
  80. package/@types/soundfont/write/imod.d.ts +0 -6
  81. package/@types/soundfont/write/inst.d.ts +0 -6
  82. package/@types/soundfont/write/pbag.d.ts +0 -6
  83. package/@types/soundfont/write/pgen.d.ts +0 -6
  84. package/@types/soundfont/write/phdr.d.ts +0 -6
  85. package/@types/soundfont/write/pmod.d.ts +0 -6
  86. package/@types/soundfont/write/sdta.d.ts +0 -11
  87. package/@types/soundfont/write/shdr.d.ts +0 -8
  88. package/@types/soundfont/write/soundfont_trimmer.d.ts +0 -6
  89. /package/@types/soundfont/{read → read_sf2}/modulators.d.ts +0 -0
@@ -3,10 +3,10 @@
3
3
  * @param zonesChunk {RiffChunk}
4
4
  * @param instrumentGenerators {Generator[]}
5
5
  * @param instrumentModulators {Modulator[]}
6
- * @param instrumentSamples {LoadedSample[]}
6
+ * @param instrumentSamples {BasicSample[]}
7
7
  * @returns {InstrumentZone[]}
8
8
  */
9
- export function readInstrumentZones(zonesChunk: RiffChunk, instrumentGenerators: Generator[], instrumentModulators: Modulator[], instrumentSamples: LoadedSample[]): InstrumentZone[];
9
+ export function readInstrumentZones(zonesChunk: RiffChunk, instrumentGenerators: Generator[], instrumentModulators: Modulator[], instrumentSamples: BasicSample[]): InstrumentZone[];
10
10
  /**
11
11
  * Reads the given preset zone read
12
12
  * @param zonesChunk {RiffChunk}
@@ -20,37 +20,16 @@ export function readPresetZones(zonesChunk: RiffChunk, presetGenerators: Generat
20
20
  * zones.js
21
21
  * purpose: reads instrumend and preset zones from soundfont and gets their respective samples and generators and modulators
22
22
  */
23
- export class InstrumentZone {
23
+ export class InstrumentZone extends BasicInstrumentZone {
24
24
  /**
25
25
  * Creates a zone (instrument)
26
26
  * @param dataArray {IndexedByteArray}
27
- * @param index {number}
28
27
  */
29
- constructor(dataArray: IndexedByteArray, index: number);
28
+ constructor(dataArray: IndexedByteArray);
30
29
  generatorZoneStartIndex: number;
31
30
  modulatorZoneStartIndex: number;
32
31
  modulatorZoneSize: number;
33
32
  generatorZoneSize: number;
34
- zoneID: number;
35
- keyRange: {
36
- min: number;
37
- max: number;
38
- };
39
- velRange: {
40
- min: number;
41
- max: number;
42
- };
43
- isGlobal: boolean;
44
- useCount: number;
45
- /**
46
- * @type {Generator[]}
47
- */
48
- generators: Generator[];
49
- /**
50
- * @type {Modulator[]}
51
- */
52
- modulators: Modulator[];
53
- deleteZone(): void;
54
33
  setZoneSize(modulatorZoneSize: any, generatorZoneSize: any): void;
55
34
  /**
56
35
  * grab the generators
@@ -64,10 +43,9 @@ export class InstrumentZone {
64
43
  getModulators(modulators: Modulator[]): void;
65
44
  /**
66
45
  * Loads the zone's sample
67
- * @param samples {LoadedSample[]}
46
+ * @param samples {BasicSample[]}
68
47
  */
69
- getSample(samples: LoadedSample[]): void;
70
- sample: LoadedSample;
48
+ getSample(samples: BasicSample[]): void;
71
49
  /**
72
50
  * Reads the keyRange of the zone
73
51
  */
@@ -77,37 +55,17 @@ export class InstrumentZone {
77
55
  */
78
56
  getVelRange(): void;
79
57
  }
80
- export class PresetZone {
58
+ export class PresetZone extends BasicPresetZone {
81
59
  /**
82
60
  * Creates a zone (preset)
83
61
  * @param dataArray {IndexedByteArray}
84
- * @param index {number}
85
62
  */
86
- constructor(dataArray: IndexedByteArray, index: number);
63
+ constructor(dataArray: IndexedByteArray);
87
64
  generatorZoneStartIndex: number;
88
65
  modulatorZoneStartIndex: number;
89
66
  modulatorZoneSize: number;
90
67
  generatorZoneSize: number;
91
- zoneID: number;
92
- keyRange: {
93
- min: number;
94
- max: number;
95
- };
96
- velRange: {
97
- min: number;
98
- max: number;
99
- };
100
- isGlobal: boolean;
101
- /**
102
- * @type {Generator[]}
103
- */
104
- generators: Generator[];
105
- /**
106
- * @type {Modulator[]}
107
- */
108
- modulators: Modulator[];
109
68
  setZoneSize(modulatorZoneSize: any, generatorZoneSize: any): void;
110
- deleteZone(): void;
111
69
  /**
112
70
  * grab the generators
113
71
  * @param generators {Generator[]}
@@ -123,7 +81,6 @@ export class PresetZone {
123
81
  * @param instruments {Instrument[]}
124
82
  */
125
83
  getInstrument(instruments: Instrument[]): void;
126
- instrument: Instrument;
127
84
  /**
128
85
  * Reads the keyRange of the zone
129
86
  */
@@ -133,9 +90,10 @@ export class PresetZone {
133
90
  */
134
91
  getVelRange(): void;
135
92
  }
136
- import { RiffChunk } from "./riff_chunk.js";
93
+ import { RiffChunk } from "../basic_soundfont/riff_chunk.js";
137
94
  import { Generator } from "./generators.js";
138
95
  import { Modulator } from "./modulators.js";
139
- import { LoadedSample } from "./samples.js";
140
96
  import { Instrument } from "./instruments.js";
97
+ import { BasicInstrumentZone } from '../basic_soundfont/basic_zones.js';
141
98
  import { IndexedByteArray } from "../../utils/indexed_array.js";
99
+ import { BasicPresetZone } from '../basic_soundfont/basic_zones.js';
@@ -2,48 +2,15 @@
2
2
  * soundfont.js
3
3
  * purpose: parses a soundfont2 file
4
4
  */
5
- export class SoundFont2 {
6
- /**
7
- * Merges soundfonts with the given order. Keep in mind that the info read is copied from the first one
8
- * @param soundfonts {...SoundFont2} the soundfonts to merge, the first overwrites the last
9
- * @returns {SoundFont2}
10
- */
11
- static mergeSoundfonts(...soundfonts: SoundFont2[]): SoundFont2;
5
+ export class SoundFont2 extends BasicSoundFont {
12
6
  /**
13
7
  * Initializes a new SoundFont2 Parser and parses the given data array
14
- * @param arrayBuffer {ArrayBuffer|{presets: Preset[], info: Object<string, string>}}
8
+ * @param arrayBuffer {ArrayBuffer}
15
9
  */
16
- constructor(arrayBuffer: ArrayBuffer | {
17
- presets: Preset[];
18
- info: {
19
- [x: string]: string;
20
- };
21
- });
22
- presets: Preset[];
23
- soundFontInfo: {
24
- [x: string]: string;
25
- };
10
+ constructor(arrayBuffer: ArrayBuffer);
26
11
  dataArray: IndexedByteArray;
27
12
  sampleDataStartIndex: number;
28
- samples: import("./read/samples.js").LoadedSample[];
29
- /**
30
- * read all the instruments
31
- * @type {Instrument[]}
32
- */
33
- instruments: Instrument[];
34
- removeUnusedElements(): void;
35
- /**
36
- * @param instrument {Instrument}
37
- */
38
- deleteInstrument(instrument: Instrument): void;
39
- /**
40
- * @param sample {LoadedSample}
41
- */
42
- deleteSample(sample: LoadedSample): void;
43
- /**
44
- * @param preset {Preset}
45
- */
46
- deletePreset(preset: Preset): void;
13
+ instruments: import("./read_sf2/instruments.js").Instrument[];
47
14
  /**
48
15
  * @param chunk {RiffChunk}
49
16
  * @param expected {string}
@@ -54,35 +21,7 @@ export class SoundFont2 {
54
21
  * @param expected {string}
55
22
  */
56
23
  verifyText(text: string, expected: string): void;
57
- /**
58
- * Get the appropriate preset, undefined if not foun d
59
- * @param bankNr {number}
60
- * @param presetNr {number}
61
- * @return {Preset}
62
- */
63
- getPresetNoFallback(bankNr: number, presetNr: number): Preset;
64
- /**
65
- * To avoid overlapping on multiple desfonts
66
- * @param offset {number}
67
- */
68
- setSampleIDOffset(offset: number): void;
69
- /**
70
- * Get the appropriate preset
71
- * @param bankNr {number}
72
- * @param presetNr {number}
73
- * @returns {Preset}
74
- */
75
- getPreset(bankNr: number, presetNr: number): Preset;
76
- /**
77
- * gets preset by name
78
- * @param presetName {string}
79
- * @returns {Preset}
80
- */
81
- getPresetByName(presetName: string): Preset;
82
- write: typeof write;
83
24
  }
84
- import { Preset } from "./read/presets.js";
25
+ import { BasicSoundFont } from './basic_soundfont/basic_soundfont.js';
85
26
  import { IndexedByteArray } from '../utils/indexed_array.js';
86
- import { Instrument } from "./read/instruments.js";
87
- import { RiffChunk } from './read/riff_chunk.js';
88
- import { write } from './write/write.js';
27
+ import { RiffChunk } from './basic_soundfont/riff_chunk.js';
@@ -2,7 +2,7 @@ import { dataBytesAmount, getChannel, messageTypes, MidiMessage } from './midi_m
2
2
  import { IndexedByteArray } from '../utils/indexed_array.js'
3
3
  import { arrayToHexString, consoleColors, formatTitle } from '../utils/other.js'
4
4
  import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from '../utils/loggin.js'
5
- import { readRIFFChunk } from '../soundfont/read/riff_chunk.js'
5
+ import { readRIFFChunk } from '../soundfont/basic_soundfont/riff_chunk.js'
6
6
  import { readVariableLengthQuantity } from '../utils/byte_functions/variable_length_quantity.js'
7
7
  import { readBytesAsUintBigEndian } from '../utils/byte_functions/big_endian.js'
8
8
  import { readBytesAsString } from '../utils/byte_functions/string.js'
@@ -1,6 +1,6 @@
1
1
  import { combineArrays, IndexedByteArray } from '../utils/indexed_array.js'
2
2
  import { writeMIDIFile } from './midi_writer.js'
3
- import { writeRIFFOddSize } from '../soundfont/read/riff_chunk.js'
3
+ import { writeRIFFOddSize } from '../soundfont/basic_soundfont/riff_chunk.js'
4
4
  import { getStringBytes } from '../utils/byte_functions/string.js'
5
5
  import { messageTypes, midiControllers, MidiMessage } from './midi_message.js'
6
6
  import { DEFAULT_PERCUSSION } from '../synthetizer/synthetizer.js'
@@ -340,21 +340,21 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
340
340
  const encoder = new TextEncoder();
341
341
  // software
342
342
  infoContent.push(
343
- writeRIFFOddSize(RMIDINFOChunks.software, encoder.encode("SpessaSynth"))
343
+ writeRIFFOddSize(RMIDINFOChunks.software, encoder.encode("SpessaSynth"), true)
344
344
  );
345
345
  // name
346
346
  if(metadata.name !== undefined)
347
347
  {
348
348
 
349
349
  infoContent.push(
350
- writeRIFFOddSize(RMIDINFOChunks.name, encoder.encode(metadata.name))
350
+ writeRIFFOddSize(RMIDINFOChunks.name, encoder.encode(metadata.name), true)
351
351
  );
352
352
  encoding = FORCED_ENCODING;
353
353
  }
354
354
  else
355
355
  {
356
356
  infoContent.push(
357
- writeRIFFOddSize(RMIDINFOChunks.name, mid.rawMidiName)
357
+ writeRIFFOddSize(RMIDINFOChunks.name, mid.rawMidiName, true)
358
358
  );
359
359
  }
360
360
  // creation date
@@ -362,7 +362,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
362
362
  {
363
363
  encoding = FORCED_ENCODING;
364
364
  infoContent.push(
365
- writeRIFFOddSize(RMIDINFOChunks.creationDate, encoder.encode(metadata.creationDate))
365
+ writeRIFFOddSize(RMIDINFOChunks.creationDate, encoder.encode(metadata.creationDate), true)
366
366
  );
367
367
  }
368
368
  else
@@ -376,7 +376,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
376
376
  minute: "numeric"
377
377
  });
378
378
  infoContent.push(
379
- writeRIFFOddSize(RMIDINFOChunks.creationDate, getStringBytes(today))
379
+ writeRIFFOddSize(RMIDINFOChunks.creationDate, getStringBytes(today), true)
380
380
  );
381
381
  }
382
382
  // comment
@@ -391,7 +391,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
391
391
  if(metadata.engineer !== undefined)
392
392
  {
393
393
  infoContent.push(
394
- writeRIFFOddSize(RMIDINFOChunks.engineer, encoder.encode(metadata.engineer))
394
+ writeRIFFOddSize(RMIDINFOChunks.engineer, encoder.encode(metadata.engineer), true)
395
395
  )
396
396
  }
397
397
  // album
@@ -399,7 +399,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
399
399
  {
400
400
  encoding = FORCED_ENCODING;
401
401
  infoContent.push(
402
- writeRIFFOddSize(RMIDINFOChunks.album, encoder.encode(metadata.album))
402
+ writeRIFFOddSize(RMIDINFOChunks.album, encoder.encode(metadata.album), true)
403
403
  );
404
404
  }
405
405
  // artist
@@ -407,7 +407,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
407
407
  {
408
408
  encoding = FORCED_ENCODING;
409
409
  infoContent.push(
410
- writeRIFFOddSize(RMIDINFOChunks.artist, encoder.encode(metadata.artist))
410
+ writeRIFFOddSize(RMIDINFOChunks.artist, encoder.encode(metadata.artist), true)
411
411
  );
412
412
  }
413
413
  // genre
@@ -415,7 +415,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
415
415
  {
416
416
  encoding = FORCED_ENCODING;
417
417
  infoContent.push(
418
- writeRIFFOddSize(RMIDINFOChunks.genre, encoder.encode(metadata.genre))
418
+ writeRIFFOddSize(RMIDINFOChunks.genre, encoder.encode(metadata.genre), true)
419
419
  );
420
420
  }
421
421
  // picture
@@ -430,7 +430,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
430
430
  {
431
431
  encoding = FORCED_ENCODING;
432
432
  infoContent.push(
433
- writeRIFFOddSize(RMIDINFOChunks.copyright, encoder.encode(metadata.copyright))
433
+ writeRIFFOddSize(RMIDINFOChunks.copyright, encoder.encode(metadata.copyright), true)
434
434
  );
435
435
  }
436
436
  else
@@ -5,7 +5,7 @@ import { messageTypes, midiControllers } from './midi_message.js'
5
5
 
6
6
  /**
7
7
  * @param mid {MIDI}
8
- * @param soundfont {{getPreset: function(number, number): Preset}}
8
+ * @param soundfont {{getPreset: function(number, number): BasicPreset}}
9
9
  * @returns {Object<string, Set<string>>}
10
10
  */
11
11
  export function getUsedProgramsAndKeys(mid, soundfont)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spessasynth_lib",
3
- "version": "3.16.1",
3
+ "version": "3.16.3",
4
4
  "description": "No compromise MIDI and SoundFont2 Synthesizer library",
5
5
  "browser": "index.js",
6
6
  "types": "@types/index.d.ts",
@@ -68,7 +68,7 @@ export function loadNewSequence(parsedMidi)
68
68
  if(this.synth.overrideSoundfont)
69
69
  {
70
70
  // clean up the embedded soundfont
71
- this.synth.clearSoundFont();
71
+ this.synth.clearSoundFont(true, true);
72
72
  }
73
73
  SpessaSynthGroupCollapsed("%cPreloading samples...", consoleColors.info);
74
74
  // smart preloading: load only samples used in the midi!
@@ -0,0 +1,73 @@
1
+ export class BasicInstrument
2
+ {
3
+ constructor()
4
+ {
5
+ /**
6
+ * The instrument's name
7
+ * @type {string}
8
+ */
9
+ this.instrumentName = "";
10
+ /**
11
+ * The instrument's zones
12
+ * @type {BasicInstrumentZone[]}
13
+ */
14
+ this.instrumentZones = [];
15
+ this._useCount = 0;
16
+ }
17
+
18
+ addUseCount()
19
+ {
20
+ this._useCount++;
21
+ this.instrumentZones.forEach(z => z.useCount++);
22
+ }
23
+
24
+ removeUseCount()
25
+ {
26
+ this._useCount--;
27
+ for(let i = 0; i < this.instrumentZones.length; i++)
28
+ {
29
+ if(this.safeDeleteZone(i))
30
+ {
31
+ i--;
32
+ }
33
+ }
34
+ }
35
+
36
+ /**
37
+ * @returns {number}
38
+ */
39
+ get useCount()
40
+ {
41
+ return this._useCount;
42
+ }
43
+
44
+ deleteInstrument()
45
+ {
46
+ this.instrumentZones.forEach(z => z.deleteZone());
47
+ this.instrumentZones.length = 0;
48
+ }
49
+
50
+ /**
51
+ * @param index {number}
52
+ * @returns {boolean} is the zone has been deleted
53
+ */
54
+ safeDeleteZone(index)
55
+ {
56
+ this.instrumentZones[index].useCount--;
57
+ if(this.instrumentZones[index].useCount < 1)
58
+ {
59
+ this.deleteZone(index);
60
+ return true;
61
+ }
62
+ return false;
63
+ }
64
+
65
+ /**
66
+ * @param index {number}
67
+ */
68
+ deleteZone(index)
69
+ {
70
+ this.instrumentZones[index].deleteZone();
71
+ this.instrumentZones.splice(index, 1);
72
+ }
73
+ }
@@ -1,35 +1,45 @@
1
- import {RiffChunk} from "./riff_chunk.js";
2
- import {PresetZone} from "./zones.js";
3
- import {readBytesAsUintLittleEndian} from "../../utils/byte_functions/little_endian.js";
4
- import {LoadedSample} from "./samples.js";
5
- import { Generator, generatorTypes } from './generators.js'
6
- import { defaultModulators } from './modulators.js'
7
- import { readBytesAsString } from '../../utils/byte_functions/string.js'
8
-
9
1
  /**
10
- * parses soundfont presets, also includes function for getting the generators and samples from midi note and velocity
2
+ * @typedef {{
3
+ * instrumentGenerators: Generator[],
4
+ * presetGenerators: Generator[],
5
+ * modulators: Modulator[],
6
+ * sample: BasicSample,
7
+ * sampleID: number,
8
+ * }} SampleAndGenerators
11
9
  */
10
+ import { defaultModulators } from '../read_sf2/modulators.js'
11
+ import { generatorTypes } from '../read_sf2/generators.js'
12
12
 
13
- export class Preset {
14
- /**
15
- * Creates a preset
16
- * @param presetChunk {RiffChunk}
17
- */
18
- constructor(presetChunk)
13
+ export class BasicPreset
14
+ {
15
+ constructor()
19
16
  {
20
- this.presetName = readBytesAsString(presetChunk.chunkData, 20)
21
- .trim()
22
- .replace(/\d{3}:\d{3}/, ""); // remove those pesky "000:001"
17
+ /**
18
+ * The preset's name
19
+ * @type {string}
20
+ */
21
+ this.presetName = "";
22
+ /**
23
+ * The preset's MIDI program number
24
+ * @type {number}
25
+ */
26
+ this.program = 0;
27
+ /**
28
+ * The preset's MIDI bank number
29
+ * @type {number}
30
+ */
31
+ this.bank = 0;
23
32
 
24
- this.program = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);
25
- this.bank = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);
26
- this.presetZoneStartIndex = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);
27
- this.presetZonesAmount = 0;
28
33
  /**
29
- * @type {PresetZone[]}
34
+ * The preset's zones
35
+ * @type {BasicPresetZone[]}
30
36
  */
31
37
  this.presetZones = [];
32
38
 
39
+ /**
40
+ * SampleID offset for this preset
41
+ * @type {number}
42
+ */
33
43
  this.sampleIDOffset = 0;
34
44
 
35
45
  /**
@@ -42,24 +52,21 @@ export class Preset {
42
52
  this.foundSamplesAndGenerators[i] = [];
43
53
  }
44
54
 
45
- // read the dwords
46
- this.library = readBytesAsUintLittleEndian(presetChunk.chunkData, 4);
47
- this.genre = readBytesAsUintLittleEndian(presetChunk.chunkData, 4);
48
- this.morphology = readBytesAsUintLittleEndian(presetChunk.chunkData, 4);
49
- }
50
-
51
- /**
52
- * Loads all the preset zones, given the amount
53
- * @param amount {number}
54
- * @param zones {PresetZone[]}
55
- */
56
- getPresetZones(amount, zones)
57
- {
58
- this.presetZonesAmount = amount;
59
- for (let i = this.presetZoneStartIndex; i < this.presetZonesAmount + this.presetZoneStartIndex; i++)
60
- {
61
- this.presetZones.push(zones[i]);
62
- }
55
+ /**
56
+ * unused metadata
57
+ * @type {number}
58
+ */
59
+ this.library = 0;
60
+ /**
61
+ * unused metadata
62
+ * @type {number}
63
+ */
64
+ this.genre = 0;
65
+ /**
66
+ * unused metadata
67
+ * @type {number}
68
+ */
69
+ this.morphology = 0;
63
70
  }
64
71
 
65
72
  deletePreset()
@@ -111,16 +118,6 @@ export class Preset {
111
118
  })
112
119
  }
113
120
 
114
- /**
115
- * @typedef {{
116
- * instrumentGenerators: Generator[],
117
- * presetGenerators: Generator[],
118
- * modulators: Modulator[],
119
- * sample: LoadedSample,
120
- * sampleID: number,
121
- * }} SampleAndGenerators
122
- */
123
-
124
121
  /**
125
122
  * Returns generatorTranslator and generators for given note
126
123
  * @param midiNote {number}
@@ -215,12 +212,12 @@ export class Preset {
215
212
  .filter(currentZone =>
216
213
  (
217
214
  isInRange(currentZone.keyRange.min,
218
- currentZone.keyRange.max,
219
- midiNote)
220
- &&
221
- isInRange(currentZone.velRange.min,
222
- currentZone.velRange.max,
223
- velocity)
215
+ currentZone.keyRange.max,
216
+ midiNote)
217
+ &&
218
+ isInRange(currentZone.velRange.min,
219
+ currentZone.velRange.max,
220
+ velocity)
224
221
  ) && !currentZone.isGlobal
225
222
  );
226
223
 
@@ -278,34 +275,4 @@ export class Preset {
278
275
  this.foundSamplesAndGenerators[midiNote][velocity] = parsedGeneratorsAndSamples;
279
276
  return parsedGeneratorsAndSamples;
280
277
  }
281
- }
282
-
283
- /**
284
- * Reads the presets
285
- * @param presetChunk {RiffChunk}
286
- * @param presetZones {PresetZone[]}
287
- * @returns {Preset[]}
288
- */
289
- export function readPresets(presetChunk, presetZones)
290
- {
291
- /**
292
- * @type {Preset[]}
293
- */
294
- let presets = [];
295
- while(presetChunk.chunkData.length > presetChunk.chunkData.currentIndex)
296
- {
297
- let preset = new Preset(presetChunk);
298
- if(presets.length > 0)
299
- {
300
- let presetZonesAmount = preset.presetZoneStartIndex - presets[presets.length - 1].presetZoneStartIndex;
301
- presets[presets.length - 1].getPresetZones(presetZonesAmount, presetZones);
302
- }
303
- presets.push(preset);
304
- }
305
- // remove EOP
306
- if (presets.length > 1)
307
- {
308
- presets.pop();
309
- }
310
- return presets;
311
278
  }