Skip to content
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
45ee712
refactor: move AudioFormat to separate file
vltkv Sep 4, 2025
7af9407
refactor: extract AudioDecoder into separate module
vltkv Sep 9, 2025
70195e5
refactor: simplify utility functions
vltkv Sep 11, 2025
ecb5363
refactor: one decode method with overloads
vltkv Sep 16, 2025
e798179
Merge remote-tracking branch 'origin/main' into audio-decoding-module
vltkv Sep 16, 2025
0796dd6
refactor: revert previous formatting
vltkv Sep 18, 2025
aac1a99
fix: audioDecoder interface
vltkv Sep 19, 2025
2e97d04
refactor: remove audiodecoder property from audioContexts cpp files
vltkv Sep 19, 2025
f01b4ba
refactor: move AudioDecoder to utils folder
vltkv Sep 19, 2025
47719c1
Merge branch 'main' into audio-decoding-module
vltkv Sep 23, 2025
5a06e63
docs: update desc in BaseAudioContext
vltkv Sep 25, 2025
07477f8
docs: add section about AudioDecoder
vltkv Sep 25, 2025
38057a2
refactor: audioplayer
vltkv Sep 25, 2025
0ed5964
Merge branch 'main' into audio-decoding-module
vltkv Sep 25, 2025
089abf8
fix: small fixes
vltkv Sep 25, 2025
faa134a
fix: tests
vltkv Sep 25, 2025
9fc6690
fix: test
vltkv Sep 25, 2025
dc59754
refactor: rename funtion decode
vltkv Sep 26, 2025
88d1eff
feat: add removing the file:// prefix
vltkv Sep 26, 2025
8edf837
refactor: deleted unnecessary comments
vltkv Sep 26, 2025
ea2cb2c
feat: decoder can get channelCount and sampleRate from data
vltkv Sep 30, 2025
50af869
refactor: audio decoder
vltkv Sep 30, 2025
97dcd40
fix: replace implicit conversions with explici static_cast
vltkv Sep 30, 2025
2d413e4
feat: add ffmpeg decoding
vltkv Sep 30, 2025
3c50322
refactor: ffmpeg decoding
vltkv Sep 30, 2025
75469db
fix: add ffmpeg decoding to android
vltkv Sep 30, 2025
59f2ad2
Merge branch 'main' into audio-decoding-module
vltkv Sep 30, 2025
80047c6
docs: update decoding description
vltkv Oct 1, 2025
c318a15
Merge remote-tracking branch 'refs/remotes/origin/audio-decoding-modu…
vltkv Oct 1, 2025
a93b309
docs: add desc in base-audio-context
vltkv Oct 1, 2025
2858391
fix: nitpicks
vltkv Oct 3, 2025
fb8bf2a
Merge branch 'main' into audio-decoding-module
vltkv Oct 3, 2025
ca92408
refactor: use createAsyncPromise
vltkv Oct 3, 2025
cdcbe02
Merge branch 'main' into audio-decoding-module
vltkv Oct 3, 2025
6f8af7a
Merge branch 'main' into audio-decoding-module
vltkv Oct 6, 2025
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/examples/PlaybackSpeed/PlaybackSpeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ const PlaybackSpeed: FC = () => {
setIsLoading(true);

try {
const buffer = await audioContext.decodePCMInBase64Data(
PCM_DATA,
audioSettings.PSOLA ? playbackSpeed : 1
);
const buffer = await audioContext.decodeAudioData(PCM_DATA);

const source = audioContext.createBufferSource({
pitchCorrection: audioSettings.PSOLA
Expand Down
86 changes: 52 additions & 34 deletions packages/audiodocs/docs/core/base-audio-context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -168,20 +168,51 @@ Creates [`BiquadFilterNode`](/docs/effects/biquad-filter-node).

:::caution
Supported file formats:
- mp3
- wav
- aac
- flac
- opus
- ogg
- m4a
- aac
- mp3
- mp4
- ogg
- opus
- wav
:::

### `decodeAudioData`

Decodes audio data from either a file path or an ArrayBuffer. The optional `sampleRate` parameter lets you resample the decoded audio.
If not provided, the audio will be automatically resampled to match the audio context's `sampleRate`.

<table>
<thead>
<tr>
<th align="center">Parameter</th>
<th align="center">Type</th>
<th align="center">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2" align="center"><code>input</code></td>
<td align="center"><code>ArrayBuffer</code></td>
<td align="center">ArrayBuffer with audio data.</td>
</tr>
<tr>
<td align="center"><code>string</code></td>
<td align="center">Path to audio file located on the device.</td>
</tr>
<tr>
<td align="center"><code>sampleRate</code><Optional /></td>
<td align="center"><code>number</code></td>
<td align="center">Target sample rate for the decoded audio.</td>
</tr>
</tbody>
</table>

#### Returns `Promise<AudioBuffer>`.

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

Expand All @@ -195,16 +226,6 @@ const buffer = await fetch(url)
```
</details>

Decodes audio data. It decodes with in memory audio data block.

| Parameters | Type | Description |
| :---: | :---: | :---- |
| `arrayBuffer` | `ArrayBuffer` | ArrayBuffer with audio data. |

#### Returns `Promise<AudioBuffer>`.

### `decodeAudioDataSource`

<details>
<summary>Example using expo-asset library</summary>
```tsx
Expand All @@ -216,38 +237,35 @@ const buffer = await Asset.fromModule(require('@/assets/music/example.mp3'))
if (!asset.localUri) {
throw new Error('Failed to load audio asset');
}
return this.audioContext.decodeAudioDataSource(asset.localUri);
return this.audioContext.decodeAudioData(asset.localUri);
})
```
</details>

Decodes audio data file.
### `decodePCMInBase64`

| Parameters | Type | Description |
| :---: | :---: | :---- |
| `sourcePath` | `string` | Path to audio file located on the device. |
Decodes base64-encoded PCM audio data.

#### Returns `Promise<AudioBuffer>`.
#### Parameters

### `decodePCMInBase64Data` <MobileOnly />
| Parameter | Type | Description |
|-----------|------|-------------|
| `base64String` | `string` | Base64-encoded PCM audio data. |
| `inputSampleRate` | `number` | Sample rate of the input PCM data. |
| `inputChannelCount` | `number` | Number of channels in the input PCM data. |
| `isInterleaved` <Optional />| `boolean` | Whether the PCM data is interleaved. Default is `true`. |

#### Returns `Promise<AudioBuffer>`

<details>
<summary>Example</summary>
<summary>Example decoding with data in base64 format </summary>
```tsx
const data = ... // data encoded in base64 string
const buffer = await this.audioContext.decodePCMInBase64Data(data);
// data is not interleaved (Channel1, Channel1, ..., Channel2, Channel2, ...)
const buffer = await this.audioContext.decodeAudioData(data, 4800, 2, false);
```
</details>

Decodes audio data. It decodes with PCM data in Base64.

| Parameters | Type | Description |
| :---: | :---: | :---- |
| `base64` | `string` | Base64 string with audio data. |
| `playbackRate` <Optional /> | `number` | Number that represents audio speed, which will be applied during decoding. |

#### Returns `Promise<AudioBuffer>`.

## Remarks

#### `currentTime`
Expand Down
2 changes: 1 addition & 1 deletion packages/audiodocs/docs/other/_category_.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Other",
"position": 10,
"position": 11,
"link": {
"type": "generated-index"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/audiodocs/docs/sources/audio-buffer.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ specific sample rate which is the quantity of frames that will play in one secon

![](/img/audioBuffer.png)

It can be created from audio file using [`decodeAudioData`](/docs/core/base-audio-context#decodeaudiodata), [`decodeAudioDataSource`](/docs/core/base-audio-context#decodeaudiodatasource), [`decodePCMInBase64Data`](/docs/core/base-audio-context#decodepcminbase64data-) or from raw data using `constructor`.
It can be created from audio file using [`decodeAudioData`](/docs/utils/audio-decoder#decodeaudiodata) or from raw data using `constructor`.
Once you have data in `AudioBuffer`, audio can be played by passing it to [`AudioBufferSourceNode`](audio-buffer-source-node).

## Constructor
Expand Down
7 changes: 7 additions & 0 deletions packages/audiodocs/docs/utils/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"label": "Utils",
"position": 10,
"link": {
"type": "generated-index"
}
}
116 changes: 116 additions & 0 deletions packages/audiodocs/docs/utils/decoding.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
sidebar_position: 1
---

import { Optional, MobileOnly } from '@site/src/components/Badges';

# Decoding

You can decode audio data independently, without creating an AudioContext, using the exported functions [`decodeAudioData`](/docs/utils/audio-decoder#decodeaudiodata) and
[`decodePCMInBase64`](/docs/utils/audio-decoder#decodepcminbase64).

If you already have an audio context, you can decode audio data directly using its [`decodeAudioData`](/docs/core/base-audio-context#decodeaudiodata) function;
the decoded audio will then be automatically resampled to match the context's `sampleRate`.

:::caution
Supported file formats:
- aac
- flac
- m4a
- mp3
- mp4
- ogg
- opus
- wav
:::

### `decodeAudioData`

Decodes audio data from either a file path or an ArrayBuffer. The optional `sampleRate` parameter lets you resample the decoded audio;
if not provided, the original sample rate from the file is used.

<table>
<thead>
<tr>
<th align="center">Parameter</th>
<th align="center">Type</th>
<th align="center">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2" align="center"><code>input</code></td>
<td align="center"><code>ArrayBuffer</code></td>
<td align="center">ArrayBuffer with audio data.</td>
</tr>
<tr>
<td align="center"><code>string</code></td>
<td align="center">Path to audio file located on the device.</td>
</tr>
<tr>
<td align="center"><code>sampleRate</code><Optional /></td>
<td align="center"><code>number</code></td>
<td align="center">Target sample rate for the decoded audio.</td>
</tr>
</tbody>
</table>

#### Returns `Promise<AudioBuffer>`.

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

const buffer = await fetch(url)
.then((response) => response.arrayBuffer())
// resample decoded audio to 48000 Hz
.then((arrayBuffer) => decodeAudioData(arrayBuffer, 48000))
.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');
}
// sampleRate not provided, so file will be decoded in original sampleRate
return decodeAudioData(asset.localUri);
})
```
</details>

### `decodePCMInBase64`

Decodes base64-encoded PCM audio data.

#### Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `base64String` | `string` | Base64-encoded PCM audio data. |
| `inputSampleRate` | `number` | Sample rate of the input PCM data. |
| `inputChannelCount` | `number` | Number of channels in the input PCM data. |
| `isInterleaved` <Optional />| `boolean` | Whether the PCM data is interleaved. Default is `true`. |

#### Returns `Promise<AudioBuffer>`


<details>
<summary>Example decoding with data in base64 format </summary>
```tsx
const data = ... // data encoded in base64 string
// data is interleaved (Channel1, Channel2, Channel1, Channel2, ...)
const buffer = await decodeAudioData(data, 4800, 2, true);
```
</details>
Loading