spessasynth_lib 3.25.4 → 3.25.6

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.
@@ -38,7 +38,7 @@ export function readDLSInstrument(chunk)
38
38
  const regions = readLittleEndian(instrumentHeader.chunkData, 4);
39
39
  const ulBank = readLittleEndian(instrumentHeader.chunkData, 4);
40
40
  const ulInstrument = readLittleEndian(instrumentHeader.chunkData, 4);
41
- const preset = new DLSPreset(ulBank, ulInstrument);
41
+ const preset = new DLSPreset(this, ulBank, ulInstrument);
42
42
 
43
43
  // read preset name in INFO
44
44
  let presetName = "unnamedPreset";
@@ -13,11 +13,11 @@ export class Preset extends BasicPreset
13
13
  /**
14
14
  * Creates a preset
15
15
  * @param presetChunk {RiffChunk}
16
- * @param defaultModulators {Modulator[]}
16
+ * @param sf2 {BasicSoundBank}
17
17
  */
18
- constructor(presetChunk, defaultModulators)
18
+ constructor(presetChunk, sf2)
19
19
  {
20
- super(defaultModulators);
20
+ super(sf2);
21
21
  this.presetName = readBytesAsString(presetChunk.chunkData, 20)
22
22
  .trim()
23
23
  .replace(/\d{3}:\d{3}/, ""); // remove those pesky "000:001"
@@ -52,10 +52,10 @@ export class Preset extends BasicPreset
52
52
  * Reads the presets
53
53
  * @param presetChunk {RiffChunk}
54
54
  * @param presetZones {PresetZone[]}
55
- * @param defaultModulators {Modulator[]}
55
+ * @param sf2 {BasicSoundBank}
56
56
  * @returns {Preset[]}
57
57
  */
58
- export function readPresets(presetChunk, presetZones, defaultModulators)
58
+ export function readPresets(presetChunk, presetZones, sf2)
59
59
  {
60
60
  /**
61
61
  * @type {Preset[]}
@@ -63,7 +63,7 @@ export function readPresets(presetChunk, presetZones, defaultModulators)
63
63
  let presets = [];
64
64
  while (presetChunk.chunkData.length > presetChunk.chunkData.currentIndex)
65
65
  {
66
- let preset = new Preset(presetChunk, defaultModulators);
66
+ let preset = new Preset(presetChunk, sf2);
67
67
  if (presets.length > 0)
68
68
  {
69
69
  let presetZonesAmount = preset.presetZoneStartIndex - presets[presets.length - 1].presetZoneStartIndex;
@@ -6,7 +6,7 @@ import { SpessaSynthWarn } from "../../utils/loggin.js";
6
6
  import { readBytesAsString } from "../../utils/byte_functions/string.js";
7
7
  import { BasicSample } from "../basic_soundfont/basic_sample.js";
8
8
 
9
- export class LoadedSample extends BasicSample
9
+ export class SoundFontSample extends BasicSample
10
10
  {
11
11
  /**
12
12
  * Creates a sample
@@ -25,19 +25,20 @@ export class LoadedSample extends BasicSample
25
25
  * @param isDataRaw {boolean} if false, the data is decoded as float32.
26
26
  * Used for SF2Pack support
27
27
  */
28
- constructor(sampleName,
29
- sampleStartIndex,
30
- sampleEndIndex,
31
- sampleLoopStartIndex,
32
- sampleLoopEndIndex,
33
- sampleRate,
34
- samplePitch,
35
- samplePitchCorrection,
36
- sampleLink,
37
- sampleType,
38
- smplArr,
39
- sampleIndex,
40
- isDataRaw
28
+ constructor(
29
+ sampleName,
30
+ sampleStartIndex,
31
+ sampleEndIndex,
32
+ sampleLoopStartIndex,
33
+ sampleLoopEndIndex,
34
+ sampleRate,
35
+ samplePitch,
36
+ samplePitchCorrection,
37
+ sampleLink,
38
+ sampleType,
39
+ smplArr,
40
+ sampleIndex,
41
+ isDataRaw
41
42
  )
42
43
  {
43
44
  super(
@@ -216,12 +217,12 @@ export class LoadedSample extends BasicSample
216
217
  * @param sampleHeadersChunk {RiffChunk}
217
218
  * @param smplChunkData {IndexedByteArray|Float32Array}
218
219
  * @param isSmplDataRaw {boolean}
219
- * @returns {LoadedSample[]}
220
+ * @returns {SoundFontSample[]}
220
221
  */
221
222
  export function readSamples(sampleHeadersChunk, smplChunkData, isSmplDataRaw = true)
222
223
  {
223
224
  /**
224
- * @type {LoadedSample[]}
225
+ * @type {SoundFontSample[]}
225
226
  */
226
227
  let samples = [];
227
228
  let index = 0;
@@ -245,7 +246,7 @@ export function readSamples(sampleHeadersChunk, smplChunkData, isSmplDataRaw = t
245
246
  * @param sampleHeaderData {IndexedByteArray}
246
247
  * @param smplArrayData {IndexedByteArray|Float32Array}
247
248
  * @param isDataRaw {boolean} true means binary 16-bit data, false means float32
248
- * @returns {LoadedSample}
249
+ * @returns {SoundFontSample}
249
250
  */
250
251
  function readSample(index, sampleHeaderData, smplArrayData, isDataRaw)
251
252
  {
@@ -285,7 +286,7 @@ function readSample(index, sampleHeaderData, smplArrayData, isDataRaw)
285
286
  let sampleType = readLittleEndian(sampleHeaderData, 2);
286
287
 
287
288
 
288
- return new LoadedSample(
289
+ return new SoundFontSample(
289
290
  sampleName,
290
291
  sampleStartIndex,
291
292
  sampleEndIndex,
@@ -247,9 +247,9 @@ export class SoundFont2 extends BasicSoundBank
247
247
 
248
248
  let presetZones = readPresetZones(presetZonesChunk, presetGenerators, presetModulators, this.instruments);
249
249
 
250
- this.presets.push(...readPresets(presetHeadersChunk, presetZones, this.defaultModulators));
250
+ this.presets.push(...readPresets(presetHeadersChunk, presetZones, this));
251
251
  this.presets.sort((a, b) => (a.program - b.program) + (a.bank - b.bank));
252
- // preload the first preset
252
+ this._parseInternal();
253
253
  SpessaSynthInfo(
254
254
  `%cParsing finished! %c"${this.soundFontInfo["INAM"]}"%c has %c${this.presets.length} %cpresets,
255
255
  %c${this.instruments.length}%c instruments and %c${this.samples.length}%c samples.`,
@@ -1,7 +1,6 @@
1
1
  import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
2
2
  import { IndexedByteArray } from "../../utils/indexed_array.js";
3
3
  import { RiffChunk } from "../basic_soundfont/riff_chunk.js";
4
- import { Instrument } from "./instruments.js";
5
4
  import { BasicInstrumentZone, BasicPresetZone } from "../basic_soundfont/basic_zones.js";
6
5
  import { Generator, generatorTypes } from "../basic_soundfont/generator.js";
7
6
  import { Modulator } from "../basic_soundfont/modulator.js";
@@ -185,7 +184,7 @@ export class PresetZone extends BasicPresetZone
185
184
 
186
185
  /**
187
186
  * grab the instrument
188
- * @param instruments {Instrument[]}
187
+ * @param instruments {BasicInstrument[]}
189
188
  */
190
189
  getInstrument(instruments)
191
190
  {
@@ -229,7 +228,7 @@ export class PresetZone extends BasicPresetZone
229
228
  * Reads the given preset zone read
230
229
  * @param zonesChunk {RiffChunk}
231
230
  * @param presetGenerators {Generator[]}
232
- * @param instruments {Instrument[]}
231
+ * @param instruments {BasicInstrument[]}
233
232
  * @param presetModulators {Modulator[]}
234
233
  * @returns {PresetZone[]}
235
234
  */
@@ -155,6 +155,9 @@ export class Synthetizer
155
155
  return new AudioWorkletNode(ctx, name, opts);
156
156
  };
157
157
  }
158
+ /**
159
+ * @type {AudioWorkletNode}
160
+ */
158
161
  this.worklet = workletConstructor(this.context, WORKLET_PROCESSOR_NAME, {
159
162
  outputChannelCount: processorChannelCount,
160
163
  numberOfOutputs: processorOutputsCount,
@@ -526,6 +529,24 @@ export class Synthetizer
526
529
  }
527
530
  }
528
531
 
532
+ /**
533
+ * Disconnects the individual audio outputs to the given audio nodes. In the app, it's used by the renderer.
534
+ * @param audioNodes {AudioNode[]}
535
+ */
536
+ disconnectIndividualOutputs(audioNodes)
537
+ {
538
+ if (audioNodes.length !== this._outputsAmount)
539
+ {
540
+ throw new Error(`input nodes amount differs from the system's outputs amount!
541
+ Expected ${this._outputsAmount} got ${audioNodes.length}`);
542
+ }
543
+ for (let outputNumber = 0; outputNumber < this._outputsAmount; outputNumber++)
544
+ {
545
+ // + 2 because chorus and reverb come first!
546
+ this.worklet.disconnect(audioNodes[outputNumber], outputNumber + 2);
547
+ }
548
+ }
549
+
529
550
  /*
530
551
  * Disables the GS NRPN parameters like vibrato or drum key tuning.
531
552
  */