spessasynth_core 4.2.11 → 4.2.13
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/dist/index.d.ts +27 -96
- package/dist/index.js +80 -115
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -2626,79 +2626,6 @@ interface RMIDIWriteOptions {
|
|
|
2626
2626
|
}
|
|
2627
2627
|
type RMIDInfoFourCC = "INAM" | "IPRD" | "IALB" | "IART" | "IGNR" | "IPIC" | "ICOP" | "ICRD" | "ICRT" | "ICMT" | "IENG" | "ISFT" | "ISBJ" | "IENC" | "MENC" | "DBNK";
|
|
2628
2628
|
//#endregion
|
|
2629
|
-
//#region src/synthesizer/audio_engine/engine_methods/controller_control/reset_controllers.d.ts
|
|
2630
|
-
/**
|
|
2631
|
-
* Reset all controllers for channel.
|
|
2632
|
-
* This will reset all controllers to their default values,
|
|
2633
|
-
* except for the locked controllers.
|
|
2634
|
-
*/
|
|
2635
|
-
declare function resetControllers(this: MIDIChannel, sendCCEvents?: boolean): void;
|
|
2636
|
-
declare function resetPreset(this: MIDIChannel): void;
|
|
2637
|
-
/**
|
|
2638
|
-
* https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp15.pdf
|
|
2639
|
-
* Reset controllers according to RP-15 Recommended Practice.
|
|
2640
|
-
*/
|
|
2641
|
-
declare function resetControllersRP15Compliant(this: MIDIChannel): void;
|
|
2642
|
-
/**
|
|
2643
|
-
* Reset all parameters to their default values.
|
|
2644
|
-
* This includes NRPN and RPN controllers, data entry state,
|
|
2645
|
-
* and generator overrides and offsets.
|
|
2646
|
-
*/
|
|
2647
|
-
declare function resetParameters(this: MIDIChannel): void;
|
|
2648
|
-
//#endregion
|
|
2649
|
-
//#region src/synthesizer/audio_engine/engine_methods/controller_control/data_entry/data_entry_fine.d.ts
|
|
2650
|
-
/**
|
|
2651
|
-
* Executes a data entry fine (LSB) change for the current channel.
|
|
2652
|
-
* @param dataValue The value to set for the data entry fine controller (0-127).
|
|
2653
|
-
*/
|
|
2654
|
-
declare function dataEntryFine(this: MIDIChannel, dataValue: number): void;
|
|
2655
|
-
//#endregion
|
|
2656
|
-
//#region src/synthesizer/audio_engine/engine_methods/controller_control/controller_change.d.ts
|
|
2657
|
-
/**
|
|
2658
|
-
* Handles MIDI controller changes for a channel.
|
|
2659
|
-
* @param controllerNumber The MIDI controller number (0-127).
|
|
2660
|
-
* @param controllerValue The value of the controller (0-127).
|
|
2661
|
-
* @param sendEvent If an event should be emitted.
|
|
2662
|
-
* @remarks
|
|
2663
|
-
* This function processes MIDI controller changes, updating the channel's
|
|
2664
|
-
* midiControllers table and handling special cases like bank select,
|
|
2665
|
-
* data entry, and sustain pedal. It also computes modulators for all voices
|
|
2666
|
-
* in the channel based on the controller change.
|
|
2667
|
-
* to allow changes.
|
|
2668
|
-
*/
|
|
2669
|
-
declare function controllerChange(this: MIDIChannel, controllerNumber: MIDIController, controllerValue: number, sendEvent?: boolean): void;
|
|
2670
|
-
//#endregion
|
|
2671
|
-
//#region src/synthesizer/audio_engine/engine_methods/controller_control/data_entry/data_entry_coarse.d.ts
|
|
2672
|
-
/**
|
|
2673
|
-
* Executes a data entry coarse (MSB) change for the current channel.
|
|
2674
|
-
* @param dataCoarse The value to set for the data entry coarse controller (0-127).
|
|
2675
|
-
*/
|
|
2676
|
-
declare function dataEntryCoarse(this: MIDIChannel, dataCoarse: number): void;
|
|
2677
|
-
//#endregion
|
|
2678
|
-
//#region src/synthesizer/audio_engine/engine_methods/note_on.d.ts
|
|
2679
|
-
/**
|
|
2680
|
-
* Sends a "MIDI Note on" message and starts a note.
|
|
2681
|
-
* @param midiNote The MIDI note number (0-127).
|
|
2682
|
-
* @param velocity The velocity of the note (0-127). If less than 1, it will send a note off instead.
|
|
2683
|
-
*/
|
|
2684
|
-
declare function noteOn(this: MIDIChannel, midiNote: number, velocity: number): void;
|
|
2685
|
-
//#endregion
|
|
2686
|
-
//#region src/synthesizer/audio_engine/engine_methods/note_off.d.ts
|
|
2687
|
-
/**
|
|
2688
|
-
* Releases a note by its MIDI note number.
|
|
2689
|
-
* If the note is in high performance mode and the channel is not a drum channel,
|
|
2690
|
-
* it kills the note instead of releasing it.
|
|
2691
|
-
* @param midiNote The MIDI note number to release (0-127).
|
|
2692
|
-
*/
|
|
2693
|
-
declare function noteOff(this: MIDIChannel, midiNote: number): void;
|
|
2694
|
-
//#endregion
|
|
2695
|
-
//#region src/synthesizer/audio_engine/engine_methods/program_change.d.ts
|
|
2696
|
-
/**
|
|
2697
|
-
* Changes the program (preset) of the channel.
|
|
2698
|
-
* @param program The program number (0-127) to change to.
|
|
2699
|
-
*/
|
|
2700
|
-
declare function programChange(this: MIDIChannel, program: number): void;
|
|
2701
|
-
//#endregion
|
|
2702
2629
|
//#region src/synthesizer/audio_engine/engine_components/dynamic_modulator_system.d.ts
|
|
2703
2630
|
/**
|
|
2704
2631
|
* A class for dynamic modulators
|
|
@@ -3473,48 +3400,48 @@ declare class MIDIChannel {
|
|
|
3473
3400
|
* @param midiNote The MIDI note number (0-127).
|
|
3474
3401
|
* @param velocity The velocity of the note (0-127). If less than 1, it will send a note off instead.
|
|
3475
3402
|
*/
|
|
3476
|
-
noteOn:
|
|
3403
|
+
noteOn: (midiNote: number, velocity: number) => void;
|
|
3477
3404
|
/**
|
|
3478
3405
|
* Releases a note by its MIDI note number.
|
|
3479
3406
|
* If the note is in high performance mode and the channel is not a drum channel,
|
|
3480
3407
|
* it kills the note instead of releasing it.
|
|
3481
3408
|
* @param midiNote The MIDI note number to release (0-127).
|
|
3482
3409
|
*/
|
|
3483
|
-
noteOff:
|
|
3410
|
+
noteOff: (midiNote: number) => void;
|
|
3484
3411
|
/**
|
|
3485
3412
|
* Changes the program (preset) of the channel.
|
|
3486
3413
|
* @param programNumber The program number (0-127) to change to.
|
|
3487
3414
|
*/
|
|
3488
|
-
programChange:
|
|
3489
|
-
controllerChange:
|
|
3415
|
+
programChange: (program: number) => void;
|
|
3416
|
+
controllerChange: (controllerNumber: MIDIController, controllerValue: number, sendEvent?: boolean | undefined) => void;
|
|
3490
3417
|
/**
|
|
3491
3418
|
* Reset all controllers for channel.
|
|
3492
3419
|
* This will reset all controllers to their default values,
|
|
3493
3420
|
* except for the locked controllers.
|
|
3494
3421
|
*/
|
|
3495
|
-
readonly resetControllers:
|
|
3496
|
-
readonly resetPreset:
|
|
3422
|
+
readonly resetControllers: (sendCCEvents?: boolean | undefined) => void;
|
|
3423
|
+
readonly resetPreset: () => void;
|
|
3497
3424
|
/**
|
|
3498
3425
|
* https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp15.pdf
|
|
3499
3426
|
* Reset controllers according to RP-15 Recommended Practice.
|
|
3500
3427
|
*/
|
|
3501
|
-
readonly resetControllersRP15Compliant:
|
|
3428
|
+
readonly resetControllersRP15Compliant: () => void;
|
|
3502
3429
|
/**
|
|
3503
3430
|
* Reset all parameters to their default values.
|
|
3504
3431
|
* This includes NRPN and RPN controllers, data entry state,
|
|
3505
3432
|
* and generator overrides and offsets.
|
|
3506
3433
|
*/
|
|
3507
|
-
resetParameters:
|
|
3434
|
+
resetParameters: () => void;
|
|
3508
3435
|
/**
|
|
3509
3436
|
* Executes a data entry fine (LSB) change for the current channel.
|
|
3510
3437
|
* @param dataValue The value to set for the data entry fine controller (0-127).
|
|
3511
3438
|
*/
|
|
3512
|
-
dataEntryFine:
|
|
3439
|
+
dataEntryFine: (dataValue: number) => void;
|
|
3513
3440
|
/**
|
|
3514
3441
|
* Executes a data entry coarse (MSB) change for the current channel.
|
|
3515
3442
|
* @param dataValue The value to set for the data entry coarse controller (0-127).
|
|
3516
3443
|
*/
|
|
3517
|
-
dataEntryCoarse:
|
|
3444
|
+
dataEntryCoarse: (dataCoarse: number) => void;
|
|
3518
3445
|
readonly renderVoice: (voice: Voice, timeNow: number, outputL: Float32Array<ArrayBufferLike>, outputR: Float32Array<ArrayBufferLike>, startIndex: number, sampleCount: number) => void;
|
|
3519
3446
|
/**
|
|
3520
3447
|
* Per-note pitch wheel mode uses the pitchWheels table as source
|
|
@@ -3696,7 +3623,7 @@ declare class SpessaSynthProcessor {
|
|
|
3696
3623
|
*/
|
|
3697
3624
|
onEventCall?: (event: SynthProcessorEvent) => unknown;
|
|
3698
3625
|
/**
|
|
3699
|
-
* Renders float32 audio data to stereo outputs; buffer size must be equal or smaller than `maxBufferSize
|
|
3626
|
+
* Renders float32 audio data to stereo outputs; buffer size must be equal or smaller than `maxBufferSize`.
|
|
3700
3627
|
* All float arrays must have the same length.
|
|
3701
3628
|
* @param left the left output channel.
|
|
3702
3629
|
* @param right the right output channel.
|
|
@@ -3705,7 +3632,7 @@ declare class SpessaSynthProcessor {
|
|
|
3705
3632
|
*/
|
|
3706
3633
|
readonly process: (left: Float32Array, right: Float32Array, startIndex?: number, sampleCount?: number) => void;
|
|
3707
3634
|
/**
|
|
3708
|
-
* Renders float32 audio data to stereo outputs; buffer size must be equal or smaller than `maxBufferSize
|
|
3635
|
+
* Renders float32 audio data to stereo outputs; buffer size must be equal or smaller than `maxBufferSize`.
|
|
3709
3636
|
* All float arrays must have the same length.
|
|
3710
3637
|
* @param outputs any number stereo pairs (L, R) to render channels separately into.
|
|
3711
3638
|
* @param effectsLeft the left stereo effect output buffer.
|
|
@@ -4596,22 +4523,30 @@ sampleIndex: number,
|
|
|
4596
4523
|
*/
|
|
4597
4524
|
|
|
4598
4525
|
sampleCount: number) => Promise<unknown>;
|
|
4526
|
+
interface SoundBankWriteOptions {
|
|
4527
|
+
/**
|
|
4528
|
+
* A function to show progress for writing large sound banks. It can be undefined.
|
|
4529
|
+
*/
|
|
4530
|
+
progressFunction?: ProgressFunction;
|
|
4531
|
+
/**
|
|
4532
|
+
* The `ISFT` field to set when writing. If unset, "SpessaSynth" is written.
|
|
4533
|
+
* This field indicates the last software that was used to edit this sound bank.
|
|
4534
|
+
*/
|
|
4535
|
+
software?: string;
|
|
4536
|
+
}
|
|
4599
4537
|
/**
|
|
4600
4538
|
* Options for writing a SoundFont2 file.
|
|
4601
4539
|
*/
|
|
4602
|
-
interface SoundFont2WriteOptions {
|
|
4540
|
+
interface SoundFont2WriteOptions extends SoundBankWriteOptions {
|
|
4603
4541
|
/**
|
|
4604
4542
|
* If the soundfont should be compressed with a given function.
|
|
4543
|
+
* This changes the version to 3.0.
|
|
4605
4544
|
*/
|
|
4606
4545
|
compress: boolean;
|
|
4607
4546
|
/**
|
|
4608
4547
|
* The function for compressing samples. It can be undefined if not compressed.
|
|
4609
4548
|
*/
|
|
4610
4549
|
compressionFunction?: SampleEncodingFunction;
|
|
4611
|
-
/**
|
|
4612
|
-
* A function to show progress for writing large banks. It can be undefined.
|
|
4613
|
-
*/
|
|
4614
|
-
progressFunction?: ProgressFunction;
|
|
4615
4550
|
/**
|
|
4616
4551
|
* If the DMOD chunk should be written. Recommended.
|
|
4617
4552
|
* Note that it will only be written if the modulators are unchanged.
|
|
@@ -4624,18 +4559,14 @@ interface SoundFont2WriteOptions {
|
|
|
4624
4559
|
writeExtendedLimits: boolean;
|
|
4625
4560
|
/**
|
|
4626
4561
|
* If an SF3 bank should be decompressed back to SF2. Not recommended.
|
|
4562
|
+
* This changes the version to 2.4.
|
|
4627
4563
|
*/
|
|
4628
4564
|
decompress: boolean;
|
|
4629
4565
|
}
|
|
4630
4566
|
/**
|
|
4631
4567
|
* Options for writing a DLS file.
|
|
4632
4568
|
*/
|
|
4633
|
-
|
|
4634
|
-
/**
|
|
4635
|
-
* A function to show progress for writing large banks. It can be undefined.
|
|
4636
|
-
*/
|
|
4637
|
-
progressFunction?: ProgressFunction;
|
|
4638
|
-
}
|
|
4569
|
+
type DLSWriteOptions = SoundBankWriteOptions;
|
|
4639
4570
|
interface GenericRange {
|
|
4640
4571
|
min: number;
|
|
4641
4572
|
max: number;
|
package/dist/index.js
CHANGED
|
@@ -1813,12 +1813,39 @@ const dataEntryStates = {
|
|
|
1813
1813
|
DataFine: 6
|
|
1814
1814
|
};
|
|
1815
1815
|
const customControllers = {
|
|
1816
|
+
/**
|
|
1817
|
+
* Cents, RPN for fine-tuning
|
|
1818
|
+
*/
|
|
1816
1819
|
channelTuning: 0,
|
|
1820
|
+
/**
|
|
1821
|
+
* Cents, only the decimal tuning, (e.g., transpose is 4.5,
|
|
1822
|
+
* Then shift by 4 keys + tune by 50 cents)
|
|
1823
|
+
*/
|
|
1817
1824
|
channelTransposeFine: 1,
|
|
1825
|
+
/**
|
|
1826
|
+
* The MIDI specification assumes the default modulation depth is 50 cents,
|
|
1827
|
+
* but it may vary for different sound banks.
|
|
1828
|
+
* For example, if you want a modulation depth of 100 cents,
|
|
1829
|
+
* the multiplier will be 2,
|
|
1830
|
+
* which, for a preset with a depth of 50,
|
|
1831
|
+
* will create a total modulation depth of 100 cents.
|
|
1832
|
+
*/
|
|
1818
1833
|
modulationMultiplier: 2,
|
|
1834
|
+
/**
|
|
1835
|
+
* Cents, set by system exclusive
|
|
1836
|
+
*/
|
|
1819
1837
|
masterTuning: 3,
|
|
1838
|
+
/**
|
|
1839
|
+
* Semitones, for RPN coarse tuning
|
|
1840
|
+
*/
|
|
1820
1841
|
channelTuningSemitones: 4,
|
|
1842
|
+
/**
|
|
1843
|
+
* Key shift: for system exclusive
|
|
1844
|
+
*/
|
|
1821
1845
|
channelKeyShift: 5,
|
|
1846
|
+
/**
|
|
1847
|
+
* Sf2 NPRN LSB for selecting a generator value
|
|
1848
|
+
*/
|
|
1822
1849
|
sf2NPRNGeneratorLSB: 6
|
|
1823
1850
|
};
|
|
1824
1851
|
//#endregion
|
|
@@ -6180,8 +6207,8 @@ var VolumeEnvelope = class {
|
|
|
6180
6207
|
this.enteredRelease = false;
|
|
6181
6208
|
this.state = 0;
|
|
6182
6209
|
this.sampleTime = 0;
|
|
6183
|
-
this.canEndOnSilentSustain = voice.modulatedGenerators[generatorTypes.sustainVolEnv] >= PERCEIVED_CB_SILENCE;
|
|
6184
6210
|
this.outputGain = 0;
|
|
6211
|
+
this.canEndOnSilentSustain = voice.modulatedGenerators[generatorTypes.sustainVolEnv] >= PERCEIVED_CB_SILENCE;
|
|
6185
6212
|
this.sustainCb = Math.min(CB_SILENCE, voice.modulatedGenerators[generatorTypes.sustainVolEnv]);
|
|
6186
6213
|
this.attackDuration = this.timecentsToSamples(voice.modulatedGenerators[generatorTypes.attackVolEnv]);
|
|
6187
6214
|
const keyNumAddition = (60 - voice.targetKey) * voice.modulatedGenerators[generatorTypes.keyNumToVolEnvDecay];
|
|
@@ -8334,8 +8361,6 @@ function writeSF2Elements(bank, isPreset = false) {
|
|
|
8334
8361
|
//#region src/soundbank/soundfont/write/write.ts
|
|
8335
8362
|
const DEFAULT_SF2_WRITE_OPTIONS = {
|
|
8336
8363
|
compress: false,
|
|
8337
|
-
compressionFunction: void 0,
|
|
8338
|
-
progressFunction: void 0,
|
|
8339
8364
|
writeDefaultModulators: true,
|
|
8340
8365
|
writeExtendedLimits: true,
|
|
8341
8366
|
decompress: false
|
|
@@ -8359,65 +8384,40 @@ async function writeSF2Internal(bank, writeOptions = DEFAULT_SF2_WRITE_OPTIONS)
|
|
|
8359
8384
|
* Write INFO
|
|
8360
8385
|
*/
|
|
8361
8386
|
const infoArrays = [];
|
|
8362
|
-
bank.soundBankInfo
|
|
8387
|
+
const info = bank.soundBankInfo;
|
|
8363
8388
|
if (options?.compress || bank.samples.some((s) => s.isCompressed)) {
|
|
8364
|
-
|
|
8365
|
-
|
|
8389
|
+
info.version.major = 3;
|
|
8390
|
+
info.version.minor = 0;
|
|
8366
8391
|
}
|
|
8367
8392
|
if (options?.decompress) {
|
|
8368
|
-
|
|
8369
|
-
|
|
8393
|
+
info.version.major = 2;
|
|
8394
|
+
info.version.minor = 4;
|
|
8370
8395
|
}
|
|
8371
8396
|
const writeSF2Info = (type, data) => {
|
|
8397
|
+
if (!data) return;
|
|
8372
8398
|
infoArrays.push(RIFFChunk.write(type, getStringBytes(data, true, true)));
|
|
8373
8399
|
};
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8400
|
+
{
|
|
8401
|
+
const ifilData = new IndexedByteArray(4);
|
|
8402
|
+
writeWord(ifilData, info.version.major);
|
|
8403
|
+
writeWord(ifilData, info.version.minor);
|
|
8404
|
+
infoArrays.push(RIFFChunk.write("ifil", ifilData));
|
|
8405
|
+
}
|
|
8406
|
+
writeSF2Info("isng", info.soundEngine);
|
|
8407
|
+
writeSF2Info("INAM", info.name);
|
|
8408
|
+
writeSF2Info("irom", info.romInfo);
|
|
8409
|
+
if (info.romVersion) {
|
|
8379
8410
|
const ifilData = new IndexedByteArray(4);
|
|
8380
|
-
writeWord(ifilData,
|
|
8381
|
-
writeWord(ifilData,
|
|
8411
|
+
writeWord(ifilData, info.romVersion.major);
|
|
8412
|
+
writeWord(ifilData, info.romVersion.minor);
|
|
8382
8413
|
infoArrays.push(RIFFChunk.write("iver", ifilData));
|
|
8383
8414
|
}
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
switch (type) {
|
|
8391
|
-
case "name":
|
|
8392
|
-
writeSF2Info("INAM", data);
|
|
8393
|
-
break;
|
|
8394
|
-
case "comment":
|
|
8395
|
-
writeSF2Info("ICMT", commentText);
|
|
8396
|
-
break;
|
|
8397
|
-
case "copyright":
|
|
8398
|
-
writeSF2Info("ICOP", data);
|
|
8399
|
-
break;
|
|
8400
|
-
case "creationDate":
|
|
8401
|
-
writeSF2Info("ICRD", toISODateString(data));
|
|
8402
|
-
break;
|
|
8403
|
-
case "engineer":
|
|
8404
|
-
writeSF2Info("IENG", data);
|
|
8405
|
-
break;
|
|
8406
|
-
case "product":
|
|
8407
|
-
writeSF2Info("IPRD", data);
|
|
8408
|
-
break;
|
|
8409
|
-
case "romInfo":
|
|
8410
|
-
writeSF2Info("irom", data);
|
|
8411
|
-
break;
|
|
8412
|
-
case "software":
|
|
8413
|
-
writeSF2Info("ISFT", data);
|
|
8414
|
-
break;
|
|
8415
|
-
case "soundEngine":
|
|
8416
|
-
writeSF2Info("isng", data);
|
|
8417
|
-
break;
|
|
8418
|
-
case "subject": break;
|
|
8419
|
-
}
|
|
8420
|
-
}
|
|
8415
|
+
writeSF2Info("ICRD", toISODateString(info.creationDate));
|
|
8416
|
+
writeSF2Info("IENG", info.engineer);
|
|
8417
|
+
writeSF2Info("IPRD", info.product);
|
|
8418
|
+
writeSF2Info("ICOP", info.copyright);
|
|
8419
|
+
writeSF2Info("ICMT", info?.subject ? (info?.comment ? info.comment + "\n" : "") + info.subject : info?.comment);
|
|
8420
|
+
writeSF2Info("ISFT", options.software ?? "SpessaSynth");
|
|
8421
8421
|
if (bank.defaultModulators.some((mod) => !SPESSASYNTH_DEFAULT_MODULATORS.some((m) => Modulator.isIdentical(m, mod, true))) && options?.writeDefaultModulators) {
|
|
8422
8422
|
const mods = bank.defaultModulators;
|
|
8423
8423
|
SpessaSynthInfo(`%cWriting %c${mods.length}%c default modulators...`, consoleColors.info, consoleColors.recognized, consoleColors.info);
|
|
@@ -8453,9 +8453,8 @@ ${bank.soundBankInfo.subject}` : "");
|
|
|
8453
8453
|
];
|
|
8454
8454
|
const pdtaChunk = RIFFChunk.writeParts("pdta", chunks.map((c) => c.pdta), true);
|
|
8455
8455
|
if (options.writeExtendedLimits && (instData.writeXdta || presData.writeXdta || bank.presets.some((p) => p.name.length > 20) || bank.instruments.some((i) => i.name.length > 20) || bank.samples.some((s) => s.name.length > 20))) {
|
|
8456
|
-
SpessaSynthInfo(`%cWriting the xdta chunk as
|
|
8457
|
-
|
|
8458
|
-
infoArrays.push(xpdtaChunk);
|
|
8456
|
+
SpessaSynthInfo(`%cWriting the xdta chunk as writeExtendedLimits is enabled and at least one condition was met.`, consoleColors.info, consoleColors.value);
|
|
8457
|
+
infoArrays.push(RIFFChunk.writeParts("xdta", chunks.map((c) => c.xdta), true));
|
|
8459
8458
|
}
|
|
8460
8459
|
const infoChunk = RIFFChunk.writeParts("INFO", infoArrays, true);
|
|
8461
8460
|
SpessaSynthInfo("%cWriting the output file...", consoleColors.info);
|
|
@@ -8465,7 +8464,7 @@ ${bank.soundBankInfo.subject}` : "");
|
|
|
8465
8464
|
sdtaChunk,
|
|
8466
8465
|
pdtaChunk
|
|
8467
8466
|
]);
|
|
8468
|
-
SpessaSynthInfo(`%cSaved
|
|
8467
|
+
SpessaSynthInfo(`%cSaved successfully! Final file size: %c${main.length}`, consoleColors.info, consoleColors.recognized);
|
|
8469
8468
|
SpessaSynthGroupEnd();
|
|
8470
8469
|
return main.buffer;
|
|
8471
8470
|
}
|
|
@@ -10003,10 +10002,11 @@ var DownloadableSounds = class DownloadableSounds extends DLSVerifier {
|
|
|
10003
10002
|
samples = new Array();
|
|
10004
10003
|
instruments = new Array();
|
|
10005
10004
|
soundBankInfo = {
|
|
10006
|
-
name: "Unnamed",
|
|
10005
|
+
name: "Unnamed DLS sound bank",
|
|
10007
10006
|
creationDate: /* @__PURE__ */ new Date(),
|
|
10008
10007
|
software: "SpessaSynth",
|
|
10009
10008
|
soundEngine: "DLS Level 2.2",
|
|
10009
|
+
product: "SpessaSynth DLS",
|
|
10010
10010
|
version: {
|
|
10011
10011
|
major: 2,
|
|
10012
10012
|
minor: 4
|
|
@@ -10025,9 +10025,6 @@ var DownloadableSounds = class DownloadableSounds extends DLSVerifier {
|
|
|
10025
10025
|
const chunks = [];
|
|
10026
10026
|
while (dataArray.currentIndex < dataArray.length) chunks.push(RIFFChunk.read(dataArray));
|
|
10027
10027
|
const dls = new DownloadableSounds();
|
|
10028
|
-
dls.soundBankInfo.name = "Unnamed DLS";
|
|
10029
|
-
dls.soundBankInfo.product = "SpessaSynth DLS";
|
|
10030
|
-
dls.soundBankInfo.comment = "(no description)";
|
|
10031
10028
|
const infoChunk = RIFFChunk.findListType(chunks, "INFO");
|
|
10032
10029
|
if (infoChunk) while (infoChunk.data.currentIndex < infoChunk.data.length) {
|
|
10033
10030
|
const infoPart = RIFFChunk.read(infoChunk.data);
|
|
@@ -10145,7 +10142,6 @@ var DownloadableSounds = class DownloadableSounds extends DLSVerifier {
|
|
|
10145
10142
|
SpessaSynthGroupCollapsed("%cSaving SF2 to DLS level 2...", consoleColors.info);
|
|
10146
10143
|
const dls = new DownloadableSounds();
|
|
10147
10144
|
dls.soundBankInfo = { ...bank.soundBankInfo };
|
|
10148
|
-
dls.soundBankInfo.comment = (dls.soundBankInfo.comment ?? "(No description)") + "\nConverted from SF2 to DLS with SpessaSynth";
|
|
10149
10145
|
for (const s of bank.samples) dls.samples.push(DownloadableSoundsSample.fromSFSample(s));
|
|
10150
10146
|
for (const p of bank.presets) dls.instruments.push(DownloadableSoundsInstrument.fromSFPreset(p, bank.samples));
|
|
10151
10147
|
SpessaSynthInfo("%cConversion complete!", consoleColors.recognized);
|
|
@@ -10153,13 +10149,10 @@ var DownloadableSounds = class DownloadableSounds extends DLSVerifier {
|
|
|
10153
10149
|
return dls;
|
|
10154
10150
|
}
|
|
10155
10151
|
static printInfo(dls) {
|
|
10156
|
-
for (const [info, value] of Object.entries(dls.soundBankInfo)) {
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
|
|
10160
|
-
}
|
|
10161
|
-
SpessaSynthInfo(`%c${info}: %c${value.toLocaleString()}`, consoleColors.info, consoleColors.recognized);
|
|
10162
|
-
}
|
|
10152
|
+
for (const [info, value] of Object.entries(dls.soundBankInfo)) if (typeof value === "object" && "major" in value) {
|
|
10153
|
+
const v = value;
|
|
10154
|
+
SpessaSynthInfo(`%c${info}: %c"${v.major}.${v.minor}"`, consoleColors.info, consoleColors.recognized);
|
|
10155
|
+
} else SpessaSynthInfo(`%c${info}: %c${value.toLocaleString()}`, consoleColors.info, consoleColors.recognized);
|
|
10163
10156
|
}
|
|
10164
10157
|
/**
|
|
10165
10158
|
* Writes a DLS file
|
|
@@ -10196,43 +10189,19 @@ var DownloadableSounds = class DownloadableSounds extends DLSVerifier {
|
|
|
10196
10189
|
const ptbl = RIFFChunk.write("ptbl", ptblData);
|
|
10197
10190
|
this.soundBankInfo.software = "SpessaSynth";
|
|
10198
10191
|
const infos = [];
|
|
10192
|
+
const info = this.soundBankInfo;
|
|
10199
10193
|
const writeDLSInfo = (type, data) => {
|
|
10194
|
+
if (!data) return;
|
|
10200
10195
|
infos.push(RIFFChunk.write(type, getStringBytes(data, true)));
|
|
10201
10196
|
};
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10210
|
-
case "comment":
|
|
10211
|
-
writeDLSInfo("ICMT", data);
|
|
10212
|
-
break;
|
|
10213
|
-
case "copyright":
|
|
10214
|
-
writeDLSInfo("ICOP", data);
|
|
10215
|
-
break;
|
|
10216
|
-
case "creationDate":
|
|
10217
|
-
writeDLSInfo("ICRD", toISODateString(data));
|
|
10218
|
-
break;
|
|
10219
|
-
case "engineer":
|
|
10220
|
-
writeDLSInfo("IENG", data);
|
|
10221
|
-
break;
|
|
10222
|
-
case "product":
|
|
10223
|
-
writeDLSInfo("IPRD", data);
|
|
10224
|
-
break;
|
|
10225
|
-
case "romVersion":
|
|
10226
|
-
case "version":
|
|
10227
|
-
case "soundEngine":
|
|
10228
|
-
case "romInfo": break;
|
|
10229
|
-
case "software":
|
|
10230
|
-
writeDLSInfo("ISFT", data);
|
|
10231
|
-
break;
|
|
10232
|
-
case "subject": writeDLSInfo("ISBJ", data);
|
|
10233
|
-
}
|
|
10234
|
-
}
|
|
10235
|
-
const info = RIFFChunk.writeParts("INFO", infos, true);
|
|
10197
|
+
writeDLSInfo("INAM", info.name);
|
|
10198
|
+
writeDLSInfo("ICMT", info.comment);
|
|
10199
|
+
writeDLSInfo("ICOP", info.copyright);
|
|
10200
|
+
writeDLSInfo("ICRD", toISODateString(info.creationDate));
|
|
10201
|
+
writeDLSInfo("IENG", info.engineer);
|
|
10202
|
+
writeDLSInfo("IPRD", info.product);
|
|
10203
|
+
writeDLSInfo("ISFT", options.software ?? "SpessaSynth");
|
|
10204
|
+
writeDLSInfo("ISBJ", info.subject);
|
|
10236
10205
|
SpessaSynthInfo("%cCombining everything...");
|
|
10237
10206
|
const out = RIFFChunk.writeParts("RIFF", [
|
|
10238
10207
|
getStringBytes("DLS "),
|
|
@@ -10240,7 +10209,7 @@ var DownloadableSounds = class DownloadableSounds extends DLSVerifier {
|
|
|
10240
10209
|
lins,
|
|
10241
10210
|
ptbl,
|
|
10242
10211
|
wvpl,
|
|
10243
|
-
|
|
10212
|
+
RIFFChunk.writeParts("INFO", infos, true)
|
|
10244
10213
|
]);
|
|
10245
10214
|
SpessaSynthInfo("%cSaved successfully!", consoleColors.recognized);
|
|
10246
10215
|
SpessaSynthGroupEnd();
|
|
@@ -10255,7 +10224,6 @@ var DownloadableSounds = class DownloadableSounds extends DLSVerifier {
|
|
|
10255
10224
|
soundBank.soundBankInfo.version.minor = 4;
|
|
10256
10225
|
soundBank.soundBankInfo.version.major = 2;
|
|
10257
10226
|
soundBank.soundBankInfo = { ...this.soundBankInfo };
|
|
10258
|
-
soundBank.soundBankInfo.comment = (soundBank.soundBankInfo.comment ?? "(No description)") + "\nConverted from DLS to SF2 with SpessaSynth";
|
|
10259
10227
|
for (const sample of this.samples) sample.toSFSample(soundBank);
|
|
10260
10228
|
for (const instrument of this.instruments) instrument.toSFPreset(soundBank);
|
|
10261
10229
|
soundBank.flush();
|
|
@@ -10635,13 +10603,10 @@ var BasicSoundBank = class BasicSoundBank {
|
|
|
10635
10603
|
}
|
|
10636
10604
|
}
|
|
10637
10605
|
printInfo() {
|
|
10638
|
-
for (const [info, value] of Object.entries(this.soundBankInfo)) {
|
|
10639
|
-
|
|
10640
|
-
|
|
10641
|
-
|
|
10642
|
-
}
|
|
10643
|
-
SpessaSynthInfo(`%c${info}: %c${value.toLocaleString()}`, consoleColors.info, consoleColors.recognized);
|
|
10644
|
-
}
|
|
10606
|
+
for (const [info, value] of Object.entries(this.soundBankInfo)) if (typeof value === "object" && "major" in value) {
|
|
10607
|
+
const v = value;
|
|
10608
|
+
SpessaSynthInfo(`%c${info}: %c"${v.major}.${v.minor}"`, consoleColors.info, consoleColors.recognized);
|
|
10609
|
+
} else SpessaSynthInfo(`%c${info}: %c${value.toLocaleString()}`, consoleColors.info, consoleColors.recognized);
|
|
10645
10610
|
}
|
|
10646
10611
|
};
|
|
10647
10612
|
//#endregion
|
|
@@ -10887,7 +10852,7 @@ var SoundFont2 = class extends BasicSoundBank {
|
|
|
10887
10852
|
const infoString = readBinaryStringIndexed(infoChunk.data, 4);
|
|
10888
10853
|
if (infoString !== "INFO") {
|
|
10889
10854
|
SpessaSynthGroupEnd();
|
|
10890
|
-
throw new SyntaxError(`Invalid soundFont! Expected "INFO"
|
|
10855
|
+
throw new SyntaxError(`Invalid soundFont! Expected "INFO" got "${infoString}"`);
|
|
10891
10856
|
}
|
|
10892
10857
|
let xdtaChunk;
|
|
10893
10858
|
while (infoChunk.data.length > infoChunk.data.currentIndex) {
|
|
@@ -11789,7 +11754,7 @@ function dataEntryFine(dataValue) {
|
|
|
11789
11754
|
case dataEntryStates.NRPFine: {
|
|
11790
11755
|
const paramCoarse = this.midiControllers[midiControllers.nonRegisteredParameterMSB] >> 7;
|
|
11791
11756
|
const paramFine = this.midiControllers[midiControllers.nonRegisteredParameterLSB] >> 7;
|
|
11792
|
-
if (paramCoarse === nonRegisteredMSB.SF2 || paramCoarse >= nonRegisteredMSB.drumPitch &&
|
|
11757
|
+
if (paramCoarse === nonRegisteredMSB.SF2 || paramCoarse >= nonRegisteredMSB.drumPitch && paramCoarse <= nonRegisteredMSB.drumDelay || paramCoarse === nonRegisteredMSB.partParameter) return;
|
|
11793
11758
|
switch (paramCoarse) {
|
|
11794
11759
|
default:
|
|
11795
11760
|
SpessaSynthInfo(`%cUnrecognized NRPN LSB for %c${this.channel}%c: %c(0x${paramCoarse.toString(16).toUpperCase()} 0x${paramFine.toString(16).toUpperCase()})%c data value: %c${dataValue}`, consoleColors.warn, consoleColors.recognized, consoleColors.warn, consoleColors.unrecognized, consoleColors.warn, consoleColors.value);
|
|
@@ -19557,7 +19522,7 @@ var SpessaSynthProcessor = class {
|
|
|
19557
19522
|
*/
|
|
19558
19523
|
onEventCall;
|
|
19559
19524
|
/**
|
|
19560
|
-
* Renders float32 audio data to stereo outputs; buffer size must be equal or smaller than `maxBufferSize
|
|
19525
|
+
* Renders float32 audio data to stereo outputs; buffer size must be equal or smaller than `maxBufferSize`.
|
|
19561
19526
|
* All float arrays must have the same length.
|
|
19562
19527
|
* @param left the left output channel.
|
|
19563
19528
|
* @param right the right output channel.
|
|
@@ -19566,7 +19531,7 @@ var SpessaSynthProcessor = class {
|
|
|
19566
19531
|
*/
|
|
19567
19532
|
process;
|
|
19568
19533
|
/**
|
|
19569
|
-
* Renders float32 audio data to stereo outputs; buffer size must be equal or smaller than `maxBufferSize
|
|
19534
|
+
* Renders float32 audio data to stereo outputs; buffer size must be equal or smaller than `maxBufferSize`.
|
|
19570
19535
|
* All float arrays must have the same length.
|
|
19571
19536
|
* @param outputs any number stereo pairs (L, R) to render channels separately into.
|
|
19572
19537
|
* @param effectsLeft the left stereo effect output buffer.
|