spessasynth_core 4.4.5 → 4.4.7

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
@@ -6,7 +6,7 @@
6
6
  export interface WaveWriteOptions {
7
7
  /**
8
8
  * If true, the gain of the entire song will be adjusted,
9
- * so the max sample is always 32,767 or min is always -32,768 (whichever is greater). Recommended.
9
+ * so the loudest sample (by absolute value) becomes 32,767 or -32,767. Recommended.
10
10
  */
11
11
  normalizeAudio: boolean;
12
12
  /**
@@ -190,8 +190,9 @@ export declare class SpessaLog {
190
190
  /**
191
191
  * Enables or disables logging at various levels.
192
192
  * All the input variables are booleans corresponding to the things SpessaSynth logs.
193
- * @param enableInfo enables info: all general info such as parsing sound banks, MIDI files, RPN changes, etc.
194
- * @param enableWarn enables warning: all messages unrecognized by the synthesizer, other warnings.
193
+ * @param enableInfo enables info: all general info such as parsing sound banks, MIDI files, RPN changes,
194
+ * messages unrecognized by the synthesizer, etc.
195
+ * @param enableWarn enables warning: unexpected and erroneous behavior, such as invalid data or missing presets.
195
196
  * @param enableGroup enables groups: the groups for parsing the sound banks and MIDI files.
196
197
  */
197
198
  static setLogLevel(enableInfo: boolean, enableWarn: boolean, enableGroup: boolean): void;
@@ -425,7 +426,7 @@ export declare const ModulatorControllerSources: {
425
426
  */
426
427
  readonly pitchWheel: 14;
427
428
  /**
428
- * The current pitch wheel range (where 1 means 127 semitones) on the channel.
429
+ * The current pitch wheel range (where 1 means 128 semitones) on the channel.
429
430
  */
430
431
  readonly pitchWheelRange: 16;
431
432
  /**
@@ -454,7 +455,7 @@ export declare const ModulatorCurveTypes: {
454
455
  */
455
456
  readonly concave: 1;
456
457
  /**
457
- * Inverse of concave.
458
+ * Exponential ramp, the inverse of concave.
458
459
  */
459
460
  readonly convex: 2;
460
461
  /**
@@ -506,7 +507,7 @@ export declare class ModulatorSource {
506
507
  /**
507
508
  * If this field is set true, the direction of the controller should be from the maximum value to the minimum value. So, for
508
509
  * example, if the controller source is Key Number, then a Key Number value of 0 corresponds to the maximum possible
509
- * controller output, and the Key Number value of 127 corresponds to the minimum possible controller input.
510
+ * controller output, and the Key Number value of 127 corresponds to the minimum possible controller output.
510
511
  */
511
512
  isNegative: boolean;
512
513
  /**
@@ -787,12 +788,14 @@ export declare class MIDIPatchTools {
787
788
  /**
788
789
  * Converts a given {@link MIDIPatch} to a string.
789
790
  * The format is:
790
- * - `DRUM:program` for `isGMGSDrum` set to `true`.
791
+ * - `DRUM:bankMSB:bankLSB:program` for `isGMGSDrum` set to `true`.
791
792
  * - `bankLSB:bankMSB:program` for `isGMGSDrum` set to `false`.
793
+ * @param patch The patch to convert.
792
794
  */
793
795
  static toMIDIString(patch: MIDIPatch): string;
794
796
  /**
795
797
  * Gets {@link MIDIPatch} from a given string.
798
+ * @param string The string in the {@link MIDIPatchTools.toMIDIString} format.
796
799
  */
797
800
  static fromMIDIString(string: string): MIDIPatch;
798
801
  /**
@@ -800,23 +803,30 @@ export declare class MIDIPatchTools {
800
803
  * The format is:
801
804
  * - `<MIDIPatch string> D <name>` for `isDrum` set to `true`.
802
805
  * - `<MIDIPatch string> M <name>` for `isDrum` set to `false`.
806
+ * @param patch The patch to convert.
803
807
  */
804
808
  static toFullMIDIString(patch: MIDIPatchFull): string;
805
809
  /**
806
810
  * Gets {@link MIDIPatchFull} from a given string.
811
+ * @param string The string in the {@link MIDIPatchTools.toFullMIDIString} format.
807
812
  */
808
813
  static fromFullMIDIString(string: string): MIDIPatchFull;
809
814
  /**
810
815
  * Checks if two MIDI patches represent the same one.
816
+ * @param patch1 The first patch.
817
+ * @param patch2 The second patch.
811
818
  */
812
819
  static matches(patch1: MIDIPatch, patch2: MIDIPatch): boolean;
813
820
  /**
814
821
  * A comparison function for `.sort()` or `.toSorted()`,
815
- * ordering the patches in ascending order.
822
+ * ordering the patches in ascending order: by program, then bank MSB, then bank LSB, with GM/GS drums last.
823
+ * @param a The first patch.
824
+ * @param b The second patch.
816
825
  */
817
826
  static compare(a: MIDIPatch, b: MIDIPatch): number;
818
827
  /**
819
828
  * Checks if the given {@link MIDIPatchFull} is an XG/GM2 drum patch.
829
+ * @param p The patch to check.
820
830
  */
821
831
  static isXGDrum(p: MIDIPatchFull): boolean;
822
832
  /**
@@ -826,7 +836,7 @@ export declare class MIDIPatchTools {
826
836
  * @param patch The {@link MIDIPatch} to select.
827
837
  * @param system The MIDI system to select for.
828
838
  * @returns The selected patch.
829
- * @throws Error An error if the array is empty,
839
+ * @throws Error An error if the array is empty.
830
840
  */
831
841
  static selectPatch<T extends MIDIPatchFull>(patches: T[], patch: MIDIPatch, system: MIDISystem): T;
832
842
  private static getAnyDrums;
@@ -956,7 +966,7 @@ export declare class BasicPreset implements MIDIPatchFull {
956
966
  * >
957
967
  * > Consider reading about [the DLS conversion problem](../../../docs/extra/dls-conversion-problem.md).
958
968
  *
959
- * @returns The instrument containing the flattened zones. If flattening was successful, it should exactly the same as this preset.
969
+ * @returns The instrument containing the flattened zones. If flattening was successful, it should sound exactly the same as this preset.
960
970
  */
961
971
  toFlattenedInstrument(): BasicInstrument;
962
972
  }
@@ -964,9 +974,8 @@ export declare class BasicPreset implements MIDIPatchFull {
964
974
  * This module handles parsing and writing SoundFont2 (`.sf2`, `.sf3` and `.sfogg`) files.
965
975
  * It represents a single sound bank.
966
976
  *
967
- * It also contains support for `.dls` files and experimental read and write support for [64-bit SFE](https://github.com/SFe-Team-was-taken/SFE).
977
+ * It also contains support for `.dls` files and experimental read and write support for [64-bit SFE](https://sfe-team-was-taken.github.io/SFE/).
968
978
  *
969
-
970
979
  * **Specifications:**
971
980
  *
972
981
  * - [SoundFont2 Specification](http://www.synthfont.com/sfspec24.pdf)
@@ -1001,7 +1010,7 @@ export declare class BasicSoundBank {
1001
1010
  */
1002
1011
  soundBankInfo: SoundBankInfoData;
1003
1012
  /**
1004
- * An array of all presets in the bank, ordered by bank and preset number.
1013
+ * An array of all presets in the bank, ordered by program and bank number, with GM/GS drum presets last.
1005
1014
  */
1006
1015
  presets: BasicPreset[];
1007
1016
  /**
@@ -1052,12 +1061,15 @@ export declare class BasicSoundBank {
1052
1061
  */
1053
1062
  static mergeSoundBanks(...soundBanks: BasicSoundBank[]): BasicSoundBank;
1054
1063
  /**
1055
- * Creates a simple sound bank with a single saw wave preset.
1064
+ * Creates a simple SF2 file with a single saw wave preset.
1056
1065
  * Useful for testing synthesizer's functionality without providing a file.
1066
+ * @returns The binary representation of the SF2 file.
1057
1067
  */
1058
1068
  static getSampleSoundBankFile(): ArrayBuffer;
1059
1069
  /**
1060
- * Copies a given sound bank, deeply cloning all presets instruments and samples.
1070
+ * Copies a given sound bank, cloning all presets, instruments and samples.
1071
+ * The sample data is shared with the original, not copied.
1072
+ * Elements sharing a name are all copied, the repeats get a free name like `Piano-1`.
1061
1073
  * @param bank The sound bank to copy.
1062
1074
  */
1063
1075
  static copyFrom(bank: BasicSoundBank): BasicSoundBank;
@@ -1071,8 +1083,8 @@ export declare class BasicSoundBank {
1071
1083
  *
1072
1084
  * > **Warning**
1073
1085
  * >
1074
- * > Note that decompressing (sample format `pcm`) usually results
1075
- * > in permanent sample quality loss!
1086
+ * > Note that compressing (sample format `compressed`) usually results
1087
+ * > in permanent sample quality loss! Decompressing does not restore it.
1076
1088
  * > This method is memory and CPU intensive with large sound banks.
1077
1089
  *
1078
1090
  * @param options Options associated with setting the sample format.
@@ -1082,7 +1094,7 @@ export declare class BasicSoundBank {
1082
1094
  setSampleFormat(options: SetSampleFormatOptions): Promise<BasicSample[]>;
1083
1095
  /**
1084
1096
  * Writes out a DLS Level 2 sound bank. This may not be 100% accurate.
1085
- * Samples data is always written in the S16LE PCM encoding.
1097
+ * Sample data is always written in the S16LE PCM encoding.
1086
1098
  *
1087
1099
  * > **Note**
1088
1100
  * >
@@ -1180,16 +1192,15 @@ export declare class BasicSoundBank {
1180
1192
  /**
1181
1193
  * Trims the sound bank _in-place_ to only contain samples in a given MIDI file.
1182
1194
  *
1183
-
1184
1195
  * Absent presets will be removed from the sound bank,
1185
1196
  * and samples that don't get activated in the remaining presets will be removed as well.
1186
1197
  *
1187
1198
  * > **Note**
1188
1199
  * >
1189
- * > This exact type is returned from {@link BasicMIDI.getUsedProgramsAndKeys}
1200
+ * > This exact type is returned from {@link BasicMIDI.getUsedProgramsAndKeys}.
1190
1201
  * > Consider reading the page for more explanation about the parameter.
1191
1202
  *
1192
- * @param presetData - A `Map`: `BasicPreset` -> `Set<"key-velocity">`.
1203
+ * @param presetData A `Map`: `BasicPreset` -> `Map<MIDI note, Set<velocity>>`.
1193
1204
  * Absent presets will be removed from the sound bank,
1194
1205
  * and samples that don't get activated in the remaining presets will be removed as well.
1195
1206
  */
@@ -1438,7 +1449,7 @@ export declare class BasicSample {
1438
1449
  *
1439
1450
  * > **Warning**
1440
1451
  * >
1441
- * > Do not change this value directly. use {@link BasicSample.setSampleType},
1452
+ * > Do not change this value directly. Use {@link BasicSample.setSampleType},
1442
1453
  * > {@link BasicSample.setLinkedSample} or {@link BasicSample.unlinkSample} instead.
1443
1454
  */
1444
1455
  sampleType: SampleType;
@@ -1500,7 +1511,7 @@ export declare class BasicSample {
1500
1511
  * @param sampleRate The sample's rate in Hz.
1501
1512
  * @param originalKey The sample's pitch as a MIDI note number.
1502
1513
  * @param pitchCorrection The sample's pitch correction in cents.
1503
- * @param sampleType The sample's type, an enum that defines the sample type/compression.
1514
+ * @param sampleType The sample's type, one of the {@link SampleTypes}.
1504
1515
  * @param loopStart The sample's loop start relative to the sample start in sample points.
1505
1516
  * @param loopEnd The sample's loop end relative to the sample start in sample points. Exclusive.
1506
1517
  */
@@ -1700,7 +1711,7 @@ export declare const MIDIMessageTypes: {
1700
1711
  */
1701
1712
  type MIDIMessageType = (typeof MIDIMessageTypes)[keyof typeof MIDIMessageTypes];
1702
1713
  /**
1703
- * All MIDI 1.0 controller values.
1714
+ * All MIDI 1.0 controller numbers.
1704
1715
  *
1705
1716
  * > **Tip**
1706
1717
  * >
@@ -1757,10 +1768,10 @@ export declare const MIDIControllers: {
1757
1768
  readonly effectControl2LSB: 45;
1758
1769
  readonly undefinedCC14LSB: 46;
1759
1770
  readonly undefinedCC15LSB: 47;
1760
- readonly undefinedCC16LSB: 48;
1761
- readonly undefinedCC17LSB: 49;
1762
- readonly undefinedCC18LSB: 50;
1763
- readonly undefinedCC19LSB: 51;
1771
+ readonly generalPurposeController1LSB: 48;
1772
+ readonly generalPurposeController2LSB: 49;
1773
+ readonly generalPurposeController3LSB: 50;
1774
+ readonly generalPurposeController4LSB: 51;
1764
1775
  readonly undefinedCC20LSB: 52;
1765
1776
  readonly undefinedCC21LSB: 53;
1766
1777
  readonly undefinedCC22LSB: 54;
@@ -1811,32 +1822,120 @@ export declare const MIDIControllers: {
1811
1822
  readonly nonRegisteredParameterMSB: 99;
1812
1823
  readonly registeredParameterLSB: 100;
1813
1824
  readonly registeredParameterMSB: 101;
1825
+ readonly undefinedCC102: 102;
1826
+ readonly undefinedCC103: 103;
1827
+ readonly undefinedCC104: 104;
1828
+ readonly undefinedCC105: 105;
1829
+ readonly undefinedCC106: 106;
1830
+ readonly undefinedCC107: 107;
1831
+ readonly undefinedCC108: 108;
1832
+ readonly undefinedCC109: 109;
1833
+ readonly undefinedCC110: 110;
1834
+ readonly undefinedCC111: 111;
1835
+ readonly undefinedCC112: 112;
1836
+ readonly undefinedCC113: 113;
1837
+ readonly undefinedCC114: 114;
1838
+ readonly undefinedCC115: 115;
1839
+ readonly undefinedCC116: 116;
1840
+ readonly undefinedCC117: 117;
1841
+ readonly undefinedCC118: 118;
1842
+ readonly undefinedCC119: 119;
1843
+ readonly allSoundOff: 120;
1844
+ readonly resetAllControllers: 121;
1845
+ readonly localControlOnOff: 122;
1846
+ readonly allNotesOff: 123;
1847
+ readonly omniModeOff: 124;
1848
+ readonly omniModeOn: 125;
1849
+ readonly monoModeOn: 126;
1850
+ readonly polyModeOn: 127;
1851
+ /**
1852
+ * @deprecated Use {@link MIDIControllers.generalPurposeController1LSB} instead.
1853
+ */
1854
+ readonly undefinedCC16LSB: 48;
1855
+ /**
1856
+ * @deprecated Use {@link MIDIControllers.generalPurposeController2LSB} instead.
1857
+ */
1858
+ readonly undefinedCC17LSB: 49;
1859
+ /**
1860
+ * @deprecated Use {@link MIDIControllers.generalPurposeController3LSB} instead.
1861
+ */
1862
+ readonly undefinedCC18LSB: 50;
1863
+ /**
1864
+ * @deprecated Use {@link MIDIControllers.generalPurposeController4LSB} instead.
1865
+ */
1866
+ readonly undefinedCC19LSB: 51;
1867
+ /**
1868
+ * @deprecated Use {@link MIDIControllers.undefinedCC102} instead.
1869
+ */
1814
1870
  readonly undefinedCC102LSB: 102;
1871
+ /**
1872
+ * @deprecated Use {@link MIDIControllers.undefinedCC103} instead.
1873
+ */
1815
1874
  readonly undefinedCC103LSB: 103;
1875
+ /**
1876
+ * @deprecated Use {@link MIDIControllers.undefinedCC104} instead.
1877
+ */
1816
1878
  readonly undefinedCC104LSB: 104;
1879
+ /**
1880
+ * @deprecated Use {@link MIDIControllers.undefinedCC105} instead.
1881
+ */
1817
1882
  readonly undefinedCC105LSB: 105;
1883
+ /**
1884
+ * @deprecated Use {@link MIDIControllers.undefinedCC106} instead.
1885
+ */
1818
1886
  readonly undefinedCC106LSB: 106;
1887
+ /**
1888
+ * @deprecated Use {@link MIDIControllers.undefinedCC107} instead.
1889
+ */
1819
1890
  readonly undefinedCC107LSB: 107;
1891
+ /**
1892
+ * @deprecated Use {@link MIDIControllers.undefinedCC108} instead.
1893
+ */
1820
1894
  readonly undefinedCC108LSB: 108;
1895
+ /**
1896
+ * @deprecated Use {@link MIDIControllers.undefinedCC109} instead.
1897
+ */
1821
1898
  readonly undefinedCC109LSB: 109;
1899
+ /**
1900
+ * @deprecated Use {@link MIDIControllers.undefinedCC110} instead.
1901
+ */
1822
1902
  readonly undefinedCC110LSB: 110;
1903
+ /**
1904
+ * @deprecated Use {@link MIDIControllers.undefinedCC111} instead.
1905
+ */
1823
1906
  readonly undefinedCC111LSB: 111;
1907
+ /**
1908
+ * @deprecated Use {@link MIDIControllers.undefinedCC112} instead.
1909
+ */
1824
1910
  readonly undefinedCC112LSB: 112;
1911
+ /**
1912
+ * @deprecated Use {@link MIDIControllers.undefinedCC113} instead.
1913
+ */
1825
1914
  readonly undefinedCC113LSB: 113;
1915
+ /**
1916
+ * @deprecated Use {@link MIDIControllers.undefinedCC114} instead.
1917
+ */
1826
1918
  readonly undefinedCC114LSB: 114;
1919
+ /**
1920
+ * @deprecated Use {@link MIDIControllers.undefinedCC115} instead.
1921
+ */
1827
1922
  readonly undefinedCC115LSB: 115;
1923
+ /**
1924
+ * @deprecated Use {@link MIDIControllers.undefinedCC116} instead.
1925
+ */
1828
1926
  readonly undefinedCC116LSB: 116;
1927
+ /**
1928
+ * @deprecated Use {@link MIDIControllers.undefinedCC117} instead.
1929
+ */
1829
1930
  readonly undefinedCC117LSB: 117;
1931
+ /**
1932
+ * @deprecated Use {@link MIDIControllers.undefinedCC118} instead.
1933
+ */
1830
1934
  readonly undefinedCC118LSB: 118;
1935
+ /**
1936
+ * @deprecated Use {@link MIDIControllers.undefinedCC119} instead.
1937
+ */
1831
1938
  readonly undefinedCC119LSB: 119;
1832
- readonly allSoundOff: 120;
1833
- readonly resetAllControllers: 121;
1834
- readonly localControlOnOff: 122;
1835
- readonly allNotesOff: 123;
1836
- readonly omniModeOff: 124;
1837
- readonly omniModeOn: 125;
1838
- readonly monoModeOn: 126;
1839
- readonly polyModeOn: 127;
1840
1939
  };
1841
1940
  /**
1842
1941
  * @inheritDoc MIDIControllers
@@ -2057,7 +2156,8 @@ export interface VoiceParameters {
2057
2156
  * This function is used to compress/encode a {@link BasicSample}.
2058
2157
  * The function is recommended to be asynchronous.
2059
2158
  *
2060
- * > **Note**
2159
+ * > **Note**
2160
+ * >
2061
2161
  * > Using a custom function allows for using *any* type of compression for the SF3 soundBank.
2062
2162
  * > This is allowed by the [RFC describing SF3 spec](https://github.com/FluidSynth/fluidsynth/wiki/SoundFont3Format),
2063
2163
  * > but SpessaSynth can only read Ogg Vorbis compression.
@@ -2099,7 +2199,7 @@ export type SetSampleFormatOptions = {
2099
2199
  * - `pcm` - decompresses the sound bank and changes its version to `2.04` (SF2)
2100
2200
  * - `compressed` - compresses the sound bank with a given function and changes its version to `3.0` (SF3)
2101
2201
  *
2102
- * Note that decompressing usually results in permanent sample quality loss!
2202
+ * Note that compressing usually results in permanent sample quality loss! Decompressing does not restore it.
2103
2203
  */
2104
2204
  format: "pcm";
2105
2205
  } | {
@@ -2108,7 +2208,7 @@ export type SetSampleFormatOptions = {
2108
2208
  * - `pcm` - decompresses the sound bank and changes its version to `2.04` (SF2)
2109
2209
  * - `compressed` - compresses the sound bank with a given function and changes its version to `3.0` (SF3)
2110
2210
  *
2111
- * Note that decompressing usually results in permanent sample quality loss!
2211
+ * Note that compressing usually results in permanent sample quality loss! Decompressing does not restore it.
2112
2212
  */
2113
2213
  format: "compressed";
2114
2214
  /**
@@ -2129,7 +2229,7 @@ export interface SoundBankWriteOptions {
2129
2229
  */
2130
2230
  software: string;
2131
2231
  /**
2132
- * A function to allow showing progress long operations. It can be undefined.
2232
+ * A function to allow showing progress of long operations. It can be undefined.
2133
2233
  */
2134
2234
  progressFunction?: ProgressFunction;
2135
2235
  }
@@ -2189,7 +2289,7 @@ export interface GenericRange {
2189
2289
  * - Key: The MIDI note number.
2190
2290
  * - Value: A set of all velocities this key was pressed with.
2191
2291
  *
2192
- * @group MIDI.Protocol
2292
+ * @group Sound Banks
2193
2293
  */
2194
2294
  export type PresetsWithKeyCombinations<T extends MIDIPatchFull> = Map<T, Map<number, Set<number>>>;
2195
2295
  /**
@@ -2291,9 +2391,28 @@ export declare const InterpolationTypes: {
2291
2391
  */
2292
2392
  readonly nearestNeighbor: 1;
2293
2393
  /**
2294
- * Slowest, high quality with little artifacting. (Default)
2394
+ * Cubic Hermite interpolation. Good quality with little artifacting. (Default)
2395
+ *
2396
+ * Recommended for most use-cases.
2295
2397
  */
2296
2398
  readonly hermite: 2;
2399
+ /**
2400
+ * 32-point windowed sinc interpolation.
2401
+ *
2402
+ * Very high quality with almost no aliasing or harmonic distortion,
2403
+ * usable in real time, but at a significantly higher CPU cost.
2404
+ */
2405
+ readonly sinc32: 3;
2406
+ /**
2407
+ * 128-point windowed sinc interpolation with antialiasing.
2408
+ *
2409
+ * The best quality, but extremely high cpu cost.
2410
+ *
2411
+ * > **Warning**
2412
+ * >
2413
+ * > This is very slow (especially for pitched up samples) and is meant for offline rendering, not real time playback.
2414
+ */
2415
+ readonly sinc128: 4;
2297
2416
  };
2298
2417
  /**
2299
2418
  * @inheritDoc InterpolationTypes
@@ -2401,7 +2520,9 @@ interface ChannelSystemParameter {
2401
2520
  */
2402
2521
  interpolationType: InterpolationType | null;
2403
2522
  /**
2404
- * If the channel should prevent changing any parameters via NRPN.
2523
+ * If the channel should prevent changing the part parameters via NRPN (MSB 0x01).
2524
+ * Drum, AWE32 and SF2 NRPNs are not affected.
2525
+ * The vibrato NRPNs are only locked when they control the custom vibrato.
2405
2526
  *
2406
2527
  * Overrides the global parameter if set.
2407
2528
  */
@@ -2409,7 +2530,7 @@ interface ChannelSystemParameter {
2409
2530
  /**
2410
2531
  * Indicates whether the channel is in monophonic retrigger mode.
2411
2532
  * This emulates the behavior of Microsoft GS Wavetable Synth,
2412
- * Where a new note will kill the previous one if it is still playing.
2533
+ * where a new note will kill the previous one on the same key if it is still playing.
2413
2534
  *
2414
2535
  * Overrides the global parameter if set.
2415
2536
  */
@@ -2625,7 +2746,7 @@ export interface GSChorusProcessor extends GSChorusParameter {
2625
2746
  */
2626
2747
  export interface GSDelayParameter extends GSSystemEffectParameter {
2627
2748
  /**
2628
- * 0-115
2749
+ * 1-115
2629
2750
  * 0.1ms-340ms-1000ms
2630
2751
  * The delay effect has three delay times; center, left and
2631
2752
  * right (when listening in stereo). Delay Time Center sets the delay time of the delay
@@ -2634,7 +2755,7 @@ export interface GSDelayParameter extends GSSystemEffectParameter {
2634
2755
  */
2635
2756
  timeCenter: number;
2636
2757
  /**
2637
- * 0-120
2758
+ * 1-120
2638
2759
  * 4% - 500%
2639
2760
  * This parameter sets the delay time of the delay located at the left as a percentage of
2640
2761
  * the Delay Time Center (up to a max. of 1.0 s).
@@ -2756,6 +2877,14 @@ export interface GSInsertionParameter {
2756
2877
  * Higher values result in more sound being sent.
2757
2878
  */
2758
2879
  sendLevelToDelay: number;
2880
+ /**
2881
+ * EFX send EQ switch: routes the insertion output through the equalizer (see {@link GSEqualizerProcessor})
2882
+ * when on, or straight to the output when off.
2883
+ * Default is `true` (on).
2884
+ *
2885
+ * In the SysEx message, `0` is off and any other value is on.
2886
+ */
2887
+ sendEQSwitch: boolean;
2759
2888
  /**
2760
2889
  * `0-127`
2761
2890
  *
@@ -2816,7 +2945,8 @@ export interface GSInsertionBlockSnapshot extends GSInsertionParameter {
2816
2945
  }
2817
2946
  /**
2818
2947
  * The Insertion effect (EFX) processes the parts (channels) that have EFX assigned
2819
- * (see {@link ChannelMIDIParameter.efxAssign}) and is routed straight to the output.
2948
+ * (see {@link ChannelMIDIParameter.efxAssign}) and is routed to the output,
2949
+ * through the equalizer unless {@link GSInsertionParameter.sendEQSwitch} is off.
2820
2950
  * It can additionally send its output to the reverb, chorus and delay.
2821
2951
  *
2822
2952
  * This is a Roland GS-compatible insertion interface.
@@ -2841,7 +2971,7 @@ export interface GSInsertionBlock extends GSInsertionParameter {
2841
2971
  /**
2842
2972
  * Sets the EFX type of the block.
2843
2973
  *
2844
- * Type change resets the parameters and the send levels to their defaults.
2974
+ * Type change resets the parameters, the send levels and the send EQ switch to their defaults.
2845
2975
  * The EFX control sources and depths are kept.
2846
2976
  * Behavior for unsupported types is up to the implementation.
2847
2977
  *
@@ -2894,6 +3024,93 @@ export interface GSInsertionBlock extends GSInsertionParameter {
2894
3024
  */
2895
3025
  applySnapshot(snapshot: GSInsertionBlockSnapshot): void;
2896
3026
  }
3027
+ /**
3028
+ * GS-compatible equalizer parameters.
3029
+ *
3030
+ * Also see {@link GSEqualizerProcessor} to see how to implement a custom GS-compatible equalizer processor.
3031
+ *
3032
+ * @group Synthesizer.GS Effects
3033
+ */
3034
+ export interface GSEqualizerParameter {
3035
+ /**
3036
+ * 0-1
3037
+ * 200 Hz, 400 Hz
3038
+ * This parameter sets the frequency of the low range shelf.
3039
+ */
3040
+ lowFrequency: number;
3041
+ /**
3042
+ * 52-76 (`0x34`-`0x4C`)
3043
+ * -12 dB - 0 dB - +12 dB
3044
+ * This parameter sets the amount of boost or cut for the low frequency range.
3045
+ * 64 is 0 dB, each step is 1 dB.
3046
+ */
3047
+ lowGain: number;
3048
+ /**
3049
+ * 0-1
3050
+ * 3 kHz, 6 kHz
3051
+ * This parameter sets the frequency of the high range shelf.
3052
+ */
3053
+ highFrequency: number;
3054
+ /**
3055
+ * 52-76 (`0x34`-`0x4C`)
3056
+ * -12 dB - 0 dB - +12 dB
3057
+ * This parameter sets the amount of boost or cut for the high frequency range.
3058
+ * 64 is 0 dB, each step is 1 dB.
3059
+ */
3060
+ highGain: number;
3061
+ }
3062
+ /**
3063
+ * The equalizer is a two-band (low and high) shelving equalizer which boosts or cuts specified frequency
3064
+ * ranges of the sound. An equalizer lets you
3065
+ * boost or cut specified frequency ranges of a sound to adjust the tone. For each range,
3066
+ * high and low, you can specify the frequency and the amount of boost or cut (gain).
3067
+ *
3068
+ * Only the parts with EQ enabled (see {@link ChannelMIDIParameter.eqEnabled}) pass through it,
3069
+ * and the insertion effect passes through it when {@link GSInsertionParameter.sendEQSwitch} is on.
3070
+ * The reverb, chorus and delay outputs do not.
3071
+ *
3072
+ * This is a Roland GS-compatible equalizer interface.
3073
+ *
3074
+ * It is used when {@link GlobalMIDIParameter.system} is `gm` `gm2` or `gs`.
3075
+ *
3076
+ * > **Note**
3077
+ * >
3078
+ * > The equalizer is disabled in XG mode.
3079
+ *
3080
+ * {@link SpessaSynthProcessor} allows you to supply a custom equalizer processor.
3081
+ * A custom equalizer processor must implement this interface.
3082
+ *
3083
+ * ### Editing the parameters
3084
+ *
3085
+ * Editing the parameters can be done via GS system exclusive messages.
3086
+ *
3087
+ * > **Tip**
3088
+ * >
3089
+ * > Refer to [SC-8850 Owner's Manual](https://cdn.roland.com/assets/media/pdf/SC-8850_OM.pdf) (p.78, 86, 236) for more information.
3090
+ *
3091
+ * @group Synthesizer.GS Effects
3092
+ */
3093
+ export interface GSEqualizerProcessor extends GSEqualizerParameter {
3094
+ /**
3095
+ * Process the effect and **adds** it to the output.
3096
+ * @param inputLeft The left input buffer to process. It always starts at index 0.
3097
+ * @param inputRight The right input buffer to process. It always starts at index 0.
3098
+ * @param outputLeft The left output buffer.
3099
+ * @param outputRight The right output buffer.
3100
+ * @param startIndex The index to start mixing at into the output buffers.
3101
+ * @param sampleCount The amount of samples to mix. This will never be larger than {@link SynthProcessorOptions.maxBufferSize} of the parent {@link SpessaSynthProcessor} instance.
3102
+ */
3103
+ process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, startIndex: number, sampleCount: number): void;
3104
+ /**
3105
+ * Gets a snapshot of this effect processor instance.
3106
+ */
3107
+ getSnapshot(): GSEqualizerParameter;
3108
+ /**
3109
+ * Restores this effect processor instance from a snapshot.
3110
+ * @param snapshot The snapshot to restore.
3111
+ */
3112
+ applySnapshot(snapshot: GSEqualizerParameter): void;
3113
+ }
2897
3114
  /**
2898
3115
  * A snapshot of a {@link XGEffectBlock}.
2899
3116
  *
@@ -2918,7 +3135,7 @@ export interface XGEffectBlockSnapshot {
2918
3135
  *
2919
3136
  * It represents a single effect block.
2920
3137
  *
2921
- * There are 4 effect blocks types in XG:
3138
+ * There are 4 effect block types in XG:
2922
3139
  * - Reverb
2923
3140
  * - Chorus
2924
3141
  * - Variation
@@ -2998,7 +3215,14 @@ export interface XGSystemEffectBlockSnapshot extends XGSystemEffectParameter, XG
2998
3215
  * @group Synthesizer.XG Effects
2999
3216
  */
3000
3217
  export interface XGSystemEffectBlock extends XGEffectBlock, XGSystemEffectParameter {
3218
+ /**
3219
+ * Gets a snapshot of this XG effect block.
3220
+ */
3001
3221
  getSnapshot(): XGSystemEffectBlockSnapshot;
3222
+ /**
3223
+ * Restores this XG effect block from a snapshot.
3224
+ * @param snapshot The snapshot to restore.
3225
+ */
3002
3226
  applySnapshot(snapshot: XGSystemEffectBlockSnapshot): void;
3003
3227
  }
3004
3228
  /**
@@ -3080,13 +3304,20 @@ export interface XGChorusBlock extends XGSystemEffectBlock, XGChorusParameter {
3080
3304
  * @param inputRight The input buffer to process. It always starts at index 0.
3081
3305
  * @param outputLeft The left output buffer.
3082
3306
  * @param outputRight The right output buffer.
3083
- * @param reverbLeft The left reverb send buffer.
3084
- * @param reverbRight The right reverb send buffer.
3307
+ * @param reverbLeft The left reverb send buffer. It always starts at index 0.
3308
+ * @param reverbRight The right reverb send buffer. It always starts at index 0.
3085
3309
  * @param startIndex The index to start mixing at into the output buffers.
3086
3310
  * @param sampleCount The amount of samples to mix. This will never be larger than {@link SynthProcessorOptions.maxBufferSize} of the parent {@link SpessaSynthProcessor} instance.
3087
3311
  */
3088
3312
  process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, reverbLeft: Float32Array, reverbRight: Float32Array, startIndex: number, sampleCount: number): void;
3313
+ /**
3314
+ * Gets a snapshot of this XG effect block.
3315
+ */
3089
3316
  getSnapshot(): XGChorusBlockSnapshot;
3317
+ /**
3318
+ * Restores this XG effect block from a snapshot.
3319
+ * @param snapshot The snapshot to restore.
3320
+ */
3090
3321
  applySnapshot(snapshot: XGChorusBlockSnapshot): void;
3091
3322
  }
3092
3323
  /**
@@ -3098,7 +3329,7 @@ export interface XGInsertionParameter {
3098
3329
  /**
3099
3330
  * The channel routed through the insertion effect, 0-based.
3100
3331
  *
3101
- * 127 or a value that's above the current channel count means OFF.
3332
+ * 127 or any value that's not below the current channel count means OFF.
3102
3333
  */
3103
3334
  partNumber: number;
3104
3335
  }
@@ -3143,7 +3374,14 @@ export interface XGInsertionBlock extends XGInsertionParameter, XGEffectBlock {
3143
3374
  * @param sampleCount The amount of samples to mix. This will never be larger than {@link SynthProcessorOptions.maxBufferSize} of the parent {@link SpessaSynthProcessor} instance.
3144
3375
  */
3145
3376
  processInsertion(inputLeft: Float32Array, inputRight: Float32Array, sampleCount: number): void;
3377
+ /**
3378
+ * Gets a snapshot of this XG effect block.
3379
+ */
3146
3380
  getSnapshot(): XGInsertionBlockSnapshot;
3381
+ /**
3382
+ * Restores this XG effect block from a snapshot.
3383
+ * @param snapshot The snapshot to restore.
3384
+ */
3147
3385
  applySnapshot(snapshot: XGInsertionBlockSnapshot): void;
3148
3386
  }
3149
3387
  /**
@@ -3156,7 +3394,7 @@ export interface XGVariationParameter extends XGSystemEffectParameter, XGInserti
3156
3394
  * Indicates if variation is in the insertion mode (CONNECTION).
3157
3395
  * If `false`, then variation is in the `system` mode.
3158
3396
  *
3159
- * The two connection modes work as following:
3397
+ * The two connection modes work as follows:
3160
3398
  * - `system` routes all channels via sends (like reverb and chorus).
3161
3399
  * - `insertion` routes a single `partNumber` channel straight through. Note that variation is processed last, after all insertion effects.
3162
3400
  */
@@ -3232,7 +3470,14 @@ export interface XGVariationBlock extends XGVariationParameter, XGSystemEffectBl
3232
3470
  * @param sampleCount The amount of samples to mix. This will never be larger than {@link SynthProcessorOptions.maxBufferSize} of the parent {@link SpessaSynthProcessor} instance.
3233
3471
  */
3234
3472
  process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, chorusLeft: Float32Array, chorusRight: Float32Array, reverbLeft: Float32Array, reverbRight: Float32Array, startIndex: number, sampleCount: number): void;
3473
+ /**
3474
+ * Gets a snapshot of this XG effect block.
3475
+ */
3235
3476
  getSnapshot(): XGVariationBlockSnapshot;
3477
+ /**
3478
+ * Restores this XG effect block from a snapshot.
3479
+ * @param snapshot The snapshot to restore.
3480
+ */
3236
3481
  applySnapshot(snapshot: XGVariationBlockSnapshot): void;
3237
3482
  }
3238
3483
  /**
@@ -3283,7 +3528,7 @@ interface GlobalSystemParameter {
3283
3528
  * The reverb effect gain.
3284
3529
  * From 0 to any number. 1 is 100% reverb.
3285
3530
  *
3286
- * Applies to both GS and XG reverb.
3531
+ * Applies to both GS and XG reverb, including XG parts with an insertion effect assigned.
3287
3532
  */
3288
3533
  reverbGain: number;
3289
3534
  /**
@@ -3304,7 +3549,7 @@ interface GlobalSystemParameter {
3304
3549
  * The chorus effect gain.
3305
3550
  * From 0 to any number. 1 is 100% chorus.
3306
3551
  *
3307
- * Applies to both GS and XG chorus.
3552
+ * Applies to both GS and XG chorus, including XG parts with an insertion effect assigned.
3308
3553
  */
3309
3554
  chorusGain: number;
3310
3555
  /**
@@ -3333,6 +3578,17 @@ interface GlobalSystemParameter {
3333
3578
  * the delay parameters then locking it to prevent changes by MIDI files.
3334
3579
  */
3335
3580
  gsDelayLock: boolean;
3581
+ /**
3582
+ * If the synthesizer should prevent editing of the GS equalizer parameters.
3583
+ * This effect is modified using MIDI system exclusive messages, so
3584
+ * the recommended use case would be setting
3585
+ * the equalizer parameters then locking it to prevent changes by MIDI files.
3586
+ *
3587
+ * > **Warning**
3588
+ * >
3589
+ * > To lock the channel equalizer switch, lock the {@link ChannelMIDIParameter.eqEnabled `eqEnabled`} parameter instead.
3590
+ */
3591
+ gsEqualizerLock: boolean;
3336
3592
  /**
3337
3593
  * The XG variation gain when in system mode. {@link XGVariationConnection}
3338
3594
  * From 0 to any number. 1 is 100% variation.
@@ -3432,7 +3688,11 @@ interface GlobalSystemParameter {
3432
3688
  */
3433
3689
  interpolationType: InterpolationType;
3434
3690
  /**
3435
- * If the synthesizer should prevent changing any parameters via NRPN.
3691
+ * If the synthesizer should prevent changing the part parameters via NRPN (MSB 0x01).
3692
+ * Drum, AWE32 and SF2 NRPNs are not affected.
3693
+ * The vibrato NRPNs are only locked when they control the custom vibrato.
3694
+ *
3695
+ * Channels can override it with {@link ChannelSystemParameter.nrpnParamLock}.
3436
3696
  */
3437
3697
  nrpnParamLock: boolean;
3438
3698
  /**
@@ -3781,6 +4041,10 @@ interface SynthesizerSnapshot {
3781
4041
  * A snapshot of the delay processor.
3782
4042
  */
3783
4043
  gsDelayProcessor: GSDelayParameter;
4044
+ /**
4045
+ * A snapshot of the equalizer processor.
4046
+ */
4047
+ gsEqualizerProcessor: GSEqualizerParameter;
3784
4048
  /**
3785
4049
  * A snapshot of the GS insertion block.
3786
4050
  */
@@ -3918,6 +4182,11 @@ export declare class SpessaSynthProcessor {
3918
4182
  * Current total amount of voices that are playing.
3919
4183
  */
3920
4184
  get voiceCount(): number;
4185
+ /**
4186
+ * The decoded sample data kept under {@link SynthProcessorOptions.decodedSampleBudget}, in bytes.
4187
+ * It is only counted when a budget is set.
4188
+ */
4189
+ get decodedSampleBytes(): number;
3921
4190
  /**
3922
4191
  * Locks or unlocks a given {@link GlobalMIDIParameter}.
3923
4192
  * This prevents any changes to it until it's unlocked.
@@ -3948,7 +4217,7 @@ export declare class SpessaSynthProcessor {
3948
4217
  * > Refer to the [MIDI Implementation](../../docs/extra/midi-implementation.md)
3949
4218
  * > for the list of supported System Exclusives.
3950
4219
  *
3951
- * @param syx The system exclusive message as an array of bytes.
4220
+ * @param syx The system exclusive message as an array of bytes, without the starting `F0` byte.
3952
4221
  * @param channelOffset The channel offset for the message as they usually can only address the first 16 channels.
3953
4222
  * For example, to send a system exclusive on channel 16,
3954
4223
  * send a system exclusive for channel 0 and set an offset of 16.
@@ -4039,11 +4308,11 @@ export declare class SpessaSynthProcessor {
4039
4308
  */
4040
4309
  processMessages(messages: (SysExAcceptedArray | MIDIMessage)[], channelOffset?: number, options?: SynthMethodOptions): void;
4041
4310
  /**
4042
- * Destroy the synthesizer processor, clearing all channels and voices.
4311
+ * Destroy the synthesizer processor, clearing all channels and voices.
4043
4312
  *
4044
- * > **Warning**
4045
- * >
4046
- * > This is irreversible, so use with caution.
4313
+ * > **Warning**
4314
+ * >
4315
+ * > This is irreversible, so use with caution.
4047
4316
  */
4048
4317
  destroy(): void;
4049
4318
  /**
@@ -4053,6 +4322,9 @@ export declare class SpessaSynthProcessor {
4053
4322
  * >
4054
4323
  * > This method overrides the existing System Parameters with the ones from the snapshot.
4055
4324
  *
4325
+ * If this processor has more XG insertion blocks than the snapshot,
4326
+ * the blocks without snapshot data are reset to their defaults.
4327
+ *
4056
4328
  * @param snapshot The snapshot to apply.
4057
4329
  */
4058
4330
  applySnapshot(snapshot: SynthesizerSnapshot): void;
@@ -4113,11 +4385,6 @@ export declare class SpessaSynthProcessor {
4113
4385
  * > For edits inside existing presets, {@link clearCache} is enough.
4114
4386
  */
4115
4387
  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;
4121
4388
  /**
4122
4389
  * Clears the synthesizer's voice cache.
4123
4390
  * This can be used to hear the changes after editing a {@link BasicSoundBank}
@@ -4258,7 +4525,7 @@ export type ChannelMIDIParameterMessage = { [P in keyof ChannelMIDIParameter]: {
4258
4525
  channel: number;
4259
4526
  }; }[keyof ChannelMIDIParameter];
4260
4527
  /**
4261
- * Represents an analyzed channel GS Reverb Processor change.
4528
+ * Represents an analyzed GS Reverb Processor change.
4262
4529
  *
4263
4530
  * @group MIDI.Protocol
4264
4531
  */
@@ -4290,7 +4557,7 @@ export type GSReverbParameterMessage = { [P in keyof GSReverbParameter]: {
4290
4557
  value: number;
4291
4558
  };
4292
4559
  /**
4293
- * Represents an analyzed channel GS Chorus Processor change.
4560
+ * Represents an analyzed GS Chorus Processor change.
4294
4561
  *
4295
4562
  * @group MIDI.Protocol
4296
4563
  */
@@ -4322,7 +4589,7 @@ export type GSChorusParameterMessage = { [P in keyof GSChorusParameter]: {
4322
4589
  value: number;
4323
4590
  };
4324
4591
  /**
4325
- * Represents an analyzed channel GS Delay Processor change.
4592
+ * Represents an analyzed GS Delay Processor change.
4326
4593
  *
4327
4594
  * @group MIDI.Protocol
4328
4595
  */
@@ -4354,7 +4621,26 @@ export type GSDelayParameterMessage = { [P in keyof GSDelayParameter]: {
4354
4621
  value: number;
4355
4622
  };
4356
4623
  /**
4357
- * Represents an analyzed channel GS Insertion Processor change.
4624
+ * Represents an analyzed GS Equalizer Processor change.
4625
+ *
4626
+ * @group MIDI.Protocol
4627
+ */
4628
+ export type GSEqualizerParameterMessage = { [P in keyof GSEqualizerParameter]: {
4629
+ /**
4630
+ * The message type identifier.
4631
+ */
4632
+ type: "GS Equalizer Param";
4633
+ /**
4634
+ * The GS equalizer parameter being modified.
4635
+ */
4636
+ parameter: P;
4637
+ /**
4638
+ * The new value of the GS equalizer parameter.
4639
+ */
4640
+ value: GSEqualizerParameter[P];
4641
+ }; }[keyof GSEqualizerParameter];
4642
+ /**
4643
+ * Represents an analyzed GS Insertion Processor change.
4358
4644
  *
4359
4645
  * @group MIDI.Protocol
4360
4646
  */
@@ -4379,11 +4665,24 @@ export type GSInsertionParameterMessage = {
4379
4665
  /**
4380
4666
  * The parameter name that was modified in the processor: a send level or an EFX control setting.
4381
4667
  */
4382
- parameter: keyof GSInsertionParameter;
4668
+ parameter: Exclude<keyof GSInsertionParameter, "sendEQSwitch">;
4383
4669
  /**
4384
4670
  * The new value of the parameter.
4385
4671
  */
4386
4672
  value: number;
4673
+ } | {
4674
+ /**
4675
+ * An insertion effect processor parameter message (Roland GS).
4676
+ */
4677
+ type: "GS Insertion Param";
4678
+ /**
4679
+ * The send EQ switch, see {@link GSInsertionParameter.sendEQSwitch}.
4680
+ */
4681
+ parameter: "sendEQSwitch";
4682
+ /**
4683
+ * If the insertion output goes through the equalizer.
4684
+ */
4685
+ value: boolean;
4387
4686
  } | {
4388
4687
  /**
4389
4688
  * An insertion effect processor parameter message (Roland GS).
@@ -4728,7 +5027,7 @@ export type AnalyzedParameter = {
4728
5027
  *
4729
5028
  * @group MIDI.Protocol
4730
5029
  */
4731
- export type AnalyzedMIDIMessage = AnalyzedParameter | GSReverbParameterMessage | GSChorusParameterMessage | GSDelayParameterMessage | GSInsertionParameterMessage | XGReverbParameterMessage | XGChorusParameterMessage | XGVariationParameterMessage | XGInsertionParameterMessage | {
5030
+ export type AnalyzedMIDIMessage = AnalyzedParameter | GSReverbParameterMessage | GSChorusParameterMessage | GSDelayParameterMessage | GSEqualizerParameterMessage | GSInsertionParameterMessage | XGReverbParameterMessage | XGChorusParameterMessage | XGVariationParameterMessage | XGInsertionParameterMessage | {
4732
5031
  /**
4733
5032
  * A MIDI program change message configured via System Exclusive.
4734
5033
  */
@@ -4869,7 +5168,7 @@ export interface ControllerChangeEvent extends ChannelEvent {
4869
5168
  }
4870
5169
  /**
4871
5170
  * This event is triggered when a MIDI polyphonic pressure event is received. This controls the pressure of a single note.
4872
- * By default, this controls vibrato in SpessaSynth, though it can be changed with sound bank modulators.
5171
+ * It has no effect by default, it has to be assigned with sound bank modulators or system exclusives.
4873
5172
  *
4874
5173
  * @group Synthesizer.Events
4875
5174
  */
@@ -4955,6 +5254,7 @@ export type FXType<K> = Exclude<keyof K, "process" | "getSnapshot" | "applySnaps
4955
5254
  * - {@link GSReverbProcessor} (`effect: "gsReverb"`)
4956
5255
  * - {@link GSChorusProcessor} (`effect: "gsChorus"`)
4957
5256
  * - {@link GSDelayProcessor} (`effect: "gsDelay"`)
5257
+ * - {@link GSEqualizerProcessor} (`effect: "gsEqualizer"`)
4958
5258
  * - {@link GSInsertionBlock} (`effect: "gsInsertion"`)
4959
5259
  * - {@link XGReverbBlock} (`effect: "xgReverb"`)
4960
5260
  * - {@link XGChorusBlock} (`effect: "xgChorus"`)
@@ -5003,6 +5303,19 @@ export type EffectChangeEvent = {
5003
5303
  * The new 7-bit value.
5004
5304
  */
5005
5305
  value: number;
5306
+ } | {
5307
+ /**
5308
+ * The effect that was changed: Roland GS equalizer.
5309
+ */
5310
+ effect: "gsEqualizer";
5311
+ /**
5312
+ * The parameter, see {@link GSEqualizerParameter}.
5313
+ */
5314
+ parameter: keyof GSEqualizerParameter;
5315
+ /**
5316
+ * The new 7-bit value.
5317
+ */
5318
+ value: number;
5006
5319
  } | {
5007
5320
  /**
5008
5321
  * The effect that was changed: Roland GS insertion.
@@ -5015,11 +5328,24 @@ export type EffectChangeEvent = {
5015
5328
  * - `"controlSource1" | "controlDepth1" | "controlSource2" | "controlDepth2"` - EFX control (7-bit), see {@link GSInsertionParameter}.
5016
5329
  * - `number` - 0-based type-specific EFX parameter index (0-19). EFX parameter 1 is 0. Value is 7-bit.
5017
5330
  */
5018
- parameter: "type" | keyof GSInsertionParameter | number;
5331
+ parameter: "type" | Exclude<keyof GSInsertionParameter, "sendEQSwitch"> | number;
5019
5332
  /**
5020
5333
  * The new value for the parameter.
5021
5334
  */
5022
5335
  value: number;
5336
+ } | {
5337
+ /**
5338
+ * The effect that was changed: Roland GS insertion.
5339
+ */
5340
+ effect: "gsInsertion";
5341
+ /**
5342
+ * The send EQ switch, see {@link GSInsertionParameter.sendEQSwitch}.
5343
+ */
5344
+ parameter: "sendEQSwitch";
5345
+ /**
5346
+ * If the insertion output goes through the equalizer.
5347
+ */
5348
+ value: boolean;
5023
5349
  } | {
5024
5350
  /**
5025
5351
  * The effect that was changed: Yamaha XG reverb block.
@@ -5145,12 +5471,11 @@ export type UserDrumSetChangeEvent = { [P in keyof UserDrumSetParameter]: {
5145
5471
  * | `noteOff` | {@link NoteOffEvent} | Key has been released. |
5146
5472
  * | `controllerChange` | {@link ControllerChangeEvent} | Controller has been changed. |
5147
5473
  * | `programChange` | {@link ProgramChangeEvent} | Program has been changed. |
5148
- * | `channelPressure` | — | Channel's pressure has been changed. |
5149
- * | `polyPressure` | {@link PolyPressureEvent} | Note's pressure has been changed. |
5474
+ * | `polyPressure` | {@link PolyPressureEvent} | Note's pressure has been changed. |
5150
5475
  * | `stopAll` | {@link StopAllEvent} | All voices were stopped on a given channel. |
5151
5476
  * | `channelAdded` | — | A new channel was added to the synth. |
5152
5477
  * | `presetListChange` | — | The preset list has been changed/initialized. |
5153
- * | `reset` | — | The synthesizer has been reset. |
5478
+ * | `reset` | — | The synthesizer is about to be reset. |
5154
5479
  * | `displayMessage` | — | The synthesizer has received a display message. |
5155
5480
  * | `globalParamChange` | {@link GlobalMIDIParameterChangeEvent} | A global MIDI Parameter has been changed. |
5156
5481
  * | `channelParamChange` | {@link ChannelMIDIParameterChangeEvent} | A channel MIDI Parameter has been changed. |
@@ -5163,6 +5488,11 @@ export type UserDrumSetChangeEvent = { [P in keyof UserDrumSetParameter]: {
5163
5488
  * > It automatically combines the sound banks and sends the list of presets as they will be played.
5164
5489
  * > It also signals that the sound bank has been fully loaded.
5165
5490
  *
5491
+ * > **Note**
5492
+ * >
5493
+ * > There is no separate channel pressure event.
5494
+ * > Channel pressure changes are reported as `channelParamChange` with the `pressure` parameter.
5495
+ *
5166
5496
  * @group Synthesizer.Events
5167
5497
  */
5168
5498
  export interface SynthesizerEvent {
@@ -5176,7 +5506,7 @@ export interface SynthesizerEvent {
5176
5506
  noteOff: NoteOffEvent;
5177
5507
  /**
5178
5508
  * This event is triggered when a controller is changed on any channel (usually MIDI controller change),
5179
- * though [some system exclusives can change it too.](../../docs/extra/midi-implementation.md)
5509
+ * though [some system exclusives can change it too.](../../docs/extra/midi-implementation.md)
5180
5510
  *
5181
5511
  * > **Note**
5182
5512
  * >
@@ -5195,7 +5525,7 @@ export interface SynthesizerEvent {
5195
5525
  programChange: ProgramChangeEvent;
5196
5526
  /**
5197
5527
  * This event is triggered when a MIDI polyphonic pressure event is received. This controls the pressure of a single note.
5198
- * By default, this controls vibrato in SpessaSynth, though it can be changed with sound bank modulators.
5528
+ * It has no effect by default, it has to be assigned with sound bank modulators or system exclusives.
5199
5529
  */
5200
5530
  polyPressure: PolyPressureEvent;
5201
5531
  /**
@@ -5228,9 +5558,10 @@ export interface SynthesizerEvent {
5228
5558
  */
5229
5559
  presetListChange: MIDIPatchFull[];
5230
5560
  /**
5231
- * This event is triggered when all controllers and programs have been reset. Effectively a system reset.
5561
+ * This event is triggered when the synthesizer is about to be reset (all controllers and programs). Effectively a system reset.
5562
+ * It is called before anything is reset, so the synthesizer still has its old state at that point.
5232
5563
  *
5233
- * The data is the new system the synthesizer was reset with.
5564
+ * The data is the new system the synthesizer will be reset to.
5234
5565
  *
5235
5566
  * > **Note**
5236
5567
  * >
@@ -5244,9 +5575,10 @@ export interface SynthesizerEvent {
5244
5575
  *
5245
5576
  * Notable messages that can trigger this event:
5246
5577
  *
5247
- * - All messages with GS Model ID of `0x45` (Display Data)
5578
+ * - GS Display Data (Model ID `0x45`) messages with the first address byte `0x10` or `0x20`
5248
5579
  * - GS Patch Name
5249
5580
  * - GS Drum Map Name
5581
+ * - GS User Drum Set Name
5250
5582
  * - XG Display Letter
5251
5583
  * - XG Display Bitmap
5252
5584
  *
@@ -5361,6 +5693,8 @@ interface DefaultXGEffectProcessorConstructor {
5361
5693
  export declare abstract class DefaultXGEffect implements XGEffectBlock {
5362
5694
  /**
5363
5695
  * The currently used processor.
5696
+ * Hidden from the docs as the processor types are internal.
5697
+ * @hidden
5364
5698
  */
5365
5699
  protected processor: DefaultXGEffectProcessor;
5366
5700
  protected readonly outputLeft: Float32Array<ArrayBuffer>;
@@ -5380,8 +5714,9 @@ export declare abstract class DefaultXGEffect implements XGEffectBlock {
5380
5714
  * @param defaultType The default effect type.
5381
5715
  * @param sampleRate The sample rate, in Hertz.
5382
5716
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
5383
- * Attempting to `.process()` more samples than this will result in an error.
5717
+ * Processing more samples than this is not supported and produces undefined output.
5384
5718
  * @param variation True for the variation and insertion blocks.
5719
+ * @hidden
5385
5720
  */
5386
5721
  protected constructor(effectMap: Map<number, DefaultXGEffectProcessorConstructor>, fallbackProcessor: DefaultXGEffectProcessorConstructor, defaultType: number, sampleRate: number, maxBufferSize: number, variation: boolean);
5387
5722
  setType(type: number): void;
@@ -5404,8 +5739,18 @@ export declare abstract class DefaultXGEffect implements XGEffectBlock {
5404
5739
  export declare abstract class DefaultXGSystemEffect extends DefaultXGEffect implements XGSystemEffectBlock {
5405
5740
  return: number;
5406
5741
  pan: number;
5742
+ /**
5743
+ * Resets this block to default values, including the processor type.
5744
+ */
5407
5745
  reset(): void;
5746
+ /**
5747
+ * Gets a snapshot of this XG effect block.
5748
+ */
5408
5749
  getSnapshot(): XGSystemEffectBlockSnapshot;
5750
+ /**
5751
+ * Restores this XG effect block from a snapshot.
5752
+ * @param snapshot The snapshot to restore.
5753
+ */
5409
5754
  applySnapshot(snapshot: XGSystemEffectBlockSnapshot): void;
5410
5755
  /**
5411
5756
  * Mixes the staged wet output into the system effect destination, applying return and pan.
@@ -5419,6 +5764,8 @@ export declare abstract class DefaultXGSystemEffect extends DefaultXGEffect impl
5419
5764
  /**
5420
5765
  * The default implementation for {@link XGReverbBlock}.
5421
5766
  *
5767
+ * The default type is HALL 1. Unknown types use the type with LSB 0, or NO EFFECT (silence) if that is missing too.
5768
+ *
5422
5769
  * @group Synthesizer.XG Effects
5423
5770
  * @sealed
5424
5771
  */
@@ -5427,7 +5774,7 @@ export declare class DefaultXGReverb extends DefaultXGSystemEffect implements XG
5427
5774
  * Constructs a new default XG reverb processor.
5428
5775
  * @param sampleRate The sample rate, in Hertz.
5429
5776
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
5430
- * Attempting to `.process()` more samples than this will result in an error.
5777
+ * Processing more samples than this is not supported and produces undefined output.
5431
5778
  */
5432
5779
  constructor(sampleRate: number, maxBufferSize: number);
5433
5780
  process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, startIndex: number, sampleCount: number): void;
@@ -5435,6 +5782,8 @@ export declare class DefaultXGReverb extends DefaultXGSystemEffect implements XG
5435
5782
  /**
5436
5783
  * The default implementation for {@link XGChorusBlock}.
5437
5784
  *
5785
+ * The default type is CHORUS 1. Unknown types use the type with LSB 0, or NO EFFECT (silence) if that is missing too.
5786
+ *
5438
5787
  * @group Synthesizer.XG Effects
5439
5788
  * @sealed
5440
5789
  */
@@ -5444,11 +5793,17 @@ export declare class DefaultXGChorus extends DefaultXGSystemEffect implements XG
5444
5793
  * Constructs a new default XG chorus processor.
5445
5794
  * @param sampleRate The sample rate, in Hertz.
5446
5795
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
5447
- * Attempting to `.process()` more samples than this will result in an error.
5796
+ * Processing more samples than this is not supported and produces undefined output.
5448
5797
  */
5449
5798
  constructor(sampleRate: number, maxBufferSize: number);
5799
+ /**
5800
+ * Resets this block to default values, including the processor type.
5801
+ */
5450
5802
  reset(): void;
5451
5803
  process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, reverbLeft: Float32Array, reverbRight: Float32Array, startIndex: number, sampleCount: number): void;
5804
+ /**
5805
+ * Gets a snapshot of this XG effect block.
5806
+ */
5452
5807
  getSnapshot(): {
5453
5808
  sendToReverb: number;
5454
5809
  return: number;
@@ -5456,11 +5811,18 @@ export declare class DefaultXGChorus extends DefaultXGSystemEffect implements XG
5456
5811
  type: number;
5457
5812
  params: Int16Array;
5458
5813
  };
5814
+ /**
5815
+ * Restores this XG effect block from a snapshot.
5816
+ * @param snapshot The snapshot to restore.
5817
+ */
5459
5818
  applySnapshot(snapshot: XGChorusBlockSnapshot): void;
5460
5819
  }
5461
5820
  /**
5462
5821
  * The default implementation for {@link XGVariationBlock}.
5463
5822
  *
5823
+ * The default type is DELAY L,C,R in the insertion connection.
5824
+ * Unknown types use the type with LSB 0, or THRU if that is missing too.
5825
+ *
5464
5826
  * @group Synthesizer.XG Effects
5465
5827
  * @sealed
5466
5828
  */
@@ -5473,12 +5835,18 @@ export declare class DefaultXGVariation extends DefaultXGSystemEffect implements
5473
5835
  * Constructs a new default XG variation processor.
5474
5836
  * @param sampleRate The sample rate, in Hertz.
5475
5837
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
5476
- * Attempting to `.process()` more samples than this will result in an error.
5838
+ * Processing more samples than this is not supported and produces undefined output.
5477
5839
  */
5478
5840
  constructor(sampleRate: number, maxBufferSize: number);
5841
+ /**
5842
+ * Resets this block to default values, including the processor type.
5843
+ */
5479
5844
  reset(): void;
5480
5845
  process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, chorusLeft: Float32Array, chorusRight: Float32Array, reverbLeft: Float32Array, reverbRight: Float32Array, startIndex: number, sampleCount: number): void;
5481
5846
  processInsertion(inputLeft: Float32Array, inputRight: Float32Array, sampleCount: number): void;
5847
+ /**
5848
+ * Gets a snapshot of this XG effect block.
5849
+ */
5482
5850
  getSnapshot(): {
5483
5851
  insertionMode: boolean;
5484
5852
  partNumber: number;
@@ -5489,11 +5857,19 @@ export declare class DefaultXGVariation extends DefaultXGSystemEffect implements
5489
5857
  type: number;
5490
5858
  params: Int16Array;
5491
5859
  };
5860
+ /**
5861
+ * Restores this XG effect block from a snapshot.
5862
+ * @param snapshot The snapshot to restore.
5863
+ */
5492
5864
  applySnapshot(snapshot: XGVariationBlockSnapshot): void;
5493
5865
  }
5494
5866
  /**
5495
5867
  * The default implementation for {@link XGInsertionBlock}.
5496
5868
  *
5869
+ * The default type is DISTORTION. The EFFECT 2 types run on the same processors as the variation block types.
5870
+ * The early reflection types and PHASER 2 are variation only, so PHASER 2 falls back to PHASER 1 here.
5871
+ * Unknown types use the type with LSB 0, or THRU if that is missing too.
5872
+ *
5497
5873
  * @group Synthesizer.XG Effects
5498
5874
  * @sealed
5499
5875
  */
@@ -5503,16 +5879,26 @@ export declare class DefaultXGInsertion extends DefaultXGEffect implements XGIns
5503
5879
  * Constructs a new default XG insertion processor.
5504
5880
  * @param sampleRate The sample rate, in Hertz.
5505
5881
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
5506
- * Attempting to `.process()` more samples than this will result in an error.
5882
+ * Processing more samples than this is not supported and produces undefined output.
5507
5883
  */
5508
5884
  constructor(sampleRate: number, maxBufferSize: number);
5885
+ /**
5886
+ * Resets this block to default values, including the processor type.
5887
+ */
5509
5888
  reset(): void;
5510
5889
  processInsertion(inputLeft: Float32Array, inputRight: Float32Array, sampleCount: number): void;
5890
+ /**
5891
+ * Gets a snapshot of this XG effect block.
5892
+ */
5511
5893
  getSnapshot(): {
5512
5894
  partNumber: number;
5513
5895
  type: number;
5514
5896
  params: Int16Array<ArrayBufferLike>;
5515
5897
  };
5898
+ /**
5899
+ * Restores this XG effect block from a snapshot.
5900
+ * @param snapshot The snapshot to restore.
5901
+ */
5516
5902
  applySnapshot(snapshot: XGInsertionBlockSnapshot): void;
5517
5903
  }
5518
5904
  /**
@@ -5532,7 +5918,8 @@ export interface SoundBankManagerListEntry {
5532
5918
  soundBank: BasicSoundBank;
5533
5919
  /**
5534
5920
  * The bank MSB offset for this sound bank.
5535
- * This value will be added to all {@link BasicPreset.bankMSB} fields when resolving the preset list.
5921
+ * This value will be added to all {@link BasicPreset.bankMSB} fields when resolving the preset list,
5922
+ * except for the XG drum banks (120 and 127). The result is capped at 127.
5536
5923
  */
5537
5924
  bankOffset: number;
5538
5925
  }
@@ -5603,6 +5990,10 @@ export interface SynthProcessorOptions {
5603
5990
  * Optional custom GS delay processor for the synthesizer. Leave undefined to use {@link DefaultGSDelay}.
5604
5991
  */
5605
5992
  gsDelayProcessor?: GSDelayProcessor;
5993
+ /**
5994
+ * Optional custom GS equalizer processor for the synthesizer. Leave undefined to use {@link DefaultGSEqualizer}.
5995
+ */
5996
+ gsEqualizerProcessor?: GSEqualizerProcessor;
5606
5997
  /**
5607
5998
  * Optional custom GS insertion block for the synthesizer. Leave undefined to use {@link DefaultGSInsertion}.
5608
5999
  */
@@ -5686,11 +6077,6 @@ export declare class MIDIChannel {
5686
6077
  * The channel's number (0-based index).
5687
6078
  */
5688
6079
  readonly channel: number;
5689
- /**
5690
- * If true, this skips sends as they all go through insertion.
5691
- * Set by {@link SpessaSynthProcessor}.
5692
- */
5693
- xgInsertionAssigned: boolean;
5694
6080
  /**
5695
6081
  * Current amount of voices that are playing on this channel.
5696
6082
  */
@@ -5852,7 +6238,7 @@ interface ChannelMIDIParameter {
5852
6238
  randomPan: boolean;
5853
6239
  /**
5854
6240
  * Assign mode for the channel:
5855
- * - `0` - A new note will kill the previous one if it is still playing.
6241
+ * - `0` - A new note will kill the previous one on the same key if it is still playing.
5856
6242
  * - Any other value - A new note will not kill the previous notes (default).
5857
6243
  *
5858
6244
  * While GS and XG differentiate 1 (Limited Multi for GS/Multi for XG) and 2 (Full Multi for GS/Inst (for Drum)),
@@ -5870,6 +6256,16 @@ interface ChannelMIDIParameter {
5870
6256
  * Indicates whether this channel uses the GS insertion EFX processor.
5871
6257
  */
5872
6258
  efxAssign: boolean;
6259
+ /**
6260
+ * Indicates whether this channel passes through the GS equalizer (see {@link GSEqualizerProcessor}).
6261
+ * Default is `true`, like on the Sound Canvas.
6262
+ *
6263
+ * > **Note**
6264
+ * >
6265
+ * > Channels with {@link efxAssign} enabled ignore this.
6266
+ * > Their equalizer routing is set by {@link GSInsertionParameter.sendEQSwitch} instead.
6267
+ */
6268
+ eqEnabled: boolean;
5873
6269
  /**
5874
6270
  * CC1 for GS controller matrix.
5875
6271
  * An arbitrary MIDI controller, which can be bound to any synthesis parameter.
@@ -6115,7 +6511,7 @@ interface ModifyMIDIOptions {
6115
6511
  * > **Note**
6116
6512
  * >
6117
6513
  * > By default, a meaningful GM reset (one with notes after it)
6118
- * > is replaced with a GS reset. Set the `system` parameter to `gm`
6514
+ * > is replaced with a GS reset (or `fallbackReset`, if set). Set the `system` parameter to `gm`
6119
6515
  * > to keep the GM reset (and replace all others with GM).
6120
6516
  * > This is done to allow the bank selections and other parameters to work.
6121
6517
  */
@@ -6138,6 +6534,12 @@ interface ModifyMIDIOptions {
6138
6534
  * - {@link GSDelayParameter} - clear + the new parameters are set via System Exclusive messages.
6139
6535
  */
6140
6536
  gsDelayParams?: ClearableParameter<GSDelayParameter>;
6537
+ /**
6538
+ * The GS equalizer parameters.
6539
+ * - `"clear"` - all existing parameter change MIDI messages are cleared.
6540
+ * - {@link GSEqualizerParameter} - clear + the new parameters are set via System Exclusive messages.
6541
+ */
6542
+ gsEqualizerParams?: ClearableParameter<GSEqualizerParameter>;
6141
6543
  /**
6142
6544
  * The GS Insertion Effect parameters.
6143
6545
  * - `"clear"` - all existing parameter change MIDI messages are cleared.
@@ -6175,8 +6577,9 @@ interface ModifyMIDIOptions {
6175
6577
  /**
6176
6578
  * The system reset to add when the file contains no reset.
6177
6579
  * Unlike `midiParams.system`, existing resets are left untouched.
6178
- * Ignored when `midiParams.system` is set (it takes precedence)
6179
- * and when `midiParams.system` is `"clear"` (no reset is added).
6580
+ * Ignored when `midiParams.system` is set (it takes precedence).
6581
+ * When `midiParams.system` is `"clear"`, no reset is added,
6582
+ * but this still selects the system the setup messages are written for.
6180
6583
  * When unset, the added reset defaults to `"xg"`
6181
6584
  * if only XG setups are requested, otherwise to `"gs"`.
6182
6585
  *
@@ -6224,7 +6627,7 @@ export interface RMIDInfoData {
6224
6627
  creationDate: Date;
6225
6628
  /**
6226
6629
  * The copyright string.
6227
- * If not provided, `Created with SpessaSynth` is used.
6630
+ * If not provided, `Created using SpessaSynth` is used.
6228
6631
  */
6229
6632
  copyright: string;
6230
6633
  /**
@@ -6238,6 +6641,7 @@ export interface RMIDInfoData {
6238
6641
  midiEncoding: string;
6239
6642
  /**
6240
6643
  * The software used to write the file.
6644
+ * If not provided, `SpessaSynth` is used.
6241
6645
  */
6242
6646
  software: string;
6243
6647
  /**
@@ -6246,6 +6650,8 @@ export interface RMIDInfoData {
6246
6650
  subject: string;
6247
6651
  }
6248
6652
  /**
6653
+ * A single tempo change in a MIDI sequence.
6654
+ *
6249
6655
  * @group MIDI.Sequence
6250
6656
  */
6251
6657
  export interface TempoChange {
@@ -6279,7 +6685,7 @@ export interface MIDILoop {
6279
6685
  * the start of the file to ensure that synthesizer is in the correct state.
6280
6686
  * This is the default behavior.
6281
6687
  *
6282
- * Soft loop types are enabled for Touhou and GameMaker loop points.
6688
+ * Soft loop types are enabled for Touhou loop points (CC 2 and CC 4) and RPG Maker loop points (CC 111).
6283
6689
  */
6284
6690
  type: "soft" | "hard";
6285
6691
  }
@@ -6293,7 +6699,9 @@ export interface MIDILoop {
6293
6699
  */
6294
6700
  export type MIDIFormat = 0 | 1 | 2;
6295
6701
  /**
6296
- * @group MIDI.Sequence
6702
+ * A single note's time and velocity, as returned by {@link BasicMIDI.getNoteTimes}.
6703
+ *
6704
+ * @group MIDI.Sequence
6297
6705
  */
6298
6706
  export interface NoteTime {
6299
6707
  /**
@@ -6330,8 +6738,10 @@ export interface RMIDIWriteOptions {
6330
6738
  *
6331
6739
  * > **Warning**
6332
6740
  * >
6333
- * > Providing *any* of the metadata fields overrides the info encoding with `utf-8`.
6741
+ * > Writing always sets the info encoding to `utf-8`,
6742
+ * > since the default fields (such as the creation date) are always written.
6334
6743
  * > This behavior is forced due to lack of support for other encodings by the `TextEncoder` class.
6744
+ * > Existing info chunks in another encoding (see {@link BasicMIDI.infoEncoding}) are re-encoded to UTF-8.
6335
6745
  *
6336
6746
  */
6337
6747
  metadata: Partial<Omit<RMIDInfoData, "infoEncoding">>;
@@ -6343,7 +6753,7 @@ export interface RMIDIWriteOptions {
6343
6753
  /**
6344
6754
  * The sound bank instance that `soundBankBinary` contains.
6345
6755
  * Used for correcting bank and program changes when `correctBankOffset` is enabled.
6346
- * If omitted, bank correction may be less accurate.
6756
+ * If it is omitted, the correction is skipped and a warning is logged.
6347
6757
  */
6348
6758
  soundBank?: BasicSoundBank;
6349
6759
  }
@@ -6354,6 +6764,8 @@ export interface RMIDIWriteOptions {
6354
6764
  */
6355
6765
  export type RMIDInfoFourCC = "INAM" | "IPRD" | "IALB" | "IART" | "IGNR" | "IPIC" | "ICOP" | "ICRD" | "ICRT" | "ICMT" | "IENG" | "ISFT" | "ISBJ" | "IENC" | "MENC" | "DBNK";
6356
6766
  /**
6767
+ * A reference to an event in {@link BasicMIDI.timeline}, pointing at its track and its index in that track.
6768
+ *
6357
6769
  * @group MIDI.Sequence
6358
6770
  */
6359
6771
  export interface TimelineEvent {
@@ -6517,7 +6929,7 @@ export declare class MIDITrack {
6517
6929
  */
6518
6930
  port: number;
6519
6931
  /**
6520
- * A set that contains the MIDI channel numbers used by this track.
6932
+ * A set that contains the MIDI channel numbers (0-15) that have note on events in this track.
6521
6933
  */
6522
6934
  channels: Set<number>;
6523
6935
  /**
@@ -6537,7 +6949,7 @@ export declare class MIDITrack {
6537
6949
  copyFrom(track: MIDITrack): void;
6538
6950
  /**
6539
6951
  * Adds events to the track.
6540
- * @param index The index at which to add these event.
6952
+ * @param index The index at which to add these events.
6541
6953
  * @param events The events to add.
6542
6954
  */
6543
6955
  addEvents(index: number, ...events: MIDIMessage[]): void;
@@ -6666,7 +7078,8 @@ export declare class BasicMIDI {
6666
7078
  * The loop points (in ticks) of the sequence, including both start and end points.
6667
7079
  *
6668
7080
  * If there's nothing detected, the loop will start from the first note on event and end will be the last voice message.
6669
- * Current looping detection is: CC 2/4, 116/117 and "start," "loopStart" and "loopEnd" markers.
7081
+ * Current looping detection is: CC 2/4 (Touhou), CC 111 (RPG Maker), CC 116/117 and 118/119 (EMIDI/XMI)
7082
+ * and the "start", "loopStart" and "loopEnd" markers.
6670
7083
  */
6671
7084
  loop: MIDILoop;
6672
7085
  /**
@@ -6680,6 +7093,7 @@ export declare class BasicMIDI {
6680
7093
  format: MIDIFormat;
6681
7094
  /**
6682
7095
  * The RMID (Resource-Interchangeable MIDI) info data, if the file is RMID formatted.
7096
+ * XMF metadata and converted tracker modules are stored here as well.
6683
7097
  * Otherwise, this object is empty.
6684
7098
  * Info type: Chunk data as a binary array.
6685
7099
  *
@@ -6745,7 +7159,7 @@ export declare class BasicMIDI {
6745
7159
  * This function reads the MIDI file format, extracts the header and track chunks,
6746
7160
  * and populates the BasicMIDI instance with the parsed data.
6747
7161
  * It supports Standard MIDI Files (SMF), RIFF MIDI (RMIDI), and Extensible Music Format (XMF).
6748
- * It also handles embedded soundbanks in RMIDI files.
7162
+ * It also handles embedded soundbanks in RMIDI and XMF files.
6749
7163
  * Tracker modules (ProTracker MOD, Fast Tracker 2 XM, Scream Tracker 3 S3M) are converted
6750
7164
  * into MIDI with an embedded sound bank.
6751
7165
  */
@@ -6762,7 +7176,7 @@ export declare class BasicMIDI {
6762
7176
  */
6763
7177
  static copyFrom(mid: BasicMIDI): BasicMIDI;
6764
7178
  /**
6765
- * Copies another instance this `BasicMIDI` instance, including track data.
7179
+ * Copies another instance into this `BasicMIDI` instance, including track data.
6766
7180
  * @param mid The MIDI to copy.
6767
7181
  */
6768
7182
  copyFrom(mid: BasicMIDI): void;
@@ -6794,7 +7208,7 @@ export declare class BasicMIDI {
6794
7208
  getUsedProgramsAndKeys<T extends MIDIPatchFull>(soundbank: CallableSoundBank<T>): PresetsWithKeyCombinations<T>;
6795
7209
  /**
6796
7210
  * Preloads all voices for this sequence in a given {@link SpessaSynthProcessor}.
6797
- * This caches all the needed voices for playing back this sequencer, resulting in a smooth playback.
7211
+ * This caches all the needed voices for playing back this sequence, resulting in a smooth playback.
6798
7212
  * The sequencer calls this function by default when loading the songs. (it can be disabled: {@link SpessaSynthSequencer.preload}).
6799
7213
  * @param synth The synthesizer to preload.
6800
7214
  */
@@ -6813,6 +7227,12 @@ export declare class BasicMIDI {
6813
7227
  flush(sortEvents?: boolean): void;
6814
7228
  /**
6815
7229
  * Calculates all note times in seconds.
7230
+ *
7231
+ * > **Note**
7232
+ * >
7233
+ * > MIDI ports are ignored, so the channels of every port are merged into the 16 channels.
7234
+ * > For example, channel 1 of port 2 is returned as channel 1.
7235
+ *
6816
7236
  * @param minDrumLength In seconds, represents the minimum allowed time for a drum note,
6817
7237
  * since they sometimes have a length of 0.
6818
7238
  * @returns An array of 16 channels, each channel containing its notes,
@@ -6861,7 +7281,7 @@ export declare class BasicMIDI {
6861
7281
  */
6862
7282
  writeMIDI(): ArrayBuffer;
6863
7283
  /**
6864
- * Writes out an RMIDI file (MIDI + SF2).
7284
+ * Writes out an RMIDI file (MIDI + SF2 or DLS).
6865
7285
  * [See more info about this format](https://github.com/spessasus/sf2-rmidi-specification#readme).
6866
7286
  *
6867
7287
  * Note that this method modifies the MIDI file in-place.
@@ -6870,11 +7290,16 @@ export declare class BasicMIDI {
6870
7290
  * The method is called on a `BasicMIDI` instance;
6871
7291
  * that instance is the MIDI file to embed.
6872
7292
  *
7293
+ * > **Warning**
7294
+ * >
7295
+ * > Do not call in audioWorkletGlobalScope as it uses TextDecoder and TextEncoder.
7296
+ * > Bank offset correction (on by default) needs `soundBank`. Without it, the correction is skipped with a warning.
7297
+ *
6873
7298
  * > **Tip**
6874
7299
  * >
6875
7300
  * > Use {@link BasicSoundBank.trim} to drastically reduce the file size.
6876
- * > consider also using compression (like shown in example) to save even more space.
6877
- * > (using these both methods, I managed to shrink a 1GB sound bank into a 5MB RMIDI!)
7301
+ * > Consider also using compression (like shown in example) to save even more space.
7302
+ * > (using both of these methods, I managed to shrink a 1GB sound bank into a 5MB RMIDI!)
6878
7303
  *
6879
7304
  * @param soundBankBinary The binary sound bank (SF2 or DLS) to embed into the file.
6880
7305
  * @param configuration Extra options for writing the file.
@@ -6912,7 +7337,7 @@ export declare class BasicMIDI {
6912
7337
  *
6913
7338
  * // trim the soundfont
6914
7339
  * soundBank.trim(midi.getUsedProgramsAndKeys(soundBank));
6915
- * // write out with compression to save space (0.5 is medium quality)
7340
+ * // write out with compression to save space
6916
7341
  * await soundBank.setSampleFormat({
6917
7342
  * format: "compressed",
6918
7343
  * compressionFunction: SampleEncodingFunction // Remember to get your compression function
@@ -6948,6 +7373,8 @@ export declare class BasicMIDI {
6948
7373
  * and inserts/deletes messages appropriately.
6949
7374
  *
6950
7375
  * This modifies the MIDI sequence _in-place_.
7376
+ *
7377
+ * @param opts The modifications to apply.
6951
7378
  */
6952
7379
  modify(opts: Partial<ModifyMIDIOptions>): void;
6953
7380
  /**
@@ -6955,8 +7382,10 @@ export declare class BasicMIDI {
6955
7382
  * This means changing the programs and controllers if they are locked.
6956
7383
  *
6957
7384
  * For example, if channel 1 has locked preset on `Drawbar Organ`,
6958
- * this will remove all program changes for channel 1 and add one at the start to change the program to
7385
+ * this will remove all program changes for channel 1 and add one before the channel's first note on
7386
+ * (and again after every system reset) to change the program to
6959
7387
  * `Drawbar organ` (using bank MSB/LSB and program change).
7388
+ * Muted channels are removed from the sequence.
6960
7389
  *
6961
7390
  * > **Warning**
6962
7391
  * >
@@ -7002,6 +7431,12 @@ export declare class BasicMIDI {
7002
7431
  * > **Note**
7003
7432
  * >
7004
7433
  * > This sets the Info encoding to `utf-8`.
7434
+ * > Text chunks that are already present get re-encoded from their old encoding (IENC) to UTF-8,
7435
+ * > so they stay readable. Without IENC, they are assumed to be UTF-8 already, like {@link BasicMIDI.getRMIDInfo} does.
7436
+ *
7437
+ * > **Warning**
7438
+ * >
7439
+ * > Do not call in audioWorkletGlobalScope as it uses TextDecoder and TextEncoder.
7005
7440
  *
7006
7441
  * @param infoType The type to set.
7007
7442
  * @param infoData The value to set it to.
@@ -7009,6 +7444,11 @@ export declare class BasicMIDI {
7009
7444
  setRMIDInfo<K extends keyof RMIDInfoData>(infoType: K, infoData: RMIDInfoData[K]): void;
7010
7445
  /**
7011
7446
  * Gets a given chunk from the RMIDI information.
7447
+ *
7448
+ * > **Warning**
7449
+ * >
7450
+ * > Do not call in audioWorkletGlobalScope as it uses TextDecoder.
7451
+ *
7012
7452
  * @param infoType The metadata type.
7013
7453
  * @returns `string`, `Date`, `ArrayBuffer` or undefined if the info is not set.
7014
7454
  */
@@ -7022,7 +7462,7 @@ export declare class BasicMIDI {
7022
7462
  * > if you are not editing the MIDI file in your loop.
7023
7463
  * > It is usually a faster solution and allows custom loops.
7024
7464
  *
7025
- * If the track data is being edited, remember to call {@link BasicMIDI.flush} it after editing!
7465
+ * If the track data is being edited, remember to call {@link BasicMIDI.flush} after editing!
7026
7466
  *
7027
7467
  * @param callback The callback function to process each event.
7028
7468
  */
@@ -7056,11 +7496,13 @@ export interface MIDIBuilderOptions {
7056
7496
  /**
7057
7497
  * The MIDI file track format.
7058
7498
  * Format 0 allows only one track while format 1 allows more than one.
7059
- * Format 2 is very rare and should not be used.
7499
+ * Format 2 is very rare and is not supported by the builder (an error is thrown).
7500
+ * Defaults to 0.
7060
7501
  */
7061
7502
  format: MIDIFormat;
7062
7503
  /**
7063
7504
  * The MIDI file's name. Will be appended to the conductor (first) track and encoded with UTF-8.
7505
+ * Defaults to `Untitled song`.
7064
7506
  */
7065
7507
  name: string;
7066
7508
  }
@@ -7075,6 +7517,7 @@ export interface MIDIBuilderOptions {
7075
7517
  * > **Warning**
7076
7518
  * >
7077
7519
  * > Remember to call {@link BasicMIDI.flush} after you're done building the file!
7520
+ * > Do not use in audioWorkletGlobalScope as it uses TextEncoder.
7078
7521
  *
7079
7522
  * @group MIDI.Files
7080
7523
  */
@@ -7218,7 +7661,7 @@ export declare class MIDIUtils {
7218
7661
  * @param channel The MIDI channel number.
7219
7662
  * @param rpn The 14-bit RPN number.
7220
7663
  * @param value The 14-bit value for that number.
7221
- * @returns The analysis result(s) of the message.
7664
+ * @returns The analysis result of the message.
7222
7665
  */
7223
7666
  static analyzeRPN(channel: number, rpn: number, value: number): AnalyzedParameter;
7224
7667
  /**
@@ -7229,7 +7672,7 @@ export declare class MIDIUtils {
7229
7672
  * @param value The 14-bit value for that number.
7230
7673
  * @param drumPitchStep The drum pitch coarse resolution in semitones.
7231
7674
  * 0.5 for GS (SC-88 and above), 1 for XG and the SC-55 drum map (bank LSB 1).
7232
- * @returns The analysis result(s) of the message.
7675
+ * @returns The analysis result of the message.
7233
7676
  */
7234
7677
  static analyzeNRPN(channel: number, nrpn: number, value: number, drumPitchStep?: number): AnalyzedParameter;
7235
7678
  /**
@@ -7262,15 +7705,23 @@ export declare class MIDIUtils {
7262
7705
  static setGSDelayParameter<P extends GSDelayParameterMessage["parameter"]>(ticks: number, parameter: P, value: Extract<GSDelayParameterMessage, {
7263
7706
  parameter: P;
7264
7707
  }>["value"]): MIDIMessage;
7708
+ /**
7709
+ * Returns a MIDI event needed to set the given GS Equalizer Parameter.
7710
+ * @param ticks The MIDI tick time for the output event.
7711
+ * @param parameter The parameter to set.
7712
+ * @param value The value to set it to.
7713
+ * @returns The {@link MIDIMessage} needed to set this GS Equalizer Parameter.
7714
+ */
7715
+ static setGSEqualizerParameter(ticks: number, parameter: GSEqualizerParameterMessage["parameter"], value: number): MIDIMessage;
7265
7716
  /**
7266
7717
  * Returns a MIDI event needed to set the given GS Insertion Parameter.
7267
7718
  * @param ticks The MIDI tick time for the output event.
7268
7719
  * @param parameter The parameter to set: `"type"`, a send level or EFX control name (see {@link GSInsertionParameter}),
7269
7720
  * or a 0-based effect-specific parameter number (0-19).
7270
- * @param value The value to set it to.
7721
+ * @param value The value to set it to. A boolean for `"sendEQSwitch"`.
7271
7722
  * @returns The {@link MIDIMessage} needed to set this GS Insertion Parameter.
7272
7723
  */
7273
- static setGSInsertionParameter(ticks: number, parameter: GSInsertionParameterMessage["parameter"], value: number): MIDIMessage;
7724
+ static setGSInsertionParameter(ticks: number, parameter: GSInsertionParameterMessage["parameter"], value: number | boolean): MIDIMessage;
7274
7725
  /**
7275
7726
  * Returns a MIDI event needed to set the given XG Reverb Parameter.
7276
7727
  * @param ticks The MIDI tick time for the output event.
@@ -7493,7 +7944,7 @@ export declare class DrumParameterUtils {
7493
7944
  */
7494
7945
  static copyInto(source: DrumParameter, dest: DrumParameter): void;
7495
7946
  /**
7496
- * Checks if this user drum parameter is the default.
7947
+ * Checks if this drum parameter is the default.
7497
7948
  * @param param the param to check.
7498
7949
  * @param midiNote the MIDI note of this parameter.
7499
7950
  */
@@ -7551,7 +8002,11 @@ export interface SequencerEvent {
7551
8002
  newTime: number;
7552
8003
  };
7553
8004
  /**
7554
- * This event is called when the playback stops.
8005
+ * This event is called when the song finishes and the playback stops.
8006
+ * It is not called when pausing manually.
8007
+ *
8008
+ * With more than one song in the list, the sequencer moves on to the next song instead,
8009
+ * so this event is not called.
7555
8010
  */
7556
8011
  songEnded: object;
7557
8012
  /**
@@ -7559,7 +8014,8 @@ export interface SequencerEvent {
7559
8014
  */
7560
8015
  songChange: {
7561
8016
  /**
7562
- * The index of the new song in {@link SpessaSynthSequencer.songs}.
8017
+ * The new {@link SpessaSynthSequencer.songIndex}.
8018
+ * If shuffle mode is enabled, this is the index in the shuffled song list, not in {@link SpessaSynthSequencer.songs}.
7563
8019
  */
7564
8020
  songIndex: number;
7565
8021
  };
@@ -7865,7 +8321,7 @@ export declare class DefaultGSReverb implements GSReverbProcessor {
7865
8321
  * Constructs a new default GS reverb processor.
7866
8322
  * @param sampleRate The sample rate, in Hertz.
7867
8323
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
7868
- * Attempting to `.process()` more samples than this will result in an error.
8324
+ * Processing more samples than this is not supported and produces undefined output.
7869
8325
  */
7870
8326
  constructor(sampleRate: number, maxBufferSize: number);
7871
8327
  private _delayFeedback;
@@ -7887,12 +8343,12 @@ export declare class DefaultGSReverb implements GSReverbProcessor {
7887
8343
  get preLowpass(): number;
7888
8344
  set preLowpass(value: number);
7889
8345
  /**
7890
- *
7891
- * @param input 0-based
7892
- * @param outputLeft startIndex-based
7893
- * @param outputRight startIndex-based
7894
- * @param startIndex
7895
- * @param sampleCount
8346
+ * Process the effect and **adds** it to the output.
8347
+ * @param input The input buffer to process. It always starts at index 0.
8348
+ * @param outputLeft The left output buffer.
8349
+ * @param outputRight The right output buffer.
8350
+ * @param startIndex The index to start mixing at into the output buffers.
8351
+ * @param sampleCount The amount of samples to mix.
7896
8352
  */
7897
8353
  process(input: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, startIndex: number, sampleCount: number): void;
7898
8354
  getSnapshot(): GSReverbParameter;
@@ -7939,7 +8395,7 @@ export declare class DefaultGSChorus implements GSChorusProcessor {
7939
8395
  * Constructs a new default GS chorus processor.
7940
8396
  * @param sampleRate The sample rate, in Hertz.
7941
8397
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
7942
- * Attempting to `.process()` more samples than this will result in an error.
8398
+ * Processing more samples than this is not supported and produces undefined output.
7943
8399
  */
7944
8400
  constructor(sampleRate: number, maxBufferSize: number);
7945
8401
  private _sendLevelToReverb;
@@ -8019,7 +8475,7 @@ export declare class DefaultGSDelay implements GSDelayProcessor {
8019
8475
  * Constructs a new default GS delay processor.
8020
8476
  * @param sampleRate The sample rate, in Hertz.
8021
8477
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
8022
- * Attempting to `.process()` more samples than this will result in an error.
8478
+ * Processing more samples than this is not supported and produces undefined output.
8023
8479
  */
8024
8480
  constructor(sampleRate: number, maxBufferSize: number);
8025
8481
  private _sendLevelToReverb;
@@ -8067,6 +8523,47 @@ export declare class DefaultGSDelay implements GSDelayProcessor {
8067
8523
  private updateDelayTimes;
8068
8524
  private updateGain;
8069
8525
  }
8526
+ /**
8527
+ * The default GS Equalizer implementation for {@link SpessaSynthProcessor}.
8528
+ *
8529
+ * @group Synthesizer.GS Effects
8530
+ */
8531
+ export declare class DefaultGSEqualizer implements GSEqualizerProcessor {
8532
+ private readonly sampleRate;
8533
+ private lowB0;
8534
+ private lowB1;
8535
+ private lowA1;
8536
+ private highB0;
8537
+ private highB1;
8538
+ private highA1;
8539
+ private lowZL;
8540
+ private lowZR;
8541
+ private highZL;
8542
+ private highZR;
8543
+ /**
8544
+ * Constructs a new default GS equalizer processor.
8545
+ * @param sampleRate The sample rate, in Hertz.
8546
+ */
8547
+ constructor(sampleRate: number);
8548
+ private _lowFrequency;
8549
+ get lowFrequency(): number;
8550
+ set lowFrequency(value: number);
8551
+ private _lowGain;
8552
+ get lowGain(): number;
8553
+ set lowGain(value: number);
8554
+ private _highFrequency;
8555
+ get highFrequency(): number;
8556
+ set highFrequency(value: number);
8557
+ private _highGain;
8558
+ get highGain(): number;
8559
+ set highGain(value: number);
8560
+ process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, startIndex: number, sampleCount: number): void;
8561
+ getSnapshot(): GSEqualizerParameter;
8562
+ applySnapshot(snapshot: GSEqualizerParameter): void;
8563
+ private getBand;
8564
+ private updateLow;
8565
+ private updateHigh;
8566
+ }
8070
8567
  /**
8071
8568
  * The default implementation for {@link GSInsertionBlock}.
8072
8569
  *
@@ -8077,6 +8574,7 @@ export declare class DefaultGSInsertion implements GSInsertionBlock {
8077
8574
  sendLevelToReverb: number;
8078
8575
  sendLevelToChorus: number;
8079
8576
  sendLevelToDelay: number;
8577
+ sendEQSwitch: boolean;
8080
8578
  controlSource1: number;
8081
8579
  controlDepth1: number;
8082
8580
  controlSource2: number;
@@ -8119,7 +8617,7 @@ export declare class DefaultGSInsertion implements GSInsertionBlock {
8119
8617
  * Constructs a new default GS insertion block.
8120
8618
  * @param sampleRate The sample rate, in Hertz.
8121
8619
  * @param maxBufferSize The maximum buffer size the synthesizer can render at once.
8122
- * Attempting to `.process()` more samples than this will result in an error.
8620
+ * Processing more samples than this is not supported and produces undefined output.
8123
8621
  */
8124
8622
  constructor(sampleRate: number, maxBufferSize: number);
8125
8623
  setType(type: number): void;