react-native-audio-api
Version:
react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification
1,231 lines (1,036 loc) • 31.3 kB
text/typescript
import {
AudioContextOptions,
AudioRecorderCallbackOptions,
AudioRecorderFileOptions,
AudioRecorderStartOptions,
AudioWorkletRuntime,
BiquadFilterType,
ChannelCountMode,
ChannelInterpretation,
ContextState,
FileDirectory,
FileFormat,
FileInfo,
FilePresetType,
OfflineAudioContextOptions,
OscillatorType,
OverSampleType,
Result,
AnalyserOptions,
AudioBufferSourceOptions,
BaseAudioBufferSourceOptions,
BiquadFilterOptions,
ConstantSourceOptions,
ConvolverOptions,
DelayOptions,
DecodeDataInput,
GainOptions,
OscillatorOptions,
PeriodicWaveOptions,
StereoPannerOptions,
StreamerOptions,
WaveShaperOptions,
} from '../types';
/* eslint-disable no-useless-constructor */
const noop = () => {};
class MockEventSubscription {
public subscriptionId: string = Number(1).toString();
remove = noop;
}
class MockAudioEventEmitter {
private listeners: {
[event: string]: Array<
(event: Partial<Record<string, unknown>> | undefined) => void
>;
} = {};
addAudioEventListener(
event: string,
callback: (event: Partial<Record<string, unknown>> | undefined) => void
): MockEventSubscription {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event].push(callback);
const subscription = new MockEventSubscription();
subscription.remove = () => {
const index = this.listeners[event]?.indexOf(callback);
if (index && index > -1) {
this.listeners[event].splice(index, 1);
}
};
return subscription;
}
emit(event: string, data: Record<string, unknown>): void {
this.listeners[event]?.forEach((callback) => callback(data));
}
}
class AudioParamMock {
private _value: number = 0;
public defaultValue: number = 0;
public minValue: number = -3.4028235e38;
public maxValue: number = 3.4028235e38;
constructor(_audioParam: unknown, _context: BaseAudioContextMock) {}
get value(): number {
return this._value;
}
set value(newValue: number) {
this._value = newValue;
}
public setValueAtTime(value: number, _startTime: number): AudioParamMock {
this._value = value;
return this;
}
public linearRampToValueAtTime(
value: number,
_endTime: number
): AudioParamMock {
this._value = value;
return this;
}
public exponentialRampToValueAtTime(
value: number,
_endTime: number
): AudioParamMock {
this._value = value;
return this;
}
public setTargetAtTime(
target: number,
_startTime: number,
_timeConstant: number
): AudioParamMock {
this._value = target;
return this;
}
public setValueCurveAtTime(
_values: Float32Array,
_startTime: number,
_duration: number
): AudioParamMock {
return this;
}
public cancelScheduledValues(_startTime: number): AudioParamMock {
return this;
}
public cancelAndHoldAtTime(_startTime: number): AudioParamMock {
return this;
}
}
class AudioBufferMock {
public sampleRate: number;
public length: number;
public duration: number;
public numberOfChannels: number;
constructor(options: {
numberOfChannels: number;
length: number;
sampleRate: number;
}) {
this.numberOfChannels = options.numberOfChannels;
this.length = options.length;
this.sampleRate = options.sampleRate;
this.duration = options.length / options.sampleRate;
}
getChannelData(_channel: number): Float32Array {
return new Float32Array(this.length);
}
copyFromChannel(
_destination: Float32Array,
_channelNumber: number,
_startInChannel?: number
): void {}
copyToChannel(
_source: Float32Array,
_channelNumber: number,
_startInChannel?: number
): void {}
}
class AudioNodeMock {
public context: BaseAudioContextMock;
public numberOfInputs: number = 1;
public numberOfOutputs: number = 1;
public channelCount: number = 2;
public channelCountMode: ChannelCountMode = 'max';
public channelInterpretation: ChannelInterpretation = 'speakers';
constructor(context: BaseAudioContextMock, _node: unknown) {
this.context = context;
}
public connect(
destination: AudioNodeMock | AudioParamMock
): AudioNodeMock | void {
if (destination instanceof AudioParamMock) {
return;
}
return destination;
}
public disconnect(_destination?: AudioNodeMock): void {}
}
class AudioScheduledSourceNodeMock extends AudioNodeMock {
private _onended: ((event: Event) => void) | null = null;
constructor(context: BaseAudioContextMock, node: unknown) {
super(context, node);
}
public start(_when: number = 0): void {}
public stop(_when: number = 0): void {}
public get onended(): ((event: Event) => void) | null {
return this._onended;
}
public set onended(callback: ((event: Event) => void) | null) {
this._onended = callback;
}
}
class AnalyserNodeMock extends AudioNodeMock {
public fftSize: number = 2048;
public frequencyBinCount: number = 1024;
public minDecibels: number = -100;
public maxDecibels: number = -30;
public smoothingTimeConstant: number = 0.8;
constructor(context: BaseAudioContextMock, _options?: AnalyserOptions) {
super(context, {});
}
getByteFrequencyData(_array: Uint8Array): void {}
getByteTimeDomainData(_array: Uint8Array): void {}
getFloatFrequencyData(_array: Float32Array): void {}
getFloatTimeDomainData(_array: Float32Array): void {}
}
class GainNodeMock extends AudioNodeMock {
readonly gain: AudioParamMock;
constructor(context: BaseAudioContextMock, _options?: GainOptions) {
super(context, {});
this.gain = new AudioParamMock({}, context);
this.gain.value = 1;
}
}
class DelayNodeMock extends AudioNodeMock {
readonly delayTime: AudioParamMock;
constructor(context: BaseAudioContextMock, _options?: DelayOptions) {
super(context, {});
this.delayTime = new AudioParamMock({}, context);
this.delayTime.maxValue = 1;
}
}
class BiquadFilterNodeMock extends AudioNodeMock {
private _type: BiquadFilterType = 'lowpass';
readonly frequency: AudioParamMock;
readonly detune: AudioParamMock;
readonly Q: AudioParamMock;
readonly gain: AudioParamMock;
constructor(context: BaseAudioContextMock, _options?: BiquadFilterOptions) {
super(context, {});
this.frequency = new AudioParamMock({}, context);
this.detune = new AudioParamMock({}, context);
this.Q = new AudioParamMock({}, context);
this.gain = new AudioParamMock({}, context);
this.frequency.value = 350;
this.Q.value = 1;
this.gain.value = 0;
}
get type(): BiquadFilterType {
return this._type;
}
set type(value: BiquadFilterType) {
this._type = value;
}
getFrequencyResponse(
_frequencyHz: Float32Array,
_magResponse: Float32Array,
_phaseResponse: Float32Array
): void {}
}
class ConvolverNodeMock extends AudioNodeMock {
private _buffer: AudioBufferMock | null = null;
public normalize: boolean = true;
constructor(context: BaseAudioContextMock, _options?: ConvolverOptions) {
super(context, {});
}
get buffer(): AudioBufferMock | null {
return this._buffer;
}
set buffer(value: AudioBufferMock | null) {
this._buffer = value;
}
}
class WaveShaperNodeMock extends AudioNodeMock {
private _curve: Float32Array | null = null;
private _oversample: OverSampleType = 'none';
constructor(context: BaseAudioContextMock, _options?: WaveShaperOptions) {
super(context, {});
}
get curve(): Float32Array | null {
return this._curve;
}
set curve(value: Float32Array | null) {
this._curve = value;
}
get oversample(): OverSampleType {
return this._oversample;
}
set oversample(value: OverSampleType) {
this._oversample = value;
}
}
class StereoPannerNodeMock extends AudioNodeMock {
readonly pan: AudioParamMock;
constructor(context: BaseAudioContextMock, _options?: StereoPannerOptions) {
super(context, {});
this.pan = new AudioParamMock({}, context);
}
}
class OscillatorNodeMock extends AudioScheduledSourceNodeMock {
private _type: OscillatorType = 'sine';
readonly frequency: AudioParamMock;
readonly detune: AudioParamMock;
constructor(context: BaseAudioContextMock, _options?: OscillatorOptions) {
super(context, {});
this.frequency = new AudioParamMock({}, context);
this.detune = new AudioParamMock({}, context);
this.frequency.value = 440;
}
get type(): OscillatorType {
return this._type;
}
set type(value: OscillatorType) {
this._type = value;
}
public setPeriodicWave(_wave: PeriodicWaveMock): void {}
}
class ConstantSourceNodeMock extends AudioScheduledSourceNodeMock {
readonly offset: AudioParamMock;
constructor(context: BaseAudioContextMock, _options?: ConstantSourceOptions) {
super(context, {});
this.offset = new AudioParamMock({}, context);
this.offset.value = 1;
}
}
class AudioBufferSourceNodeMock extends AudioScheduledSourceNodeMock {
private _buffer: AudioBufferMock | null = null;
private _loop: boolean = false;
private _loopStart: number = 0;
private _loopEnd: number = 0;
readonly playbackRate: AudioParamMock;
constructor(
context: BaseAudioContextMock,
_options?: AudioBufferSourceOptions
) {
super(context, {});
this.playbackRate = new AudioParamMock({}, context);
this.playbackRate.value = 1;
}
get buffer(): AudioBufferMock | null {
return this._buffer;
}
set buffer(value: AudioBufferMock | null) {
this._buffer = value;
}
get loop(): boolean {
return this._loop;
}
set loop(value: boolean) {
this._loop = value;
}
get loopStart(): number {
return this._loopStart;
}
set loopStart(value: number) {
this._loopStart = value;
}
get loopEnd(): number {
return this._loopEnd;
}
set loopEnd(value: number) {
this._loopEnd = value;
}
}
class RecorderAdapterNodeMock extends AudioNodeMock {
public wasConnected: boolean = false;
constructor(context: BaseAudioContextMock) {
super(context, {});
}
getNode(): Record<string, unknown> {
return {};
}
}
class AudioBufferQueueSourceNodeMock extends AudioScheduledSourceNodeMock {
private _onBufferEnded: ((event: { bufferId: string }) => void) | null = null;
private eventEmitter = new MockAudioEventEmitter();
constructor(
context: BaseAudioContextMock,
_options?: BaseAudioBufferSourceOptions
) {
super(context, {});
}
enqueueBuffer(_buffer: AudioBufferMock): string {
return Math.random().toString(36).substr(2, 9);
}
dequeueBuffer(_bufferId: string): void {}
clearBuffers(): void {}
pause(): void {}
get onBufferEnded(): ((event: { bufferId: string }) => void) | null {
return this._onBufferEnded;
}
set onBufferEnded(callback: ((event: { bufferId: string }) => void) | null) {
this._onBufferEnded = callback;
}
}
class StreamerNodeMock extends AudioScheduledSourceNodeMock {
readonly streamPath: string = '';
constructor(context: BaseAudioContextMock, options: StreamerOptions) {
super(context, options);
this.streamPath = options.streamPath;
}
pause(): void {}
resume(): void {}
}
class MediaElementAudioSourceNodeMock extends AudioNodeMock {
readonly mediaElement: HTMLMediaElement | AudioNodeMock;
constructor(
context: BaseAudioContextMock,
mediaElement: HTMLMediaElement | AudioNodeMock
) {
super(context, {});
this.mediaElement = mediaElement;
this.numberOfInputs = 0;
}
}
class WorkletNodeMock extends AudioNodeMock {
constructor(
context: BaseAudioContextMock,
_runtime: AudioWorkletRuntime,
_callback: (audioData: Array<Float32Array>, channelCount: number) => void,
_bufferLength: number,
_inputChannelCount: number
) {
super(context, {});
}
}
class WorkletProcessingNodeMock extends AudioNodeMock {
constructor(
context: BaseAudioContextMock,
_runtime: AudioWorkletRuntime,
_callback: (
inputData: Array<Float32Array>,
outputData: Array<Float32Array>,
framesToProcess: number,
currentTime: number
) => void
) {
super(context, {});
}
}
class WorkletSourceNodeMock extends AudioScheduledSourceNodeMock {
constructor(
context: BaseAudioContextMock,
_runtime: AudioWorkletRuntime,
_callback: (
audioData: Array<Float32Array>,
framesToProcess: number,
currentTime: number,
startOffset: number
) => void
) {
super(context, {});
}
}
class PeriodicWaveMock {
constructor(_context: BaseAudioContextMock, _options?: PeriodicWaveOptions) {}
}
class AudioDestinationNodeMock extends AudioNodeMock {
public maxChannelCount: number = 2;
constructor(context: BaseAudioContextMock) {
super(context, {});
this.numberOfOutputs = 0;
}
}
class BaseAudioContextMock {
public destination: AudioDestinationNodeMock;
private _sampleRate: number = 44100;
private _currentTime: number = 0;
protected _state: ContextState = 'running';
constructor(options?: AudioContextOptions) {
this.destination = new AudioDestinationNodeMock(this);
if (options?.sampleRate) {
this._sampleRate = options.sampleRate;
}
}
get currentTime(): number {
return this._currentTime;
}
get sampleRate(): number {
return this._sampleRate;
}
get state(): ContextState {
return this._state;
}
createBuffer(
numberOfChannels: number,
length: number,
sampleRate: number
): AudioBufferMock {
return new AudioBufferMock({ numberOfChannels, length, sampleRate });
}
createPeriodicWave(
_real?: Float32Array,
_imag?: Float32Array,
_constraints?: { disableNormalization?: boolean }
): PeriodicWaveMock {
return new PeriodicWaveMock(this);
}
decodeAudioData(_audioData: ArrayBuffer): Promise<AudioBufferMock> {
return Promise.resolve(
new AudioBufferMock({
numberOfChannels: 2,
length: 44100,
sampleRate: 44100,
})
);
}
createAnalyser(options?: AnalyserOptions): AnalyserNodeMock {
return new AnalyserNodeMock(this, options);
}
createBiquadFilter(options?: BiquadFilterOptions): BiquadFilterNodeMock {
return new BiquadFilterNodeMock(this, options);
}
createBufferSource(
options?: AudioBufferSourceOptions
): AudioBufferSourceNodeMock {
return new AudioBufferSourceNodeMock(this, options);
}
createChannelMerger(_numberOfInputs?: number): AudioNodeMock {
return new AudioNodeMock(this, {});
}
createChannelSplitter(_numberOfOutputs?: number): AudioNodeMock {
return new AudioNodeMock(this, {});
}
createConstantSource(
options?: ConstantSourceOptions
): ConstantSourceNodeMock {
return new ConstantSourceNodeMock(this, options);
}
createConvolver(options?: ConvolverOptions): ConvolverNodeMock {
return new ConvolverNodeMock(this, options);
}
createDelay(options?: DelayOptions): DelayNodeMock {
return new DelayNodeMock(this, options);
}
createGain(options?: GainOptions): GainNodeMock {
return new GainNodeMock(this, options);
}
createOscillator(options?: OscillatorOptions): OscillatorNodeMock {
return new OscillatorNodeMock(this, options);
}
createStereoPanner(options?: StereoPannerOptions): StereoPannerNodeMock {
return new StereoPannerNodeMock(this, options);
}
createWaveShaper(options?: WaveShaperOptions): WaveShaperNodeMock {
return new WaveShaperNodeMock(this, options);
}
createRecorderAdapter(): RecorderAdapterNodeMock {
return new RecorderAdapterNodeMock(this);
}
createBufferQueueSource(
options?: BaseAudioBufferSourceOptions
): AudioBufferQueueSourceNodeMock {
return new AudioBufferQueueSourceNodeMock(this, options);
}
createStreamer(options: StreamerOptions): StreamerNodeMock {
return new StreamerNodeMock(this, options);
}
createWorkletNode(
_shareableWorklet: Record<string, unknown>,
_runOnUI: boolean,
_bufferLength: number,
_inputChannelCount: number
): WorkletNodeMock {
return new WorkletNodeMock(this, 'AudioRuntime', noop, 0, 0);
}
createWorkletProcessingNode(
_shareableWorklet: Record<string, unknown>,
_runOnUI: boolean
): WorkletProcessingNodeMock {
return new WorkletProcessingNodeMock(this, 'AudioRuntime', noop);
}
createWorkletSourceNode(
_shareableWorklet: Record<string, unknown>,
_runOnUI: boolean
): WorkletSourceNodeMock {
return new WorkletSourceNodeMock(this, 'AudioRuntime', noop);
}
}
class AudioContextMock extends BaseAudioContextMock {
constructor(options?: AudioContextOptions) {
super(options);
}
close(): Promise<void> {
this._state = 'closed';
return Promise.resolve();
}
resume(): Promise<void> {
this._state = 'running';
return Promise.resolve();
}
suspend(): Promise<void> {
this._state = 'suspended';
return Promise.resolve();
}
createMediaElementSource(
mediaElement: HTMLMediaElement | AudioNodeMock
): MediaElementAudioSourceNodeMock {
return new MediaElementAudioSourceNodeMock(this, mediaElement);
}
}
class OfflineAudioContextMock extends BaseAudioContextMock {
public length: number;
constructor(options: OfflineAudioContextOptions) {
super({ sampleRate: options.sampleRate });
this.length = options.length;
}
startRendering(): Promise<AudioBufferMock> {
return Promise.resolve(
new AudioBufferMock({
numberOfChannels: 2,
length: this.length,
sampleRate: this.sampleRate,
})
);
}
}
class AudioRecorderMock {
private _isRecording: boolean = false;
private _isPaused: boolean = false;
private _currentDuration: number = 0;
private _options: AudioRecorderFileOptions | null = null;
private isFileOutputEnabled: boolean = false;
private eventEmitter = new MockAudioEventEmitter();
private onAudioReadySubscription: MockEventSubscription | null = null;
private onErrorSubscription: MockEventSubscription | null = null;
constructor() {}
enableFileOutput(
options?: AudioRecorderFileOptions
): Result<{ path: string }> {
this._options = options || {};
this.isFileOutputEnabled = true;
return { status: 'success', path: '/mock/path/recordings' };
}
get options(): AudioRecorderFileOptions | null {
return this._options;
}
disableFileOutput(): void {
this._options = null;
this.isFileOutputEnabled = false;
}
start(
options?: AudioRecorderStartOptions
): Promise<Result<{ path: string }>> {
this._isRecording = true;
this._isPaused = false;
const path = options?.fileNameOverride || 'recording.m4a';
return Promise.resolve({ status: 'success', path });
}
stop(): Promise<Result<FileInfo>> {
this._isRecording = false;
this._isPaused = false;
this._currentDuration = 0;
return Promise.resolve({
status: 'success',
paths: ['/mock/path/recording.m4a'],
size: 12345,
duration: 5.0,
});
}
pause(): void {
this._isPaused = true;
}
resume(): void {
this._isPaused = false;
}
connect(_node: RecorderAdapterNodeMock): void {
if (_node.wasConnected) {
throw new Error('RecorderAdapterNode cannot be connected more than once');
}
_node.wasConnected = true;
}
disconnect(): void {}
onAudioReady(
_options: AudioRecorderCallbackOptions,
callback: (event: Partial<Record<string, unknown>> | undefined) => void
): Result<{}> {
if (this.onAudioReadySubscription) {
this.onAudioReadySubscription.remove();
}
this.onAudioReadySubscription = this.eventEmitter.addAudioEventListener(
'audioReady',
callback
);
return { status: 'success' };
}
clearOnAudioReady(): void {
if (this.onAudioReadySubscription) {
this.onAudioReadySubscription.remove();
this.onAudioReadySubscription = null;
}
}
isRecording(): boolean {
return this._isRecording;
}
isPaused(): boolean {
return this._isPaused;
}
getCurrentDuration(): number {
return this._currentDuration;
}
onError(
callback: (error: Record<string, unknown> | undefined) => void
): void {
if (this.onErrorSubscription) {
this.onErrorSubscription.remove();
}
this.onErrorSubscription = this.eventEmitter.addAudioEventListener(
'recorderError',
callback
);
}
clearOnError(): void {
if (this.onErrorSubscription) {
this.onErrorSubscription.remove();
this.onErrorSubscription = null;
}
}
}
const decodeAudioData = (_audioData: ArrayBuffer): Promise<AudioBufferMock> => {
return Promise.resolve(
new AudioBufferMock({
numberOfChannels: 2,
length: 44100,
sampleRate: 44100,
})
);
};
const decodePCMInBase64 = (_base64Data: string): Promise<AudioBufferMock> => {
return Promise.resolve(
new AudioBufferMock({
numberOfChannels: 2,
length: 44100,
sampleRate: 44100,
})
);
};
const getAudioDuration = (_input: DecodeDataInput): Promise<number> => {
if (_input instanceof ArrayBuffer) {
return Promise.resolve(1);
}
if (
typeof _input === 'string' &&
_input.startsWith('data:audio/') &&
_input.includes(';base64,')
) {
return Promise.reject(
new AudioApiErrorMock(
'Base64 source decoding is not currently supported, to decode raw PCM base64 strings use decodePCMInBase64 method.'
)
);
}
if (typeof _input === 'string' && _input.startsWith('blob:')) {
return Promise.reject(
new AudioApiErrorMock(
'Data Blob string decoding is not currently supported.'
)
);
}
return Promise.resolve(1);
};
const changePlaybackSpeed = (
buffer: AudioBufferMock,
_speed: number
): Promise<AudioBufferMock> => {
return Promise.resolve(buffer);
};
const concatAudioFiles = (
inputPaths: string[],
outputPath: string
): Promise<string> => {
if (!Array.isArray(inputPaths) || inputPaths.length === 0) {
return Promise.reject(
new AudioApiErrorMock(
'concatAudioFiles requires at least one input path.'
)
);
}
if (inputPaths.some((inputPath) => typeof inputPath !== 'string')) {
return Promise.reject(
new TypeError('concatAudioFiles input paths must be strings.')
);
}
if (typeof outputPath !== 'string' || outputPath.length === 0) {
return Promise.reject(
new AudioApiErrorMock('concatAudioFiles requires an output path.')
);
}
return Promise.resolve(outputPath);
};
const isFfmpegEnabled = (): boolean => true;
class AudioManagerMock {
static getDevicePreferredSampleRate(): number {
return 44100;
}
static observeVolumeChanges(_observe: boolean): void {}
static addSystemEventListener(
_event: string,
_callback: (event: { value: number }) => void
): { remove: () => void } {
return { remove: noop };
}
static removeSystemEventListener(_listener: { remove: () => void }): void {}
}
class NotificationManagerMock {
static create(_options: Record<string, unknown>): {
update: () => void;
destroy: () => void;
} {
return {
update: noop,
destroy: noop,
};
}
}
class PlaybackNotificationManagerMock {
static create(_options: Record<string, unknown>): {
update: () => void;
destroy: () => void;
} {
return {
update: noop,
destroy: noop,
};
}
}
class RecordingNotificationManagerMock {
static create(_options: Record<string, unknown>): {
update: () => void;
destroy: () => void;
} {
return {
update: noop,
destroy: noop,
};
}
}
let mockSystemVolumeValue = 0.5;
const useSystemVolume = (): number => mockSystemVolumeValue;
const setMockSystemVolume = (volume: number): void => {
mockSystemVolumeValue = volume;
};
class FilePresetMock {
static get Low(): FilePresetType {
return {} as FilePresetType;
}
static get Medium(): FilePresetType {
return {} as FilePresetType;
}
static get High(): FilePresetType {
return {} as FilePresetType;
}
static get Lossless(): FilePresetType {
return {} as FilePresetType;
}
}
class NotSupportedErrorMock extends Error {
constructor(message: string) {
super(message);
this.name = 'NotSupportedError';
}
}
class InvalidAccessErrorMock extends Error {
constructor(message: string) {
super(message);
this.name = 'InvalidAccessError';
}
}
class InvalidStateErrorMock extends Error {
constructor(message: string) {
super(message);
this.name = 'InvalidStateError';
}
}
class IndexSizeErrorMock extends Error {
constructor(message: string) {
super(message);
this.name = 'IndexSizeError';
}
}
class RangeErrorMock extends Error {
constructor(message: string) {
super(message);
this.name = 'RangeError';
}
}
class AudioApiErrorMock extends Error {
constructor(message: string) {
super(message);
this.name = 'AudioApiError';
}
}
// Export classes with original API names (for compatibility)
export const AnalyserNode = AnalyserNodeMock;
export const AudioBuffer = AudioBufferMock;
export const AudioBufferQueueSourceNode = AudioBufferQueueSourceNodeMock;
export const AudioBufferSourceNode = AudioBufferSourceNodeMock;
export const AudioContext = AudioContextMock;
export const AudioDestinationNode = AudioDestinationNodeMock;
export const AudioNode = AudioNodeMock;
export const AudioParam = AudioParamMock;
export const AudioRecorder = AudioRecorderMock;
export const AudioScheduledSourceNode = AudioScheduledSourceNodeMock;
export const BaseAudioContext = BaseAudioContextMock;
export const BiquadFilterNode = BiquadFilterNodeMock;
export const ConstantSourceNode = ConstantSourceNodeMock;
export const ConvolverNode = ConvolverNodeMock;
export const DelayNode = DelayNodeMock;
export const GainNode = GainNodeMock;
export const MediaElementAudioSourceNode = MediaElementAudioSourceNodeMock;
export const OfflineAudioContext = OfflineAudioContextMock;
export const OscillatorNode = OscillatorNodeMock;
export const RecorderAdapterNode = RecorderAdapterNodeMock;
export const StereoPannerNode = StereoPannerNodeMock;
export const StreamerNode = StreamerNodeMock;
export const WaveShaperNode = WaveShaperNodeMock;
export const WorkletNode = WorkletNodeMock;
export const WorkletProcessingNode = WorkletProcessingNodeMock;
export const WorkletSourceNode = WorkletSourceNodeMock;
export const PeriodicWave = PeriodicWaveMock;
export const AudioManager = AudioManagerMock;
export const NotificationManager = NotificationManagerMock;
export const PlaybackNotificationManager = PlaybackNotificationManagerMock;
export const RecordingNotificationManager = RecordingNotificationManagerMock;
export const FilePreset = FilePresetMock;
export const NotSupportedError = NotSupportedErrorMock;
export const InvalidAccessError = InvalidAccessErrorMock;
export const InvalidStateError = InvalidStateErrorMock;
export const IndexSizeError = IndexSizeErrorMock;
export const RangeError = RangeErrorMock;
export const AudioApiError = AudioApiErrorMock;
// Export functions
export {
concatAudioFiles,
decodeAudioData,
decodePCMInBase64,
getAudioDuration,
isFfmpegEnabled,
setMockSystemVolume,
useSystemVolume,
};
// Type exports to allow using classes as types
export type AnalyserNode = AnalyserNodeMock;
export type AudioBuffer = AudioBufferMock;
export type AudioBufferQueueSourceNode = AudioBufferQueueSourceNodeMock;
export type AudioBufferSourceNode = AudioBufferSourceNodeMock;
export type AudioContext = AudioContextMock;
export type AudioDestinationNode = AudioDestinationNodeMock;
export type AudioNode = AudioNodeMock;
export type AudioParam = AudioParamMock;
export type AudioRecorder = AudioRecorderMock;
export type AudioScheduledSourceNode = AudioScheduledSourceNodeMock;
export type BaseAudioContext = BaseAudioContextMock;
export type BiquadFilterNode = BiquadFilterNodeMock;
export type ConstantSourceNode = ConstantSourceNodeMock;
export type ConvolverNode = ConvolverNodeMock;
export type DelayNode = DelayNodeMock;
export type GainNode = GainNodeMock;
export type MediaElementAudioSourceNode = MediaElementAudioSourceNodeMock;
export type OfflineAudioContext = OfflineAudioContextMock;
export type OscillatorNode = OscillatorNodeMock;
export type RecorderAdapterNode = RecorderAdapterNodeMock;
export type StereoPannerNode = StereoPannerNodeMock;
export type StreamerNode = StreamerNodeMock;
export type WaveShaperNode = WaveShaperNodeMock;
export type WorkletNode = WorkletNodeMock;
export type WorkletProcessingNode = WorkletProcessingNodeMock;
export type WorkletSourceNode = WorkletSourceNodeMock;
export type PeriodicWave = PeriodicWaveMock;
// Export types and enums
export {
AudioContextOptions,
AudioRecorderCallbackOptions,
AudioRecorderFileOptions,
AudioRecorderStartOptions,
AudioWorkletRuntime,
BiquadFilterType,
ChannelCountMode,
ChannelInterpretation,
ContextState,
FileDirectory,
FileFormat,
FileInfo,
FilePresetType,
OfflineAudioContextOptions,
OscillatorType,
OverSampleType,
Result,
AnalyserOptions,
AudioBufferSourceOptions,
BaseAudioBufferSourceOptions,
BiquadFilterOptions,
ConstantSourceOptions,
ConvolverOptions,
DelayOptions,
GainOptions,
OscillatorOptions,
PeriodicWaveOptions,
StereoPannerOptions,
StreamerOptions,
WaveShaperOptions,
};
export default {
AnalyserNode: AnalyserNodeMock,
AudioBuffer: AudioBufferMock,
AudioBufferQueueSourceNode: AudioBufferQueueSourceNodeMock,
AudioBufferSourceNode: AudioBufferSourceNodeMock,
AudioContext: AudioContextMock,
AudioDestinationNode: AudioDestinationNodeMock,
AudioNode: AudioNodeMock,
AudioParam: AudioParamMock,
AudioRecorder: AudioRecorderMock,
AudioScheduledSourceNode: AudioScheduledSourceNodeMock,
BaseAudioContext: BaseAudioContextMock,
BiquadFilterNode: BiquadFilterNodeMock,
ConstantSourceNode: ConstantSourceNodeMock,
ConvolverNode: ConvolverNodeMock,
DelayNode: DelayNodeMock,
GainNode: GainNodeMock,
MediaElementAudioSourceNode: MediaElementAudioSourceNodeMock,
OfflineAudioContext: OfflineAudioContextMock,
OscillatorNode: OscillatorNodeMock,
RecorderAdapterNode: RecorderAdapterNodeMock,
StereoPannerNode: StereoPannerNodeMock,
StreamerNode: StreamerNodeMock,
WaveShaperNode: WaveShaperNodeMock,
WorkletNode: WorkletNodeMock,
WorkletProcessingNode: WorkletProcessingNodeMock,
WorkletSourceNode: WorkletSourceNodeMock,
PeriodicWave: PeriodicWaveMock,
// Functions
decodeAudioData,
decodePCMInBase64,
getAudioDuration,
changePlaybackSpeed,
concatAudioFiles,
isFfmpegEnabled,
useSystemVolume,
setMockSystemVolume,
// System classes
AudioManager: AudioManagerMock,
NotificationManager: NotificationManagerMock,
PlaybackNotificationManager: PlaybackNotificationManagerMock,
RecordingNotificationManager: RecordingNotificationManagerMock,
// Utils
FilePreset: FilePresetMock,
// Errors
NotSupportedError: NotSupportedErrorMock,
InvalidAccessError: InvalidAccessErrorMock,
InvalidStateError: InvalidStateErrorMock,
IndexSizeError: IndexSizeErrorMock,
RangeError: RangeErrorMock,
AudioApiError: AudioApiErrorMock,
// Enums
FileDirectory,
FileFormat,
};