UNPKG

spessasynth_core

Version:

MIDI and SoundFont2/DLS library with no compromises

1,625 lines 157 kB
//#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