spessasynth_core 3.26.39 → 3.26.41

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spessasynth_core",
3
- "version": "3.26.39",
3
+ "version": "3.26.41",
4
4
  "description": "MIDI and SoundFont2/DLS library with no compromises",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -35,16 +35,16 @@ const DEFAULT_COPYRIGHT = "Created using SpessaSynth";
35
35
 
36
36
  /**
37
37
  * @typedef {Object} RMIDMetadata
38
- * @property {string|undefined} name - the name of the file
39
- * @property {string|undefined} engineer - the engineer who worked on the file
40
- * @property {string|undefined} artist - the artist
41
- * @property {string|undefined} album - the album
42
- * @property {string|undefined} genre - the genre of the song
43
- * @property {ArrayBuffer|undefined} picture - the image for the file (album cover)
44
- * @property {string|undefined} comment - the coment of the file
45
- * @property {string|undefined} creationDate - the creation date of the file
46
- * @property {string|undefined} copyright - the copyright of the file
47
- * @property {string|unescape} midiEncoding - the encoding of the inner MIDI file
38
+ * @property {string} name - the name of the file
39
+ * @property {string} engineer - the engineer who worked on the file
40
+ * @property {string} artist - the artist
41
+ * @property {string} album - the album
42
+ * @property {string} genre - the genre of the song
43
+ * @property {ArrayBuffer} picture - the image for the file (album cover)
44
+ * @property {string} comment - the coment of the file
45
+ * @property {string} creationDate - the creation date of the file
46
+ * @property {string} copyright - the copyright of the file
47
+ * @property {string} midiEncoding - the encoding of the inner MIDI file
48
48
  */
49
49
 
50
50
  /**
@@ -54,7 +54,7 @@ const DEFAULT_COPYRIGHT = "Created using SpessaSynth";
54
54
  * @param soundfont {BasicSoundBank}
55
55
  * @param bankOffset {number} the bank offset for RMIDI
56
56
  * @param encoding {string} the encoding of the RMIDI info chunk
57
- * @param metadata {RMIDMetadata} the metadata of the file. Optional. If provided, the encoding is forced to utf-8/
57
+ * @param metadata {Partial<RMIDMetadata>} the metadata of the file. Optional. If provided, the encoding is forced to utf-8/
58
58
  * @param correctBankOffset {boolean}
59
59
  * @returns {IndexedByteArray}
60
60
  */
@@ -85,6 +85,7 @@ export class BasicInstrument
85
85
  });
86
86
  }
87
87
 
88
+ // unlinks everything from this instrument
88
89
  deleteInstrument()
89
90
  {
90
91
  if (this.useCount > 0)
@@ -92,7 +93,6 @@ export class BasicInstrument
92
93
  throw new Error(`Cannot delete an instrument that is used by: ${this.linkedPresets.map(p => p.presetName)}.`);
93
94
  }
94
95
  this.instrumentZones.forEach(z => z.deleteZone());
95
- this.instrumentZones.length = 0;
96
96
  }
97
97
 
98
98
  /**
@@ -91,10 +91,10 @@ export class BasicPreset
91
91
  );
92
92
  }
93
93
 
94
+ // unlinks everything from this preset
94
95
  deletePreset()
95
96
  {
96
97
  this.presetZones.forEach(z => z.deleteZone());
97
- this.presetZones.length = 0;
98
98
  }
99
99
 
100
100
  /**
@@ -271,6 +271,11 @@ export class BasicSample
271
271
  */
272
272
  setLinkedSample(sample, type)
273
273
  {
274
+ // sanity check
275
+ if (sample.linkedSample)
276
+ {
277
+ throw new Error(`${sample.sampleName} is linked tp ${sample.linkedSample.sampleName}. Unlink it first.`);
278
+ }
274
279
  this.linkedSample = sample;
275
280
  sample.linkedSample = this;
276
281
  if (type === sampleTypes.leftSample)
@@ -263,7 +263,11 @@ class BasicSoundBank
263
263
  if (sample.linkedSample)
264
264
  {
265
265
  const clonedLinked = this.cloneSample(sample.linkedSample);
266
- newSample.setLinkedSample(clonedLinked, newSample.sampleType);
266
+ // sanity check
267
+ if (!clonedLinked.linkedSample)
268
+ {
269
+ newSample.setLinkedSample(clonedLinked, newSample.sampleType);
270
+ }
267
271
  }
268
272
  return newSample;
269
273
  }
@@ -10,7 +10,7 @@ import { fillWithDefaults } from "../../../utils/fill_with_defaults.js";
10
10
 
11
11
  /**
12
12
  * @typedef {Object} DLSWriteOptions
13
- * @property {ProgressFunction|undefined} progressFunction - a function to show progress for writing large banks. It can be undefined.
13
+ * @property {ProgressFunction} progressFunction - a function to show progress for writing large banks. It can be undefined.
14
14
  */
15
15
 
16
16
 
