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.
- package/README.md +1 -1
- package/midi_parser/basic_midi.js +0 -28
- package/package.json +1 -1
- package/soundfont/basic_soundfont/basic_instrument.js +18 -14
- package/soundfont/basic_soundfont/basic_preset.js +64 -59
- package/soundfont/basic_soundfont/basic_sample.js +75 -55
- package/soundfont/basic_soundfont/basic_soundfont.js +121 -68
- package/soundfont/dls/dls_preset.js +3 -3
- package/soundfont/dls/dls_soundfont.js +1 -1
- package/soundfont/dls/dls_sources.js +3 -2
- package/soundfont/dls/read_instrument.js +1 -1
- package/soundfont/read_sf2/presets.js +6 -6
- package/soundfont/read_sf2/samples.js +19 -18
- package/soundfont/read_sf2/soundfont.js +2 -2
- package/soundfont/read_sf2/zones.js +2 -3
- package/synthetizer/synthetizer.js +21 -0
- package/synthetizer/worklet_processor.min.js +11 -11
- package/synthetizer/worklet_system/worklet_methods/controller_control/master_parameters.js +3 -1
- package/synthetizer/worklet_system/worklet_methods/program_change.js +1 -0
- package/synthetizer/worklet_system/worklet_methods/soundfont_management/reload_sound_font.js +0 -2
- package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +0 -13
- package/synthetizer/worklet_system/worklet_utilities/lowpass_filter.js +16 -10
|
@@ -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
|
|
16
|
+
* @param sf2 {BasicSoundBank}
|
|
17
17
|
*/
|
|
18
|
-
constructor(presetChunk,
|
|
18
|
+
constructor(presetChunk, sf2)
|
|
19
19
|
{
|
|
20
|
-
super(
|
|
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
|
|
55
|
+
* @param sf2 {BasicSoundBank}
|
|
56
56
|
* @returns {Preset[]}
|
|
57
57
|
*/
|
|
58
|
-
export function readPresets(presetChunk, presetZones,
|
|
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,
|
|
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
|
|
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(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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 {
|
|
220
|
+
* @returns {SoundFontSample[]}
|
|
220
221
|
*/
|
|
221
222
|
export function readSamples(sampleHeadersChunk, smplChunkData, isSmplDataRaw = true)
|
|
222
223
|
{
|
|
223
224
|
/**
|
|
224
|
-
* @type {
|
|
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 {
|
|
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
|
|
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
|
|
250
|
+
this.presets.push(...readPresets(presetHeadersChunk, presetZones, this));
|
|
251
251
|
this.presets.sort((a, b) => (a.program - b.program) + (a.bank - b.bank));
|
|
252
|
-
|
|
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 {
|
|
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 {
|
|
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
|
*/
|