react-native-audio-api
Version:
react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification
404 lines (342 loc) • 11.6 kB
text/typescript
import { AudioEventCallback, AudioEventName } from './events/types';
import type {
AnalyserOptions,
AudioBufferSourceOptions,
AudioRecorderCallbackOptions,
AudioRecorderFileOptions,
AutomationEventData,
BaseAudioBufferSourceOptions,
BiquadFilterOptions,
BiquadFilterType,
ChannelCountMode,
ChannelInterpretation,
ConstantSourceOptions,
ConvolverOptions,
ContextState,
DelayOptions,
FileInfo,
GainOptions,
IIRFilterOptions,
OscillatorOptions,
OscillatorType,
OverSampleType,
Result,
StereoPannerOptions,
StreamerOptions,
WaveShaperOptions,
AudioFileSourceOptions,
} from './types';
// IMPORTANT: use only IClass, because it is a part of contract between cpp host object and js layer
export type WorkletNodeCallback = (
audioData: Array<ArrayBuffer>,
channelCount: number
) => void;
export type WorkletSourceNodeCallback = (
audioData: Array<ArrayBuffer>,
framesToProcess: number,
currentTime: number,
startOffset: number
) => void;
export type WorkletProcessingNodeCallback = (
inputData: Array<ArrayBuffer>,
outputData: Array<ArrayBuffer>,
framesToProcess: number,
currentTime: number
) => void;
export type ShareableWorkletCallback =
| WorkletNodeCallback
| WorkletSourceNodeCallback
| WorkletProcessingNodeCallback;
export interface IBaseAudioContext {
readonly destination: IAudioDestinationNode;
readonly state: ContextState;
readonly sampleRate: number;
readonly currentTime: number;
readonly decoder: IAudioDecoder;
createRecorderAdapter(): IRecorderAdapterNode;
createWorkletSourceNode(
shareableWorklet: ShareableWorkletCallback,
shouldUseUiRuntime: boolean
): IWorkletSourceNode;
createWorkletNode(
shareableWorklet: ShareableWorkletCallback,
shouldUseUiRuntime: boolean,
bufferLength: number,
inputChannelCount: number
): IWorkletNode;
createWorkletProcessingNode(
shareableWorklet: ShareableWorkletCallback,
shouldUseUiRuntime: boolean
): IWorkletProcessingNode;
createOscillator(oscillatorOptions: OscillatorOptions): IOscillatorNode;
createConstantSource(
constantSourceOptions: ConstantSourceOptions
): IConstantSourceNode;
createGain(gainOptions: GainOptions): IGainNode;
createStereoPanner(
stereoPannerOptions: StereoPannerOptions
): IStereoPannerNode;
createBiquadFilter: (
biquadFilterOptions: BiquadFilterOptions
) => IBiquadFilterNode;
createBufferSource: (
audioBufferSourceOptions: AudioBufferSourceOptions
) => IAudioBufferSourceNode;
createDelay(delayOptions: DelayOptions): IDelayNode;
createIIRFilter: (IIRFilterOptions: IIRFilterOptions) => IIIRFilterNode;
createBufferQueueSource: (
audioBufferQueueSourceOptions: BaseAudioBufferSourceOptions
) => IAudioBufferQueueSourceNode;
createPeriodicWave: (
real: Float32Array,
imag: Float32Array,
disableNormalization: boolean
) => IPeriodicWave;
createAnalyser: (analyserOptions: AnalyserOptions) => IAnalyserNode;
createConvolver: (convolverOptions: ConvolverOptions) => IConvolverNode;
createStreamer: (streamerOptions: StreamerOptions) => IStreamerNode | null; // null when FFmpeg is not enabled
createWaveShaper: (waveShaperOptions: WaveShaperOptions) => IWaveShaperNode;
createFileSource: (
audioFileOptions: AudioFileSourceOptions
) => IAudioFileSourceNode | null; // null when FFmpeg is not enabled, but needed
}
export interface IAudioContext extends IBaseAudioContext {
createMediaElementSource: (
mediaElement: IAudioFileSourceNode
) => IMediaElementAudioSourceNode;
close(): Promise<void>;
resume(): Promise<void>;
suspend(): Promise<void>;
}
export interface IOfflineAudioContext extends IBaseAudioContext {
resume(): Promise<void>;
suspend(suspendTime: number): Promise<void>;
startRendering(): Promise<IAudioBuffer>;
}
export interface IAudioNode {
readonly context: BaseAudioContext;
readonly numberOfInputs: number;
readonly numberOfOutputs: number;
readonly channelCount: number;
readonly channelCountMode: ChannelCountMode;
readonly channelInterpretation: ChannelInterpretation;
connect: (destination: IAudioNode | IAudioParam) => void;
disconnect: (destination?: IAudioNode | IAudioParam) => void;
}
export interface IDelayNode extends IAudioNode {
readonly delayTime: IAudioParam;
maxDelayTime: number;
}
export interface IGainNode extends IAudioNode {
readonly gain: IAudioParam;
}
export interface IStereoPannerNode extends IAudioNode {
readonly pan: IAudioParam;
}
export interface IBiquadFilterNode extends IAudioNode {
readonly frequency: IAudioParam;
readonly detune: IAudioParam;
readonly Q: IAudioParam;
readonly gain: IAudioParam;
type: BiquadFilterType;
getFrequencyResponse(
frequencyArray: Float32Array,
magResponseOutput: Float32Array,
phaseResponseOutput: Float32Array
): void;
}
export interface IIIRFilterNode extends IAudioNode {
getFrequencyResponse(
frequencyArray: Float32Array,
magResponseOutput: Float32Array,
phaseResponseOutput: Float32Array
): void;
}
export interface IAudioDestinationNode extends IAudioNode {}
export interface IAudioScheduledSourceNode extends IAudioNode {
start(when: number): void;
stop: (when: number) => void;
// passing subscriptionId(uint_64 in cpp, string in js) to the cpp
onEnded: string;
}
export interface IAudioBufferBaseSourceNode extends IAudioScheduledSourceNode {
detune: IAudioParam;
playbackRate: IAudioParam;
getInputLatency: () => number;
getOutputLatency: () => number;
// passing subscriptionId(uint_64 in cpp, string in js) to the cpp
onPositionChanged: string;
// set how often the onPositionChanged event is called
onPositionChangedInterval: number;
}
export interface IOscillatorNode extends IAudioScheduledSourceNode {
readonly frequency: IAudioParam;
readonly detune: IAudioParam;
type: OscillatorType;
setPeriodicWave(periodicWave: IPeriodicWave): void;
}
export interface IStreamerNode extends IAudioNode {}
export interface IConstantSourceNode extends IAudioScheduledSourceNode {
readonly offset: IAudioParam;
}
export interface IAudioBufferSourceNode extends IAudioBufferBaseSourceNode {
buffer: IAudioBuffer | null;
loop: boolean;
loopSkip: boolean;
loopStart: number;
loopEnd: number;
start: (when?: number, offset?: number, duration?: number) => void;
setBuffer: (audioBuffer: IAudioBuffer | null) => void;
// passing subscriptionId(uint_64 in cpp, string in js) to the cpp
onLoopEnded: string;
}
export interface IAudioBufferQueueSourceNode extends IAudioBufferBaseSourceNode {
dequeueBuffer: (bufferId: number) => void;
clearBuffers: () => void;
// returns bufferId
enqueueBuffer: (audioBuffer: IAudioBuffer) => string;
start: (when?: number, offset?: number) => void;
pause: () => void;
// passing subscriptionId(uint_64 in cpp, string in js) to the cpp
onBufferEnded: string;
}
export interface IAudioFileSourceNode extends IAudioScheduledSourceNode {
volume?: number;
playbackRate: number;
preservesPitch: boolean;
loop: boolean;
readonly currentTime: number;
readonly duration: number;
readonly routedThroughMediaElement: boolean;
pause: () => void;
seekToTime: (seconds: number) => void;
// passing subscriptionId(uint_64 in cpp, string in js) to the cpp
onPositionChanged: string;
}
export interface IMediaElementAudioSourceNode extends IAudioNode {}
export interface IConvolverNode extends IAudioNode {
readonly buffer: IAudioBuffer | null;
normalize: boolean;
setBuffer: (audioBuffer: IAudioBuffer | null) => void;
}
export interface IAudioBuffer {
readonly length: number;
readonly duration: number;
readonly sampleRate: number;
readonly numberOfChannels: number;
getChannelData(channel: number): Float32Array<ArrayBuffer>;
copyFromChannel(
destination: Float32Array<ArrayBuffer>,
channelNumber: number,
startInChannel: number
): void;
copyToChannel(
source: Float32Array<ArrayBuffer>,
channelNumber: number,
startInChannel: number
): void;
}
export interface IAudioParam {
value: number;
defaultValue: number;
minValue: number;
maxValue: number;
setValueAtTime: (value: number, startTime: number) => void;
linearRampToValueAtTime: (value: number, endTime: number) => void;
exponentialRampToValueAtTime: (value: number, endTime: number) => void;
setTargetAtTime: (
target: number,
startTime: number,
timeConstant: number
) => void;
setValueCurveAtTime: (
values: Float32Array,
startTime: number,
duration: number
) => void;
cancelScheduledValues: (cancelTime: number) => void;
cancelAndHoldAtTime: (cancelTime: number) => void;
checkCurveExclusion: (eventData: AutomationEventData) => Result<void>;
}
export interface IPeriodicWave {}
export interface IAnalyserNode extends IAudioNode {
fftSize: number;
readonly frequencyBinCount: number;
minDecibels: number;
maxDecibels: number;
smoothingTimeConstant: number;
getFloatFrequencyData: (array: Float32Array) => void;
getByteFrequencyData: (array: Uint8Array) => void;
getFloatTimeDomainData: (array: Float32Array) => void;
getByteTimeDomainData: (array: Uint8Array) => void;
}
export interface IRecorderAdapterNode extends IAudioNode {}
export interface IWorkletNode extends IAudioNode {}
export interface IWorkletSourceNode extends IAudioScheduledSourceNode {}
export interface IWorkletProcessingNode extends IAudioNode {}
export interface IWaveShaperNode extends IAudioNode {
readonly curve: Float32Array | null;
oversample: OverSampleType;
setCurve(curve: Float32Array | null): void;
}
export interface IAudioRecorderCallbackOptions extends AudioRecorderCallbackOptions {
callbackId: string;
}
export interface IAudioRecorder {
// default recorder methods
start: (fileNameOverride?: string) => Promise<Result<{}>>;
stop: () => Promise<Result<FileInfo>>;
isRecording: () => boolean;
isPaused: () => boolean;
enableFileOutput: (options: AudioRecorderFileOptions) => Result<{}>;
disableFileOutput: () => void;
// pause and resume methods for file recording
pause: () => void;
resume: () => void;
// Graph integration methods
connect: (node: IRecorderAdapterNode) => void;
disconnect: () => void;
setOnAudioReady: (options: IAudioRecorderCallbackOptions) => Result<void>;
clearOnAudioReady: () => void;
setOnError: (options: { callbackId: string }) => void;
clearOnError: () => void;
getCurrentDuration: () => number;
getFilePath: () => string | null;
}
export interface IAudioDecoder {
decodeWithMemoryBlock: (
arrayBuffer: ArrayBuffer,
sampleRate?: number
) => Promise<IAudioBuffer>;
decodeWithFilePath: (
sourcePath: string,
sampleRate?: number
) => Promise<IAudioBuffer>;
decodeWithPCMInBase64: (
b64: string,
inputSampleRate: number,
inputChannelCount: number,
interleaved?: boolean
) => Promise<IAudioBuffer>;
}
export interface IAudioFileUtils {
concatAudioFiles: (
inputPaths: string[],
outputPath: string
) => Promise<string>;
probeDuration: (
input: ArrayBuffer | string,
sampleRate?: number,
headers?: Record<string, string>
) => Promise<number | null>;
}
export interface IAudioEventEmitter {
addAudioEventListener<Name extends AudioEventName>(
name: Name,
callback: AudioEventCallback<Name>
): string;
removeAudioEventListener<Name extends AudioEventName>(
name: Name,
subscriptionId: string
): void;
}