@@ -24,7 +24,7 @@ const DEFAULT_DLS_OPTIONS = {
24
24
  /**
25
25
  * Write the soundfont as a .dls file. Experimental
26
26
  * @this {BasicSoundBank}
27
- * @param {DLSWriteOptions|undefined} options - options for writing the file.
27
+ * @param {Partial<DLSWriteOptions>} options - options for writing the file.
28
28
  * @returns {Uint8Array}
29
29
  */
30
30
  export async function writeDLS(options = DEFAULT_DLS_OPTIONS)
@@ -26,15 +26,15 @@ import { fillWithDefaults } from "../../../utils/fill_with_defaults.js";
26
26
 
27
27
  /**
28
28
  * @typedef {Object} SoundFont2WriteOptions
29
- * @property {boolean|undefined} compress - if the soundfont should be compressed with a given function.
30
- * @property {SampleEncodingFunction|undefined} compressionFunction -
29
+ * @property {boolean} compress - if the soundfont should be compressed with a given function.
30
+ * @property {SampleEncodingFunction} compressionFunction -
31
31
  * the encode vorbis function. It can be undefined if not compressed.
32
- * @property {ProgressFunction|undefined} progressFunction - a function to show progress for writing large banks. It can be undefined.
33
- * @property {boolean|undefined} writeDefaultModulators - if the DMOD chunk should be written.
32
+ * @property {ProgressFunction} progressFunction - a function to show progress for writing large banks. It can be undefined.
33
+ * @property {boolean} writeDefaultModulators - if the DMOD chunk should be written.
34
34
  * Recommended.
35
- * @property {boolean|undefined} writeExtendedLimits - if the xdta chunk should be written to allow virtually infinite parameters.
35
+ * @property {boolean} writeExtendedLimits - if the xdta chunk should be written to allow virtually infinite parameters.
36
36
  * Recommended.
37
- * @property {boolean|undefined} decompress - if an sf3 bank should be decompressed back to sf2. Not recommended.
37
+ * @property {boolean} decompress - if an sf3 bank should be decompressed back to sf2. Not recommended.
38
38
  */
39
39
 
40
40
 
@@ -61,7 +61,7 @@ const DEFAULT_WRITE_OPTIONS = {
61
61
  /**
62
62
  * Write the soundfont as an .sf2 file
63
63
  * @this {BasicSoundBank}
64
- * @param {SoundFont2WriteOptions} options
64
+ * @param {Partial<SoundFont2WriteOptions>} options
65
65
  * @returns {Uint8Array}
66
66
  */
67
67
  export async function write(options = DEFAULT_WRITE_OPTIONS)
@@ -3,7 +3,7 @@ import { IndexedByteArray } from "../../utils/indexed_array.js";
3
3
  import { readLittleEndian, signedInt8 } from "../../utils/byte_functions/little_endian.js";
4
4
  import { SpessaSynthInfo, SpessaSynthWarn } from "../../utils/loggin.js";
5
5
  import { readBytesAsString } from "../../utils/byte_functions/string.js";
6
- import { BasicSample, sampleTypes } from "../basic_soundfont/basic_sample.js";
6
+ import { BasicSample } from "../basic_soundfont/basic_sample.js";
7
7
  import { consoleColors } from "../../utils/other.js";
8
8
 
9
9
  /**
@@ -130,16 +130,28 @@ export class SoundFontSample extends BasicSample
130
130
  {
131
131
  return;
132
132
  }
133
- const linkedSample = samplesArray[this.linkedSampleIndex];
134
- if (!linkedSample)
133
+ const linked = samplesArray[this.linkedSampleIndex];
134
+ if (!linked)
135
135
  {
136
136
  // log as info because it's common and not really dangerous
137
137
  SpessaSynthInfo(`%cInvalid linked sample for ${this.sampleName}. Setting to mono.`, consoleColors.warn);
138
- this.setSampleType(sampleTypes.monoSample);
138
+ this.unlinkSample();
139
139
  }
140
140
  else
141
141
  {
142
- this.setLinkedSample(samplesArray[this.linkedSampleIndex], this.sampleType);
142
+ // check for corrupted files (like FluidR3_GM.sf2 that link EVERYTHING to a single sample)
143
+ if (linked.linkedSample)
144
+ {
145
+ SpessaSynthInfo(
146
+ `%cInvalid linked sample for ${this.sampleName}: Already linked to ${linked.linkedSample.sampleName}`,
147
+ consoleColors.warn
148
+ );
149
+ this.unlinkSample();
150
+ }
151
+ else
152
+ {
153
+ this.setLinkedSample(linked, this.sampleType);
154
+ }
143
155
  }
144
156
  }
145
157
 
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * @typedef {Object} WaveMetadata
3
- * @property {string|undefined} title - the song's title
4
- * @property {string|undefined} artist - the song's artist
5
- * @property {string|undefined} album - the song's album
6
- * @property {string|undefined} genre - the song's genre
3
+ * @property {string} title - the song's title
4
+ * @property {string} artist - the song's artist
5
+ * @property {string} album - the song's album
6
+ * @property {string} genre - the song's genre
7
7
  */
8
8
 
9
9
  import { IndexedByteArray } from "./indexed_array.js";
@@ -16,7 +16,7 @@ import { writeLittleEndian } from "./byte_functions/little_endian.js";
16
16
  * @param audioData {Float32Array[]} channels
17
17
  * @param sampleRate {number}
18
18
  * @param normalizeAudio {boolean} find the max sample point and set it to 1, and scale others with it
19
- * @param metadata {WaveMetadata}
19
+ * @param metadata {Partial<WaveMetadata>}
20
20
  * @param loop {{start: number, end: number}} loop start and end points in seconds. Undefined if no loop
21
21
  * @returns {ArrayBuffer}
22
22
  */