Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions apps/common-app/src/demos/PedalBoard/PedalBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,7 @@ export default function PedalBoard() {
} else {
if (!permissionsGranted) {
const recPerm = await AudioManager.requestRecordingPermissions();
const notPerm = await AudioManager.requestNotificationPermissions();
console.log('Recording permission:', recPerm);
// @ts-ignore
permissionsGranted = recPerm === 'Granted' && notPerm === 'granted';
permissionsGranted = recPerm === 'Granted';
}
if (permissionsGranted) {
const recorder = new AudioRecorder();
Expand Down
4 changes: 2 additions & 2 deletions apps/common-app/src/examples/AudioFile/AudioFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ const AudioFile: FC = () => {
elapsedTime: 0,
});
await PlaybackNotificationManager.enableControl('skipBackward', true);
await PlaybackNotificationManager.enableControl('next', true);
await PlaybackNotificationManager.enableControl('nextTrack', true);
await PlaybackNotificationManager.enableControl('skipForward', true);
await PlaybackNotificationManager.enableControl('previous', true);
await PlaybackNotificationManager.enableControl('previousTrack', true);
await PlaybackNotificationManager.enableControl('pause', true);
await PlaybackNotificationManager.enableControl('play', true);
await PlaybackNotificationManager.enableControl('seekTo', true);
Expand Down
9 changes: 2 additions & 7 deletions apps/common-app/src/examples/AudioFile/AudioPlayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AudioPlayer {
this.volumeNode = this.audioContext.createGain();
this.volumeNode.gain.value = this.volume;

this.sourceNode.connect(this.audioContext.destination);
this.sourceNode.connect(this.volumeNode).connect(this.audioContext.destination);
this.sourceNode.onPositionChangedInterval = 1000;
this.sourceNode.onPositionChanged = (event) => {
PlaybackNotificationManager.show({
Expand Down Expand Up @@ -108,12 +108,7 @@ class AudioPlayer {
};

loadBuffer = async (asset: string | number) => {
const buffer = await decodeAudioData(asset, 0, {
headers: {
'User-Agent':
'Mozilla/5.0 (Android; Mobile; rv:122.0) Gecko/122.0 Firefox/122.0',
},
});
const buffer = await this.audioContext.decodeAudioData(asset);

if (buffer) {
this.audioBuffer = buffer;
Expand Down
26 changes: 2 additions & 24 deletions packages/audiodocs/docs/core/base-audio-context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -275,33 +275,11 @@ If not provided, the audio will be automatically resampled to match the audio co
#### Returns `Promise<AudioBuffer>`.

<details>
<summary>Example decoding with memory block</summary>
<summary>Example decoding</summary>
```tsx
const url = ... // url to an audio

const buffer = await fetch(url)
.then((response) => response.arrayBuffer())
.then((arrayBuffer) => this.audioContext.decodeAudioData(arrayBuffer))
.catch((error) => {
console.error('Error decoding audio data source:', error);
return null;
});
```
</details>

<details>
<summary>Example using expo-asset library</summary>
```tsx
import { Asset } from 'expo-asset';

const buffer = await Asset.fromModule(require('@/assets/music/example.mp3'))
.downloadAsync()
.then((asset) => {
if (!asset.localUri) {
throw new Error('Failed to load audio asset');
}
return this.audioContext.decodeAudioData(asset.localUri);
})
const buffer = await audioContext.decodeAudioData(url);
```
</details>

Expand Down
27 changes: 0 additions & 27 deletions packages/audiodocs/docs/utils/decoding.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,33 +89,6 @@ const buffer = await decodeAudioData(url);
```
</details>

:::caution
Internally decoding local files uses Image component to retrieve asset uri, but it does not work on the web platform.
You can use expo-asset library for this purpose or retrieve ArrayBuffer on your own and pass it to decoding function.
:::
<details>
<summary>Example using expo-asset library</summary>
```tsx
import { Asset } from 'expo-asset';
import { AudioContext } from 'react-native-audio-api';

const uri = await Asset.fromModule(require('@/assets/music/example.mp3'))
.downloadAsync()
.then((asset) => {
if (!asset.localUri) {
console.error('Failed to load audio asset');
}
return asset.localUri;
})

const context = new AudioContext();
if (uri) {
const buffer = await context.decodeAudioData(uri);
}

```
</details>

### `decodePCMInBase64`

Decodes base64-encoded PCM audio data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ JSI_HOST_FUNCTION_IMPL(BiquadFilterNodeHostObject, getFrequencyResponse) {
auto arrayBufferFrequency =
args[0].getObject(runtime).getPropertyAsObject(runtime, "buffer").getArrayBuffer(runtime);
auto frequencyArray = reinterpret_cast<float *>(arrayBufferFrequency.data(runtime));
auto length = static_cast<size_t>(arrayBufferFrequency.size(runtime));
// arrayBufferFrequency is Float32Array from JS and size is in bytes thus hardcoded division by 4
auto length = static_cast<size_t>(arrayBufferFrequency.size(runtime) / 4);

auto arrayBufferMag =
args[1].getObject(runtime).getPropertyAsObject(runtime, "buffer").getArrayBuffer(runtime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ AudioBufferSourceNode::AudioBufferSourceNode(
loopSkip_(false),
loopStart_(options.loopStart),
loopEnd_(options.loopEnd) {
buffer_ = std::shared_ptr<AudioBuffer>(options.buffer);
alignedBuffer_ = std::shared_ptr<AudioBuffer>(nullptr);

setBuffer(options.buffer);
isInitialized_ = true;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-audio-api/src/core/AnalyserNode.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import BaseAudioContext from './BaseAudioContext';
import { IndexSizeError } from '../errors';
import { IAnalyserNode } from '../interfaces';
import { WindowType, TAnalyserOptions } from '../types';
import { WindowType, AnalyserOptions } from '../types';
import AudioNode from './AudioNode';
import { AnalyserOptionsValidator } from '../options-validators';

Expand All @@ -10,7 +10,7 @@ export default class AnalyserNode extends AudioNode {
32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
];

constructor(context: BaseAudioContext, options?: TAnalyserOptions) {
constructor(context: BaseAudioContext, options?: AnalyserOptions) {
AnalyserOptionsValidator.validate(options);
const analyserNode: IAnalyserNode = context.context.createAnalyser(
options || {}
Expand Down
8 changes: 4 additions & 4 deletions packages/react-native-audio-api/src/core/AudioBuffer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IAudioBuffer } from '../interfaces';
import { IndexSizeError, NotSupportedError } from '../errors';
import { TAudioBufferOptions } from '../types';
import { AudioBufferOptions } from '../types';

export default class AudioBuffer {
readonly length: number;
Expand All @@ -10,13 +10,13 @@ export default class AudioBuffer {
/** @internal */
public readonly buffer: IAudioBuffer;

constructor(options: TAudioBufferOptions);
constructor(options: AudioBufferOptions);

/** @internal */
constructor(buffer: IAudioBuffer);

/** @internal */
constructor(arg: TAudioBufferOptions | IAudioBuffer) {
constructor(arg: AudioBufferOptions | IAudioBuffer) {
this.buffer = this.isAudioBuffer(arg)
? arg
: AudioBuffer.createBufferFromOptions(arg);
Expand Down Expand Up @@ -76,7 +76,7 @@ export default class AudioBuffer {
}

private static createBufferFromOptions(
options: TAudioBufferOptions
options: AudioBufferOptions
): IAudioBuffer {
const { numberOfChannels = 1, length, sampleRate } = options;
if (numberOfChannels < 1 || numberOfChannels >= 32) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import AudioBufferBaseSourceNode from './AudioBufferBaseSourceNode';
import AudioBuffer from './AudioBuffer';
import { RangeError } from '../errors';
import BaseAudioContext from './BaseAudioContext';
import { TBaseAudioBufferSourceOptions } from '../types';
import { BaseAudioBufferSourceOptions } from '../types';
import { AudioEventSubscription } from '../events';
import { OnBufferEndEventType } from '../events/types';

Expand All @@ -13,7 +13,7 @@ export default class AudioBufferQueueSourceNode extends AudioBufferBaseSourceNod

constructor(
context: BaseAudioContext,
options?: TBaseAudioBufferSourceOptions
options?: BaseAudioBufferSourceOptions
) {
const node = context.context.createBufferQueueSource(options || {});
super(context, node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import AudioBuffer from './AudioBuffer';
import { InvalidStateError, RangeError } from '../errors';
import { EventEmptyType } from '../events/types';
import { AudioEventSubscription } from '../events';
import { TAudioBufferSourceOptions } from '../types';
import { AudioBufferSourceOptions } from '../types';
import BaseAudioContext from './BaseAudioContext';

export default class AudioBufferSourceNode extends AudioBufferBaseSourceNode {
private onLoopEndedSubscription?: AudioEventSubscription;
private onLoopEndedCallback?: (event: EventEmptyType) => void;

constructor(context: BaseAudioContext, options?: TAudioBufferSourceOptions) {
const node = context.context.createBufferSource(options || {});
constructor(context: BaseAudioContext, options?: AudioBufferSourceOptions) {
const node = context.context.createBufferSource({
...options,
...(options?.buffer ? { buffer: options.buffer.buffer } : {}),
});
super(context, node);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-audio-api/src/core/BiquadFilterNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { IBiquadFilterNode } from '../interfaces';
import AudioNode from './AudioNode';
import AudioParam from './AudioParam';
import BaseAudioContext from './BaseAudioContext';
import { TBiquadFilterOptions } from '../types';
import { BiquadFilterOptions } from '../types';

export default class BiquadFilterNode extends AudioNode {
readonly frequency: AudioParam;
readonly detune: AudioParam;
readonly Q: AudioParam;
readonly gain: AudioParam;

constructor(context: BaseAudioContext, options?: TBiquadFilterOptions) {
constructor(context: BaseAudioContext, options?: BiquadFilterOptions) {
const biquadFilter: IBiquadFilterNode = context.context.createBiquadFilter(
options || {}
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { IConstantSourceNode } from '../interfaces';
import { TConstantSourceOptions } from '../types';
import { ConstantSourceOptions } from '../types';
import AudioParam from './AudioParam';
import AudioScheduledSourceNode from './AudioScheduledSourceNode';
import BaseAudioContext from './BaseAudioContext';

export default class ConstantSourceNode extends AudioScheduledSourceNode {
readonly offset: AudioParam;

constructor(context: BaseAudioContext, options?: TConstantSourceOptions) {
constructor(context: BaseAudioContext, options?: ConstantSourceOptions) {
const node: IConstantSourceNode = context.context.createConstantSource(
options || {}
);
Expand Down
11 changes: 6 additions & 5 deletions packages/react-native-audio-api/src/core/ConvolverNode.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { IConvolverNode } from '../interfaces';
import { TConvolverOptions } from '../types';
import { ConvolverOptions } from '../types';
import BaseAudioContext from './BaseAudioContext';
import AudioNode from './AudioNode';
import AudioBuffer from './AudioBuffer';

export default class ConvolverNode extends AudioNode {
constructor(context: BaseAudioContext, options?: TConvolverOptions) {
const convolverNode: IConvolverNode = context.context.createConvolver(
options || {}
);
constructor(context: BaseAudioContext, options?: ConvolverOptions) {
const convolverNode: IConvolverNode = context.context.createConvolver({
...options,
...(options?.buffer ? { buffer: options.buffer.buffer } : {}),
});
super(context, convolverNode);
this.normalize = convolverNode.normalize;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-audio-api/src/core/DelayNode.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import AudioNode from './AudioNode';
import AudioParam from './AudioParam';
import BaseAudioContext from './BaseAudioContext';
import { TDelayOptions } from '../types';
import { DelayOptions } from '../types';

export default class DelayNode extends AudioNode {
readonly delayTime: AudioParam;

constructor(context: BaseAudioContext, options?: TDelayOptions) {
constructor(context: BaseAudioContext, options?: DelayOptions) {
const delay = context.context.createDelay(options || {});
super(context, delay);
this.delayTime = new AudioParam(delay.delayTime, context);
Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-audio-api/src/core/GainNode.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { IGainNode } from '../interfaces';
import { TGainOptions } from '../types';
import { GainOptions } from '../types';
import AudioNode from './AudioNode';
import AudioParam from './AudioParam';
import BaseAudioContext from './BaseAudioContext';

export default class GainNode extends AudioNode {
readonly gain: AudioParam;

constructor(context: BaseAudioContext, options?: TGainOptions) {
constructor(context: BaseAudioContext, options?: GainOptions) {
const gainNode: IGainNode = context.context.createGain(options || {});
super(context, gainNode);
this.gain = new AudioParam(gainNode.gain, context);
Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-audio-api/src/core/IIRFilterNode.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { NotSupportedError } from '../errors';
import { IIIRFilterNode } from '../interfaces';
import AudioNode from './AudioNode';
import { TIIRFilterOptions } from '../types';
import { IIRFilterOptions } from '../types';
import BaseAudioContext from './BaseAudioContext';

export default class IIRFilterNode extends AudioNode {
constructor(context: BaseAudioContext, options: TIIRFilterOptions) {
constructor(context: BaseAudioContext, options: IIRFilterOptions) {
const iirFilterNode = context.context.createIIRFilter(options || {});
super(context, iirFilterNode);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-audio-api/src/core/OscillatorNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import AudioParam from './AudioParam';
import BaseAudioContext from './BaseAudioContext';
import PeriodicWave from './PeriodicWave';
import { InvalidStateError } from '../errors';
import { TOscillatorOptions } from '../types';
import { OscillatorOptions } from '../types';

export default class OscillatorNode extends AudioScheduledSourceNode {
readonly frequency: AudioParam;
readonly detune: AudioParam;

constructor(context: BaseAudioContext, options?: TOscillatorOptions) {
constructor(context: BaseAudioContext, options?: OscillatorOptions) {
if (options?.periodicWave) {
options.type = 'custom';
}
Expand Down
8 changes: 4 additions & 4 deletions packages/react-native-audio-api/src/core/PeriodicWave.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { IPeriodicWave } from '../interfaces';
import BaseAudioContext from './BaseAudioContext';
import { TPeriodicWaveOptions } from '../types';
import { PeriodicWaveOptions } from '../types';
import { PeriodicWaveOptionsValidator } from '../options-validators';

export function generateRealAndImag(
options?: TPeriodicWaveOptions
): TPeriodicWaveOptions {
options?: PeriodicWaveOptions
): PeriodicWaveOptions {
let real: Float32Array | undefined;
let imag: Float32Array | undefined;
if (!options || (!options.real && !options.imag)) {
Expand All @@ -32,7 +32,7 @@ export default class PeriodicWave {
/** @internal */
public readonly periodicWave: IPeriodicWave;

constructor(context: BaseAudioContext, options?: TPeriodicWaveOptions) {
constructor(context: BaseAudioContext, options?: PeriodicWaveOptions) {
const finalOptions = generateRealAndImag(options);
this.periodicWave = context.context.createPeriodicWave(
finalOptions.real!,
Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-audio-api/src/core/StereoPannerNode.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { IStereoPannerNode } from '../interfaces';
import { TStereoPannerOptions } from '../types';
import { StereoPannerOptions } from '../types';
import AudioNode from './AudioNode';
import AudioParam from './AudioParam';
import BaseAudioContext from './BaseAudioContext';

export default class StereoPannerNode extends AudioNode {
readonly pan: AudioParam;

constructor(context: BaseAudioContext, options?: TStereoPannerOptions) {
constructor(context: BaseAudioContext, options?: StereoPannerOptions) {
const pan: IStereoPannerNode = context.context.createStereoPanner(
options || {}
);
Expand Down
4 changes: 2 additions & 2 deletions packages/react-native-audio-api/src/core/StreamerNode.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { IStreamerNode } from '../interfaces';
import AudioScheduledSourceNode from './AudioScheduledSourceNode';
import { TStreamerOptions } from '../types';
import { StreamerOptions } from '../types';
import { InvalidStateError, NotSupportedError } from '../errors';
import BaseAudioContext from './BaseAudioContext';

export default class StreamerNode extends AudioScheduledSourceNode {
private hasBeenSetup: boolean = false;
constructor(context: BaseAudioContext, options?: TStreamerOptions) {
constructor(context: BaseAudioContext, options?: StreamerOptions) {
const node = context.context.createStreamer(options || {});
if (!node) {
throw new NotSupportedError('StreamerNode requires FFmpeg build');
Expand Down
Loading