spessasynth_core 4.4.3 → 4.4.5

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 CHANGED
@@ -289,6 +289,27 @@ export declare const GeneratorTypes: Readonly<{
289
289
  readonly vibLfoToVolume: 65;
290
290
  readonly modLfoRate: 66;
291
291
  readonly modLfoAmplitudeDepth: 67;
292
+ readonly ignoreNoteOff: 68;
293
+ readonly delayVoice: 69;
294
+ readonly fadeVibLFO: 70;
295
+ readonly fadeModLFO: 71;
296
+ readonly vibLfoWaveform: 72;
297
+ readonly modLfoWaveform: 73;
298
+ readonly vibLfoStartPhase: 74;
299
+ readonly modLfoStartPhase: 75;
300
+ readonly maxFilterFc: 76;
301
+ readonly decay2VolEnv: 77;
302
+ readonly sustain2VolEnv: 78;
303
+ readonly delayModEnv2: 79;
304
+ readonly attackModEnv2: 80;
305
+ readonly holdModEnv2: 81;
306
+ readonly decayModEnv2: 82;
307
+ readonly sustainModEnv2: 83;
308
+ readonly releaseModEnv2: 84;
309
+ readonly keyNumToModEnv2Hold: 85;
310
+ readonly keyNumToModEnv2Decay: 86;
311
+ readonly modEnv2ToPitch: 87;
312
+ readonly modEnv2ToFilterFc: 88;
292
313
  }>;
293
314
  /**
294
315
  * @inheritDoc GeneratorTypes
@@ -331,6 +352,17 @@ export interface GeneratorLimit {
331
352
  * SoundFont2 NRPN scale factor for this generator type.
332
353
  */
333
354
  nrpn: number;
355
+ /**
356
+ * Minimum value of this generator in a preset zone.
357
+ * Preset generators are offsets added to the instrument, so they can go below the instrument range.
358
+ * If not set, it is the same as `min`.
359
+ */
360
+ presetMin?: number;
361
+ /**
362
+ * Maximum value of this generator in a preset zone.
363
+ * If not set, it is the same as `max`.
364
+ */
365
+ presetMax?: number;
334
366
  }
335
367
  /**
336
368
  * Limits and defaults for all the {@link BasicSoundBank} generator types.
@@ -653,53 +685,27 @@ export declare class BasicZone {
653
685
  */
654
686
  copyFrom(zone: BasicZone): void;
655
687
  }
656
- /**
657
- * Represents a single instrument zone with an associated {@link BasicSample}.
658
- *
659
- * @group Sound Banks.Zones
660
- */
661
- export declare class BasicInstrumentZone extends BasicZone {
662
- /**
663
- * The instrument this zone belongs to.
664
- */
665
- readonly parentInstrument: BasicInstrument;
666
- /**
667
- * Zone's sample.
668
- */
669
- private _sample;
670
- /**
671
- * The sample associated with this zone.
672
- */
673
- get sample(): BasicSample;
674
- /**
675
- * Sets a sample for this zone, unliking the previous one from it.
676
- * @param sample The sample to set.
677
- */
678
- set sample(sample: BasicSample);
679
- }
680
688
  /**
681
689
  * Represents a single preset zone with an associated {@link BasicInstrument}.
682
690
  *
683
691
  * @group Sound Banks.Zones
684
692
  */
