import { InterpolationValues, ChorusModulation, GeneratorTypes, LegatoMode, PortamentoMode, PlayerSetTempoType } from './Constants'; import IMIDIEvent from './IMIDIEvent'; import ISequencer from './ISequencer'; import ISequencerEventData from './ISequencerEventData'; import ISynthesizer from './ISynthesizer'; import SynthesizerSettings from './SynthesizerSettings'; import SequencerEvent, { EventType as SequencerEventType } from './SequencerEvent'; import Soundfont from './Soundfont'; /** Hook callback function type */ export interface HookMIDIEventCallback { /** * Hook callback function type. * @param synth the base synthesizer instance * @param eventType MIDI event type (e.g. 0x90 is note-on event) * @param eventData detailed event data * @param param parameter data passed to the registration method * @return true if the event data is processed, or false if the default processing is necessary */ (synth: Synthesizer, eventType: number, eventData: IMIDIEvent, param: any): boolean; } /** Client callback function type for sequencer object */ export interface SequencerClientCallback { /** * Client callback function type for sequencer object. * @param time the sequencer tick value * @param eventType sequencer event type * @param event actual event data (can only be used in this callback function) * @param sequencer the base sequencer object * @param param parameter data passed to the registration method */ (time: number, eventType: SequencerEventType, event: ISequencerEventData, sequencer: ISequencer, param: number): void; } /** Default implementation of ISynthesizer */ export default class Synthesizer implements ISynthesizer { constructor(); /** * Initializes with loaded FluidSynth module. * If using this method, you must call this before all methods/constructors, including `waitForWasmInitialized`. * @param mod loaded libfluidsynth.js instance (typically `const mod = Module` (loaded via script tag) or `const mod = require('libfluidsynth-*.js')` (in Node.js)) */ static initializeWithFluidSynthModule(mod: unknown): void; /** Return the promise object that resolves when WebAssembly has been initialized. */ static waitForWasmInitialized(): Promise; isInitialized(): boolean; /** Return the raw synthesizer instance value (pointer for libfluidsynth). */ getRawSynthesizer(): number; createAudioNode(context: AudioContext, frameSize?: number): AudioNode; init(sampleRate: number, settings?: SynthesizerSettings): void; close(): void; isPlaying(): boolean; setInterpolation(value: InterpolationValues, channel?: number): void; getGain(): number; setGain(gain: number): void; setChannelType(channel: number, isDrum: boolean): void; waitForVoicesStopped(): Promise; loadSFont(bin: ArrayBuffer): Promise; unloadSFont(id: number): void; unloadSFontAsync(id: number): Promise; /** * Returns the `Soundfont` instance for specified SoundFont. * @param sfontId loaded SoundFont id ({@link loadSFont} returns this) * @return `Soundfont` instance or `null` if `sfontId` is not valid or loaded */ getSFontObject(sfontId: number): Soundfont | null; getSFontBankOffset(id: number): Promise; setSFontBankOffset(id: number, offset: number): void; render(outBuffer: AudioBuffer | Float32Array[]): void; midiNoteOn(chan: number, key: number, vel: number): void; midiNoteOff(chan: number, key: number): void; midiKeyPressure(chan: number, key: number, val: number): void; midiControl(chan: number, ctrl: number, val: number): void; midiProgramChange(chan: number, prognum: number): void; midiChannelPressure(chan: number, val: number): void; midiPitchBend(chan: number, val: number): void; midiSysEx(data: Uint8Array): void; midiPitchWheelSensitivity(chan: number, val: number): void; midiBankSelect(chan: number, bank: number): void; midiSFontSelect(chan: number, sfontId: number): void; midiProgramSelect(chan: number, sfontId: number, bank: number, presetNum: number): void; midiUnsetProgram(chan: number): void; midiProgramReset(): void; midiSystemReset(): void; midiAllNotesOff(chan?: number): void; midiAllSoundsOff(chan?: number): void; midiSetChannelType(chan: number, isDrum: boolean): void; /** * Set reverb parameters to the synthesizer. */ setReverb(roomsize: number, damping: number, width: number, level: number): void; /** * Set reverb roomsize parameter to the synthesizer. */ setReverbRoomsize(roomsize: number): void; /** * Set reverb damping parameter to the synthesizer. */ setReverbDamp(damping: number): void; /** * Set reverb width parameter to the synthesizer. */ setReverbWidth(width: number): void; /** * Set reverb level to the synthesizer. */ setReverbLevel(level: number): void; /** * Enable or disable reverb effect of the synthesizer. */ setReverbOn(on: boolean): void; /** * Get reverb roomsize parameter of the synthesizer. */ getReverbRoomsize(): number; /** * Get reverb damping parameter of the synthesizer. */ getReverbDamp(): number; /** * Get reverb level of the synthesizer. */ getReverbLevel(): number; /** * Get reverb width parameter of the synthesizer. */ getReverbWidth(): number; /** * Set chorus parameters to the synthesizer. */ setChorus(voiceCount: number, level: number, speed: number, depthMillisec: number, type: ChorusModulation): void; /** * Set chorus voice count parameter to the synthesizer. */ setChorusVoiceCount(voiceCount: number): void; /** * Set chorus level parameter to the synthesizer. */ setChorusLevel(level: number): void; /** * Set chorus speed parameter to the synthesizer. */ setChorusSpeed(speed: number): void; /** * Set chorus depth parameter to the synthesizer. */ setChorusDepth(depthMillisec: number): void; /** * Set chorus modulation type to the synthesizer. */ setChorusType(type: ChorusModulation): void; /** * Enable or disable chorus effect of the synthesizer. */ setChorusOn(on: boolean): void; /** * Get chorus voice count of the synthesizer. */ getChorusVoiceCount(): number; /** * Get chorus level of the synthesizer. */ getChorusLevel(): number; /** * Get chorus speed of the synthesizer. */ getChorusSpeed(): number; /** * Get chorus depth (in milliseconds) of the synthesizer. */ getChorusDepth(): number; /** * Get chorus modulation type of the synthesizer. */ getChorusType(): ChorusModulation; /** * Get generator value assigned to the MIDI channel. * @param channel MIDI channel number * @param param generator ID * @return a value related to the generator */ getGenerator(channel: number, param: GeneratorTypes): number; /** * Set generator value assigned to the MIDI channel. * @param channel MIDI channel number * @param param generator ID * @param value a value related to the generator */ setGenerator(channel: number, param: GeneratorTypes, value: number): void; /** * Return the current legato mode of the channel. * @param channel MIDI channel number * @return legato mode */ getLegatoMode(channel: number): LegatoMode; /** * Set the current legato mode of the channel. * @param channel MIDI channel number * @param mode legato mode */ setLegatoMode(channel: number, mode: LegatoMode): void; /** * Return the current portamento mode of the channel. * @param channel MIDI channel number * @return portamento mode */ getPortamentoMode(channel: number): PortamentoMode; /** * Set the current portamento mode of the channel. * @param channel MIDI channel number * @param mode portamento mode */ setPortamentoMode(channel: number, mode: PortamentoMode): void; /** * Return the current breath mode of the channel. * @param channel MIDI channel number * @return breath mode (BreathFlags) */ getBreathMode(channel: number): number; /** * Set the current breath mode of the channel. * @param channel MIDI channel number * @param flags breath mode flags (BreathFlags) */ setBreathMode(channel: number, flags: number): void; resetPlayer(): Promise; closePlayer(): void; isPlayerPlaying(): boolean; addSMFDataToPlayer(bin: ArrayBuffer): Promise; playPlayer(): Promise; stopPlayer(): void; retrievePlayerCurrentTick(): Promise; retrievePlayerTotalTicks(): Promise; retrievePlayerBpm(): Promise; retrievePlayerMIDITempo(): Promise; seekPlayer(ticks: number): void; setPlayerLoop(loopTimes: number): void; setPlayerTempo(tempoType: PlayerSetTempoType, tempo: number): void; /** * Retrieve current (timing that method called) tick value of the player. * {@linkcode init} must be called before calling this method. * @return the tick value * @note This method is not available in `AudioWorkletNodeSynthesizer` because of synchronous processings. */ getPlayerCurrentTick(): number; /** * Retrieve tick value of the last event timing of current playing data. * {@linkcode init} must be called before calling this method. * @return the tick value * @note This method is not available in `AudioWorkletNodeSynthesizer` because of synchronous processings. */ getPlayerTotalTicks(): number; /** * Retrieve current (timing that method called) BPM value of the player. * The BPM value is calculated by dividing 60000000 by the MIDI tempo value. * {@linkcode init} must be called before calling this method. * @return the BPM value * @note This method is not available in `AudioWorkletNodeSynthesizer` because of synchronous processings. */ getPlayerBpm(): number; /** * Retrieve current (timing that method called) MIDI tempo value of the player. * {@linkcode init} must be called before calling this method. * @return the MIDI tempo value * @note This method is not available in `AudioWorkletNodeSynthesizer` because of synchronous processings. */ getPlayerMIDITempo(): number; /** * Returns the raw 'player' instance value (pointer). * @return the raw player pointer or `null` if not initialized */ getRawPlayer(): number | null; /** * Hooks MIDI events sent by the player. * {@linkcode init} must be called before calling this method. * @param callback hook callback function, or null to unhook * @param param any additional data passed to the callback */ hookPlayerMIDIEvents(callback: HookMIDIEventCallback | null, param?: any): void; waitForPlayerStopped(): Promise; /** * Create the sequencer object for this class. */ static createSequencer(): Promise; /** * Registers the user-defined client to the sequencer. * The client can receive events in the time from sequencer process. * @param seq the sequencer instance created by {@linkcode Synthesizer.createSequencer} * @param name the client name * @param callback the client callback function that processes event data * @param param additional parameter passed to the callback * @return registered sequencer client id (can be passed to seq.unregisterClient()) */ static registerSequencerClient(seq: ISequencer, name: string, callback: SequencerClientCallback, param: number): number; /** * Send sequencer event immediately to the specific client. * @param seq the sequencer instance created by {@linkcode Synthesizer.createSequencer} * @param clientId registered client id (-1 for registered synthesizer) * @param event event data */ static sendEventToClientNow(seq: ISequencer, clientId: number, event: SequencerEvent): void; /** * (Re-)send event data immediately. * @param seq the sequencer instance created by {@linkcode Synthesizer.createSequencer} * @param clientId registered client id (-1 for registered synthesizer) * @param eventData event data which can be retrieved in {@linkcode SequencerClientCallback} */ static sendEventNow(seq: ISequencer, clientId: number, eventData: ISequencerEventData): void; /** * Set interval timer process to call {@linkcode ISequencer.processSequencer} for this sequencer. * This method uses 'setInterval' global method to register timer. * @param seq the sequencer instance created by {@linkcode Synthesizer.createSequencer} * @param msec time in milliseconds passed to both `setInterval` and `processSequencer` * @return return value of 'setInterval' (usually passing to 'clearInterval' will reset event) */ static setIntervalForSequencer(seq: ISequencer, msec: number): number; }