import { IAnalyserNode, IAudioBuffer, IAudioBufferSourceNode, IAudioNode, IAudioWorklet, IBaseAudioContext, IBiquadFilterNode, IConstantSourceNode, IConvolverNode, IDelayNode, IDynamicsCompressorNode, IGainNode, IIIRFilterNode, IOscillatorNode, IPannerNode, IPeriodicWave, IPeriodicWaveConstraints, IStereoPannerNode, IWaveShaperNode, IWorkletOptions } from '../interfaces'; import { TBaseAudioContextConstructorFactory, TContext, TDecodeErrorCallback, TDecodeSuccessCallback, TNativeContext } from '../types'; export const createBaseAudioContextConstructor: TBaseAudioContextConstructorFactory = ( addAudioWorkletModule, analyserNodeConstructor, audioBufferConstructor, audioBufferSourceNodeConstructor, biquadFilterNodeConstructor, channelMergerNodeConstructor, channelSplitterNodeConstructor, constantSourceNodeConstructor, convolverNodeConstructor, decodeAudioData, delayNodeConstructor, dynamicsCompressorNodeConstructor, gainNodeConstructor, iIRFilterNodeConstructor, minimalBaseAudioContextConstructor, oscillatorNodeConstructor, pannerNodeConstructor, periodicWaveConstructor, stereoPannerNodeConstructor, waveShaperNodeConstructor ) => { return class BaseAudioContext extends minimalBaseAudioContextConstructor implements IBaseAudioContext { private _audioWorklet: undefined | IAudioWorklet; constructor(private _nativeContext: TNativeContext, numberOfChannels: number) { super(_nativeContext, numberOfChannels); this._audioWorklet = addAudioWorkletModule === undefined ? undefined : { addModule: (moduleURL: string, options?: IWorkletOptions) => { return addAudioWorkletModule((this), moduleURL, options); } }; } get audioWorklet(): undefined | IAudioWorklet { return this._audioWorklet; } public createAnalyser(): IAnalyserNode { return new analyserNodeConstructor((this)); } public createBiquadFilter(): IBiquadFilterNode { return new biquadFilterNodeConstructor((this)); } public createBuffer(numberOfChannels: number, length: number, sampleRate: number): IAudioBuffer { return new audioBufferConstructor({ length, numberOfChannels, sampleRate }); } public createBufferSource(): IAudioBufferSourceNode { return new audioBufferSourceNodeConstructor((this)); } public createChannelMerger(numberOfInputs = 6): IAudioNode { return new channelMergerNodeConstructor((this), { numberOfInputs }); } public createChannelSplitter(numberOfOutputs = 6): IAudioNode { return new channelSplitterNodeConstructor((this), { numberOfOutputs }); } public createConstantSource(): IConstantSourceNode { return new constantSourceNodeConstructor((this)); } public createConvolver(): IConvolverNode { return new convolverNodeConstructor((this)); } public createDelay(maxDelayTime = 1): IDelayNode { return new delayNodeConstructor((this), { maxDelayTime }); } public createDynamicsCompressor(): IDynamicsCompressorNode { return new dynamicsCompressorNodeConstructor((this)); } public createGain(): IGainNode { return new gainNodeConstructor((this)); } public createIIRFilter(feedforward: Iterable, feedback: Iterable): IIIRFilterNode { return new iIRFilterNodeConstructor((this), { feedback, feedforward }); } public createOscillator(): IOscillatorNode { return new oscillatorNodeConstructor((this)); } public createPanner(): IPannerNode { return new pannerNodeConstructor((this)); } public createPeriodicWave( real: Iterable, imag: Iterable, constraints: Partial = { disableNormalization: false } ): IPeriodicWave { return new periodicWaveConstructor((this), { ...constraints, imag, real }); } public createStereoPanner(): IStereoPannerNode { return new stereoPannerNodeConstructor((this)); } public createWaveShaper(): IWaveShaperNode { return new waveShaperNodeConstructor((this)); } public decodeAudioData( audioData: ArrayBuffer, successCallback?: TDecodeSuccessCallback, errorCallback?: TDecodeErrorCallback ): Promise { return decodeAudioData(this._nativeContext, audioData).then( (audioBuffer) => { if (typeof successCallback === 'function') { successCallback(audioBuffer); } return audioBuffer; }, (err) => { if (typeof errorCallback === 'function') { errorCallback(err); } throw err; } ); } }; };