685
- export declare class BasicPresetZone extends BasicZone {
693
+ export declare class BasicPresetZone extends BasicLinkedZone<BasicPreset, BasicInstrument> {
694
+ protected readonly childGenerator: 41;
686
695
  /**
687
696
  * The preset this zone belongs to.
688
697
  */
689
- readonly parentPreset: BasicPreset;
690
- /**
691
- * The instrument associated with this zone.
692
- */
693
- private _instrument;
698
+ get parentPreset(): BasicPreset;
694
699
  /**
695
700
  * The instrument associated with this zone.
696
701
  */
697
702
  get instrument(): BasicInstrument;
698
703
  /**
699
- * Sets an instrument for this zone, unliking the previous one from it.
704
+ * Sets an instrument for this zone, unlinking the previous one from it.
700
705
  * @param instrument The instrument to set.
701
706
  */
702
707
  set instrument(instrument: BasicInstrument);
708
+ protected getChildList(bank: BasicSoundBank): BasicInstrument[];
703
709
  }
704
710
  /**
705
711
  * SpessaSynth 4.0 brings the full bank LSB support in the API.
@@ -825,6 +831,135 @@ export declare class MIDIPatchTools {
825
831
  static selectPatch<T extends MIDIPatchFull>(patches: T[], patch: MIDIPatch, system: MIDISystem): T;
826
832
  private static getAnyDrums;
827
833
  }
834
+ /**
835
+ * Represents a single preset.
836
+ * This is what is used for MIDI playback.
837
+ *
838
+ * @group Sound Banks
839
+ */
840
+ export declare class BasicPreset implements MIDIPatchFull {
841
+ /**
842
+ * The parent soundbank instance
843
+ * Currently used for determining default modulators and XG status
844
+ */
845
+ readonly parentSoundBank: BasicSoundBank;
846
+ /**
847
+ * The preset's name.
848
+ */
849
+ name: string;
850
+ program: number;
851
+ bankMSB: number;
852
+ bankLSB: number;
853
+ isGMGSDrum: boolean;
854
+ /**
855
+ * The preset's zones.
856
+ * These are limited to specific key/velocity ranges and contain associated instruments.
857
+ */
858
+ zones: BasicPresetZone[];
859
+ /**
860
+ * Preset's global zone.
861
+ * Its parameters are overridden by the local zone parameters.
862
+ */
863
+ readonly globalZone: BasicZone;
864
+ /**
865
+ * Unused preset metadata, preserved.
866
+ */
867
+ library: number;
868
+ /**
869
+ * Unused preset metadata, preserved.
870
+ */
871
+ genre: number;
872
+ /**
873
+ * Unused preset metadata, preserved.
874
+ */
875
+ morphology: number;
876
+ /**
877
+ * Creates a new preset.
878
+ * @param parentSoundBank The sound bank this preset belongs to.
879
+ * @param globalZone The optional global zone to associate within the preset.
880
+ */
881
+ constructor(parentSoundBank: BasicSoundBank, globalZone?: BasicZone);
882
+ /**
883
+ * A boolean indicating if this preset is a drum preset.
884
+ */
885
+ get isDrum(): boolean;
886
+ private static isInRange;
887
+ private static addUniqueModulators;
888
+ private static subtractRanges;
889
+ /**
890
+ * Unlinks everything from this preset.
891
+ * This is what {@link BasicSoundBank.deletePreset} calls, the preset itself stays intact.
892
+ * Use {@link restore} to undo it.
893
+ */
894
+ delete(): void;
895
+ /**
896
+ * Links the instruments back to this preset, the inverse of {@link delete}.
897
+ * Use it to restore a deleted preset, for example when undoing the deletion.
898
+ * Add the preset back to the sound bank as well.
899
+ */
900
+ restore(): void;
901
+ /**
902
+ * Deletes a preset zone from this preset.
903
+ * @param index The zone's index to delete.
904
+ */
905
+ deleteZone(index: number): void;
906
+ /**
907
+ * Creates a new preset zone and returns it.
908
+ * @param instrument The instrument to associate with the zone.
909
+ * @param link If the instrument should be linked to this preset.
910
+ * Pass false for helper presets that are not part of a sound bank.
911
+ * Such a zone never changes the instrument's use count or its `linkedTo` list.
912
+ *
913
+ * > **Warning**
914
+ * >
915
+ * > A preset with unlinked zones must not be added to a sound bank.
916
+ */
917
+ createZone(instrument: BasicInstrument, link?: boolean): BasicPresetZone;
918
+ /**
919
+ * Preloads (loads and caches synthesis data) for a given key range.
920
+ * @param keyMin The lowest allowed MIDI note number.
921
+ * @param keyMax The highest allowed MIDI note number.
922
+ */
923
+ preload(keyMin: number, keyMax: number): void;
924
+ /**
925
+ * Checks if the bank and program numbers are the same for the given preset as this one.
926
+ * Shortened version of {@link MIDIPatchTools.matches}
927
+ * @param preset The preset to check.
928
+ */
929
+ matches(preset: MIDIPatch): boolean;
930
+ /**
931
+ * Returns the voice synthesis data for this preset.
932
+ *
933
+ * > **Note**
934
+ * >
935
+ * > The `E-mu` attenuation correction
936
+ * > (`initialAttenuation` generator value being multiplied by `0.4`) is already performed.
937
+ *
938
+ * @param midiNote The MIDI note number.
939
+ * @param velocity The MIDI velocity.
940
+ * @returns The returned sound data.
941
+ */
942
+ getVoiceParameters(midiNote: number, velocity: number): VoiceParameters[];
943
+ /**
944
+ * Alias for {@link MIDIPatchTools.toMIDIString}
945
+ */
946
+ toMIDIString(): string;
947
+ /**
948
+ * Alias for {@link MIDIPatchTools.toFullMIDIString}
949
+ */
950
+ toString(): string;
951
+ /**
952
+ * Combines preset into an instrument, flattening the preset zones into instrument zones.
953
+ * This is a really complex function that attempts to work around the DLS limitations of only having the instrument layer.
954
+ *
955
+ * > **Tip**
956
+ * >
957
+ * > Consider reading about [the DLS conversion problem](../../../docs/extra/dls-conversion-problem.md).
958
+ *
959
+ * @returns The instrument containing the flattened zones. If flattening was successful, it should exactly the same as this preset.
960
+ */
961
+ toFlattenedInstrument(): BasicInstrument;
962
+ }
828
963
  /**
829
964
  * This module handles parsing and writing SoundFont2 (`.sf2`, `.sf3` and `.sfogg`) files.
830
965
  * It represents a single sound bank.
@@ -941,8 +1076,10 @@ export declare class BasicSoundBank {
941
1076
  * > This method is memory and CPU intensive with large sound banks.
942
1077
  *
943
1078
  * @param options Options associated with setting the sample format.
1079
+ * @returns The samples whose sample rate or loop points changed.
1080
+ * Compressing resamples samples outside 8000 to 96000 Hz.
944
1081
  */
945
- setSampleFormat(options: SetSampleFormatOptions): Promise<void>;
1082
+ setSampleFormat(options: SetSampleFormatOptions): Promise<BasicSample[]>;
946
1083
  /**
947
1084
  * Writes out a DLS Level 2 sound bank. This may not be 100% accurate.
948
1085
  * Samples data is always written in the S16LE PCM encoding.
@@ -995,41 +1132,47 @@ export declare class BasicSoundBank {
995
1132
  */
996
1133
  addSamples(...samples: BasicSample[]): void;
997
1134
  /**
998
- * Clones a sample into this bank.
1135
+ * Clones a sample into this bank, together with its stereo partner.
999
1136
  *
1000
1137
  * > **Important**
1001
1138
  * >
1002
- * > If a sample with the same name already exists in the sound bank,
1139
+ * > By default, if a sample with the same name already exists in the sound bank,
1003
1140
  * > it is returned instead and the new sample is not copied.
1141
+ * > Use the options or a {@link SoundBankCloner} to change that.
1004
1142
  *
1005
1143
  * @param sample The sample to copy.
1144
+ * @param options Options for cloning.
1006
1145
  * @returns The copied sample.
1007
1146
  */
1008
- cloneSample(sample: BasicSample): BasicSample;
1147
+ cloneSample(sample: BasicSample, options?: Partial<SoundBankCloneOptions>): BasicSample;
1009
1148
  /**
1010
1149
  * Recursively clones an instrument into this sound bank, as well as its samples.
1011
1150
  *
1012
1151
  * > **Important**
1013
1152
  * >
1014
- * > If an instrument with the same name already exists in the sound bank,
1153
+ * > By default, if an instrument with the same name already exists in the sound bank,
1015
1154
  * > it is returned instead and the new instrument is not copied.
1155
+ * > Use the options or a {@link SoundBankCloner} to change that.
1016
1156
  *
1017
1157
  * @param instrument The instrument to copy.
1158
+ * @param options Options for cloning.
1018
1159
  * @returns The copied instrument.
1019
1160
  */
1020
- cloneInstrument(instrument: BasicInstrument): BasicInstrument;
1161
+ cloneInstrument(instrument: BasicInstrument, options?: Partial<SoundBankCloneOptions>): BasicInstrument;
1021
1162
  /**
1022
1163
  * Recursively clones a preset into this sound bank, as well as its instruments and samples.
1023
1164
  *
1024
1165
  * > **Important**
1025
1166
  * >
1026
- * > If a preset with the same name already exists in the sound bank,
1167
+ * > By default, if a preset with the same name already exists in the sound bank,
1027
1168
  * > it is returned instead and the new preset is not copied.
1169
+ * > Use the options or a {@link SoundBankCloner} to change that.
1028
1170
  *
1029
1171
  * @param preset The preset to copy.
1172
+ * @param options Options for cloning.
1030
1173
  * @returns The copied preset.
1031
1174
  */
1032
- clonePreset(preset: BasicPreset): BasicPreset;
1175
+ clonePreset(preset: BasicPreset, options?: Partial<SoundBankCloneOptions>): BasicPreset;
1033
1176
  /**
1034
1177
  * Updates internal values. Call after updating the preset list.
1035
1178
  */
@@ -1091,114 +1234,90 @@ export declare class BasicSoundBank {
1091
1234
  protected printInfo(): void;
1092
1235
  }
1093
1236
  /**
1094
- * Represents a single preset.
1095
- * This is what is used for MIDI playback.
1237
+ * An element that zones can link to, a {@link BasicInstrument} or a {@link BasicSample}.
1096
1238
  *
1097
- * @group Sound Banks
1239
+ * @group Sound Banks.Zones
1098
1240
  */
1099
- export declare class BasicPreset implements MIDIPatchFull {
1241
+ interface LinkableZoneChild<P> {
1100
1242
  /**
1101
- * The parent soundbank instance
1102
- * Currently used for determining default modulators and XG status
1103
- */
1104
- readonly parentSoundBank: BasicSoundBank;
1105
- /**
1106
- * The preset's name.
1243
+ * The element's name.
1107
1244
  */
1108
1245
  name: string;
1109
- program: number;
1110
- bankMSB: number;
1111
- bankLSB: number;
1112
- isGMGSDrum: boolean;
1113
1246
  /**
1114
- * The preset's zones.
1115
- * These are limited to specific key/velocity ranges and contain associated instruments.
1116
- */
1117
- zones: BasicPresetZone[];
1118
- /**
1119
- * Preset's global zone.
1120
- * Its parameters are overridden by the local zone parameters.
1121
- */
1122
- readonly globalZone: BasicZone;
1123
- /**
1124
- * Unused preset metadata, preserved.
1125
- */
1126
- library: number;
1127
- /**
1128
- * Unused preset metadata, preserved.
1247
+ * Links the element to a parent.
1248
+ * @param parent The parent that uses the element.
1129
1249
  */
1130
- genre: number;
1250
+ linkTo(parent: P): void;
1131
1251
  /**
1132
- * Unused preset metadata, preserved.
1252
+ * Unlinks the element from a parent.
1253
+ * @param parent The parent that no longer uses the element.
1133
1254
  */
1134
- morphology: number;
1255
+ unlinkFrom(parent: P): void;
1256
+ }
1257
+ /**
1258
+ * A zone that belongs to a parent and uses a child: a preset zone with its instrument,
1259
+ * or an instrument zone with its sample.
1260
+ * It keeps the child linked to the parent while the zone uses it.
1261
+ *
1262
+ * @group Sound Banks.Zones
1263
+ */
1264
+ export declare abstract class BasicLinkedZone<P, C extends LinkableZoneChild<P>> extends BasicZone {
1135
1265
  /**
1136
- * Creates a new preset.
1137
- * @param parentSoundBank The sound bank this preset belongs to.
1138
- * @param globalZone The optional global zone to associate within the preset.
1266
+ * The element this zone belongs to.
1139
1267
  */
1140
- constructor(parentSoundBank: BasicSoundBank, globalZone?: BasicZone);
1268
+ protected readonly parent: P;
1141
1269
  /**
1142
- * A boolean indicating if this preset is a drum preset.
1270
+ * The element this zone uses.
1143
1271
  */
1144
- get isDrum(): boolean;
1145
- private static isInRange;
1146
- private static addUniqueModulators;
1147
- private static subtractRanges;
1272
+ protected child: C;
1148
1273
  /**
1149
- * Deletes a preset zone from this preset.
1150
- * @param index The zone's index to delete.
1274
+ * The generator that stores the child's index when writing.
1151
1275
  */
1152
- deleteZone(index: number): void;
1276
+ protected abstract readonly childGenerator: GeneratorType;
1153
1277
  /**
1154
- * Creates a new preset zone and returns it.
1155
- * @param instrument The instrument to associate with the zone.
1278
+ * If this zone counts as a use of its child.
1279
+ * Zones created without linking never change the child's links.
1156
1280
  */
1157
- createZone(instrument: BasicInstrument): BasicPresetZone;
1281
+ private readonly linked;
1158
1282
  /**
1159
- * Preloads (loads and caches synthesis data) for a given key range.
1160
- * @param keyMin The lowest allowed MIDI note number.
1161
- * @param keyMax The highest allowed MIDI note number.
1283
+ * Creates a new zone and links the child to the parent.
1284
+ * @param parent The element this zone belongs to.
1285
+ * @param child The element this zone uses.
1286
+ * @param link If the child should be linked to the parent.
1162
1287
  */
1163
- preload(keyMin: number, keyMax: number): void;
1288
+ protected constructor(parent: P, child: C, link: boolean);
1164
1289
  /**
1165
- * Checks if the bank and program numbers are the same for the given preset as this one.
1166
- * Shortened version of {@link MIDIPatchTools.matches}
1167
- * @param preset The preset to check.
1290
+ * Replaces the child, moving the link from the previous one to the new one.
1291
+ * @param child The new child.
1168
1292
  */
1169
- matches(preset: MIDIPatch): boolean;
1293
+ protected setChild(child: C): void;
1170
1294
  /**
1171
- * Returns the voice synthesis data for this preset.
1172
- *
1173
- * > **Note**
1174
- * >
1175
- * > The `E-mu` attenuation correction
1176
- * > (`initialAttenuation` generator value being multiplied by `0.4`) is already performed.
1177
- *
1178
- * @param midiNote The MIDI note number.
1179
- * @param velocity The MIDI velocity.
1180
- * @returns The returned sound data.
1295
+ * The bank's list that the child's index is written from.
1296
+ * @param bank The bank being written.
1181
1297
  */
1182
- getVoiceParameters(midiNote: number, velocity: number): VoiceParameters[];
1298
+ protected abstract getChildList(bank: BasicSoundBank): C[];
1299
+ }
1300
+ /**
1301
+ * Represents a single instrument zone with an associated {@link BasicSample}.
1302
+ *
1303
+ * @group Sound Banks.Zones
1304
+ */
1305
+ export declare class BasicInstrumentZone extends BasicLinkedZone<BasicInstrument, BasicSample> {
1306
+ protected readonly childGenerator: 53;
1183
1307
  /**
1184
- * Alias for {@link MIDIPatchTools.toMIDIString}
1308
+ * The instrument this zone belongs to.
1185
1309
  */
1186
- toMIDIString(): string;
1310
+ get parentInstrument(): BasicInstrument;
1187
1311
  /**
1188
- * Alias for {@link MIDIPatchTools.toFullMIDIString}
1312
+ * The sample associated with this zone.
1189
1313
  */
1190
- toString(): string;
1314
+ get sample(): BasicSample;
1191
1315
  /**
1192
- * Combines preset into an instrument, flattening the preset zones into instrument zones.
1193
- * This is a really complex function that attempts to work around the DLS limitations of only having the instrument layer.
1194
- *
1195
- * > **Tip**
1196
- * >
1197
- * > Consider reading about [the DLS conversion problem](../../../docs/extra/dls-conversion-problem.md).
1198
- *
1199
- * @returns The instrument containing the flattened zones. If flattening was successful, it should exactly the same as this preset.
1316
+ * Sets a sample for this zone, unlinking the previous one from it.
1317
+ * @param sample The sample to set.
1200
1318
  */
1201
- toFlattenedInstrument(): BasicInstrument;
1319
+ set sample(sample: BasicSample);
1320
+ protected getChildList(bank: BasicSoundBank): BasicSample[];
1202
1321
  }
1203
1322
  /**
1204
1323
  * This class represents a single instrument, a layer below the BasicPreset.
@@ -1239,13 +1358,33 @@ export declare class BasicInstrument {
1239
1358
  /**
1240
1359
  * Creates a new instrument zone, adds it to this instrument and returns it.
1241
1360
  * @param sample The sample to associate with the zone.
1361
+ * @param link If the sample should be linked to this instrument.
1362
+ * Pass false for helper instruments that are not part of a sound bank.
1363
+ * Such a zone never changes the sample's use count or its `linkedTo` list.
1364
+ *
1365
+ * > **Warning**
1366
+ * >
1367
+ * > An instrument with unlinked zones must not be added to a sound bank!
1242
1368
  */
1243
- createZone(sample: BasicSample): BasicInstrumentZone;
1369
+ createZone(sample: BasicSample, link?: boolean): BasicInstrumentZone;
1244
1370
  /**
1245
1371
  * Unlinks the instrument from a given preset.
1246
1372
  * @param preset The preset to unlink from.
1247
1373
  */
1248
1374
  unlinkFrom(preset: BasicPreset): void;
1375
+ /**
1376
+ * Unlinks everything from this instrument.
1377
+ * This is what {@link BasicSoundBank.deleteInstrument} calls, the instrument itself stays intact.
1378
+ * Use {@link restore} to undo it.
1379
+ * @throws Error if the instrument is still used by a preset.
1380
+ */
1381
+ delete(): void;
1382
+ /**
1383
+ * Links the samples back to this instrument, the inverse of {@link delete}.
1384
+ * Use it to restore a deleted instrument, for example when undoing the deletion.
1385
+ * Add the instrument back to the sound bank as well.
1386
+ */
1387
+ restore(): void;
1249
1388
  /**
1250
1389
  * Deletes a given instrument zone if it has no uses.
1251
1390
  * @param index The index of the zone to delete.
@@ -1337,6 +1476,19 @@ export declare class BasicSample {
1337
1476
  * The sample's audio data.
1338
1477
  */
1339
1478
  protected audioData?: Float32Array;
1479
+ /**
1480
+ * The signed 16-bit little endian PCM data, as read from the file.
1481
+ */
1482
+ protected s16leData?: Uint8Array;
1483
+ /**
1484
+ * The length in sample points when it is not known from the data,
1485
+ * either a sample without data or a vorbis stream's length that was read once.
1486
+ */
1487
+ protected cachedLength?: number;
1488
+ /**
1489
+ * The form the data had before it was released or when it was loaded without data.
1490
+ */
1491
+ protected releasedForm?: SampleStoredData["form"];
1340
1492
  /**
1341
1493
  * Creates a new `BasicSample`.
1342
1494
  *
@@ -1357,6 +1509,27 @@ export declare class BasicSample {
1357
1509
  * Indicates if the sample contains compressed audio.
1358
1510
  */
1359
1511
  get isCompressed(): boolean;
1512
+ /**
1513
+ * The form the sample stores its data in, see {@link BasicSample.getStoredData}.
1514
+ * A sample without data reports the form it had, or undefined if it never had data.
1515
+ */
1516
+ get storedForm(): SampleStoredData["form"] | undefined;
1517
+ /**
1518
+ * Indicates if the sample holds any audio data.
1519
+ * A sample loaded with `sampleData: false` or released with {@link BasicSample.releaseData} does not.
1520
+ */
1521
+ get hasData(): boolean;
1522
+ /**
1523
+ * The sample's length in sample points, known without decoding the data.
1524
+ * Samples without data keep the length they had.
1525
+ *
1526
+ * > **Note**
1527
+ * >
1528
+ * > For compressed samples, it is read from the Ogg page headers, which is exact for well-formed streams.
1529
+ * > A stream with gaps in its granule positions decodes shorter. Once it is decoded,
1530
+ * > the length is the decoded one.
1531
+ */
1532
+ get sampleLength(): number;
1360
1533
  /**
1361
1534
  * If the sample is linked to another sample.
1362
1535
  */
@@ -1371,6 +1544,34 @@ export declare class BasicSample {
1371
1544
  * @return either s16le or vorbis data.
1372
1545
  */
1373
1546
  getRawData(allowVorbis: boolean): Uint8Array;
1547
+ /**
1548
+ * Gets the sample's data in the form it is stored, without decoding, encoding or copying it.
1549
+ * Use {@link BasicSample.setStoredData} to give it to another sample, for example in another thread.
1550
+ * @returns The stored form and its data.
1551
+ */
1552
+ getStoredData(): SampleStoredData;
1553
+ /**
1554
+ * Replaces the sample's data with data in a given stored form, without decoding or encoding it.
1555
+ * The sample rate and loop points are not changed.
1556
+ *
1557
+ * > **Note**
1558
+ * >
1559
+ * > s16le and vorbis data is written back unchanged when saving, float32 data is encoded.
1560
+ *
1561
+ * @param stored The stored form and its data, as returned by {@link BasicSample.getStoredData}.
1562
+ */
1563
+ setStoredData(stored: SampleStoredData): void;
1564
+ /**
1565
+ * Drops all the sample's data. The parameters and {@link BasicSample.sampleLength} stay.
1566
+ * Reading the audio data afterward throws an error until {@link BasicSample.setStoredData} gives it new data.
1567
+ */
1568
+ releaseData(): void;
1569
+ /**
1570
+ * Drops the decoded float data if the sample can decode it again from its stored s16le or vorbis data.
1571
+ * Replaced data (set with {@link BasicSample.setAudioData}) is kept.
1572
+ * @returns True if the decoded data was dropped.
1573
+ */
1574
+ releaseDecoded(): boolean;
1374
1575
  /**
1375
1576
  * Resamples the audio data _in-place_ to a given sample rate.
1376
1577
  * @param newSampleRate The new sample rate, in hertz.
@@ -1413,6 +1614,15 @@ export declare class BasicSample {
1413
1614
  * @param data The new compressed data.
1414
1615
  */
1415
1616
  setCompressedData(data: Uint8Array): void;
1617
+ /**
1618
+ * The error for reading the data of a sample that has none.
1619
+ */
1620
+ protected noDataError(): Error;
1621
+ /**
1622
+ * Decodes signed 16-bit little endian PCM into float.
1623
+ * @param data The s16le data. It may be a view at any offset.
1624
+ */
1625
+ protected decodeS16LE(data: Uint8Array): Float32Array<ArrayBuffer>;
1416
1626
  /**
1417
1627
  * Encodes s16le sample
1418
1628
  * @return the encoded data
@@ -1993,6 +2203,75 @@ export type PresetsWithKeyCombinations<T extends MIDIPatchFull> = Map<T, Map<num
1993
2203
  * @group MIDI.Protocol
1994
2204
  */
1995
2205
  export type MIDISystem = "gm" | "gm2" | "gs" | "xg";
2206
+ /**
2207
+ * A sample's data in the form the sample stores it, without decoding or encoding.
2208
+ * - `s16le` - signed 16-bit little endian PCM
2209
+ * - `vorbis` - an Ogg Vorbis stream (SF3)
2210
+ * - `float32` - decoded or replaced float PCM
2211
+ *
2212
+ * @group Sound Banks.Samples
2213
+ */
2214
+ export type SampleStoredData = {
2215
+ form: "s16le";
2216
+ data: Uint8Array;
2217
+ } | {
2218
+ form: "vorbis";
2219
+ data: Uint8Array;
2220
+ } | {
2221
+ form: "float32";
2222
+ data: Float32Array;
2223
+ };
2224
+ /**
2225
+ * Options for loading a sound bank with {@link SoundBankLoader.fromArrayBuffer}.
2226
+ *
2227
+ * @group Sound Banks
2228
+ */
2229
+ export interface SoundBankLoadOptions {
2230
+ /**
2231
+ * If the sample data should be loaded.
2232
+ * When false, the samples keep all their parameters and their length, but hold no data.
2233
+ * Presets, instruments and samples come out in the same order as with a full load.
2234
+ * Use {@link BasicSample.setStoredData} to give a sample its data later.
2235
+ *
2236
+ * > **Note**
2237
+ * >
2238
+ * > DLS files and SF2Pack banks are still decoded fully during loading. The data is dropped afterward.
2239
+ */
2240
+ sampleData: boolean;
2241
+ /**
2242
+ * If the sample data should be copied out of the file buffer.
2243
+ * When false, the samples are views into the given buffer, which saves memory and time during loading,
2244
+ * but keeps the whole buffer alive as long as any of the samples are.
2245
+ *
2246
+ * > **Note**
2247
+ * >
2248
+ * > DLS files always copy their data.
2249
+ */
2250
+ copySampleData: boolean;
2251
+ }
2252
+ /**
2253
+ * Options for cloning elements into a sound bank with {@link SoundBankCloner}.
2254
+ *
2255
+ * @group Sound Banks
2256
+ */
2257
+ export interface SoundBankCloneOptions {
2258
+ /**
2259
+ * If the cloned element itself is reused when an element with the same name exists in the bank.
2260
+ * When false, it is always copied, under a free name (`Name-1`, `Name-2` and so on).
2261
+ */
2262
+ reuseByName: boolean;
2263
+ /**
2264
+ * If the instruments and samples used by a cloned element are reused when one with the same name exists.
2265
+ * When false, they are copied under a free name as well.
2266
+ * A stereo partner of a copied sample is always copied with it.
2267
+ */
2268
+ reuseChildrenByName: boolean;
2269
+ /**
2270
+ * If the new elements are added to the bank.
2271
+ * When false, they are only listed in {@link SoundBankCloner.created}.
2272
+ */
2273
+ addToBank: boolean;
2274
+ }
1996
2275
  /**
1997
2276
  * The available interpolation types of the synthesizer.
1998
2277
  * Interpolation defines how sample points between the sample data are calculated.
@@ -2022,6 +2301,32 @@ export declare const InterpolationTypes: {
2022
2301
  * @group Synthesizer.Options
2023
2302
  */
2024
2303
  export type InterpolationType = (typeof InterpolationTypes)[keyof typeof InterpolationTypes];
2304
+ /**
2305
+ * The special EFX control sources of a {@link GSInsertionBlock} (EFX CONTROL SOURCE 1/2).
2306
+ * Values `1-95` select the control change with that number, other values are off.
2307
+ *
2308
+ * @group Synthesizer.GS Effects
2309
+ */
2310
+ export declare const GSInsertionControlSources: {
2311
+ /**
2312
+ * No control.
2313
+ */
2314
+ readonly off: 0;
2315
+ /**
2316
+ * Channel aftertouch (channel pressure).
2317
+ */
2318
+ readonly channelPressure: 112;
2319
+ /**
2320
+ * Pitch bend.
2321
+ */
2322
+ readonly pitchBend: 113;
2323
+ };
2324
+ /**
2325
+ * @inheritDoc GSInsertionControlSources
2326
+ *
2327
+ * @group Synthesizer.GS Effects
2328
+ */
2329
+ export type GSInsertionControlSource = (typeof GSInsertionControlSources)[keyof typeof GSInsertionControlSources];
2025
2330
  /**
2026
2331
  * Channel System Parameters are API-only parameters
2027
2332
  * that affect a single MIDI channel.
@@ -2451,6 +2756,35 @@ export interface GSInsertionParameter {
2451
2756
  * Higher values result in more sound being sent.
2452
2757
  */
2453
2758
  sendLevelToDelay: number;
2759
+ /**
2760
+ * `0-127`
2761
+ *
2762
+ * EFX control source 1: the controller that modulates the first controlled parameter of the type
2763
+ * (marked with `+` in the SC-8850 manual).
2764
+ * `1-95` selects a control change number, see {@link GSInsertionControlSources} for the others.
2765
+ * Only the parts with EFX assigned (see {@link ChannelMIDIParameter.efxAssign}) control it.
2766
+ */
2767
+ controlSource1: number;
2768
+ /**
2769
+ * `0-127`
2770
+ *
2771
+ * EFX control depth 1: how far control source 1 moves its parameter,
2772
+ * from `0` (-100%) through `64` (0%) to `127` (+100%) of the full parameter range.
2773
+ */
2774
+ controlDepth1: number;
2775
+ /**
2776
+ * `0-127`
2777
+ *
2778
+ * EFX control source 2: the controller that modulates the second controlled parameter of the type
2779
+ * (marked with `#` in the SC-8850 manual). See {@link controlSource1}.
2780
+ */
2781
+ controlSource2: number;
2782
+ /**
2783
+ * `0-127`
2784
+ *
2785
+ * EFX control depth 2, see {@link controlDepth1}.
2786
+ */
2787
+ controlDepth2: number;
2454
2788
  }
2455
2789
  /**
2456
2790
  * A snapshot of a {@link GSInsertionBlock}.
@@ -2475,6 +2809,10 @@ export interface GSInsertionBlockSnapshot extends GSInsertionParameter {
2475
2809
  * Value `255` means the parameter has not been changed since the type was set, so it uses the type default.
2476
2810
  */
2477
2811
  params: Uint8Array;
2812
+ /**
2813
+ * The last controller values of the two EFX control sources (signed, pitch bend is centered at 0).
2814
+ */
2815
+ controlValues: number[];
2478
2816
  }
2479
2817
  /**
2480
2818
  * The Insertion effect (EFX) processes the parts (channels) that have EFX assigned
@@ -2504,6 +2842,7 @@ export interface GSInsertionBlock extends GSInsertionParameter {
2504
2842
  * Sets the EFX type of the block.
2505
2843
  *
2506
2844
  * Type change resets the parameters and the send levels to their defaults.
2845
+ * The EFX control sources and depths are kept.
2507
2846
  * Behavior for unsupported types is up to the implementation.
2508
2847
  *
2509
2848
  * @param type The 16-bit type value to use, `MSB << 8 | LSB`.
@@ -2515,7 +2854,7 @@ export interface GSInsertionBlock extends GSInsertionParameter {
2515
2854
  */
2516
2855
  getType(): number;
2517
2856
  /**
2518
- * Resets this block to default values, including the EFX type and the send levels.
2857
+ * Resets this block to default values, including the EFX type, the send levels and the EFX control.
2519
2858
  */
2520
2859
  reset(): void;
2521
2860
  /**
@@ -2524,6 +2863,14 @@ export interface GSInsertionBlock extends GSInsertionParameter {
2524
2863
  * @param value The 7-bit value.
2525
2864
  */
2526
2865
  setParameter(param: number, value: number): void;
2866
+ /**
2867
+ * Passes a controller value of a part with EFX assigned (see {@link ChannelMIDIParameter.efxAssign})
2868
+ * for the EFX control sources ({@link controlSource1}, {@link controlSource2}).
2869
+ * @param source The controller, encoded like the control sources:
2870
+ * `1-95` a control change number, or a value of {@link GSInsertionControlSources}.
2871
+ * @param value The controller value: 7-bit, or 14-bit for {@link GSInsertionControlSources.pitchBend}.
2872
+ */
2873
+ setControllerValue(source: number, value: number): void;
2527
2874
  /**
2528
2875
  * Process the effect and **adds** it to the output.
2529
2876
  * @param inputLeft The left input buffer to process. It always starts at index 0.
@@ -3164,6 +3511,15 @@ export declare class SoundBankManager {
3164
3511
  * @param bankOffset The bank offset of the sound bank. Offsets the bank MSB value of all presets in this sound bank.
3165
3512
  */
3166
3513
  addSoundBank(bank: BasicSoundBank, id: string, bankOffset?: number): void;
3514
+ /**
3515
+ * Rebuilds the preset list from the current sound banks.
3516
+ * Call it after editing a sound bank that is already added,
3517
+ * for example after adding, removing or renumbering presets.
3518
+ *
3519
+ * The synthesizer then updates its channels to the new presets without resetting,
3520
+ * see {@link SpessaSynthProcessor.refreshPresets}.
3521
+ */
3522
+ refresh(): void;
3167
3523
  private generatePresetList;
3168
3524
  }
