spessasynth_core
Version:
MIDI and SoundFont2/DLS library with no compromises
1,625 lines • 157 kB
TypeScript
//#region src/utils/indexed_array.d.ts
/**
* Indexed_array.ts
* purpose: extends Uint8Array with a currentIndex property.
*/
declare class IndexedByteArray extends Uint8Array {
/**
* The current index of the array.
*/
currentIndex: number;
/**
* Returns a section of an array.
* @param start The beginning of the specified portion of the array.
* @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.
*/
slice(start?: number, end?: number): IndexedByteArray;
}
//#endregion
//#region src/utils/byte_functions/big_endian.d.ts
/**
* Reads number as Big endian.
* @param dataArray the array to read from.
* @param bytesAmount the number of bytes to read.
* @param offset the offset to start reading from.
* @returns the number.
*/
declare function readBigEndian(dataArray: number[] | ArrayLike<number>, bytesAmount: number, offset?: number): number;
//#endregion
//#region src/utils/byte_functions/little_endian.d.ts
/**
* Reads the number as little endian from an IndexedByteArray.
* @param dataArray the array to read from.
* @param bytesAmount the number of bytes to read.
* @returns the number.
*/
declare function readLittleEndianIndexed(dataArray: IndexedByteArray, bytesAmount: number): number;
/**
* Reads the number as little endian.
* @param dataArray the array to read from.
* @param bytesAmount the number of bytes to read.
* @param offset the offset to start reading at.
* @returns the number.
*/
declare function readLittleEndian(dataArray: number[] | ArrayLike<number>, bytesAmount: number, offset?: number): number;
//#endregion
//#region src/utils/byte_functions/string.d.ts
/**
* Reads bytes as an ASCII string. This version works with any numeric array.
* @param dataArray the array to read from.
* @param bytes the amount of bytes to read.
* @param offset the offset in the array to start reading from.
* @returns the string.
*/
declare function readBinaryString(dataArray: ArrayLike<number>, bytes?: number, offset?: number): string;
/**
* Reads bytes as an ASCII string from an IndexedByteArray.
* @param dataArray the IndexedByteArray to read from.
* @param bytes the amount of bytes to read.
* @returns the string.
*/
declare function readBinaryStringIndexed(dataArray: IndexedByteArray, bytes: number): string;
//#endregion
//#region src/utils/byte_functions/variable_length_quantity.d.ts
/**
* Reads VLQ from a MIDI byte array.
* @param midiByteArray the array to read from.
* @returns the number.
*/
declare function readVariableLengthQuantity(midiByteArray: IndexedByteArray): number;
//#endregion
//#region src/utils/write_wav.d.ts
/**
* Writes an audio into a valid WAV file.
* @param audioData the audio data channels.
* @param sampleRate the sample rate, in Hertz.
* @param options Additional options for writing the file.
* @returns the binary file.
*/
declare function audioToWav(audioData: Float32Array[], sampleRate: number, options?: Partial<WaveWriteOptions>): ArrayBuffer;
//#endregion
//#region src/utils/loggin.d.ts
/**
* Manage the log level of `spessasynth_core`.
*/
declare class SpessaLog {
/**
* The most verbose log level, prints out a lot of small details.
*/
static infoEnabled: boolean;
/**
* The default log level, prints out warnings for unexpected and erroneous behavior.
*/
static warnEnabled: boolean;
/**
* If grouping of the log messages is allowed. Recommended for the `info` verbosity level.
*/
static groupEnabled: boolean;
/**
* Enables or disables logging.
* @param enableInfo enables info.
* @param enableWarn enables warning.
* @param enableGroup enables groups.
*/
static setLogLevel(enableInfo: boolean, enableWarn: boolean, enableGroup: boolean): void;
static info(...message: unknown[]): void;
static warn(...message: unknown[]): void;
static group(...message: unknown[]): void;
static groupCollapsed(...message: unknown[]): void;
static groupEnd(): void;
}
//#endregion
//#region src/soundbank/basic_soundbank/generator_types.d.ts
/**
* All SoundFont2 Generator enumerations.
*/
declare const GeneratorTypes: Readonly<{
readonly invalid: -1;
readonly startAddrsOffset: 0;
readonly endAddrOffset: 1;
readonly startloopAddrsOffset: 2;
readonly endloopAddrsOffset: 3;
readonly startAddrsCoarseOffset: 4;
readonly modLfoToPitch: 5;
readonly vibLfoToPitch: 6;
readonly modEnvToPitch: 7;
readonly initialFilterFc: 8;
readonly initialFilterQ: 9;
readonly modLfoToFilterFc: 10;
readonly modEnvToFilterFc: 11;
readonly endAddrsCoarseOffset: 12;
readonly modLfoToVolume: 13;
readonly chorusEffectsSend: 15;
readonly reverbEffectsSend: 16;
readonly pan: 17;
readonly delayModLFO: 21;
readonly freqModLFO: 22;
readonly delayVibLFO: 23;
readonly freqVibLFO: 24;
readonly delayModEnv: 25;
readonly attackModEnv: 26;
readonly holdModEnv: 27;
readonly decayModEnv: 28;
readonly sustainModEnv: 29;
readonly releaseModEnv: 30;
readonly keyNumToModEnvHold: 31;
readonly keyNumToModEnvDecay: 32;
readonly delayVolEnv: 33;
readonly attackVolEnv: 34;
readonly holdVolEnv: 35;
readonly decayVolEnv: 36;
readonly sustainVolEnv: 37;
readonly releaseVolEnv: 38;
readonly keyNumToVolEnvHold: 39;
readonly keyNumToVolEnvDecay: 40;
readonly instrument: 41;
readonly keyRange: 43;
readonly velRange: 44;
readonly startloopAddrsCoarseOffset: 45;
readonly keyNum: 46;
readonly velocity: 47;
readonly initialAttenuation: 48;
readonly endloopAddrsCoarseOffset: 50;
readonly coarseTune: 51;
readonly fineTune: 52;
readonly sampleID: 53;
readonly sampleModes: 54;
readonly scaleTuning: 56;
readonly exclusiveClass: 57;
readonly overridingRootKey: 58;
readonly endOper: 60;
readonly amplitude: 61;
readonly vibLfoRate: 62;
readonly vibLfoAmplitudeDepth: 63;
readonly vibLfoToFilterFc: 64;
readonly modLfoRate: 65;
readonly modLfoAmplitudeDepth: 66;
}>;
type GeneratorType = (typeof GeneratorTypes)[keyof typeof GeneratorTypes];
declare const MAX_GENERATOR: number;
declare const GENERATORS_AMOUNT: number;
interface GeneratorLimit {
/**
* Minimum value for this generator type.
*/
min: number;
/**
* Maximum allowed value for this generator type.
*/
max: number;
/**
* Default value for this generator type.
*/
def: number;
/**
* SoundFont2 NRPN scale factor for this generator type.
*/
nrpn: number;
}
/**
* Min: minimum value, max: maximum value, def: default value, nrpn: nrpn scale
*/
declare const GeneratorLimits: Readonly<Record<GeneratorType, GeneratorLimit>>;
//#endregion
//#region src/soundbank/enums.d.ts
declare const SampleTypes: {
readonly monoSample: 1;
readonly rightSample: 2;
readonly leftSample: 4;
readonly linkedSample: 8;
readonly romMonoSample: 32769;
readonly romRightSample: 32770;
readonly romLeftSample: 32772;
readonly romLinkedSample: 32776;
};
type SampleType = (typeof SampleTypes)[keyof typeof SampleTypes];
declare const ModulatorControllerSources: {
readonly noController: 0;
readonly noteOnVelocity: 2;
readonly noteOnKeyNum: 3;
readonly polyPressure: 10;
readonly channelPressure: 13;
readonly pitchWheel: 14;
readonly pitchWheelRange: 16;
readonly link: 127;
};
type ModulatorControllerSource = (typeof ModulatorControllerSources)[keyof typeof ModulatorControllerSources];
declare const ModulatorCurveTypes: {
readonly linear: 0;
readonly concave: 1;
readonly convex: 2;
readonly switch: 3;
};
type ModulatorCurveType = (typeof ModulatorCurveTypes)[keyof typeof ModulatorCurveTypes];
declare const ModulatorTransformTypes: {
readonly linear: 0;
readonly absolute: 2;
};
type ModulatorTransformType = (typeof ModulatorTransformTypes)[keyof typeof ModulatorTransformTypes];
//#endregion
//#region src/synthesizer/audio_engine/voice/lowpass_filter.d.ts
declare class LowpassFilter {
/**
* For smoothing the filter cutoff frequency.
*/
static smoothingConstant: number;
/**
* Cached coefficient calculations.
* stored as cachedCoefficients[resonanceCb + currentInitialFc * 961].
*/
private static cachedCoefficients;
/**
* Resonance in centibels.
*/
resonanceCb: number;
/**
* Current cutoff frequency in absolute cents.
*/
currentInitialFc: number;
/**
* Filter coefficient 1.
*/
a0: number;
/**
* Filter coefficient 2.
*/
a1: number;
/**
* Filter coefficient 3.
*/
a2: number;
/**
* Filter coefficient 4.
*/
a3: number;
/**
* Filter coefficient 5.
*/
a4: number;
/**
* Input history 1.
*/
x1: number;
/**
* Input history 2.
*/
x2: number;
/**
* Output history 1.
*/
y1: number;
/**
* Output history 2.
*/
y2: number;
/**
* For tracking the last cutoff frequency in the apply method, absolute cents.
* Set to infinity to force recalculation.
*/
lastTargetCutoff: number;
/**
* Used for tracking if the filter has been initialized.
*/
initialized: boolean;
/**
* Filter's sample rate in Hz.
*/
private readonly sampleRate;
/**
* Maximum cutoff frequency in Hz.
* This is used to prevent aliasing and ensure the filter operates within the valid frequency range.
*/
private readonly maxCutoff;
/**
* Initializes a new instance of the filter.
* @param sampleRate the sample rate of the audio engine in Hz.
*/
constructor(sampleRate: number);
static initCache(sampleRate: number): void;
init(): void;
/**
* Calculates the filter coefficients based on the current resonance and cutoff frequency and caches them.
* @param cutoffCents The cutoff frequency in cents.
*/
calculateCoefficients(cutoffCents: number): void;
}
//#endregion
//#region src/synthesizer/audio_engine/voice/volume_envelope.d.ts
/**
* VOL ENV STATES:
* 0 - delay
* 1 - attack
* 2 - hold/peak
* 3 - decay
* 4 - sustain
* release indicates by isInRelease property
*/
type VolumeEnvelopeState = 0 | 1 | 2 | 3 | 4;
declare class VolumeEnvelope {
/**
* The target gain for the current rendering block.
*/
outputGain: number;
/**
* The current attenuation of the envelope in cB.
*/
attenuationCb: number;
/**
* The current stage of the volume envelope.
*/
state: VolumeEnvelopeState;
/**
* The sample rate in Hz.
*/
private readonly sampleRate;
/**
* The sample count between updates of the volume envelope.
* Since the volume envelope calculation runs once per rendering quantum,
* this effectively the buffer size.
*/
private readonly updateInterval;
/**
* The envelope's current time in samples.
*/
private sampleTime;
/**
* The dB attenuation of the envelope when it entered the release stage.
*/
private releaseStartCb;
/**
* The time in samples relative to the start of the envelope.
*/
private releaseStartTimeSamples;
/**
* The attack duration in samples.
*/
private attackDuration;
/**
* The decay duration in samples.
*/
private decayDuration;
/**
* The release duration in samples.
*/
private releaseDuration;
/**
* The voice's sustain amount in cB.
*/
private sustainCb;
/**
* The time in samples to the end of delay stage, relative to the start of the envelope.
*/
private delayEnd;
/**
* The time in samples to the end of attack stage, relative to the start of the envelope.
*/
private attackEnd;
/**
* The time in samples to the end of hold stage, relative to the start of the envelope.
*/
private holdEnd;
/**
* The time in samples to the end of decay stage, relative to the start of the envelope.
*/
private decayEnd;
/**
* If the volume envelope has ever entered the release phase.
* @private
*/
private enteredRelease;
/**
* If sustain stage is silent,
* then we can turn off the voice when it is silent.
* We can't do that with modulated as it can silence the volume and then raise it again, and the voice must keep playing.
*/
private canEndOnSilentSustain;
/**
* @param sampleRate Hz
* @param bufferSize samples
*/
constructor(sampleRate: number, bufferSize: number);
/**
* Starts the release phase in the envelope.
* @param voice the voice this envelope belongs to.
*/
startRelease(voice: Voice): void;
/**
* Initialize the volume envelope
* @param voice The voice this envelope belongs to
*/
init(voice: Voice): void;
/**
* Calculates the gain value for the last sample in the block and writes it to `outputGain`.
* Essentially we use approach of 100dB is silence, 0dB is peak.
* @param sampleCount the amount of samples to write
* @param gainTarget the gain to apply.
* @returns if the voice has finished.
*/
process(sampleCount: number, gainTarget: number): boolean;
private timecentsToSamples;
}
//#endregion
//#region src/synthesizer/audio_engine/voice/modulation_envelope.d.ts
declare class ModulationEnvelope {
/**
* The attack duration, in seconds.
*/
private attackDuration;
/**
* The decay duration, in seconds.
*/
private decayDuration;
/**
* The hold duration, in seconds.
*/
private holdDuration;
/**
* Release duration, in seconds.
*/
private releaseDuration;
/**
* The sustain level 0-1.
*/
private sustainLevel;
/**
* Delay phase end time in seconds, absolute (audio context time).
*/
private delayEnd;
/**
* Attack phase end time in seconds, absolute (audio context time).
*/
private attackEnd;
/**
* Hold phase end time in seconds, absolute (audio context time).
*/
private holdEnd;
/**
* The level of the envelope when the release phase starts.
*/
private releaseStartLevel;
/**
* The current modulation envelope value.
*/
private currentValue;
/**
* If the modulation envelope has ever entered the release phase.
*/
private enteredRelease;
/**
* Decay phase end time in seconds, absolute (audio context time).
*/
private decayEnd;
/**
* Calculates the current modulation envelope value for the given time and voice.
* @param voice the voice we are working on.
* @param currentTime in seconds.
* @returns mod env value, from 0 to 1.
*/
process(voice: Voice, currentTime: number): number;
/**
* Starts the release phase in the envelope.
* @param voice the voice this envelope belongs to.
*/
startRelease(voice: Voice): void;
/**
* Initializes the modulation envelope.
* @param voice the voice this envelope belongs to.
*/
init(voice: Voice): void;
private tc2Sec;
}
//#endregion
//#region src/soundbank/basic_soundbank/midi_patch.d.ts
interface MIDIPatch {
/**
* The MIDI program number.
*/
program: number;
/**
* The MIDI bank MSB number.
*/
bankMSB: number;
/**
* The MIDI bank LSB number.
*/
bankLSB: number;
/**
* If the preset is marked as GM/GS drum preset. Note that XG drums do not have this flag.
*/
isGMGSDrum: boolean;
}
interface MIDIPatchFull extends MIDIPatch {
/**
* The name of the patch.
*/
name: string;
/**
* Indicates if this patch is a drum patch.
* This is the recommended way of determining if this is a drum preset.
* If `isGMGSDrum` is true, then this is a GM/GS drum preset.
* If `isGMGSDrum` is false, then this is a GM2/XG drum preset.
*/
isDrum: boolean;
}
declare class MIDIPatchTools {
/**
* Converts a given `MIDIPatch` to a string.
* The format is:
* - `DRUM:program` for `GMGSDrum` set to `true`.
* - `bankLSB:bankMSB:program` for `GMGSDrum` set to `false`.
*/
static toMIDIString(patch: MIDIPatch): string;
/**
* Gets `MIDIPatch` from a given string.
*/
static fromMIDIString(string: string): MIDIPatch;
/**
* Converts a given `MIDIPatchFull`to string.
* The format is:
* - `<MIDIPatch string> D <name>` for `isDrum` set to `true`.
* - `<MIDIPatch string> M <name>` for `isDrum` set to `true`.
*/
static toFullMIDIString(patch: MIDIPatchFull): string;
/**
* Gets `MIDIPatchFull` from a given string.
*/
static fromFullMIDIString(string: string): MIDIPatchFull;
/**
* Checks if two MIDI patches represent the same one.
*/
static matches(patch1: MIDIPatch, patch2: MIDIPatch): boolean;
/**
* A comparison function for `.sort()` or `.toSorted()`,
* ordering the patches in ascending order.
*/
static compare(a: MIDIPatch, b: MIDIPatch): number;
/**
* Checks if the given `MIDIPatchFull` is an XG/GM2 drum patch.
*/
static isXGDrum(p: MIDIPatchFull): boolean;
/**
* A sophisticated patch selection system based on the MIDI Patch system.
* This is the algorithm that the synthesizer uses for selecting presets.
* @param patches The `MIDIPatchFull` array to select from.
* @param patch The `MIDIPatch` to select.
* @param system The MIDI system to select for.
* @returns The selected patch.
*/
static selectPatch<T extends MIDIPatchFull>(patches: T[], patch: MIDIPatch, system: MIDISystem): T;
private static getAnyDrums;
}
//#endregion
//#region src/soundbank/basic_soundbank/generator.d.ts
declare class Generator {
/**
* The generator's SF2 type.
*/
type: GeneratorType;
/**
* The generator's 16-bit value.
*/
value: number;
/**
* Constructs a new generator
* @param type generator type
* @param value generator value
* @param validate if the limits should be validated and clamped.
*/
constructor(type: GeneratorType, value: number, validate?: boolean);
write(genData: IndexedByteArray): void;
toString(): string;
}
//#endregion
//#region src/soundbank/basic_soundbank/basic_zone.d.ts
declare class BasicZone {
/**
* The zone's velocity range.
* min -1 means that it is a default value
*/
velRange: GenericRange;
/**
* The zone's key range.
* min -1 means that it is a default value.
*/
keyRange: GenericRange;
/**
* The zone's generators.
*/
generators: Generator[];
/**
* The zone's modulators.
*/
modulators: Modulator[];
get hasKeyRange(): boolean;
get hasVelRange(): boolean;
/**
* The current tuning in cents, taking in both coarse and fine generators.
*/
get fineTuning(): number;
/**
* The current tuning in cents, taking in both coarse and fine generators.
*/
set fineTuning(tuningCents: number);
/**
* Adds to a given generator, or its default value.
* @param type the generator type.
* @param value the value to add.
* @param validate if the value should be clamped to allowed limits.
*/
addToGenerator(type: GeneratorType, value: number, validate?: boolean): void;
/**
* Sets a generator to a given value if preset, otherwise adds a new one.
* @param type the generator type.
* @param value the value to set. Set to null to remove this generator (set as "unset").
* @param validate if the value should be clamped to allowed limits.
*/
setGenerator(type: GeneratorType, value: number | null, validate?: boolean): void;
/**
* Adds generators to the zone.
* @param generators the generators to add.
*/
addGenerators(...generators: Generator[]): void;
/**
* Adds modulators to the zone.
* @param modulators the modulators to add.
*/
addModulators(...modulators: Modulator[]): void;
/**
* Gets a generator value.
* @param generatorType the generator type.
* @param notFoundValue if the generator is not found, this value is returned. A default value can be passed here, or null for example,
* to check if the generator is set.
*/
getGenerator<K>(generatorType: GeneratorType, notFoundValue: number | K): number | K;
copyFrom(zone: BasicZone): void;
/**
* Filters the generators and prepends the range generators.
*/
getWriteGenerators(bank: BasicSoundBank): Generator[];
}
//#endregion
//#region src/soundbank/basic_soundbank/basic_instrument_zone.d.ts
declare class BasicInstrumentZone extends BasicZone {
/**
* The instrument this zone belongs to.
*/
readonly parentInstrument: BasicInstrument;
/**
* For tracking on the individual zone level, since multiple presets can refer to the same instrument.
*/
useCount: number;
/**
* Creates a new instrument zone.
* @param instrument The parent instrument.
* @param sample The sample to use in this zone.
*/
constructor(instrument: BasicInstrument, sample: BasicSample);
/**
* Zone's sample.
*/
private _sample;
/**
* Zone's sample.
*/
get sample(): BasicSample;
/**
* Sets a sample for this zone.
* @param sample the sample to set.
*/
set sample(sample: BasicSample);
getWriteGenerators(bank: BasicSoundBank): Generator[];
}
//#endregion
//#region src/soundbank/basic_soundbank/basic_preset_zone.d.ts
declare class BasicPresetZone extends BasicZone {
/**
* The preset this zone belongs to.
*/
readonly parentPreset: BasicPreset;
/**
* Creates a new preset zone.
* @param preset the preset this zone belongs to.
* @param instrument the instrument to use in this zone.
*/
constructor(preset: BasicPreset, instrument: BasicInstrument);
/**
* Zone's instrument.
*/
private _instrument;
/**
* Zone's instrument.
*/
get instrument(): BasicInstrument;
/**
* Zone's instrument.
*/
set instrument(instrument: BasicInstrument);
getWriteGenerators(bank: BasicSoundBank): Generator[];
}
//#endregion
//#region src/soundbank/basic_soundbank/basic_preset.d.ts
declare class BasicPreset implements MIDIPatchFull {
/**
* The parent soundbank instance
* Currently used for determining default modulators and XG status
*/
readonly parentSoundBank: BasicSoundBank;
/**
* The preset's name
*/
name: string;
program: number;
bankMSB: number;
bankLSB: number;
isGMGSDrum: boolean;
/**
* The preset's zones
*/
zones: BasicPresetZone[];
/**
* Preset's global zone
*/
readonly globalZone: BasicZone;
/**
* Unused metadata
*/
library: number;
/**
* Unused metadata
*/
genre: number;
/**
* Unused metadata
*/
morphology: number;
/**
* Creates a new preset representation.
* @param parentSoundBank the sound bank this preset belongs to.
* @param globalZone optional, a global zone to use.
*/
constructor(parentSoundBank: BasicSoundBank, globalZone?: BasicZone);
/**
* Checks if this preset is a drum preset
*/
get isDrum(): boolean;
private static isInRange;
private static addUniqueModulators;
private static subtractRanges;
/**
* Unlinks everything from this preset.
*/
delete(): void;
/**
* Deletes an instrument zone from this preset.
* @param index the zone's index to delete.
*/
deleteZone(index: number): void;
/**
* Creates a new preset zone and returns it.
* @param instrument the instrument to use in the zone.
*/
createZone(instrument: BasicInstrument): BasicPresetZone;
/**
* Preloads (loads and caches synthesis data) for a given key range.
*/
preload(keyMin: number, keyMax: number): void;
/**
* Checks if the bank and program numbers are the same for the given preset as this one.
* @param preset The preset to check.
*/
matches(preset: MIDIPatch): boolean;
/**
* Returns the voice synthesis data for this preset.
* @param midiNote the MIDI note number.
* @param velocity the MIDI velocity.
* @returns the returned sound data.
*/
getVoiceParameters(midiNote: number, velocity: number): VoiceParameters[];
/**
* BankMSB:bankLSB:program:isGMGSDrum
*/
toMIDIString(): string;
toString(): string;
/**
* Combines preset into an instrument, flattening the preset zones into instrument zones.
* This is a really complex function that attempts to work around the DLS limitations of only having the instrument layer.
* @returns The instrument containing the flattened zones. In theory, it should exactly the same as this preset.
*/
toFlattenedInstrument(): BasicInstrument;
}
//#endregion
//#region src/soundbank/basic_soundbank/basic_instrument.d.ts
/**
* Represents a single instrument
*/
declare class BasicInstrument {
/**
* The instrument's name
*/
name: string;
/**
* The instrument's zones
*/
zones: BasicInstrumentZone[];
/**
* Instrument's global zone
*/
readonly globalZone: BasicZone;
/**
* Instrument's linked presets (the presets that use it)
* note that duplicates are allowed since one preset can use the same instrument multiple times.
*/
readonly linkedTo: BasicPreset[];
/**
* How many presets is this instrument used by
*/
get useCount(): number;
/**
* Creates a new instrument zone and returns it.
* @param sample The sample to use in the zone.
*/
createZone(sample: BasicSample): BasicInstrumentZone;
/**
* Links the instrument ta a given preset
* @param preset the preset to link to
*/
linkTo(preset: BasicPreset): void;
/**
* Unlinks the instrument from a given preset
* @param preset the preset to unlink from
*/
unlinkFrom(preset: BasicPreset): void;
deleteUnusedZones(): void;
delete(): void;
/**
* Deletes a given instrument zone if it has no uses
* @param index the index of the zone to delete
* @param force ignores the use count and deletes forcibly
* @returns if the zone has been deleted
*/
deleteZone(index: number, force?: boolean): boolean;
/**
* Globalizes the instrument *in-place.*
* This means trying to move as many generators and modulators
* to the global zone as possible to reduce clutter and the count of parameters.
*/
globalize(): void;
}
//#endregion
//#region src/soundbank/basic_soundbank/basic_sample.d.ts
declare class BasicSample {
/**
* The sample's name.
*/
name: string;
/**
* Sample rate in Hz.
*/
sampleRate: number;
/**
* Original pitch of the sample as a MIDI note number.
*/
originalKey: number;
/**
* Pitch correction, in cents. Can be negative.
*/
pitchCorrection: number;
/**
* Linked sample, unused if mono.
*/
linkedSample?: BasicSample;
/**
* The type of the sample.
*/
sampleType: SampleType;
/**
* The sample's loop start index, inclusive.
* In sample data points, relative to the start of the sample.
*
* Minimum allowed value is 0.
*/
loopStart: number;
/**
* The sample's loop end index, exclusive.
* In sample data points, relative to the start of the sample.
*
* Maximum allowed value is the sample data length.
*/
loopEnd: number;
/**
* Sample's linked instruments (the instruments that use it)
* note that duplicates are allowed since one instrument can use the same sample multiple times.
*/
linkedTo: BasicInstrument[];
/**
* Indicates if the data was overridden, so it cannot be copied back unchanged.
*/
protected dataOverridden: boolean;
/**
* The compressed sample data if the sample has been compressed.
*/
protected compressedData?: Uint8Array;
/**
* The sample's audio data.
*/
protected audioData?: Float32Array;
/**
* The basic representation of a sample.
* @param sampleName The sample's name.
* @param sampleRate The sample's rate in Hz.
* @param originalKey The sample's pitch as a MIDI note number.
* @param pitchCorrection The sample's pitch correction in cents.
* @param sampleType The sample's type, an enum that can indicate SF3.
* @param loopStart The sample's loop start relative to the sample start in sample points.
* @param loopEnd The sample's loop end relative to the sample start in sample points. Inclusive.
*/
constructor(sampleName: string, sampleRate: number, originalKey: number, pitchCorrection: number, sampleType: SampleType, loopStart: number, loopEnd: number);
/**
* Indicates if the sample is compressed using vorbis SF3.
*/
get isCompressed(): boolean;
/**
* If the sample is linked to another sample.
*/
get isLinked(): boolean;
/**
* The sample's use count
*/
get useCount(): number;
/**
* Get raw data for writing the file, either a compressed bit stream or signed 16-bit little endian PCM data.
* @param allowVorbis if vorbis file data is allowed.
* @return either s16le or vorbis data.
*/
getRawData(allowVorbis: boolean): Uint8Array;
/**
* Resamples the audio data to a given sample rate.
*/
resampleData(newSampleRate: number): void;
/**
* Compresses the audio data
* @param encodeVorbis the compression function to use when compressing
*/
compressSample(encodeVorbis: SampleEncodingFunction): Promise<void>;
/**
* Sets the sample type and unlinks if needed.
* @param type The type to set it to.
*/
setSampleType(type: SampleType): void;
/**
* Unlinks the sample from its stereo link if it has any.
*/
unlinkSample(): void;
/**
* Links a stereo sample.
* @param sample the sample to link to.
* @param type either left, right or linked.
*/
setLinkedSample(sample: BasicSample, type: SampleType): void;
/**
* Links the sample to a given instrument
* @param instrument the instrument to link to
*/
linkTo(instrument: BasicInstrument): void;
/**
* Unlinks the sample from a given instrument
* @param instrument the instrument to unlink from
*/
unlinkFrom(instrument: BasicInstrument): void;
/**
* Get the float32 audio data.
* Note that this either decodes the compressed data or passes the ready sampleData.
* If neither are set then it will throw an error!
* @returns the audio data
*/
getAudioData(): Float32Array;
/**
* Replaces the audio data *in-place*.
* @param audioData The new audio data as Float32.
* @param sampleRate The new sample rate, in Hertz.
*/
setAudioData(audioData: Float32Array, sampleRate: number): void;
/**
* Replaces the audio with a compressed data sample and flags the sample as compressed
* @param data the new compressed data
*/
setCompressedData(data: Uint8Array): void;
/**
* Encodes s16le sample
* @return the encoded data
*/
protected encodeS16LE(): IndexedByteArray;
/**
* Decode binary vorbis into a float32 pcm
*/
protected decodeVorbis(): Float32Array;
}
declare class EmptySample extends BasicSample {
/**
* A simplified class for creating samples.
*/
constructor();
}
//#endregion
//#region src/soundbank/sound_bank_loader.d.ts
declare class SoundBankLoader {
/**
* Loads a sound bank from a file buffer.
* @param buffer The binary file buffer to load.
* @returns The loaded sound bank, a BasicSoundBank instance.
*/
static fromArrayBuffer(buffer: ArrayBuffer): BasicSoundBank;
private static loadDLS;
}
//#endregion
//#region src/synthesizer/audio_engine/voice/voice_modulator.d.ts
declare class VoiceModulator extends Modulator {
/**
* Indicates if the given modulator is chorus or reverb effects modulator.
* This is done to simulate BASSMIDI effects behavior:
* - defaults to 1000 transform amount rather than 200
* - values can be changed, but anything above 200 is 1000
* (except for values above 1000, they are copied directly)
* - all values below are multiplied by 5 (200 * 5 = 1000)
* - still can be disabled if the soundfont has its own modulator curve
* - this fixes the very low amount of reverb by default and doesn't break soundfonts
*/
readonly isEffectModulator: boolean;
/**
* The default resonant modulator does not affect the filter gain.
* Neither XG nor GS responded to cc #74 in that way.
*/
readonly isDefaultResonantModulator: boolean;
/**
* If this is a modulation wheel modulator (for modulation depth range).
*/
readonly isModWheelModulator: boolean;
private constructor();
static fromData(s1: ModulatorSource, s2: ModulatorSource, destination: GeneratorType, amount: number, transformType: ModulatorTransformType): VoiceModulator;
static fromModulator(mod: Modulator): VoiceModulator;
}
//#endregion
//#region src/synthesizer/audio_engine/voice/voice_cache.d.ts
/**
* Represents a cached voice
*/
declare class CachedVoice {
/**
* Sample data of this voice.
*/
readonly sampleData: Float32Array;
/**
* The unmodulated (copied to) generators of the voice.
*/
readonly generators: Int16Array;
/**
* The voice's modulators.
*/
readonly modulators: VoiceModulator[];
/**
* Exclusive class number for hi-hats etc.
*/
readonly exclusiveClass: number;
/**
* Target key of the voice (can be overridden by generators)
*/
readonly targetKey: number;
/**
* Target velocity of the voice (can be overridden by generators)
*/
readonly velocity: number;
/**
* MIDI root key of the sample
*/
readonly rootKey: number;
/**
* Start position of the loop
*/
readonly loopStart: number;
/**
* End position of the loop
*/
readonly loopEnd: number;
/**
* Playback step (rate) for sample pitch correction
*/
readonly playbackStep: number;
readonly loopingMode: SampleLoopingMode;
constructor(voiceParams: VoiceParameters, midiNote: number, velocity: number, sampleRate: number);
}
//#endregion
//#region src/synthesizer/audio_engine/effects/types.d.ts
interface EffectProcessor {
/**
* 0-127
* This parameter sets the amount of the effect sent to the effect output.
*/
level: number;
/**
* 0-7
* A low-pass filter can be applied to the sound coming into the effect to cut the high
* frequency range. Higher values will cut more of the high frequencies, resulting in a
* more mellow effect sound.
*/
preLowpass: number;
}
interface ReverbProcessorSnapshot extends EffectProcessor {
/**
* 0-7.
* If character is not available, it should default to the first one.
*
* This parameter selects the type of reverb. 0–5 are reverb effects, and 6 and 7 are delay
* effects.
*/
character: number;
/**
* 0-127
* This parameter sets the time over which the reverberation will continue.
* Higher values result in longer reverberation.
*/
time: number;
/**
* 0-127
* This parameter is used when the Reverb Character is set to 6 or 7, or the Reverb Type
* is set to Delay or Panning Delay (Rev Character 6, 7). It sets the way in which delays
* repeat. Higher values result in more delay repeats.
*/
delayFeedback: number;
/**
* 0 - 127 (ms)
* This parameter sets the delay time until the reverberant sound is heard.
* Higher values result in a longer pre-delay time, simulating a larger reverberant space.
*/
preDelayTime: number;
}
interface ReverbProcessor extends ReverbProcessorSnapshot {
/**
* Process the effect and ADDS it to the output.
* @param input The input buffer to process. It always starts at index 0.
* @param outputLeft The left output buffer.
* @param outputRight The right output buffer.
* @param startIndex The index to start mixing at into the output buffers.
* @param sampleCount The amount of samples to mix.
*/
process(input: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, startIndex: number, sampleCount: number): void;
/**
* Gets a synthesizer from this effect processor instance.
*/
getSnapshot(): ReverbProcessorSnapshot;
}
interface ChorusProcessorSnapshot extends EffectProcessor {
/**
* 0-127
* This parameter sets the level at which the chorus sound is re-input (fed back) into the
* chorus. By using feedback, a denser chorus sound can be created.
* Higher values result in a greater feedback level.
*/
feedback: number;
/**
* 0-127
* This parameter sets the delay time of the chorus effect.
*/
delay: number;
/**
* 0-127
* This parameter sets the speed (frequency) at which the chorus sound is modulated.
* Higher values result in faster modulation.
*/
rate: number;
/**
* 0-127
* This parameter sets the depth at which the chorus sound is modulated.
* Higher values result in deeper modulation.
*/
depth: number;
/**
* 0-127
* This parameter sets the amount of chorus sound that will be sent to the reverb.
* Higher values result in more sound being sent.
*/
sendLevelToReverb: number;
/**
* 0-127
* This parameter sets the amount of chorus sound that will be sent to the delay.
* Higher values result in more sound being sent.
*/
sendLevelToDelay: number;
}
interface ChorusProcessor extends ChorusProcessorSnapshot {
/**
* Process the effect and ADDS it to the output.
* @param input The input buffer to process. It always starts at index 0.
* @param outputLeft The left output buffer.
* @param outputRight The right output buffer.
* @param outputReverb The mono input for reverb. It always starts at index 0.
* @param outputDelay The mono input for delay. It always starts at index 0.
* @param startIndex The index to start mixing at into the output buffers.
* @param sampleCount The amount of samples to mix.
*/
process(input: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, outputReverb: Float32Array, outputDelay: Float32Array, startIndex: number, sampleCount: number): void;
/**
* Gets a synthesizer from this effect processor instance.
*/
getSnapshot(): ChorusProcessorSnapshot;
}
interface DelayProcessorSnapshot extends EffectProcessor {
/**
* 0-115
* 0.1ms-340ms-1000ms
* The delay effect has three delay times; center, left and
* right (when listening in stereo). Delay Time Center sets the delay time of the delay
* located at the center.
* Refer to SC-8850 Owner's Manual p. 236 for the exact mapping of the values.
*/
timeCenter: number;
/**
* 0-120
* 4% - 500%
* This parameter sets the delay time of the delay located at the left as a percentage of
* the Delay Time Center (up to a max. of 1.0 s).
* The resolution is 100/24(%).
*/
timeRatioLeft: number;
/**
* 1-120
* 4%-500%
* This parameter sets the delay time of the delay located at the right as a percentage of
* the Delay Time Center (up to a max. of 1.0 s).
* The resolution is 100/24(%).
*/
timeRatioRight: number;
/**
* 0-127
* This parameter sets the volume of the central delay. Higher values result in a louder
* center delay.
*/
levelCenter: number;
/**
* 0-127
* This parameter sets the volume of the left delay. Higher values result in a louder left
* delay.
*/
levelLeft: number;
/**
* 0-127
* This parameter sets the volume of the right delay. Higher values result in a louder
* right delay.
*/
levelRight: number;
/**
* 0-127
* (-64)-63
* This parameter affects the number of times the delay will repeat. With a value of 0,
* the delay will not repeat. With higher values there will be more repeats.
* With negative (-) values, the center delay will be fed back with inverted phase.
* Negative values are effective with short delay times.
*/
feedback: number;
/**
* 0-127
* This parameter sets the amount of delay sound that is sent to the reverb.
* Higher values result in more sound being sent.
*/
sendLevelToReverb: number;
}
interface DelayProcessor extends DelayProcessorSnapshot {
/**
* Process the effect and ADDS it to the output.
* @param input The input buffer to process. It always starts at index 0.
* @param outputLeft The left output buffer.
* @param outputRight The right output buffer.
* @param outputReverb The mono input for reverb. It always starts at index 0.
* @param startIndex The index to start mixing at into the output buffers.
* @param sampleCount The amount of samples to mix.
*/
process(input: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, outputReverb: Float32Array, startIndex: number, sampleCount: number): void;
/**
* Gets a synthesizer from this effect processor instance.
*/
getSnapshot(): DelayProcessorSnapshot;
}
interface InsertionProcessor {
/**
* The EFX type of this processor, stored as MSB << | LSB.
* For example 0x30, 0x10 is 0x3010
*/
readonly type: number;
/**
* 0-1 (floating point)
* This parameter sets the amount of insertion sound that will be sent to the reverb.
* Higher values result in more sound being sent.
*/
sendLevelToReverb: number;
/**
* 0-1 (floating point)
* This parameter sets the amount of insertion sound that will be sent to the chorus.
* Higher values result in more sound being sent.
*/
sendLevelToChorus: number;
/**
* 0-1 (floating point)
* This parameter sets the amount of insertion sound that will be sent to the delay.
* Higher values result in more sound being sent.
*/
sendLevelToDelay: number;
/**
* Resets the params to their default values.
* This does not need to reset send levels.
*/
reset(): void;
/**
* Sets an EFX parameter.
* @param parameter The parameter number (0x03-0x16).
* @param value The new value (0-127).
*/
setParameter(parameter: number, value: number): void;
/**
* Process the effect and ADDS it to the output.
* @param inputLeft The left input buffer to process. It always starts at index 0.
* @param inputRight The right input buffer to process. It always starts at index 0.
* @param outputLeft The left output buffer.
* @param outputRight The right output buffer.
* @param outputReverb The mono input for reverb. It always starts at index 0.
* @param outputChorus The mono input for chorus. It always starts at index 0.
* @param outputDelay The mono input for delay. It always starts at index 0.
* @param startIndex The index to start mixing at into the output buffers.
* @param sampleCount The amount of samples to mix.
*/
process(inputLeft: Float32Array, inputRight: Float32Array, outputLeft: Float32Array, outputRight: Float32Array, outputReverb: Float32Array, outputChorus: Float32Array, outputDelay: Float32Array, startIndex: number, sampleCount: number): void;
}
interface InsertionProcessorSnapshot {
type: number;
/**
* 20 parameters for the effect, 255 means "no change" + 3 effect sends (index 20, 21, 22)
*/
params: Uint8Array;
}
type InsertionProcessorConstructor = new (sampleRate: number, maxBufferSize: number) => InsertionProcessor;
//#endregion
//#region src/midi/enums.d.ts
declare const MIDIMessageTypes: {
readonly noteOff: 128;
readonly noteOn: 144;
readonly polyPressure: 160;
readonly controllerChange: 176;
readonly programChange: 192;
readonly channelPressure: 208;
readonly pitchWheel: 224;
readonly systemExclusive: 240;
readonly timecode: 241;
readonly songPosition: 242;
readonly songSelect: 243;
readonly tuneRequest: 246;
readonly clock: 248;
readonly start: 250;
readonly continue: 251;
readonly stop: 252;
readonly activeSensing: 254;
readonly reset: 255;
readonly sequenceNumber: 0;
readonly text: 1;
readonly copyright: 2;
readonly trackName: 3;
readonly instrumentName: 4;
readonly lyric: 5;
readonly marker: 6;
readonly cuePoint: 7;
readonly programName: 8;
readonly midiChannelPrefix: 32;
readonly midiPort: 33;
readonly endOfTrack: 47;
readonly setTempo: 81;
readonly smpteOffset: 84;
readonly timeSignature: 88;
readonly keySignature: 89;
readonly sequenceSpecific: 127;
};
type MIDIMessageType = (typeof MIDIMessageTypes)[keyof typeof MIDIMessageTypes];
declare const MIDIControllers: {
readonly bankSelect: 0;
readonly modulationWheel: 1;
readonly breathController: 2;
readonly undefinedCC3: 3;
readonly footController: 4;
readonly portamentoTime: 5;
readonly dataEntryMSB: 6;
readonly mainVolume: 7;
readonly balance: 8;
readonly undefinedCC9: 9;
readonly pan: 10;
readonly expression: 11;
readonly effectControl1: 12;
readonly effectControl2: 13;
readonly undefinedCC14: 14;
readonly undefinedCC15: 15;
readonly generalPurposeController1: 16;
readonly generalPurposeController2: 17;
readonly generalPurposeController3: 18;
readonly generalPurposeController4: 19;
readonly undefinedCC20: 20;
readonly undefinedCC21: 21;
readonly undefinedCC22: 22;
readonly undefinedCC23: 23;
readonly undefinedCC24: 24;
readonly undefinedCC25: 25;
readonly undefinedCC26: 26;
readonly undefinedCC27: 27;
readonly undefinedCC28: 28;
readonly undefinedCC29: 29;
readonly undefinedCC30: 30;
readonly undefinedCC31: 31;
readonly bankSelectLSB: 32;
readonly modulationWheelLSB: 33;
readonly breathControllerLSB: 34;
readonly undefinedCC3LSB: 35;
readonly footControllerLSB: 36;
readonly portamentoTimeLSB: 37;
readonly dataEntryLSB: 38;
readonly mainVolumeLSB: 39;
readonly balanceLSB: 40;
readonly undefinedCC9LSB: 41;
readonly panLSB: 42;
readonly expressionLSB: 43;
readonly effectControl1LSB: 44;
readonly effectControl2LSB: 45;
readonly undefinedCC14LSB: 46;
readonly undefinedCC15LSB: 47;
readonly undefinedCC16LSB: 48;
readonly undefinedCC17LSB: 49;
readonly undefinedCC18LSB: 50;
readonly undefinedCC19LSB: 51;
readonly undefinedCC20LSB: 52;
readonly undefinedCC21LSB: 53;
readonly undefinedCC22LSB: 54;
readonly undefinedCC23LSB: 55;
readonly undefinedCC24LSB: 56;
readonly undefinedCC25LSB: 57;
readonly undefinedCC26LSB: 58;
readonly undefinedCC27LSB: 59;
readonly undefinedCC28LSB: 60;
readonly undefinedCC29LSB: 61;
readonly undefinedCC30LSB: 62;
readonly undefinedCC31LSB: 63;
readonly sustainPedal: 64;
readonly portamentoOnOff: 65;
readonly sostenutoPedal: 66;
readonly softPedal: 67;
readonly legatoFootswitch: 68;
readonly hold2Pedal: 69;
readonly soundVariation: 70;
readonly filterResonance: 71;
readonly releaseTime: 72;
readonly attackTime: 73;
readonly brightness: 74;
readonly decayTime: 75;
readonly vibratoRate: 76;
readonly vibratoDepth: 77;
readonly vibratoDelay: 78;
readonly soundController10: 79;
readonly generalPurposeController5: 80;
readonly generalPurposeController6: 81;
readonly generalPurposeController7: 82;
readonly generalPurposeController8: 83;
readonly portamentoControl: 84;
readonly undefinedCC85: 85;
readonly undefinedCC86: 86;
readonly undefinedCC87: 87;
readonly undefinedCC88: 88;
readonly undefinedCC89: 89;
readonly undefinedCC90: 90;
readonly reverbDepth: 91;
readonly tremoloDepth: 92;
readonly chorusDepth: 93;
readonly variationDepth: 94;
readonly phaserDepth: 95;
readonly dataIncrement: 96;
readonly dataDecrement: 97;
readonly nonRegisteredParameterLSB: 98;
readonly nonRegisteredParameterMSB: 99;
readonly registeredParameterLSB: 100;
readonly registeredParameterMSB: 101;
readonly undefinedCC102LSB: 102;
readonly undefinedCC103LSB: 103;
readonly undefinedCC104LSB: 104;
readonly undefinedCC105LSB: 105;
readonly undefinedCC106LSB: 106;
readonly undefinedCC107LSB: 107;
readonly undefinedCC108LSB: 108;
readonly undefinedCC109LSB: 109;
readonly undefinedCC110LSB: 110;
readonly undefinedCC111LSB: 111;
readonly undefinedCC112LSB: 112;
readonly undefinedCC113LSB: 113;
readonly undefinedCC114LSB: 114;
readonly undefinedCC115LSB: 115;
readonly undefinedCC116LSB: 116;
readonly undefinedCC117LSB: 117;
readonly undefinedCC118LSB: 118;
readonly undefinedCC119LSB: 119;
readonly allSoundOff: 120;
readonly resetAllControllers: 121;
readonly localControlOnOff: 122;
readonly allNotesOff: 123;
readonly omniModeOff: 124;
readonly omniModeOn: 125;
readonly monoModeOn: 126;
readonly polyModeOn: 127;
};
type MIDIController = (typeof MIDIControllers)[keyof typeof MIDIControllers];
declare const RegisteredParameterTypes: {
readonly pitchWheelRange: 0;
readonly fineTuning: 1;
readonly coarseTuning: 2;
readonly modulationDepth: 5;
readonly resetParameters: 16383;
};
declare const NonRegisteredMSB: {
readonly partParameter: 1;
readonly drumPitch: 24;
readonly drumPitchFine: 25;
readonly drumLevel: 26;
readonly drumPan: 28;
readonly drumReverb: 29;
readonly drumChorus: 30;
readonly drumDelay: 31;
readonly awe32: 127;
readonly SF2: 120;
};
/**
* https://cdn.roland.com/assets/media/pdf/SC-8850_OM.pdf
* http://hummer.stanford.edu/sig/doc/classes/MidiOutput/rpn.html
* These also seem to match XG
*/
declare const NonRegisteredLSB: {
readonly vibratoRate: 8;
readonly vibratoDepth: 9;
readonly vibratoDelay: 10;
readonly tvfCutoffFrequency: 32;
readonly tvfResonance: 33;
readonly envelopeAttackTime: 99;
readonly envelopeDecayTime: 100;
readonly envelopeReleaseTime: 102;
};
//#endregion
//#region src/synthesizer/audio_engine/channel/awe32_nrpn.d.ts
interface ChannelGenerators {
/**
* An array of offsets generators for SF2 NRPN support.
* A value of 0 means no change; -10 means 10 lower, etc.
*/
offsets: Int16Array;
/**
* A small optimization that disables applying offsets until at least one is set.
*/
offsetsEnabled: boolean;
/**
* An array of overrides generators for AWE32 NRPN support.
* A value of GENERATOR_OVERRIDE_NO_CHANGE_VALUE (-32,767) means no change;
* other values replace current generators.
*/
overrides: Int16Array;
/**
* A small optimization that disables applying overrides until at least one is set.
*/
overridesEnabled: boolean;
}
//#endregion
//#region src/synthesizer/enums.d.ts
/**
* The available interpolation types of the synthesizer.
*/
declare const InterpolationTypes: {
readonly linear: 0;
readonly nearestNeighbor: 1;
readonly hermite: 2;
};
type InterpolationType = (typeof InterpolationTypes)[keyof typeof InterpolationTypes];
//#endregion
//#region src/synthesizer/audio_engine/channel/parameters/system.d.ts
/**
* The system parameters of the channel.
* These can only be changed via the API.
*/
interface ChannelSystemParameter {
/**
* If the preset is locked, preventing