spessasynth_lib 3.17.0 → 3.20.0

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 (43) hide show
  1. package/@types/soundfont/basic_soundfont/basic_sample.d.ts +2 -2
  2. package/@types/soundfont/basic_soundfont/basic_zone.d.ts +12 -12
  3. package/@types/soundfont/basic_soundfont/basic_zones.d.ts +4 -0
  4. package/@types/soundfont/basic_soundfont/riff_chunk.d.ts +6 -0
  5. package/@types/soundfont/dls/articulator_converter.d.ts +10 -0
  6. package/@types/soundfont/dls/dls_destinations.d.ts +29 -0
  7. package/@types/soundfont/dls/dls_preset.d.ts +7 -5
  8. package/@types/soundfont/dls/dls_sample.d.ts +18 -0
  9. package/@types/soundfont/dls/dls_soundfont.d.ts +9 -2
  10. package/@types/soundfont/dls/dls_sources.d.ts +22 -0
  11. package/@types/soundfont/dls/dls_zone.d.ts +22 -0
  12. package/@types/soundfont/dls/read_articulation.d.ts +12 -0
  13. package/@types/soundfont/dls/read_instrument_list.d.ts +2 -2
  14. package/@types/soundfont/dls/read_lart.d.ts +7 -0
  15. package/@types/soundfont/dls/read_region.d.ts +7 -0
  16. package/@types/soundfont/dls/read_samples.d.ts +5 -0
  17. package/@types/soundfont/read_sf2/generators.d.ts +18 -5
  18. package/@types/soundfont/read_sf2/modulators.d.ts +1 -0
  19. package/README.md +10 -0
  20. package/midi_parser/midi_loader.js +30 -3
  21. package/package.json +1 -1
  22. package/soundfont/README.md +6 -2
  23. package/soundfont/basic_soundfont/basic_sample.js +3 -3
  24. package/soundfont/basic_soundfont/basic_zone.js +28 -28
  25. package/soundfont/basic_soundfont/basic_zones.js +15 -19
  26. package/soundfont/basic_soundfont/riff_chunk.js +18 -2
  27. package/soundfont/dls/articulator_converter.js +311 -0
  28. package/soundfont/dls/dls_destinations.js +38 -0
  29. package/soundfont/dls/dls_preset.js +15 -8
  30. package/soundfont/dls/dls_sample.js +58 -0
  31. package/soundfont/dls/dls_soundfont.js +68 -11
  32. package/soundfont/dls/dls_sources.js +26 -0
  33. package/soundfont/dls/dls_zone.js +75 -0
  34. package/soundfont/dls/read_articulation.js +327 -0
  35. package/soundfont/dls/read_instrument.js +82 -4
  36. package/soundfont/dls/read_instrument_list.js +6 -6
  37. package/soundfont/dls/read_lart.js +35 -0
  38. package/soundfont/dls/read_region.js +129 -0
  39. package/soundfont/dls/read_samples.js +174 -0
  40. package/soundfont/read_sf2/generators.js +41 -6
  41. package/soundfont/read_sf2/modulators.js +3 -3
  42. package/synthetizer/worklet_processor.min.js +10 -8
  43. package/utils/buffer_to_wav.js +5 -26