3169
3525
  /**
@@ -3577,7 +3933,7 @@ export declare class SpessaSynthProcessor {
3577
3933
  setSystemParameter<P extends keyof GlobalSystemParameter>(parameter: P, value: GlobalSystemParameter[P]): void;
3578
3934
  /**
3579
3935
  * A handler for missing presets during program change.
3580
- * By default, it warns to console.
3936
+ * By default, it warns to console, unless no sound bank has been added yet.
3581
3937
  * It may be useful for allowing the synthesizer to work without any sound banks.
3582
3938
  * @param patch The MIDI patch that was requested.
3583
3939
  * @param system The MIDI System for the request.
@@ -3743,6 +4099,25 @@ export declare class SpessaSynthProcessor {
3743
4099
  * These shouldn't be added to the `left` and `right` outputs. Recommended use-case is visualization.
3744
4100
  */
3745
4101
  process(left: Float32Array, right: Float32Array, startIndex?: number, sampleCount?: number, channelOutputs?: Float32Array[][]): void;
4102
+ /**
4103
+ * Updates the synthesizer after the added sound banks were edited.
4104
+ * It rebuilds the preset list, clears the voice cache,
4105
+ * and points every channel at the current preset for its patch.
4106
+ *
4107
+ * Unlike adding a sound bank, this does not reset the synthesizer or send program changes,
4108
+ * so playback continues. Voices that are already playing keep the old data until they end.
4109
+ *
4110
+ * > **Tip**
4111
+ * >
4112
+ * > Call it after adding, removing or renumbering presets in a sound bank that is already added.
4113
+ * > For edits inside existing presets, {@link clearCache} is enough.
4114
+ */
4115
+ refreshPresets(): void;
4116
+ /**
4117
+ * The decoded sample data kept under {@link SynthProcessorOptions.decodedSampleBudget}, in bytes.
4118
+ * It is only counted when a budget is set.
4119
+ */
4120
+ get decodedSampleBytes(): number;
3746
4121
  /**
3747
4122
  * Clears the synthesizer's voice cache.
3748
4123
  * This can be used to hear the changes after editing a {@link BasicSoundBank}
@@ -4002,9 +4377,9 @@ export type GSInsertionParameterMessage = {
4002
4377
  */
