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.
- package/@types/index.d.ts +0 -2
- package/@types/soundfont/basic_soundfont/basic_instrument.d.ts +29 -0
- package/@types/soundfont/basic_soundfont/basic_preset.d.ts +76 -0
- package/@types/soundfont/basic_soundfont/basic_sample.d.ts +82 -0
- package/@types/soundfont/basic_soundfont/basic_soundfont.d.ts +80 -0
- package/@types/soundfont/basic_soundfont/basic_zone.d.ts +42 -0
- package/@types/soundfont/basic_soundfont/basic_zones.d.ts +18 -0
- package/@types/soundfont/{read → basic_soundfont}/riff_chunk.d.ts +2 -1
- package/@types/soundfont/basic_soundfont/write_sf2/ibag.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/igen.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/imod.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/inst.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/pbag.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/pgen.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/phdr.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/pmod.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/sdta.d.ts +11 -0
- package/@types/soundfont/basic_soundfont/write_sf2/shdr.d.ts +8 -0
- package/@types/soundfont/{write → basic_soundfont/write_sf2}/write.d.ts +2 -2
- package/@types/soundfont/{read → read_sf2}/generators.d.ts +2 -1
- package/@types/soundfont/{read → read_sf2}/instruments.d.ts +3 -24
- package/@types/soundfont/read_sf2/presets.d.ts +28 -0
- package/@types/soundfont/read_sf2/samples.d.ts +56 -0
- package/@types/soundfont/{read → read_sf2}/zones.d.ts +11 -53
- package/@types/soundfont/soundfont.d.ts +6 -67
- package/midi_parser/midi_loader.js +1 -1
- package/midi_parser/rmidi_writer.js +11 -11
- package/midi_parser/used_keys_loaded.js +1 -1
- package/package.json +1 -1
- package/sequencer/worklet_sequencer/song_control.js +1 -1
- package/soundfont/basic_soundfont/basic_instrument.js +73 -0
- package/soundfont/{read/presets.js → basic_soundfont/basic_preset.js} +54 -87
- package/soundfont/basic_soundfont/basic_sample.js +132 -0
- package/soundfont/basic_soundfont/basic_soundfont.js +193 -0
- package/soundfont/basic_soundfont/basic_zone.js +39 -0
- package/soundfont/basic_soundfont/basic_zones.js +47 -0
- package/soundfont/{read → basic_soundfont}/riff_chunk.js +8 -1
- package/soundfont/{write → basic_soundfont/write_sf2}/ibag.js +4 -4
- package/soundfont/{write → basic_soundfont/write_sf2}/igen.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/imod.js +4 -4
- package/soundfont/{write → basic_soundfont/write_sf2}/inst.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/pbag.js +4 -4
- package/soundfont/{write → basic_soundfont/write_sf2}/pgen.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/phdr.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/pmod.js +4 -4
- package/soundfont/{write → basic_soundfont/write_sf2}/sdta.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/shdr.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/soundfont_trimmer.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/write.js +8 -9
- package/soundfont/{read → read_sf2}/generators.js +2 -1
- package/soundfont/{read → read_sf2}/instruments.js +4 -63
- package/soundfont/{read → read_sf2}/modulators.js +1 -1
- package/soundfont/read_sf2/presets.js +78 -0
- package/soundfont/{read → read_sf2}/samples.js +4 -138
- package/soundfont/{read → read_sf2}/zones.js +14 -60
- package/soundfont/soundfont.js +21 -188
- package/synthetizer/worklet_processor.min.js +6 -6
- package/synthetizer/worklet_system/message_protocol/message_sending.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/data_entry.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/note_off.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/note_on.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/program_control.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/reset_controllers.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/tuning_control.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/voice_control.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/lowpass_filter.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/modulation_envelope.js +2 -2
- package/synthetizer/worklet_system/worklet_utilities/modulator_curves.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/volume_envelope.js +4 -4
- package/synthetizer/worklet_system/worklet_utilities/worklet_modulator.js +2 -2
- package/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/worklet_voice.js +1 -1
- package/utils/buffer_to_wav.js +6 -6
- package/@types/midi_parser/used_keys_loaded.d.ts +0 -10
- package/@types/soundfont/read/presets.d.ts +0 -88
- package/@types/soundfont/read/samples.d.ts +0 -138
- package/@types/soundfont/write/ibag.d.ts +0 -6
- package/@types/soundfont/write/igen.d.ts +0 -6
- package/@types/soundfont/write/imod.d.ts +0 -6
- package/@types/soundfont/write/inst.d.ts +0 -6
- package/@types/soundfont/write/pbag.d.ts +0 -6
- package/@types/soundfont/write/pgen.d.ts +0 -6
- package/@types/soundfont/write/phdr.d.ts +0 -6
- package/@types/soundfont/write/pmod.d.ts +0 -6
- package/@types/soundfont/write/sdta.d.ts +0 -11
- package/@types/soundfont/write/shdr.d.ts +0 -8
- package/@types/soundfont/write/soundfont_trimmer.d.ts +0 -6
- /package/@types/soundfont/{read → read_sf2}/modulators.d.ts +0 -0
package/soundfont/soundfont.js
CHANGED
|
@@ -1,36 +1,32 @@
|
|
|
1
1
|
import { IndexedByteArray } from '../utils/indexed_array.js'
|
|
2
|
-
import {readSamples} from "./
|
|
2
|
+
import {readSamples} from "./read_sf2/samples.js";
|
|
3
3
|
import { readBytesAsUintLittleEndian } from '../utils/byte_functions/little_endian.js'
|
|
4
|
-
import { readGenerators, Generator } from './
|
|
5
|
-
import {readInstrumentZones, InstrumentZone, readPresetZones} from "./
|
|
6
|
-
import {
|
|
7
|
-
import {readInstruments
|
|
8
|
-
import {readModulators, Modulator} from "./
|
|
9
|
-
import { readRIFFChunk, RiffChunk } from './
|
|
4
|
+
import { readGenerators, Generator } from './read_sf2/generators.js'
|
|
5
|
+
import {readInstrumentZones, InstrumentZone, readPresetZones} from "./read_sf2/zones.js";
|
|
6
|
+
import { readPresets } from "./read_sf2/presets.js";
|
|
7
|
+
import {readInstruments} from "./read_sf2/instruments.js";
|
|
8
|
+
import {readModulators, Modulator} from "./read_sf2/modulators.js";
|
|
9
|
+
import { readRIFFChunk, RiffChunk } from './basic_soundfont/riff_chunk.js'
|
|
10
10
|
import { consoleColors } from '../utils/other.js'
|
|
11
|
-
import { SpessaSynthGroup, SpessaSynthGroupEnd, SpessaSynthInfo
|
|
11
|
+
import { SpessaSynthGroup, SpessaSynthGroupEnd, SpessaSynthInfo } from '../utils/loggin.js'
|
|
12
12
|
import { readBytesAsString } from '../utils/byte_functions/string.js'
|
|
13
|
-
import { write } from './write/write.js'
|
|
14
13
|
import { stbvorbis } from "../externals/stbvorbis_sync/stbvorbis_sync.min.js";
|
|
14
|
+
import { BasicSoundFont } from './basic_soundfont/basic_soundfont.js'
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* soundfont.js
|
|
18
18
|
* purpose: parses a soundfont2 file
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
class SoundFont2
|
|
21
|
+
export class SoundFont2 extends BasicSoundFont
|
|
22
22
|
{
|
|
23
23
|
/**
|
|
24
24
|
* Initializes a new SoundFont2 Parser and parses the given data array
|
|
25
|
-
* @param arrayBuffer {ArrayBuffer
|
|
25
|
+
* @param arrayBuffer {ArrayBuffer}
|
|
26
26
|
*/
|
|
27
|
-
constructor(arrayBuffer)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.presets = arrayBuffer.presets;
|
|
31
|
-
this.soundFontInfo = arrayBuffer.info;
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
27
|
+
constructor(arrayBuffer)
|
|
28
|
+
{
|
|
29
|
+
super();
|
|
34
30
|
this.dataArray = new IndexedByteArray(arrayBuffer);
|
|
35
31
|
SpessaSynthGroup("%cParsing SoundFont...", consoleColors.info);
|
|
36
32
|
if(!this.dataArray)
|
|
@@ -61,12 +57,8 @@ class SoundFont2
|
|
|
61
57
|
this.verifyHeader(infoChunk, "list");
|
|
62
58
|
readBytesAsString(infoChunk.chunkData, 4);
|
|
63
59
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
*/
|
|
67
|
-
this.soundFontInfo = {};
|
|
68
|
-
|
|
69
|
-
while(infoChunk.chunkData.length > infoChunk.chunkData.currentIndex) {
|
|
60
|
+
while(infoChunk.chunkData.length > infoChunk.chunkData.currentIndex)
|
|
61
|
+
{
|
|
70
62
|
let chunk = readRIFFChunk(infoChunk.chunkData);
|
|
71
63
|
let text;
|
|
72
64
|
// special case: ifil
|
|
@@ -178,7 +170,7 @@ class SoundFont2
|
|
|
178
170
|
* (the current index points to start of the smpl read)
|
|
179
171
|
*/
|
|
180
172
|
this.dataArray.currentIndex = this.sampleDataStartIndex;
|
|
181
|
-
this.samples
|
|
173
|
+
this.samples.push(...readSamples(presetSamplesChunk, sampleData, !isSF2Pack));
|
|
182
174
|
|
|
183
175
|
/**
|
|
184
176
|
* read all the instrument generators
|
|
@@ -201,11 +193,7 @@ class SoundFont2
|
|
|
201
193
|
instrumentModulators,
|
|
202
194
|
this.samples);
|
|
203
195
|
|
|
204
|
-
|
|
205
|
-
* read all the instruments
|
|
206
|
-
* @type {Instrument[]}
|
|
207
|
-
*/
|
|
208
|
-
this.instruments = readInstruments(presetInstrumentsChunk, instrumentZones);
|
|
196
|
+
this.instruments = readInstruments(presetInstrumentsChunk, instrumentZones);
|
|
209
197
|
|
|
210
198
|
/**
|
|
211
199
|
* read all the preset generators
|
|
@@ -220,11 +208,8 @@ class SoundFont2
|
|
|
220
208
|
let presetModulators = readModulators(presetModulatorsChunk);
|
|
221
209
|
|
|
222
210
|
let presetZones = readPresetZones(presetZonesChunk, presetGenerators, presetModulators, this.instruments);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
* @type {Preset[]}
|
|
226
|
-
*/
|
|
227
|
-
this.presets = readPresets(presetHeadersChunk, presetZones);
|
|
211
|
+
|
|
212
|
+
this.presets.push(...readPresets(presetHeadersChunk, presetZones));
|
|
228
213
|
this.presets.sort((a, b) => (a.program - b.program) + (a.bank - b.bank));
|
|
229
214
|
// preload the first preset
|
|
230
215
|
SpessaSynthInfo(`%cParsing finished! %c"${this.soundFontInfo["INAM"]}"%c has %c${this.presets.length} %cpresets,
|
|
@@ -246,55 +231,6 @@ class SoundFont2
|
|
|
246
231
|
}
|
|
247
232
|
}
|
|
248
233
|
|
|
249
|
-
removeUnusedElements()
|
|
250
|
-
{
|
|
251
|
-
this.instruments.forEach(i => {
|
|
252
|
-
if(i.useCount < 1)
|
|
253
|
-
{
|
|
254
|
-
i.instrumentZones.forEach(z => {if(!z.isGlobal) z.sample.useCount--});
|
|
255
|
-
}
|
|
256
|
-
})
|
|
257
|
-
this.instruments = this.instruments.filter(i => i.useCount > 0);
|
|
258
|
-
this.samples = this.samples.filter(s => s.useCount > 0);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* @param instrument {Instrument}
|
|
263
|
-
*/
|
|
264
|
-
deleteInstrument(instrument)
|
|
265
|
-
{
|
|
266
|
-
if(instrument.useCount > 0)
|
|
267
|
-
{
|
|
268
|
-
throw new Error(`Cannot delete an instrument that has ${instrument.useCount} usages.`);
|
|
269
|
-
}
|
|
270
|
-
this.instruments.splice(this.instruments.indexOf(instrument), 1);
|
|
271
|
-
instrument.deleteInstrument();
|
|
272
|
-
this.removeUnusedElements();
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* @param sample {LoadedSample}
|
|
277
|
-
*/
|
|
278
|
-
deleteSample(sample)
|
|
279
|
-
{
|
|
280
|
-
if(sample.useCount > 0)
|
|
281
|
-
{
|
|
282
|
-
throw new Error(`Cannot delete sample that has ${sample.useCount} usages.`);
|
|
283
|
-
}
|
|
284
|
-
this.samples.splice(this.samples.indexOf(sample), 1);
|
|
285
|
-
this.removeUnusedElements();
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* @param preset {Preset}
|
|
290
|
-
*/
|
|
291
|
-
deletePreset(preset)
|
|
292
|
-
{
|
|
293
|
-
preset.deletePreset();
|
|
294
|
-
this.presets.splice(this.presets.indexOf(preset), 1);
|
|
295
|
-
this.removeUnusedElements();
|
|
296
|
-
}
|
|
297
|
-
|
|
298
234
|
/**
|
|
299
235
|
* @param chunk {RiffChunk}
|
|
300
236
|
* @param expected {string}
|
|
@@ -320,107 +256,4 @@ class SoundFont2
|
|
|
320
256
|
throw new SyntaxError(`Invalid soundFont! Expected "${expected.toLowerCase()}" got "${text.toLowerCase()}"`);
|
|
321
257
|
}
|
|
322
258
|
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Get the appropriate preset, undefined if not foun d
|
|
326
|
-
* @param bankNr {number}
|
|
327
|
-
* @param presetNr {number}
|
|
328
|
-
* @return {Preset}
|
|
329
|
-
*/
|
|
330
|
-
getPresetNoFallback(bankNr, presetNr)
|
|
331
|
-
{
|
|
332
|
-
return this.presets.find(p => p.bank === bankNr && p.program === presetNr);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* To avoid overlapping on multiple desfonts
|
|
337
|
-
* @param offset {number}
|
|
338
|
-
*/
|
|
339
|
-
setSampleIDOffset(offset)
|
|
340
|
-
{
|
|
341
|
-
this.presets.forEach(p => p.sampleIDOffset = offset);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Get the appropriate preset
|
|
346
|
-
* @param bankNr {number}
|
|
347
|
-
* @param presetNr {number}
|
|
348
|
-
* @returns {Preset}
|
|
349
|
-
*/
|
|
350
|
-
getPreset(bankNr, presetNr)
|
|
351
|
-
{
|
|
352
|
-
let preset = this.presets.find(p => p.bank === bankNr && p.program === presetNr);
|
|
353
|
-
if (!preset)
|
|
354
|
-
{
|
|
355
|
-
preset = this.presets.find(p => p.program === presetNr && p.bank !== 128);
|
|
356
|
-
if(bankNr === 128)
|
|
357
|
-
{
|
|
358
|
-
preset = this.presets.find(p => p.bank === 128 && p.program === presetNr);
|
|
359
|
-
if(!preset)
|
|
360
|
-
{
|
|
361
|
-
preset = this.presets.find(p => p.bank === 128);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
if(preset)
|
|
365
|
-
{
|
|
366
|
-
SpessaSynthWarn(`%cPreset ${bankNr}.${presetNr} not found. Replaced with %c${preset.presetName} (${preset.bank}.${preset.program})`,
|
|
367
|
-
consoleColors.warn,
|
|
368
|
-
consoleColors.recognized);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
if(!preset)
|
|
372
|
-
{
|
|
373
|
-
SpessaSynthWarn(`Preset ${presetNr} not found. Defaulting to`, this.presets[0].presetName);
|
|
374
|
-
preset = this.presets[0];
|
|
375
|
-
}
|
|
376
|
-
return preset;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* gets preset by name
|
|
381
|
-
* @param presetName {string}
|
|
382
|
-
* @returns {Preset}
|
|
383
|
-
*/
|
|
384
|
-
getPresetByName(presetName)
|
|
385
|
-
{
|
|
386
|
-
let preset = this.presets.find(p => p.presetName === presetName);
|
|
387
|
-
if(!preset)
|
|
388
|
-
{
|
|
389
|
-
SpessaSynthWarn("Preset not found. Defaulting to:", this.presets[0].presetName);
|
|
390
|
-
preset = this.presets[0];
|
|
391
|
-
}
|
|
392
|
-
return preset;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Merges soundfonts with the given order. Keep in mind that the info read is copied from the first one
|
|
398
|
-
* @param soundfonts {...SoundFont2} the soundfonts to merge, the first overwrites the last
|
|
399
|
-
* @returns {SoundFont2}
|
|
400
|
-
*/
|
|
401
|
-
static mergeSoundfonts(...soundfonts)
|
|
402
|
-
{
|
|
403
|
-
const mainSf = soundfonts.shift();
|
|
404
|
-
/**
|
|
405
|
-
* @type {Preset[]}
|
|
406
|
-
*/
|
|
407
|
-
const presets = mainSf.presets;
|
|
408
|
-
while(soundfonts.length)
|
|
409
|
-
{
|
|
410
|
-
const newPresets = soundfonts.shift().presets;
|
|
411
|
-
newPresets.forEach(newPreset => {
|
|
412
|
-
if(
|
|
413
|
-
presets.find(existingPreset => existingPreset.bank === newPreset.bank && existingPreset.program === newPreset.program) === undefined
|
|
414
|
-
)
|
|
415
|
-
{
|
|
416
|
-
presets.push(newPreset);
|
|
417
|
-
}
|
|
418
|
-
})
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
return new SoundFont2({presets: presets, info: mainSf.soundFontInfo});
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
SoundFont2.prototype.write = write;
|
|
425
|
-
|
|
426
|
-
export { SoundFont2 }
|
|
259
|
+
}
|