@@ -42,12 +42,12 @@ export class BasicSample {
42
42
  */
43
43
  sampleType: number;
44
44
  /**
45
- * Relative to start of the sample, bytes
45
+ * Relative to start of the sample, bytes assuming 16 bit
46
46
  * @type {number}
47
47
  */
48
48
  sampleLoopStartIndex: number;
49
49
  /**
50
- * Relative to start of the sample, in bytes
50
+ * Relative to start of the sample, in bytes assuming 16 bit
51
51
  * @type {number}
52
52
  */
53
53
  sampleLoopEndIndex: number;
@@ -5,30 +5,30 @@
5
5
  */
6
6
  export class BasicZone {
7
7
  /**
8
- * The zone's generators
9
- * @type {Generator[]}
8
+ * The zone's velocity range
9
+ * @type {SoundFontRange}
10
10
  */
11
- generators: Generator[];
11
+ velRange: SoundFontRange;
12
12
  /**
13
- * The zone's modulators
14
- * @type {Modulator[]}
13
+ * The zone's key range
14
+ * @type {SoundFontRange}
15
15
  */
16
- modulators: Modulator[];
16
+ keyRange: SoundFontRange;
17
17
  /**
18
18
  * Indicates if the zone is global
19
19
  * @type {boolean}
20
20
  */
21
21
  isGlobal: boolean;
22
22
  /**
23
- * The zone's key range
24
- * @type {SoundFontRange}
23
+ * The zone's generators
24
+ * @type {Generator[]}
25
25
  */
26
- keyRange: SoundFontRange;
26
+ generators: Generator[];
27
27
  /**
28
- * The zone's velocity range
29
- * @type {SoundFontRange}
28
+ * The zone's modulators
29
+ * @type {Modulator[]}
30
30
  */
31
- velRange: SoundFontRange;
31
+ modulators: Modulator[];
32
32
  }
33
33
  export type SoundFontRange = {
34
34
  /**
@@ -4,6 +4,10 @@ export class BasicInstrumentZone extends BasicZone {
4
4
  * @type {BasicSample|undefined}
5
5
  */
6
6
  sample: BasicSample | undefined;
7
+ /**
8
+ * The zone's use count
9
+ * @type {number}
10
+ */
7
11
  useCount: number;
8
12
  deleteZone(): void;
9
13
  }
@@ -18,6 +18,12 @@ export function writeRIFFChunk(chunk: RiffChunk, prepend?: IndexedByteArray): In
18
18
  * @returns {IndexedByteArray}
19
19
  */
20
20
  export function writeRIFFOddSize(header: string, data: Uint8Array, addZeroByte?: boolean): IndexedByteArray;
21
+ /**
22
+ * @param collection {RiffChunk[]}
23
+ * @param type {string}
24
+ * @returns {RiffChunk|undefined}
25
+ */
26
+ export function findRIFFListType(collection: RiffChunk[], type: string): RiffChunk | undefined;
21
27
  /**
22
28
  * riff_chunk.js
23
29
  * reads a riff read and stores it as a class
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @param source {number}
3
+ * @param control {number}
4
+ * @param destination {number}
5
+ * @param transform {number}
6
+ * @param value {number}
7
+ * @returns {Modulator|undefined}
8
+ */
9
+ export function getSF2ModulatorFromArticulator(source: number, control: number, destination: number, transform: number, value: number): Modulator | undefined;
10
+ import { Modulator } from '../read_sf2/modulators.js';
@@ -0,0 +1,29 @@
1
+ export type DLSDestinations = number;
2
+ export namespace DLSDestinations {
3
+ let none: number;
4
+ let gain: number;
5
+ let reserved: number;
6
+ let pitch: number;
7
+ let pan: number;
8
+ let keyNum: number;
9
+ let chorusSend: number;
10
+ let reverbSend: number;
11
+ let modLfoFreq: number;
12
+ let modLfoDelay: number;
13
+ let vibLfoFreq: number;
14
+ let vibLfoDelay: number;
15
+ let volEnvAttack: number;
16
+ let volEnvDecay: number;
17
+ let volEnvRelease: number;
18
+ let volEnvSustain: number;
19
+ let volEnvDelay: number;
20
+ let volEnvHold: number;
21
+ let modEnvAttack: number;
22
+ let modEnvDecay: number;
23
+ let modEnvRelease: number;
24
+ let modEnvSustain: number;
25
+ let modEnvDelay: number;
26
+ let modEnvHold: number;
27
+ let filterCutoff: number;
28
+ let filterQ: number;
29
+ }
@@ -1,11 +1,13 @@
1
1
  export class DLSPreset extends BasicPreset {
2
2
  /**
3
3
  * Creates a new DLS preset
4
- * @param ulBank {number} the ULONG value
5
- * @param ulInstrument {number} the ULONG value
6
- * @param regionsAmount {number}
4
+ * @param ulBank {number}
5
+ * @param ulInstrument {number}
7
6
  */
8
- constructor(ulBank: number, ulInstrument: number, regionsAmount: number);
9
- regionsAmount: number;
7
+ constructor(ulBank: number, ulInstrument: number);
8
+ DLSInstrument: BasicInstrument;
9
+ presetZones: BasicPresetZone[];
10
10
  }
11
11
  import { BasicPreset } from '../basic_soundfont/basic_preset.js';
12
+ import { BasicInstrument } from '../basic_soundfont/basic_instrument.js';
13
+ import { BasicPresetZone } from '../basic_soundfont/basic_zones.js';
@@ -0,0 +1,18 @@
1
+ export class DLSSample extends BasicSample {
2
+ /**
3
+ * @param name {string}
4
+ * @param rate {number}
5
+ * @param pitch {number}
6
+ * @param pitchCorrection {number}
7
+ * @param loopStart {number} sample data points
8
+ * @param loopEnd {number} sample data points
9
+ * @param data {Float32Array}
10
+ */
11
+ constructor(name: string, rate: number, pitch: number, pitchCorrection: number, loopStart: number, loopEnd: number, data: Float32Array);
12
+ /**
13
+ * @type {Float32Array}
14
+ */
15
+ sampleData: Float32Array;
16
+ getRawData(): Uint8Array;
17
+ }
18
+ import { BasicSample } from '../basic_soundfont/basic_sample.js';
@@ -4,8 +4,8 @@ export class DLSSoundFont extends BasicSoundFont {
4
4
  * @param buffer {ArrayBuffer}
5
5
  */
6
6
  constructor(buffer: ArrayBuffer);
7
- dataArray: any;
8
- instrumentAmount: any;
7
+ dataArray: IndexedByteArray;
8
+ instrumentAmount: number;
9
9
  /**
10
10
  * @param chunk {RiffChunk}
11
11
  * @param expected {string}
@@ -18,7 +18,14 @@ export class DLSSoundFont extends BasicSoundFont {
18
18
  verifyText(text: string, expected: string): void;
19
19
  readDLSInstrumentList: typeof readDLSInstrumentList;
20
20
  readDLSInstrument: typeof readDLSInstrument;
21
+ readRegion: typeof readRegion;
22
+ readLart: typeof readLart;
23
+ readDLSSamples: typeof readDLSSamples;
21
24
  }
22
25
  import { BasicSoundFont } from '../basic_soundfont/basic_soundfont.js';
26
+ import { IndexedByteArray } from '../../utils/indexed_array.js';
23
27
  import { readDLSInstrumentList } from './read_instrument_list.js';
24
28
  import { readDLSInstrument } from './read_instrument.js';
29
+ import { readRegion } from './read_region.js';
30
+ import { readLart } from './read_lart.js';
31
+ import { readDLSSamples } from './read_samples.js';
@@ -0,0 +1,22 @@
1
+ export type DLSSources = number;
2
+ export namespace DLSSources {
3
+ let none: number;
4
+ let modLfo: number;
5
+ let velocity: number;
6
+ let keyNum: number;
7
+ let volEnv: number;
8
+ let modEnv: number;
9
+ let pitchWheel: number;
10
+ let polyPressure: number;
11
+ let channelPressure: number;
12
+ let vibratoLfo: number;
13
+ let modulationWheel: number;
14
+ let volume: number;
15
+ let pan: number;
16
+ let expression: number;
17
+ let chorus: number;
18
+ let reverb: number;
19
+ let pitchWheelRange: number;
20
+ let fineTune: number;
21
+ let coarseTune: number;
22
+ }
@@ -0,0 +1,22 @@
1
+ export class DLSZone extends BasicInstrumentZone {
2
+ /**
3
+ * @param keyRange {SoundFontRange}
4
+ * @param velRange {SoundFontRange}
5
+ */
6
+ constructor(keyRange: SoundFontRange, velRange: SoundFontRange);
7
+ keyRange: SoundFontRange;
8
+ velRange: SoundFontRange;
9
+ /**
10
+ * @param attenuationCb {number} with EMU correction
11
+ * @param loopingMode {number} the sfont one
12
+ * @param loop {{start: number, end: number}}
13
+ * @param sampleKey {number}
14
+ * @param sample {BasicSample}
15
+ * @param sampleID {number}
16
+ */
17
+ setWavesample(attenuationCb: number, loopingMode: number, loop: {
18
+ start: number;
19
+ end: number;
20
+ }, sampleKey: number, sample: BasicSample, sampleID: number): void;
21
+ }
22
+ import { BasicInstrumentZone } from '../basic_soundfont/basic_zones.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Reads the articulator chunk
3
+ * @param chunk {RiffChunk}
4
+ * @param disableVibrato {boolean} it seems that dls 1 does not have vibrato lfo, so we shall disable it
5
+ * @returns {{modulators: Modulator[], generators: Generator[]}}
6
+ */
7
+ export function readArticulation(chunk: RiffChunk, disableVibrato: boolean): {
8
+ modulators: Modulator[];
9
+ generators: Generator[];
10
+ };
11
+ import { Modulator } from '../read_sf2/modulators.js';
12
+ import { Generator } from '../read_sf2/generators.js';
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * @this {DLSSoundFont}
3
- * @param dataArray {IndexedByteArray}
3
+ * @param instrumentListChunk {RiffChunk}
4
4
  */
5
- export function readDLSInstrumentList(this: DLSSoundFont, dataArray: IndexedByteArray): void;
5
+ export function readDLSInstrumentList(this: DLSSoundFont, instrumentListChunk: RiffChunk): void;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @param lartChunk {RiffChunk|undefined}
3
+ * @param lar2Chunk {RiffChunk|undefined}
4
+ * @param zone {BasicInstrumentZone}
5
+ * @this {DLSSoundFont}
6
+ */
7
+ export function readLart(this: DLSSoundFont, lartChunk: RiffChunk | undefined, lar2Chunk: RiffChunk | undefined, zone: BasicInstrumentZone): void;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @this {DLSSoundFont}
3
+ * @param chunk {RiffChunk}
4
+ * @returns {DLSZone}
5
+ */
6
+ export function readRegion(this: DLSSoundFont, chunk: RiffChunk): DLSZone;
7
+ import { DLSZone } from './dls_zone.js';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @this {DLSSoundFont}
3
+ * @param waveListChunk {RiffChunk}
4
+ */
5
+ export function readDLSSamples(this: DLSSoundFont, waveListChunk: RiffChunk): void;
@@ -84,16 +84,29 @@ export const generatorLimits: {
84
84
  def: number;
85
85
  }[];
86
86
  export class Generator {
87
+ /**
88
+ * Constructs a new generator
89
+ * @param type {generatorTypes|number}
90
+ * @param value {number}
91
+ */
92
+ constructor(type?: generatorTypes | number, value?: number);
93
+ /**
94
+ * The generator's enum number
95
+ * @type {generatorTypes|number}
96
+ */
97
+ generatorType: generatorTypes | number;
98
+ /**
99
+ * The generator's 16-bit value
100
+ * @type {number}
101
+ */
102
+ generatorValue: number;
103
+ }
104
+ export class ReadGenerator extends Generator {
87
105
  /**
88
106
  * Creates a generator
89
107
  * @param dataArray {IndexedByteArray}
90
108
  */
91
109
  constructor(dataArray: IndexedByteArray);
92
- /**
93
- * @type {generatorTypes}
94
- **/
95
- generatorType: generatorTypes;
96
- generatorValue: number;
97
110
  }
98
111
  import { RiffChunk } from '../basic_soundfont/riff_chunk.js';
99
112
  import { IndexedByteArray } from '../../utils/indexed_array.js';
@@ -1,3 +1,4 @@
1
+ export function getModSourceEnum(curveType: any, polarity: any, direction: any, isCC: any, index: any): number;
1
2
  /**
2
3
  * Reads the modulator read
3
4
  * @param modulatorChunk {RiffChunk}
package/README.md CHANGED
@@ -82,6 +82,7 @@ document.getElementById("button").onclick = async () => {
82
82
  #### Read and write [RMID files with embedded SF2 soundfonts](https://github.com/spessasus/sf2-rmidi-specification#readme)
83
83
  - **[Level 4](https://github.com/spessasus/sf2-rmidi-specification#level-4) compliance:** Reads and writes *everything!*
84
84
  - **Compression and trimming support:** Reduce a MIDI file with a 1GB soundfont to **as small as 5MB**!
85
+ - **DLS Version support:** The original legacy format with bank offset detection!
85
86
  - **Automatic bank shifting and validation:** Every soundfont *just works!*
86
87
  - **Metadata support:** Add title, artist, album name and cover and more! And of course read them too! *(In any encoding!)*
87
88
  - **Compatible with [Falcosoft Midi Player 6!](https://falcosoft.hu/softwares.html#midiplayer)**
@@ -98,5 +99,14 @@ document.getElementById("button").onclick = async () => {
98
99
  - **Variable compression quality:** You choose between file size and quality!
99
100
  - **Compression preserving:** Avoid decompressing and recompressing uncompressed samples for minimal quality loss!
100
101
 
102
+ #### Read and play DLS Level 1 or 2 files
103
+ - Read DLS (DownLoadable Sounds) files as SF2 files!
104
+ - **Works like a normal soundfont:** *Saving is still [just one function!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#write)*
105
+ - Converts articulators to both **modulators** and **generators**!
106
+ - Works with both unsigned 8-bit samples and signed 16-bit samples!
107
+ - **Covers special generator cases:** *such as modLfoToPitch*!
108
+ - **Correct volume:** *looking at you, Viena and gm.sf2!*
109
+ - Support built right into the synthesizer!
110
+
101
111
  ## License
102
112
  MIT License, except for the stbvorbis_sync.js in the `externals` folder which is licensed under the Apache-2.0 license.
@@ -1,7 +1,7 @@
1
1
  import { dataBytesAmount, getChannel, messageTypes, MidiMessage } from './midi_message.js'
2
2
  import { IndexedByteArray } from '../utils/indexed_array.js'
3
3
  import { arrayToHexString, consoleColors, formatTitle } from '../utils/other.js'
4
- import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from '../utils/loggin.js'
4
+ import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo, SpessaSynthWarn } from '../utils/loggin.js'
5
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'
@@ -33,6 +33,8 @@ class MIDI extends BasicMIDI
33
33
 
34
34
  let nameDetected = false;
35
35
 
36
+ let DLSRMID = false;
37
+
36
38
  const initialString = readBytesAsString(binaryData, 4);
37
39
  binaryData.currentIndex -= 4;
38
40
  if(initialString === "RIFF")
@@ -62,12 +64,21 @@ class MIDI extends BasicMIDI
62
64
  const currentChunk = readRIFFChunk(binaryData, true);
63
65
  if(currentChunk.header === "RIFF")
64
66
  {
65
- const type = readBytesAsString(currentChunk.chunkData, 4);
66
- if(type === "sfbk" || type === "sfpk")
67
+ const type = readBytesAsString(currentChunk.chunkData, 4).toLowerCase();
68
+ if(type === "sfbk" || type === "sfpk" || type === "dls ")
67
69
  {
68
70
  SpessaSynthInfo("%cFound embedded soundfont!", consoleColors.recognized);
69
71
  this.embeddedSoundFont = binaryData.slice(startIndex, startIndex + currentChunk.size).buffer;
70
72
  }
73
+ else
74
+ {
75
+ SpessaSynthWarn(`Unknown RIFF chunk: "${type}"`);
76
+ }
77
+ if(type === "dls ")
78
+ {
79
+ // assume bank offset of 0 by default. If we find any bank selects, then the offset is 1.
80
+ DLSRMID = true;
81
+ }
71
82
  }
72
83
  else if(currentChunk.header === "LIST")
73
84
  {
@@ -109,6 +120,13 @@ class MIDI extends BasicMIDI
109
120
  }
110
121
  }
111
122
  }
123
+
124
+ if(DLSRMID)
125
+ {
126
+ console.log(DLSRMID)
127
+ // assume bank offset of 0 by default. If we find any bank selects, then the offset is 1.
128
+ this.bankOffset = 0;
129
+ }
112
130
  }
113
131
  else
114
132
  {
@@ -388,6 +406,15 @@ class MIDI extends BasicMIDI
388
406
  loopEnd = 0;
389
407
  }
390
408
  break;
409
+
410
+ case 0:
411
+ // check RMID
412
+ if(DLSRMID && eventData[1] !== 0 && eventData[1] !== 127)
413
+ {
414
+ SpessaSynthInfo("%cDLS RMIDI with offset 1 detected!",
415
+ consoleColors.recognized);
416
+ this.bankOffset = 1;
417
+ }
391
418
  }
392
419
  }
393
420
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spessasynth_lib",
3
- "version": "3.17.0",
3
+ "version": "3.20.0",
4
4
  "description": "No compromise MIDI and SoundFont2 Synthesizer library",
5
5
  "browser": "index.js",
6
6
  "types": "@types/index.d.ts",
@@ -3,6 +3,10 @@ The code here is responsible for parsing the SoundFont2 file and
3
3
  providing an easy way to get the data out.
4
4
  Default modulators are also stored here (in `modulators.js`)
5
5
 
6
- `read` folder contains the classes that represent the soundfont file
6
+ `basic_soundfont` folder contains the classes that represent the soundfont file.
7
7
 
8
- `write` folder contains the code for writing out an `.sf2` file.
8
+ `read_sf2` folder contains the code for reading an `.sf2` file.
9
+
10
+ `write` folder contains the code for writing out an `.sf2` file.
11
+
12
+ `dls` folder contains the code for reading a `.dls` file (and converting in into a soundfont representation).
@@ -58,15 +58,15 @@ export class BasicSample {
58
58
  */
59
59
  this.sampleType = sampleType
60
60
  /**
61
- * Relative to start of the sample, bytes
61
+ * Relative to start of the sample, bytes assuming 16 bit
62
62
  * @type {number}
63
63
  */
64
64
  this.sampleLoopStartIndex = loopStart
65
65
  /**
66
- * Relative to start of the sample, in bytes
66
+ * Relative to start of the sample, in bytes assuming 16 bit
67
67
  * @type {number}
68
68
  */
69
- this.sampleLoopEndIndex = loopEnd
69
+ this.sampleLoopEndIndex = loopEnd;
70
70
 
71
71
  /**
72
72
  * Indicates if the sample is compressed
@@ -6,34 +6,34 @@
6
6
 
7
7
  export class BasicZone
8
8
  {
9
- constructor()
10
- {
11
- /**
12
- * The zone's generators
13
- * @type {Generator[]}
14
- */
15
- this.generators = [];
16
- /**
17
- * The zone's modulators
18
- * @type {Modulator[]}
19
- */
20
- this.modulators = [];
21
- /**
22
- * Indicates if the zone is global
23
- * @type {boolean}
24
- */
25
- this.isGlobal = false;
26
- /**
27
- * The zone's key range
28
- * @type {SoundFontRange}
29
- */
30
- this.keyRange = { min: 0, max: 127 };
9
+ /**
10
+ * The zone's velocity range
11
+ * @type {SoundFontRange}
12
+ */
13
+ velRange = { min: 0, max: 127 };
31
14
 
32
- /**
33
- * The zone's velocity range
34
- * @type {SoundFontRange}
35
- */
36
- this.velRange = { min: 0, max: 127 };
37
- }
15
+ /**
16
+ * The zone's key range
17
+ * @type {SoundFontRange}
18
+ */
19
+ keyRange = { min: 0, max: 127 };
20
+
21
+ /**
22
+ * Indicates if the zone is global
23
+ * @type {boolean}
24
+ */
25
+ isGlobal = false;
26
+
27
+ /**
28
+ * The zone's generators
29
+ * @type {Generator[]}
30
+ */
31
+ generators = [];
32
+
33
+ /**
34
+ * The zone's modulators
35
+ * @type {Modulator[]}
36
+ */
37
+ modulators = [];
38
38
  }