4003
4378
  type: "GS Insertion Param";
4004
4379
  /**
4005
- * The parameter name that was modified in the processor.
4380
+ * The parameter name that was modified in the processor: a send level or an EFX control setting.
4006
4381
  */
4007
- parameter: "sendLevelToReverb" | "sendLevelToChorus" | "sendLevelToDelay";
4382
+ parameter: keyof GSInsertionParameter;
4008
4383
  /**
4009
4384
  * The new value of the parameter.
4010
4385
  */
@@ -4637,6 +5012,7 @@ export type EffectChangeEvent = {
4637
5012
  * The parameter that was changed:
4638
5013
  * - `"type"` - 16-bit effect type (`MSB << 8 | LSB`). Note that this resets the parameters and the send levels!
4639
5014
  * - `"sendLevelToReverb" | "sendLevelToChorus" | "sendLevelToDelay"` - send levels (7-bit), see {@link GSInsertionParameter}.
5015
+ * - `"controlSource1" | "controlDepth1" | "controlSource2" | "controlDepth2"` - EFX control (7-bit), see {@link GSInsertionParameter}.
4640
5016
  * - `number` - 0-based type-specific EFX parameter index (0-19). EFX parameter 1 is 0. Value is 7-bit.
4641
5017
  */
4642
5018
  parameter: "type" | keyof GSInsertionParameter | number;
@@ -5177,6 +5553,18 @@ export interface SynthMethodOptions {
5177
5553
  * @group Synthesizer.Options
5178
5554
  */
5179
5555
  export interface SynthProcessorOptions {
5556
+ /**
5557
+ * The most decoded sample data the synthesizer keeps, in bytes.
5558
+ * When over it, the least recently played samples drop their decoded data and decode again when played.
5559
+ * Only samples that can decode again (loaded s16le or vorbis data) are dropped.
5560
+ * Defaults to Infinity, which keeps everything.
5561
+ *
5562
+ * > **Tip**
5563
+ * >
5564
+ * > Decoded data is 4 bytes per sample point, twice the size of 16-bit data.
5565
+ * > This helps with very large sound banks.
5566
+ */
5567
+ decodedSampleBudget: number;
5180
5568
  /**
5181
5569
  * The maximum buffer size the synthesizer can render at once.
5182
5570
  * Attempting to `.process()` more samples than this will result in an error.
@@ -5754,8 +6142,9 @@ interface ModifyMIDIOptions {
5754
6142
  * The GS Insertion Effect parameters.
5755
6143
  * - `"clear"` - all existing parameter change MIDI messages are cleared.
5756
6144
  * - {@link GSInsertionBlockSnapshot} - clear + the new parameters are set via System Exclusive messages.
6145
+ * The controller values of the EFX control sources are not part of it, they come from the controllers.
5757
6146
  */
5758
- gsInsertionParams?: ClearableParameter<GSInsertionBlockSnapshot>;
6147
+ gsInsertionParams?: ClearableParameter<Omit<GSInsertionBlockSnapshot, "controlValues">>;
5759
6148
  /**
5760
6149
  * The desired XG reverb parameters.
5761
6150
  * - `"clear"` - all existing parameter change MIDI messages are removed.
@@ -6876,7 +7265,7 @@ export declare class MIDIUtils {
6876
7265
  /**
6877
7266
  * Returns a MIDI event needed to set the given GS Insertion Parameter.
6878
7267
  * @param ticks The MIDI tick time for the output event.
6879
- * @param parameter The parameter to set: `"type"`, a send level name,
7268
+ * @param parameter The parameter to set: `"type"`, a send level or EFX control name (see {@link GSInsertionParameter}),
6880
7269
  * or a 0-based effect-specific parameter number (0-19).
6881
7270
  * @param value The value to set it to.
6882
7271
  * @returns The {@link MIDIMessage} needed to set this GS Insertion Parameter.
@@ -7688,6 +8077,14 @@ export declare class DefaultGSInsertion implements GSInsertionBlock {
7688
8077
  sendLevelToReverb: number;
7689
8078
  sendLevelToChorus: number;
7690
8079
  sendLevelToDelay: number;
8080
+ controlSource1: number;
8081
+ controlDepth1: number;
8082
+ controlSource2: number;
8083
+ controlDepth2: number;
8084
+ /**
8085
+ * The last controller values of both control sources (signed, pitch bend is centered).
8086
+ */
8087
+ private readonly controlValues;
7691
8088
  /**
7692
8089
  * The list of effects available in this block.
7693
8090
  * Effect type: processor.
@@ -7728,10 +8125,15 @@ export declare class DefaultGSInsertion implements GSInsertionBlock {
7728
8125
  setType(type: number): void;
7729
8126
  getType(): number;
7730
8127
  reset(): void;
8128
+ setControllerValue(source: number, value: number): void;
7731
8129
  setParameter(param: number, value: number): void;
7732
8130
  process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, outputReverb: Float32Array, outputChorus: Float32Array, outputDelay: Float32Array, startIndex: number, sampleCount: number): void;
7733
8131
  getSnapshot(): GSInsertionBlockSnapshot;
7734
8132
  applySnapshot(snapshot: GSInsertionBlockSnapshot): void;
8133
+ /**
8134
+ * Sends the offsets of both control sources to the processor.
8135
+ */
8136
+ private updateControl;
7735
8137
  }
7736
8138
  /**
7737
8139
  * Synthesizer's default voice cap.
@@ -7777,6 +8179,82 @@ export declare const DEFAULT_MIDI_CONTROLLERS: Readonly<Int16Array>;
7777
8179
  * @group Synthesizer.Drum Sets
7778
8180
  */
7779
8181
  export declare const DEFAULT_DRUM_REVERB: Int8Array<ArrayBuffer>;
8182
+ /**
8183
+ * The default clone options, matching {@link BasicSoundBank.clonePreset} and the other clone methods:
8184
+ * every element with a name already in the bank is reused, and the copies are added to the bank.
8185
+ *
8186
+ * @group Sound Banks
8187
+ */
8188
+ export declare const DEFAULT_SOUND_BANK_CLONE_OPTIONS: SoundBankCloneOptions;
8189
+ /**
8190
+ * Clones presets, instruments and samples into a sound bank, as one session.
8191
+ * Elements copied once in a session are reused when something else in the session uses them again,
8192
+ * so an instrument used by two cloned presets is only copied once.
8193
+ * Stereo pairs are always cloned together.
8194
+ *
8195
+ * > **Tip**
8196
+ * >
8197
+ * > With `addToBank: false`, nothing is added to the bank. The new elements are listed in {@link created},
8198
+ * > in an order they can be added in (samples first, then instruments, then presets).
8199
+ * > Their zones still link to the children they use, like {@link BasicInstrument.createZone} does,
8200
+ * > so a reused child in the bank counts them as users.
8201
+ *
8202
+ * @group Sound Banks
8203
+ */
8204
+ export declare class SoundBankCloner {
8205
+ /**
8206
+ * The new elements this session made, in the order they were made. Reused elements are not listed.
8207
+ */
8208
+ readonly created: {
8209
+ samples: BasicSample[];
8210
+ instruments: BasicInstrument[];
8211
+ presets: BasicPreset[];
8212
+ };
8213
+ /**
8214
+ * The bank the elements are cloned into.
8215
+ */
8216
+ readonly bank: BasicSoundBank;
8217
+ /**
8218
+ * The options of this session.
8219
+ */
8220
+ readonly options: SoundBankCloneOptions;
8221
+ private readonly sampleClones;
8222
+ private readonly instrumentClones;
8223
+ /**
8224
+ * Creates a new clone session.
8225
+ * @param bank The bank to clone elements into.
8226
+ * @param options The options for this session.
8227
+ */
8228
+ constructor(bank: BasicSoundBank, options?: Partial<SoundBankCloneOptions>);
8229
+ /**
8230
+ * Clones a sample and its stereo partner.
8231
+ * The data is shared with the original, not copied.
8232
+ * @param sample The sample to clone.
8233
+ * @returns The clone, or the existing sample with the same name if it is reused.
8234
+ */
8235
+ cloneSample(sample: BasicSample): BasicSample;
8236
+ /**
8237
+ * Clones an instrument and the samples it uses.
8238
+ * @param instrument The instrument to clone.
8239
+ * @returns The clone, or the existing instrument with the same name if it is reused.
8240
+ */
8241
+ cloneInstrument(instrument: BasicInstrument): BasicInstrument;
8242
+ /**
8243
+ * Clones a preset and the instruments and samples it uses.
8244
+ * @param preset The preset to clone.
8245
+ * @returns The clone, or the existing preset with the same name if it is reused.
8246
+ */
8247
+ clonePreset(preset: BasicPreset): BasicPreset;
8248
+ private copyInstrument;
8249
+ private copySample;
8250
+ private getFreeName;
8251
+ }
8252
+ /**
8253
+ * The default options for loading a sound bank: full loading with copied sample data.
8254
+ *
8255
+ * @group Sound Banks
8256
+ */
8257
+ export declare const DEFAULT_SOUND_BANK_LOAD_OPTIONS: SoundBankLoadOptions;
7780
8258
  /**
7781
8259
  * A helper class for loading sound bank files as {@link BasicSoundBank} instances.
7782
8260
  *
@@ -7786,9 +8264,10 @@ export declare class SoundBankLoader {
7786
8264
  /**
7787
8265
  * Loads a sound bank from a file buffer.
7788
8266
  * @param buffer The binary file buffer to load.
8267
+ * @param options Options for loading the sample data.
7789
8268
  * @returns The loaded sound bank.
7790
8269
  */
7791
- static fromArrayBuffer(buffer: ArrayBuffer): BasicSoundBank;
8270
+ static fromArrayBuffer(buffer: ArrayBuffer, options?: Partial<SoundBankLoadOptions>): BasicSoundBank;
7792
8271
  }
7793
- export type { ChannelDrumModification, ChannelGenerators, ChannelMIDIParameter, ChannelModification, ChannelSnapshot, ChannelSystemParameter, ClearableParameter, FourCC, GenericRIFFFourCC, GlobalMIDIParameter, GlobalSystemParameter, MIDIController, MIDIMessageType, ModifyMIDIOptions, SynthesizerSnapshot, UserDrumModification, WAVFourCC };
8272
+ export type { ChannelDrumModification, ChannelGenerators, ChannelMIDIParameter, ChannelModification, ChannelSnapshot, ChannelSystemParameter, ClearableParameter, FourCC, GenericRIFFFourCC, GlobalMIDIParameter, GlobalSystemParameter, LinkableZoneChild, MIDIController, MIDIMessageType, ModifyMIDIOptions, SynthesizerSnapshot, UserDrumModification, WAVFourCC };
7794
8273
  //# sourceMappingURL=index.d.ts.map