diff --git a/packages/audiodocs/docs/core/base-audio-context.mdx b/packages/audiodocs/docs/core/base-audio-context.mdx index bbda9d84..f70cb587 100644 --- a/packages/audiodocs/docs/core/base-audio-context.mdx +++ b/packages/audiodocs/docs/core/base-audio-context.mdx @@ -88,6 +88,13 @@ The above method lets you create [`AudioBufferSourceNode`](/sources/audio-buffer #### Returns `AudioBufferSourceNode`. + +### `createBufferQueueSource` + +The above method lets you create [`AudioBufferQueueSourceNode`](/sources/audio-buffer-queue-source-node). + +#### Returns `AudioBufferQueueSourceNode`. + ### `createGain` The above method lets you create [`GainNode`](/effects/gain-node). diff --git a/packages/audiodocs/docs/sources/audio-buffer-base-source-node.mdx b/packages/audiodocs/docs/sources/audio-buffer-base-source-node.mdx new file mode 100644 index 00000000..ddd0abea --- /dev/null +++ b/packages/audiodocs/docs/sources/audio-buffer-base-source-node.mdx @@ -0,0 +1,56 @@ +--- +sidebar_position: 4 +--- + +import { Optional } from '@site/src/components/Badges'; + +# AudioBufferBaseSourceNode + +The `AudioBufferBaseSourceNode` interface is an [`AudioScheduledSourceNode`](/sources/audio-scheduled-source-node) which aggregates behavior of nodes that requires [`AudioBuffer`](/sources/audio-buffer). + +Child classes: + - [`AudioBufferSourceNode`](/sources/audio-buffer-source-node) + - [`AudioBufferQueueSourceNode`](/sources/audio-buffer-queue-source-node) + +## Properties + +| Name | Type | Description | +| :----: | :----: | :-------- | +| `detune` | [`AudioParam`](/core/audio-param) | [`k-rate`](/core/audio-param#a-rate-vs-k-rate) `AudioParam` representing detuning of oscillation in cents. | +| `playbackRate` | [`AudioParam`](/core/audio-param) | [`k-rate`](/core/audio-param#a-rate-vs-k-rate) `AudioParam` defining speed factor at which the audio will be played. | + + +## Events + +:::info +Mobile only. +::: + +### `onPositionChanged` + +Allow to set (or remove) callback that will be fired after processing certain part of an audio. +Frequency is defined by `onPositionChangedInterval`. By setting this callback you can achieve pause functionality. +You can remove callback by passing `null`. + +### `onPositionChangedInterval` + +Allow to set frequency for `onPositionChanged` event. Value that can be set is around `1000/x` Hz. + +```ts +import { AudioContext, AudioBufferSourceNode } from 'react-native-audio-api'; + +function App() { + const ctx = new AudioContext(); + const sourceNode = ctx.createBufferSource(); + sourceNode.buffer = null; //set your buffer + let offset = 0; + + sourceNode.onPositionChanged = (event) => { //setting callback + this.offset = event.value; + }; + + sourceNode.onPositionChangedInterval = 100; //setting frequency to ~10Hz + + sourceNode.start(); +} +``` diff --git a/packages/audiodocs/docs/sources/audio-buffer-queue-source-node.mdx b/packages/audiodocs/docs/sources/audio-buffer-queue-source-node.mdx new file mode 100644 index 00000000..a408e6a9 --- /dev/null +++ b/packages/audiodocs/docs/sources/audio-buffer-queue-source-node.mdx @@ -0,0 +1,55 @@ +--- +sidebar_position: 3 +--- + +import { Optional, Experimental } from '@site/src/components/Badges'; + +# AudioBufferQueueSourceNode + +The `AudioBufferQueueSourceNode` is an [`AudioBufferBaseSourceNode`](/sources/audio-buffer-base-source-node) which represents player that consists of many short buffers. + +:::info +Mobile only. +::: + +## Constructor + +[`BaseAudioContext.createBufferQueueSource()`](/core/base-audio-context#createbuffersource) + +## Example + +```tsx +import React, { useRef } from 'react'; +import { + AudioContext, + AudioBufferQueueSourceNode, +} from 'react-native-audio-api'; + +function App() { + const audioContextRef = useRef(null); + if (!audioContextRef.current) { + audioContextRef.current = new AudioContext(); + } + const audioBufferQueue = audioContextRef.current.createBufferQueueSource(); + const buffer1 = ...; // Load your audio buffer here + const buffer2 = ...; // Load another audio buffer if needed + audioBufferQueue.enqueueBuffer(buffer1, false); + audioBufferQueue.enqueueBuffer(buffer2, true); // Last buffer should be marked as is + audioBufferQueue.connect(audioContextRef.current.destination); + audioBufferQueue.start(audioContextRef.current.currentTime); +} +``` + +## Methods + +### `enqueueBuffer` + +The above method lets you add another buffer to queue. + +| Parameters | Type | Description | +| :---: | :---: | :---- | +| `buffer` | [`AudioBuffer`](/sources/audio-buffer) | Buffer with next data. | +| `isLastBuffer` | `boolean` | Boolean indicating if it is a last buffer. Default value is `false`. Queue will stop after buffer marked as `last` will end. | + +#### Returns `undefined`. + diff --git a/packages/audiodocs/docs/sources/audio-buffer-source-node.mdx b/packages/audiodocs/docs/sources/audio-buffer-source-node.mdx index c0603339..f4746070 100644 --- a/packages/audiodocs/docs/sources/audio-buffer-source-node.mdx +++ b/packages/audiodocs/docs/sources/audio-buffer-source-node.mdx @@ -7,7 +7,7 @@ import { Optional, Overridden } from '@site/src/components/Badges'; # AudioBufferSourceNode -The `AudioBufferSourceNode` is an [`AudioScheduledSourceNode`](/sources/audio-scheduled-source-node) which represents audio source with in-memory audio data, stored in `AudioBuffer`. +The `AudioBufferSourceNode` is an [`AudioBufferBaseSourceNode`](/sources/audio-buffer-base-source-node) which represents audio source with in-memory audio data, stored in `AudioBuffer`. You can use it for audio playback, including standard pause and resume functionalities. An `AudioBufferSourceNode` can be started only once, so if you want to play the same sound again you have to create a new one. @@ -21,17 +21,37 @@ However, this node is very inexpensive to create, and what is crucial you can re [`BaseAudioContext.createBufferSource(options)`](/core/base-audio-context#createbuffersource) +## Example + +```tsx +import React, { useEffect, useRef, FC } from 'react'; +import { + AudioContext, + AudioBufferSourceNode, +} from 'react-native-audio-api'; + +function App() { + const audioContextRef = useRef(null); + if (!audioContextRef.current) { + audioContextRef.current = new AudioContext(); + } + const audioBufferSource = audioContextRef.current.createBufferSource(); + const buffer = ...; // Load your audio buffer here + audioBufferSource.buffer = buffer; + audioBufferSource.connect(audioContextRef.current.destination); + audioBufferSource.start(audioContextRef.current.currentTime); +} +``` + ## Properties | Name | Type | Description | | :----: | :----: | :-------- | | `buffer` | [`AudioBuffer`](/sources/audio-buffer) | Associated `AudioBuffer`. | -| `detune` | [`AudioParam`](/core/audio-param) | [`k-rate`](/core/audio-param#a-rate-vs-k-rate) `AudioParam` representing detuning of oscillation in cents. | | `loop` | `boolean` | Boolean indicating if audio data must be replayed after when end of the associated `AudioBuffer` is reached. | | `loopSkip` | `boolean` | Boolean indicating if upon setting up `loopStart` we want to skip immediately to the loop start. | | `loopStart` | `number` | Float value indicating the time, in seconds, at which playback of the audio must begin, if loop is true. | | `loopEnd` | `number` | Float value indicating the time, in seconds, at which playback of the audio must end and loop back to `loopStart`, if loop is true. | -| `playbackRate` | [`AudioParam`](/core/audio-param) | [`k-rate`](/core/audio-param#a-rate-vs-k-rate) `AudioParam` defining speed factor at which the audio will be played. | ## Methods diff --git a/packages/audiodocs/docs/sources/audio-scheduled-source-node.mdx b/packages/audiodocs/docs/sources/audio-scheduled-source-node.mdx index c85bb220..247635ff 100644 --- a/packages/audiodocs/docs/sources/audio-scheduled-source-node.mdx +++ b/packages/audiodocs/docs/sources/audio-scheduled-source-node.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 --- import { Optional, Experimental } from '@site/src/components/Badges'; @@ -9,6 +9,10 @@ import { Optional, Experimental } from '@site/src/components/Badges'; The `AudioScheduledSourceNode` interface is an [`AudioNode`](/core/audio-node) which serves as a parent interface for several types of audio source nodes. It provides ability to start and stop audio playback. +Child classes: + - [`AudioBufferBaseSourceNode`](/sources/audio-buffer-base-source-node) + - [`OscillatorNode`](/sources/oscillator-node) + ## Methods ### `start` @@ -49,23 +53,11 @@ If you invoke this method multiple times on the same node before the designated ## Events -### `onended` +Allow to set (or remove) callback that will be fired when source node has stopped playing. You can remove callback by passing `null`. -Above callback is fired when source node has stopped playing. -By setting this callback you can achieve pause functionality. ```ts -const [offset, setOffset] = useState(0); - -/* ... */ - -audioBufferSourceNode.onended = (stopTime?: number) => { - setOffset((_prev) => stopTime || 0); +audioBufferSourceNode.onended = () => { //setting callback + console.log("audio ended"); }; - -source.start(context.currentTime, offset) ``` - -:::caution -Tested only on Android and iOS. -::: diff --git a/packages/audiodocs/docs/sources/oscillator-node.mdx b/packages/audiodocs/docs/sources/oscillator-node.mdx index 9991bfd5..514d83ed 100644 --- a/packages/audiodocs/docs/sources/oscillator-node.mdx +++ b/packages/audiodocs/docs/sources/oscillator-node.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 5 --- import AudioNodePropsTable from "@site/src/components/AudioNodePropsTable" @@ -21,24 +21,20 @@ Similar to all of `AudioScheduledSourceNodes`, it can be started only once. If y ## Example ```tsx -import React, { useEffect, useRef, FC } from 'react'; +import React, { useRef } from 'react'; import { AudioContext, OscillatorNode, } from 'react-native-audio-api'; -export default MyComponent: FC = () => { +function App() { const audioContextRef = useRef(null); - - useEffect(() => { - if (!audioContextRef.current) { - audioContextRef.current = new AudioContext(); - } - const oscillator = audioContextRef.current.createOscillator(); - oscillator.connect(audioContextRef.current.destination); - oscillator.start(audioContextRef.current.currentTime); - } - ) + if (!audioContextRef.current) { + audioContextRef.current = new AudioContext(); + } + const oscillator = audioContextRef.current.createOscillator(); + oscillator.connect(audioContextRef.current.destination); + oscillator.start(audioContextRef.current.currentTime); } ```