39
39
 
@@ -2,16 +2,16 @@ import { BasicZone } from './basic_zone.js'
2
2
 
3
3
  export class BasicInstrumentZone extends BasicZone
4
4
  {
5
- constructor()
6
- {
7
- super()
8
- /**
9
- * Zone's sample. Undefined if global
10
- * @type {BasicSample|undefined}
11
- */
12
- this.sample = undefined
13
- this.useCount = 0
14
- }
5
+ /**
6
+ * Zone's sample. Undefined if global
7
+ * @type {BasicSample|undefined}
8
+ */
9
+ sample = undefined;
10
+ /**
11
+ * The zone's use count
12
+ * @type {number}
13
+ */
14
+ useCount = 0;
15
15
 
16
16
  deleteZone()
17
17
  {
@@ -26,15 +26,11 @@ export class BasicInstrumentZone extends BasicZone
26
26
 
27
27
  export class BasicPresetZone extends BasicZone
28
28
  {
29
- constructor()
30
- {
31
- super()
32
- /**
33
- * Zone's instrument. Undefined if global
34
- * @type {BasicInstrument|undefined}
35
- */
36
- this.instrument = undefined
37
- }
29
+ /**
30
+ * Zone's instrument. Undefined if global
31
+ * @type {BasicInstrument|undefined}
32
+ */
33
+ instrument = undefined
38
34
 
39
35
  deleteZone()
40
36
  {
@@ -37,8 +37,7 @@ export function readRIFFChunk(dataArray, readData = true, forceShift = false) {
37
37
  let chunkData = undefined
38
38
  if (readData)
39
39
  {
40
- chunkData = new IndexedByteArray(size)
41
- chunkData.set(dataArray.slice(dataArray.currentIndex, dataArray.currentIndex + size))
40
+ chunkData = new IndexedByteArray(dataArray.buffer.slice(dataArray.currentIndex, dataArray.currentIndex + size))
42
41
  }
43
42
  if(readData || forceShift)
44
43
  {
@@ -112,4 +111,21 @@ export function writeRIFFOddSize(header, data, addZeroByte = false)
112
111
  writeDword(outArray, data.length);
113
112
  outArray.set(data, 8);
114
113
  return outArray;
114
+ }
115
+
116
+ /**
117
+ * @param collection {RiffChunk[]}
118
+ * @param type {string}
119
+ * @returns {RiffChunk|undefined}
120
+ */
121
+ export function findRIFFListType(collection, type)
122
+ {
123
+ return collection.find(c => {
124
+ if(c.header !== "LIST")
125
+ {
126
+ return false;
127
+ }
128
+ c.chunkData.currentIndex = 0;
129
+ return readBytesAsString(c.chunkData, 4) === type;
130
+ });
115
131
  }