react-native-audio-api
Version:
react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification
241 lines (210 loc) • 6.89 kB
text/typescript
import {
InvalidAccessError,
InvalidStateError,
NotSupportedError,
} from '../errors';
import { IBaseAudioContext } from '../jsi-interfaces';
import { AudioWorkletRuntime, ContextState, DecodeDataInput } from '../types';
import { assertWorkletsEnabled } from '../utils';
import AnalyserNode from './AnalyserNode';
import AudioBuffer from './AudioBuffer';
import AudioBufferQueueSourceNode from './AudioBufferQueueSourceNode';
import AudioBufferSourceNode from './AudioBufferSourceNode';
import { decodeAudioData, decodePCMInBase64 } from './AudioDecoder';
import AudioDestinationNode from './AudioDestinationNode';
import BiquadFilterNode from './BiquadFilterNode';
import ConstantSourceNode from './ConstantSourceNode';
import ConvolverNode from './ConvolverNode';
import DelayNode from './DelayNode';
import GainNode from './GainNode';
import IIRFilterNode from './IIRFilterNode';
import OscillatorNode from './OscillatorNode';
import PeriodicWave from './PeriodicWave';
import RecorderAdapterNode from './RecorderAdapterNode';
import StereoPannerNode from './StereoPannerNode';
import StreamerNode from './StreamerNode';
import WaveShaperNode from './WaveShaperNode';
import WorkletNode from './WorkletNode';
import WorkletProcessingNode from './WorkletProcessingNode';
import WorkletSourceNode from './WorkletSourceNode';
export default class BaseAudioContext {
readonly destination: AudioDestinationNode;
readonly sampleRate: number;
readonly context: IBaseAudioContext;
constructor(context: IBaseAudioContext) {
this.context = context;
this.destination = new AudioDestinationNode(this, context.destination);
this.sampleRate = context.sampleRate;
}
public get currentTime(): number {
return this.context.currentTime;
}
public get state(): ContextState {
return this.context.state;
}
public async decodeAudioData(
input: DecodeDataInput,
fetchOptions?: RequestInit
): Promise<AudioBuffer> {
return await decodeAudioData(input, this.sampleRate, fetchOptions);
}
public async decodePCMInBase64(
base64String: string,
inputSampleRate: number,
inputChannelCount: number,
isInterleaved: boolean = true
): Promise<AudioBuffer> {
return await decodePCMInBase64(
base64String,
inputSampleRate,
inputChannelCount,
isInterleaved
);
}
createWorkletNode(
callback: (audioData: Array<Float32Array>, channelCount: number) => void,
bufferLength: number,
inputChannelCount: number,
workletRuntime: AudioWorkletRuntime = 'AudioRuntime'
): WorkletNode {
if (inputChannelCount < 1 || inputChannelCount > 32) {
throw new NotSupportedError(
`The number of input channels provided (${inputChannelCount}) can not be less than 1 or greater than 32`
);
}
if (bufferLength < 1) {
throw new NotSupportedError(
`The buffer length provided (${bufferLength}) can not be less than 1`
);
}
assertWorkletsEnabled();
return new WorkletNode(
this,
workletRuntime,
callback,
bufferLength,
inputChannelCount
);
}
createWorkletProcessingNode(
callback: (
inputData: Array<Float32Array>,
outputData: Array<Float32Array>,
framesToProcess: number,
currentTime: number
) => void,
workletRuntime: AudioWorkletRuntime = 'AudioRuntime'
): WorkletProcessingNode {
assertWorkletsEnabled();
return new WorkletProcessingNode(this, workletRuntime, callback);
}
createWorkletSourceNode(
callback: (
audioData: Array<Float32Array>,
framesToProcess: number,
currentTime: number,
startOffset: number
) => void,
workletRuntime: AudioWorkletRuntime = 'AudioRuntime'
): WorkletSourceNode {
assertWorkletsEnabled();
return new WorkletSourceNode(this, workletRuntime, callback);
}
createRecorderAdapter(): RecorderAdapterNode {
return new RecorderAdapterNode(this);
}
createOscillator(): OscillatorNode {
return new OscillatorNode(this);
}
createStreamer(streamPath: string): StreamerNode {
return new StreamerNode(this, { streamPath });
}
createConstantSource(): ConstantSourceNode {
return new ConstantSourceNode(this);
}
createGain(): GainNode {
return new GainNode(this);
}
createDelay(maxDelayTime?: number): DelayNode {
if (maxDelayTime !== undefined) {
return new DelayNode(this, { maxDelayTime });
} else {
return new DelayNode(this);
}
}
createStereoPanner(): StereoPannerNode {
return new StereoPannerNode(this);
}
createBiquadFilter(): BiquadFilterNode {
return new BiquadFilterNode(this);
}
createBufferSource(options?: {
pitchCorrection: boolean;
}): AudioBufferSourceNode {
if (options !== undefined) {
return new AudioBufferSourceNode(this, options);
} else {
return new AudioBufferSourceNode(this);
}
}
createIIRFilter(feedforward: number[], feedback: number[]): IIRFilterNode {
if (feedforward.length < 1 || feedforward.length > 20) {
throw new NotSupportedError(
`The provided feedforward array has length (${feedforward.length}) outside the range [1, 20]`
);
}
if (feedback.length < 1 || feedback.length > 20) {
throw new NotSupportedError(
`The provided feedback array has length (${feedback.length}) outside the range [1, 20]`
);
}
if (feedforward.every((value) => value === 0)) {
throw new InvalidStateError(
`Feedforward array must contain at least one non-zero value`
);
}
if (feedback[0] === 0) {
throw new InvalidStateError(
`First value of feedback array cannot be zero`
);
}
return new IIRFilterNode(this, { feedforward, feedback });
}
createBufferQueueSource(options?: {
pitchCorrection: boolean;
}): AudioBufferQueueSourceNode {
if (options !== undefined) {
return new AudioBufferQueueSourceNode(this, options);
} else {
return new AudioBufferQueueSourceNode(this);
}
}
createBuffer(
numberOfChannels: number,
length: number,
sampleRate: number
): AudioBuffer {
return new AudioBuffer({ numberOfChannels, length, sampleRate });
}
createPeriodicWave(
real: Float32Array,
imag: Float32Array,
constraints?: PeriodicWaveConstraints
): PeriodicWave {
if (real.length !== imag.length) {
throw new InvalidAccessError(
`The lengths of the real (${real.length}) and imaginary (${imag.length}) arrays must match.`
);
}
return new PeriodicWave(this, { real, imag, ...constraints });
}
createAnalyser(): AnalyserNode {
return new AnalyserNode(this);
}
createConvolver(): ConvolverNode {
return new ConvolverNode(this);
}
createWaveShaper(): WaveShaperNode {
return new WaveShaperNode(this);
}
}