diff --git a/packages/audiodocs/docs/core/audio-context.mdx b/packages/audiodocs/docs/core/audio-context.mdx
index fc07e78f4..20bb2cde7 100644
--- a/packages/audiodocs/docs/core/audio-context.mdx
+++ b/packages/audiodocs/docs/core/audio-context.mdx
@@ -1,5 +1,5 @@
---
-sidebar_position: 2
+sidebar_position: 1
---
# AudioContext
diff --git a/packages/audiodocs/docs/core/audio-node.mdx b/packages/audiodocs/docs/core/audio-node.mdx
index d0b4223de..3f97ee1e6 100644
--- a/packages/audiodocs/docs/core/audio-node.mdx
+++ b/packages/audiodocs/docs/core/audio-node.mdx
@@ -1,5 +1,5 @@
---
-sidebar_position: 3
+sidebar_position: 2
---
import { Optional, ReadOnly } from '@site/src/components/Badges';
diff --git a/packages/audiodocs/docs/core/audio-param.mdx b/packages/audiodocs/docs/core/audio-param.mdx
index 3289e7ab0..c7cc2cbea 100644
--- a/packages/audiodocs/docs/core/audio-param.mdx
+++ b/packages/audiodocs/docs/core/audio-param.mdx
@@ -1,5 +1,5 @@
---
-sidebar_position: 4
+sidebar_position: 3
---
import { Optional, ReadOnly } from '@site/src/components/Badges';
diff --git a/packages/audiodocs/docs/core/base-audio-context.mdx b/packages/audiodocs/docs/core/base-audio-context.mdx
index 7bf048915..d25ab6907 100644
--- a/packages/audiodocs/docs/core/base-audio-context.mdx
+++ b/packages/audiodocs/docs/core/base-audio-context.mdx
@@ -1,5 +1,5 @@
---
-sidebar_position: 1
+sidebar_position: 4
---
import { Optional, ReadOnly, MobileOnly } from '@site/src/components/Badges';
diff --git a/packages/audiodocs/docs/core/offline-audio-context.mdx b/packages/audiodocs/docs/core/offline-audio-context.mdx
new file mode 100644
index 000000000..4593dbbc2
--- /dev/null
+++ b/packages/audiodocs/docs/core/offline-audio-context.mdx
@@ -0,0 +1,9 @@
+---
+sidebar_position: 5
+---
+
+import { Optional, ReadOnly} from '@site/src/components/Badges';
+
+# OfflineAudioContext
+
+## 🚧 Under development 🚧
diff --git a/packages/audiodocs/docs/destinations/audio-destination-node.mdx b/packages/audiodocs/docs/destinations/audio-destination-node.mdx
new file mode 100644
index 000000000..f50454d45
--- /dev/null
+++ b/packages/audiodocs/docs/destinations/audio-destination-node.mdx
@@ -0,0 +1,7 @@
+---
+sidebar_position: 3
+---
+
+# AudioDestinationNode
+
+## 🚧 Under development 🚧
diff --git a/packages/audiodocs/docs/effects/periodic-wave.mdx b/packages/audiodocs/docs/effects/periodic-wave.mdx
new file mode 100644
index 000000000..ca2163bfb
--- /dev/null
+++ b/packages/audiodocs/docs/effects/periodic-wave.mdx
@@ -0,0 +1,7 @@
+---
+sidebar_position: 3
+---
+
+# PeriodicWave
+
+## 🚧 Under development 🚧
diff --git a/packages/audiodocs/docs/effects/stereo-panner-node.mdx b/packages/audiodocs/docs/effects/stereo-panner-node.mdx
index 1d403c043..6d8336435 100644
--- a/packages/audiodocs/docs/effects/stereo-panner-node.mdx
+++ b/packages/audiodocs/docs/effects/stereo-panner-node.mdx
@@ -1,5 +1,5 @@
---
-sidebar_position: 3
+sidebar_position: 4
---
import AudioNodePropsTable from "@site/src/components/AudioNodePropsTable"
diff --git a/packages/audiodocs/docs/sources/audio-buffer-source-node.mdx b/packages/audiodocs/docs/sources/audio-buffer-source-node.mdx
index 250e9242c..0045072c4 100644
--- a/packages/audiodocs/docs/sources/audio-buffer-source-node.mdx
+++ b/packages/audiodocs/docs/sources/audio-buffer-source-node.mdx
@@ -3,7 +3,7 @@ sidebar_position: 4
---
import AudioNodePropsTable from "@site/src/components/AudioNodePropsTable"
-import { Optional, Overridden } from '@site/src/components/Badges';
+import { Optional, Overridden, MobileOnly } from '@site/src/components/Badges';
# AudioBufferSourceNode
@@ -49,7 +49,7 @@ function App() {
| :----: | :----: | :-------- |
| `buffer` | [`AudioBuffer`](/docs/sources/audio-buffer) | Associated `AudioBuffer`. |
| `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. |
+| `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. |
diff --git a/packages/react-native-audio-api/src/api.ts b/packages/react-native-audio-api/src/api.ts
index 860786109..1599195e4 100644
--- a/packages/react-native-audio-api/src/api.ts
+++ b/packages/react-native-audio-api/src/api.ts
@@ -5,7 +5,7 @@ import type {
IAudioRecorder,
IOfflineAudioContext,
IAudioEventEmitter,
-} from './interfaces';
+} from './mobile/interfaces';
/* eslint-disable no-var */
declare global {
@@ -40,25 +40,25 @@ if (
NativeAudioAPIModule.install();
}
-export { default as RecorderAdapterNode } from './core/RecorderAdapterNode';
-export { default as AudioBuffer } from './core/AudioBuffer';
-export { default as AudioBufferSourceNode } from './core/AudioBufferSourceNode';
-export { default as AudioBufferQueueSourceNode } from './core/AudioBufferQueueSourceNode';
-export { default as AudioContext } from './core/AudioContext';
-export { default as OfflineAudioContext } from './core/OfflineAudioContext';
-export { default as AudioDestinationNode } from './core/AudioDestinationNode';
-export { default as AudioNode } from './core/AudioNode';
-export { default as AnalyserNode } from './core/AnalyserNode';
-export { default as AudioParam } from './core/AudioParam';
-export { default as AudioScheduledSourceNode } from './core/AudioScheduledSourceNode';
-export { default as BaseAudioContext } from './core/BaseAudioContext';
-export { default as BiquadFilterNode } from './core/BiquadFilterNode';
-export { default as GainNode } from './core/GainNode';
-export { default as OscillatorNode } from './core/OscillatorNode';
-export { default as StereoPannerNode } from './core/StereoPannerNode';
-export { default as AudioRecorder } from './core/AudioRecorder';
-export { default as AudioManager } from './system';
-export { default as useSystemVolume } from './hooks/useSytemVolume';
+export { default as AudioBuffer } from './mobile/sources/AudioBuffer';
+export { default as AudioBufferSourceNode } from './mobile/sources/AudioBufferSourceNode';
+export { default as AudioBufferQueueSourceNode } from './mobile/sources/AudioBufferQueueSourceNode';
+export { default as AudioContext } from './mobile/core/AudioContext';
+export { default as OfflineAudioContext } from './mobile/core/OfflineAudioContext';
+export { default as AudioDestinationNode } from './mobile/destinations/AudioDestinationNode';
+export { default as AudioNode } from './mobile/core/AudioNode';
+export { default as AnalyserNode } from './mobile/analysis/AnalyserNode';
+export { default as AudioParam } from './mobile/core/AudioParam';
+export { default as AudioScheduledSourceNode } from './mobile/sources/AudioScheduledSourceNode';
+export { default as BaseAudioContext } from './mobile/core/BaseAudioContext';
+export { default as BiquadFilterNode } from './mobile/effects/BiquadFilterNode';
+export { default as GainNode } from './mobile/effects/GainNode';
+export { default as OscillatorNode } from './mobile/sources/OscillatorNode';
+export { default as StereoPannerNode } from './mobile/effects/StereoPannerNode';
+export { default as AudioRecorder } from './mobile/inputs/AudioRecorder';
+export { default as AudioManager } from './mobile/system';
+export { default as useSystemVolume } from './mobile/hooks/useSystemVolume';
+export { default as RecorderAdapterNode } from './mobile/sources/RecorderAdapterNode';
export {
OscillatorType,
diff --git a/packages/react-native-audio-api/src/api.web.ts b/packages/react-native-audio-api/src/api.web.ts
index e47ce28ba..5047677c2 100644
--- a/packages/react-native-audio-api/src/api.web.ts
+++ b/packages/react-native-audio-api/src/api.web.ts
@@ -1,19 +1,19 @@
-export { default as AudioBuffer } from './web-core/AudioBuffer';
-export { default as AudioBufferSourceNode } from './web-core/AudioBufferSourceNode';
-export { default as AudioContext } from './web-core/AudioContext';
-export { default as OfflineAudioContext } from './web-core/OfflineAudioContext';
-export { default as AudioDestinationNode } from './web-core/AudioDestinationNode';
-export { default as AudioNode } from './web-core/AudioNode';
-export { default as AnalyserNode } from './web-core/AnalyserNode';
-export { default as AudioParam } from './web-core/AudioParam';
-export { default as AudioScheduledSourceNode } from './web-core/AudioScheduledSourceNode';
-export { default as BaseAudioContext } from './web-core/BaseAudioContext';
-export { default as BiquadFilterNode } from './web-core/BiquadFilterNode';
-export { default as GainNode } from './web-core/GainNode';
-export { default as OscillatorNode } from './web-core/OscillatorNode';
-export { default as StereoPannerNode } from './web-core/StereoPannerNode';
+export { default as AudioBuffer } from './web/sources/AudioBuffer';
+export { default as AudioBufferSourceNode } from './web/sources/AudioBufferSourceNode';
+export { default as AudioContext } from './web/core/AudioContext';
+export { default as OfflineAudioContext } from './web/core/OfflineAudioContext';
+export { default as AudioDestinationNode } from './web/destinations/AudioDestinationNode';
+export { default as AudioNode } from './web/core/AudioNode';
+export { default as AnalyserNode } from './web/analysis/AnalyserNode';
+export { default as AudioParam } from './web/core/AudioParam';
+export { default as AudioScheduledSourceNode } from './web/sources/AudioScheduledSourceNode';
+export { default as BaseAudioContext } from './web/core/BaseAudioContext';
+export { default as BiquadFilterNode } from './web/effects/BiquadFilterNode';
+export { default as GainNode } from './web/effects/GainNode';
+export { default as OscillatorNode } from './web/sources/OscillatorNode';
+export { default as StereoPannerNode } from './web/effects/StereoPannerNode';
-export * from './web-core/custom';
+export * from './web/custom';
export {
OscillatorType,
diff --git a/packages/react-native-audio-api/src/core/AnalyserNode.ts b/packages/react-native-audio-api/src/mobile/analysis/AnalyserNode.ts
similarity index 94%
rename from packages/react-native-audio-api/src/core/AnalyserNode.ts
rename to packages/react-native-audio-api/src/mobile/analysis/AnalyserNode.ts
index d2d8176e1..e8ba1e62d 100644
--- a/packages/react-native-audio-api/src/core/AnalyserNode.ts
+++ b/packages/react-native-audio-api/src/mobile/analysis/AnalyserNode.ts
@@ -1,7 +1,7 @@
-import { IndexSizeError } from '../errors';
+import { IndexSizeError } from '../../errors';
import { IAnalyserNode } from '../interfaces';
-import { WindowType } from '../types';
-import AudioNode from './AudioNode';
+import { WindowType } from '../../types';
+import AudioNode from '../core/AudioNode';
export default class AnalyserNode extends AudioNode {
private static allowedFFTSize: number[] = [
diff --git a/packages/react-native-audio-api/src/core/AudioContext.ts b/packages/react-native-audio-api/src/mobile/core/AudioContext.ts
similarity index 90%
rename from packages/react-native-audio-api/src/core/AudioContext.ts
rename to packages/react-native-audio-api/src/mobile/core/AudioContext.ts
index caaddfe44..1b8ee3080 100644
--- a/packages/react-native-audio-api/src/core/AudioContext.ts
+++ b/packages/react-native-audio-api/src/mobile/core/AudioContext.ts
@@ -1,8 +1,8 @@
import { IAudioContext } from '../interfaces';
import BaseAudioContext from './BaseAudioContext';
import AudioManager from '../system';
-import { AudioContextOptions } from '../types';
-import { NotSupportedError } from '../errors';
+import { AudioContextOptions } from '../../types';
+import { NotSupportedError } from '../../errors';
export default class AudioContext extends BaseAudioContext {
constructor(options?: AudioContextOptions) {
diff --git a/packages/react-native-audio-api/src/core/AudioNode.ts b/packages/react-native-audio-api/src/mobile/core/AudioNode.ts
similarity index 85%
rename from packages/react-native-audio-api/src/core/AudioNode.ts
rename to packages/react-native-audio-api/src/mobile/core/AudioNode.ts
index 2e19d51d1..7d5fc704a 100644
--- a/packages/react-native-audio-api/src/core/AudioNode.ts
+++ b/packages/react-native-audio-api/src/mobile/core/AudioNode.ts
@@ -1,8 +1,8 @@
import { IAudioNode } from '../interfaces';
import AudioParam from './AudioParam';
-import { ChannelCountMode, ChannelInterpretation } from '../types';
+import { ChannelCountMode, ChannelInterpretation } from '../../types';
import BaseAudioContext from './BaseAudioContext';
-import { InvalidAccessError } from '../errors';
+import { InvalidAccessError } from '../../errors';
export default class AudioNode {
readonly context: BaseAudioContext;
@@ -42,8 +42,10 @@ export default class AudioNode {
public disconnect(destination?: AudioNode | AudioParam): void {
if (destination instanceof AudioParam) {
this.node.disconnect(destination.audioParam);
+ } else if (destination instanceof AudioNode) {
+ this.node.disconnect(destination.node);
} else {
- this.node.disconnect(destination?.node);
+ this.node.disconnect();
}
}
}
diff --git a/packages/react-native-audio-api/src/core/AudioParam.ts b/packages/react-native-audio-api/src/mobile/core/AudioParam.ts
similarity index 98%
rename from packages/react-native-audio-api/src/core/AudioParam.ts
rename to packages/react-native-audio-api/src/mobile/core/AudioParam.ts
index d8cfb5fed..79af75b3e 100644
--- a/packages/react-native-audio-api/src/core/AudioParam.ts
+++ b/packages/react-native-audio-api/src/mobile/core/AudioParam.ts
@@ -1,5 +1,5 @@
import { IAudioParam } from '../interfaces';
-import { RangeError, InvalidStateError } from '../errors';
+import { RangeError, InvalidStateError } from '../../errors';
import BaseAudioContext from './BaseAudioContext';
export default class AudioParam {
diff --git a/packages/react-native-audio-api/src/core/BaseAudioContext.ts b/packages/react-native-audio-api/src/mobile/core/BaseAudioContext.ts
similarity index 83%
rename from packages/react-native-audio-api/src/core/BaseAudioContext.ts
rename to packages/react-native-audio-api/src/mobile/core/BaseAudioContext.ts
index c9e2e4d3f..962af5500 100644
--- a/packages/react-native-audio-api/src/core/BaseAudioContext.ts
+++ b/packages/react-native-audio-api/src/mobile/core/BaseAudioContext.ts
@@ -3,19 +3,19 @@ import {
ContextState,
PeriodicWaveConstraints,
AudioBufferSourceNodeOptions,
-} from '../types';
-import AudioDestinationNode from './AudioDestinationNode';
-import OscillatorNode from './OscillatorNode';
-import GainNode from './GainNode';
-import StereoPannerNode from './StereoPannerNode';
-import BiquadFilterNode from './BiquadFilterNode';
-import AudioBufferSourceNode from './AudioBufferSourceNode';
-import AudioBuffer from './AudioBuffer';
-import PeriodicWave from './PeriodicWave';
-import AnalyserNode from './AnalyserNode';
-import AudioBufferQueueSourceNode from './AudioBufferQueueSourceNode';
-import { InvalidAccessError, NotSupportedError } from '../errors';
-import RecorderAdapterNode from './RecorderAdapterNode';
+} from '../../types';
+import AudioDestinationNode from '../destinations/AudioDestinationNode';
+import OscillatorNode from '../sources/OscillatorNode';
+import GainNode from '../effects/GainNode';
+import StereoPannerNode from '../effects/StereoPannerNode';
+import BiquadFilterNode from '../effects/BiquadFilterNode';
+import AudioBufferSourceNode from '../sources/AudioBufferSourceNode';
+import AudioBuffer from '../sources/AudioBuffer';
+import PeriodicWave from '../effects/PeriodicWave';
+import AnalyserNode from '../analysis/AnalyserNode';
+import AudioBufferQueueSourceNode from '../sources/AudioBufferQueueSourceNode';
+import RecorderAdapterNode from '../sources/RecorderAdapterNode';
+import { InvalidAccessError, NotSupportedError } from '../../errors';
export default class BaseAudioContext {
readonly destination: AudioDestinationNode;
diff --git a/packages/react-native-audio-api/src/core/OfflineAudioContext.ts b/packages/react-native-audio-api/src/mobile/core/OfflineAudioContext.ts
similarity index 93%
rename from packages/react-native-audio-api/src/core/OfflineAudioContext.ts
rename to packages/react-native-audio-api/src/mobile/core/OfflineAudioContext.ts
index 837148d27..6ed506a43 100644
--- a/packages/react-native-audio-api/src/core/OfflineAudioContext.ts
+++ b/packages/react-native-audio-api/src/mobile/core/OfflineAudioContext.ts
@@ -1,8 +1,8 @@
import { IOfflineAudioContext } from '../interfaces';
import BaseAudioContext from './BaseAudioContext';
-import { OfflineAudioContextOptions } from '../types';
-import { InvalidStateError, NotSupportedError } from '../errors';
-import AudioBuffer from './AudioBuffer';
+import { OfflineAudioContextOptions } from '../../types';
+import { InvalidStateError, NotSupportedError } from '../../errors';
+import AudioBuffer from '../sources/AudioBuffer';
export default class OfflineAudioContext extends BaseAudioContext {
private isSuspended: boolean;
diff --git a/packages/react-native-audio-api/src/core/AudioDestinationNode.ts b/packages/react-native-audio-api/src/mobile/destinations/AudioDestinationNode.ts
similarity index 59%
rename from packages/react-native-audio-api/src/core/AudioDestinationNode.ts
rename to packages/react-native-audio-api/src/mobile/destinations/AudioDestinationNode.ts
index f1d850e90..ed658d83d 100644
--- a/packages/react-native-audio-api/src/core/AudioDestinationNode.ts
+++ b/packages/react-native-audio-api/src/mobile/destinations/AudioDestinationNode.ts
@@ -1,3 +1,3 @@
-import AudioNode from './AudioNode';
+import AudioNode from '../core/AudioNode';
export default class AudioDestinationNode extends AudioNode {}
diff --git a/packages/react-native-audio-api/src/core/BiquadFilterNode.ts b/packages/react-native-audio-api/src/mobile/effects/BiquadFilterNode.ts
similarity index 85%
rename from packages/react-native-audio-api/src/core/BiquadFilterNode.ts
rename to packages/react-native-audio-api/src/mobile/effects/BiquadFilterNode.ts
index 68db7c02a..1563cdc6b 100644
--- a/packages/react-native-audio-api/src/core/BiquadFilterNode.ts
+++ b/packages/react-native-audio-api/src/mobile/effects/BiquadFilterNode.ts
@@ -1,9 +1,9 @@
-import { InvalidAccessError } from '../errors';
+import { InvalidAccessError } from '../../errors';
import { IBiquadFilterNode } from '../interfaces';
-import AudioNode from './AudioNode';
-import AudioParam from './AudioParam';
-import BaseAudioContext from './BaseAudioContext';
-import { BiquadFilterType } from '../types';
+import AudioNode from '../core/AudioNode';
+import AudioParam from '../core/AudioParam';
+import BaseAudioContext from '../core/BaseAudioContext';
+import { BiquadFilterType } from '../../types';
export default class BiquadFilterNode extends AudioNode {
readonly frequency: AudioParam;
diff --git a/packages/react-native-audio-api/src/core/GainNode.ts b/packages/react-native-audio-api/src/mobile/effects/GainNode.ts
similarity index 64%
rename from packages/react-native-audio-api/src/core/GainNode.ts
rename to packages/react-native-audio-api/src/mobile/effects/GainNode.ts
index a216f1365..7900cadcc 100644
--- a/packages/react-native-audio-api/src/core/GainNode.ts
+++ b/packages/react-native-audio-api/src/mobile/effects/GainNode.ts
@@ -1,7 +1,7 @@
import { IGainNode } from '../interfaces';
-import AudioNode from './AudioNode';
-import AudioParam from './AudioParam';
-import BaseAudioContext from './BaseAudioContext';
+import AudioNode from '../core/AudioNode';
+import AudioParam from '../core/AudioParam';
+import BaseAudioContext from '../core/BaseAudioContext';
export default class GainNode extends AudioNode {
readonly gain: AudioParam;
diff --git a/packages/react-native-audio-api/src/core/PeriodicWave.ts b/packages/react-native-audio-api/src/mobile/effects/PeriodicWave.ts
similarity index 100%
rename from packages/react-native-audio-api/src/core/PeriodicWave.ts
rename to packages/react-native-audio-api/src/mobile/effects/PeriodicWave.ts
diff --git a/packages/react-native-audio-api/src/core/StereoPannerNode.ts b/packages/react-native-audio-api/src/mobile/effects/StereoPannerNode.ts
similarity index 66%
rename from packages/react-native-audio-api/src/core/StereoPannerNode.ts
rename to packages/react-native-audio-api/src/mobile/effects/StereoPannerNode.ts
index a8fa77006..c3ef409c1 100644
--- a/packages/react-native-audio-api/src/core/StereoPannerNode.ts
+++ b/packages/react-native-audio-api/src/mobile/effects/StereoPannerNode.ts
@@ -1,7 +1,7 @@
import { IStereoPannerNode } from '../interfaces';
-import AudioNode from './AudioNode';
-import AudioParam from './AudioParam';
-import BaseAudioContext from './BaseAudioContext';
+import AudioNode from '../core/AudioNode';
+import AudioParam from '../core/AudioParam';
+import BaseAudioContext from '../core/BaseAudioContext';
export default class StereoPannerNode extends AudioNode {
readonly pan: AudioParam;
diff --git a/packages/react-native-audio-api/src/events/AudioEventEmitter.ts b/packages/react-native-audio-api/src/mobile/events/AudioEventEmitter.ts
similarity index 100%
rename from packages/react-native-audio-api/src/events/AudioEventEmitter.ts
rename to packages/react-native-audio-api/src/mobile/events/AudioEventEmitter.ts
diff --git a/packages/react-native-audio-api/src/events/AudioEventSubscription.ts b/packages/react-native-audio-api/src/mobile/events/AudioEventSubscription.ts
similarity index 92%
rename from packages/react-native-audio-api/src/events/AudioEventSubscription.ts
rename to packages/react-native-audio-api/src/mobile/events/AudioEventSubscription.ts
index 8b82850b0..214ddef7b 100644
--- a/packages/react-native-audio-api/src/events/AudioEventSubscription.ts
+++ b/packages/react-native-audio-api/src/mobile/events/AudioEventSubscription.ts
@@ -1,5 +1,5 @@
import { AudioEventName } from './types';
-import { AudioEventEmitter } from './';
+import AudioEventEmitter from './AudioEventEmitter';
export default class AudioEventSubscription {
private readonly audioEventEmitter: AudioEventEmitter;
diff --git a/packages/react-native-audio-api/src/events/index.ts b/packages/react-native-audio-api/src/mobile/events/index.ts
similarity index 100%
rename from packages/react-native-audio-api/src/events/index.ts
rename to packages/react-native-audio-api/src/mobile/events/index.ts
diff --git a/packages/react-native-audio-api/src/events/types.ts b/packages/react-native-audio-api/src/mobile/events/types.ts
similarity index 97%
rename from packages/react-native-audio-api/src/events/types.ts
rename to packages/react-native-audio-api/src/mobile/events/types.ts
index 9a64e0ed3..ab5ea8fb1 100644
--- a/packages/react-native-audio-api/src/events/types.ts
+++ b/packages/react-native-audio-api/src/mobile/events/types.ts
@@ -1,4 +1,4 @@
-import AudioBuffer from '../core/AudioBuffer';
+import AudioBuffer from '../sources/AudioBuffer';
export interface EventEmptyType {}
diff --git a/packages/react-native-audio-api/src/hooks/useSytemVolume.ts b/packages/react-native-audio-api/src/mobile/hooks/useSystemVolume.ts
similarity index 100%
rename from packages/react-native-audio-api/src/hooks/useSytemVolume.ts
rename to packages/react-native-audio-api/src/mobile/hooks/useSystemVolume.ts
diff --git a/packages/react-native-audio-api/src/core/AudioRecorder.ts b/packages/react-native-audio-api/src/mobile/inputs/AudioRecorder.ts
similarity index 89%
rename from packages/react-native-audio-api/src/core/AudioRecorder.ts
rename to packages/react-native-audio-api/src/mobile/inputs/AudioRecorder.ts
index 77eedc389..69b439563 100644
--- a/packages/react-native-audio-api/src/core/AudioRecorder.ts
+++ b/packages/react-native-audio-api/src/mobile/inputs/AudioRecorder.ts
@@ -1,9 +1,9 @@
import { IAudioRecorder } from '../interfaces';
-import { AudioRecorderOptions } from '../types';
-import AudioBuffer from './AudioBuffer';
+import { AudioRecorderOptions } from '../../types';
+import AudioBuffer from '../sources/AudioBuffer';
import { OnAudioReadyEventType } from '../events/types';
import { AudioEventEmitter } from '../events';
-import RecorderAdapterNode from './RecorderAdapterNode';
+import RecorderAdapterNode from '../sources/RecorderAdapterNode';
export default class AudioRecorder {
protected readonly recorder: IAudioRecorder;
diff --git a/packages/react-native-audio-api/src/mobile/inputs/index.ts b/packages/react-native-audio-api/src/mobile/inputs/index.ts
new file mode 100644
index 000000000..af026ef1a
--- /dev/null
+++ b/packages/react-native-audio-api/src/mobile/inputs/index.ts
@@ -0,0 +1 @@
+export { default } from './AudioRecorder';
diff --git a/packages/react-native-audio-api/src/interfaces.ts b/packages/react-native-audio-api/src/mobile/interfaces.ts
similarity index 99%
rename from packages/react-native-audio-api/src/interfaces.ts
rename to packages/react-native-audio-api/src/mobile/interfaces.ts
index e0c3cf405..0637ba9ab 100644
--- a/packages/react-native-audio-api/src/interfaces.ts
+++ b/packages/react-native-audio-api/src/mobile/interfaces.ts
@@ -5,7 +5,7 @@ import {
BiquadFilterType,
ChannelCountMode,
ChannelInterpretation,
-} from './types';
+} from '../types';
import { AudioEventName, AudioEventCallback } from './events/types';
export interface IBaseAudioContext {
diff --git a/packages/react-native-audio-api/src/core/AudioBuffer.ts b/packages/react-native-audio-api/src/mobile/sources/AudioBuffer.ts
similarity index 97%
rename from packages/react-native-audio-api/src/core/AudioBuffer.ts
rename to packages/react-native-audio-api/src/mobile/sources/AudioBuffer.ts
index 671e48d9d..f695dd6ac 100644
--- a/packages/react-native-audio-api/src/core/AudioBuffer.ts
+++ b/packages/react-native-audio-api/src/mobile/sources/AudioBuffer.ts
@@ -1,5 +1,5 @@
import { IAudioBuffer } from '../interfaces';
-import { IndexSizeError } from '../errors';
+import { IndexSizeError } from '../../errors';
export default class AudioBuffer {
readonly length: number;
diff --git a/packages/react-native-audio-api/src/core/AudioBufferBaseSourceNode.ts b/packages/react-native-audio-api/src/mobile/sources/AudioBufferBaseSourceNode.ts
similarity index 94%
rename from packages/react-native-audio-api/src/core/AudioBufferBaseSourceNode.ts
rename to packages/react-native-audio-api/src/mobile/sources/AudioBufferBaseSourceNode.ts
index 28a409a75..ec2117930 100644
--- a/packages/react-native-audio-api/src/core/AudioBufferBaseSourceNode.ts
+++ b/packages/react-native-audio-api/src/mobile/sources/AudioBufferBaseSourceNode.ts
@@ -1,5 +1,5 @@
-import AudioParam from './AudioParam';
-import BaseAudioContext from './BaseAudioContext';
+import AudioParam from '../core/AudioParam';
+import BaseAudioContext from '../core/BaseAudioContext';
import { AudioEventSubscription } from '../events';
import { EventTypeWithValue } from '../events/types';
import { IAudioBufferBaseSourceNode } from '../interfaces';
diff --git a/packages/react-native-audio-api/src/core/AudioBufferQueueSourceNode.ts b/packages/react-native-audio-api/src/mobile/sources/AudioBufferQueueSourceNode.ts
similarity index 97%
rename from packages/react-native-audio-api/src/core/AudioBufferQueueSourceNode.ts
rename to packages/react-native-audio-api/src/mobile/sources/AudioBufferQueueSourceNode.ts
index bfc923d2a..73ca2d3f3 100644
--- a/packages/react-native-audio-api/src/core/AudioBufferQueueSourceNode.ts
+++ b/packages/react-native-audio-api/src/mobile/sources/AudioBufferQueueSourceNode.ts
@@ -1,7 +1,7 @@
import { IAudioBufferQueueSourceNode } from '../interfaces';
import AudioBufferBaseSourceNode from './AudioBufferBaseSourceNode';
import AudioBuffer from './AudioBuffer';
-import { RangeError } from '../errors';
+import { RangeError } from '../../errors';
export default class AudioBufferQueueSourceNode extends AudioBufferBaseSourceNode {
public enqueueBuffer(buffer: AudioBuffer): string {
diff --git a/packages/react-native-audio-api/src/core/AudioBufferSourceNode.ts b/packages/react-native-audio-api/src/mobile/sources/AudioBufferSourceNode.ts
similarity index 97%
rename from packages/react-native-audio-api/src/core/AudioBufferSourceNode.ts
rename to packages/react-native-audio-api/src/mobile/sources/AudioBufferSourceNode.ts
index 7bda1a425..fc66b3ddf 100644
--- a/packages/react-native-audio-api/src/core/AudioBufferSourceNode.ts
+++ b/packages/react-native-audio-api/src/mobile/sources/AudioBufferSourceNode.ts
@@ -1,7 +1,7 @@
import { IAudioBufferSourceNode } from '../interfaces';
import AudioBufferBaseSourceNode from './AudioBufferBaseSourceNode';
import AudioBuffer from './AudioBuffer';
-import { InvalidStateError, RangeError } from '../errors';
+import { InvalidStateError, RangeError } from '../../errors';
import { EventEmptyType } from '../events/types';
export default class AudioBufferSourceNode extends AudioBufferBaseSourceNode {
diff --git a/packages/react-native-audio-api/src/core/AudioScheduledSourceNode.ts b/packages/react-native-audio-api/src/mobile/sources/AudioScheduledSourceNode.ts
similarity index 82%
rename from packages/react-native-audio-api/src/core/AudioScheduledSourceNode.ts
rename to packages/react-native-audio-api/src/mobile/sources/AudioScheduledSourceNode.ts
index 80da6aeb0..0f62f48f5 100644
--- a/packages/react-native-audio-api/src/core/AudioScheduledSourceNode.ts
+++ b/packages/react-native-audio-api/src/mobile/sources/AudioScheduledSourceNode.ts
@@ -1,6 +1,6 @@
import { IAudioScheduledSourceNode } from '../interfaces';
-import AudioNode from './AudioNode';
-import { InvalidStateError, RangeError } from '../errors';
+import AudioNode from '../core/AudioNode';
+import { InvalidStateError, RangeError } from '../../errors';
import { OnEndedEventType } from '../events/types';
import { AudioEventEmitter, AudioEventSubscription } from '../events';
@@ -10,7 +10,7 @@ export default class AudioScheduledSourceNode extends AudioNode {
global.AudioEventEmitter
);
- private onendedSubscription?: AudioEventSubscription;
+ private onEndedSubscription?: AudioEventSubscription;
private onEndedCallback?: (event: OnEndedEventType) => void;
public start(when: number = 0): void {
@@ -51,19 +51,19 @@ export default class AudioScheduledSourceNode extends AudioNode {
public set onEnded(callback: ((event: OnEndedEventType) => void) | null) {
if (!callback) {
(this.node as IAudioScheduledSourceNode).onEnded = '0';
- this.onendedSubscription?.remove();
- this.onendedSubscription = undefined;
+ this.onEndedSubscription?.remove();
+ this.onEndedSubscription = undefined;
this.onEndedCallback = undefined;
return;
}
this.onEndedCallback = callback;
- this.onendedSubscription = this.audioEventEmitter.addAudioEventListener(
+ this.onEndedSubscription = this.audioEventEmitter.addAudioEventListener(
'ended',
callback
);
(this.node as IAudioScheduledSourceNode).onEnded =
- this.onendedSubscription.subscriptionId;
+ this.onEndedSubscription.subscriptionId;
}
}
diff --git a/packages/react-native-audio-api/src/core/OscillatorNode.ts b/packages/react-native-audio-api/src/mobile/sources/OscillatorNode.ts
similarity index 80%
rename from packages/react-native-audio-api/src/core/OscillatorNode.ts
rename to packages/react-native-audio-api/src/mobile/sources/OscillatorNode.ts
index 40248071e..85b71ea51 100644
--- a/packages/react-native-audio-api/src/core/OscillatorNode.ts
+++ b/packages/react-native-audio-api/src/mobile/sources/OscillatorNode.ts
@@ -1,10 +1,10 @@
import { IOscillatorNode } from '../interfaces';
-import { OscillatorType } from '../types';
+import { OscillatorType } from '../../types';
import AudioScheduledSourceNode from './AudioScheduledSourceNode';
-import AudioParam from './AudioParam';
-import BaseAudioContext from './BaseAudioContext';
-import PeriodicWave from './PeriodicWave';
-import { InvalidStateError } from '../errors';
+import AudioParam from '../core/AudioParam';
+import BaseAudioContext from '../core/BaseAudioContext';
+import PeriodicWave from '../effects/PeriodicWave';
+import { InvalidStateError } from '../../errors';
export default class OscillatorNode extends AudioScheduledSourceNode {
readonly frequency: AudioParam;
diff --git a/packages/react-native-audio-api/src/core/RecorderAdapterNode.ts b/packages/react-native-audio-api/src/mobile/sources/RecorderAdapterNode.ts
similarity index 87%
rename from packages/react-native-audio-api/src/core/RecorderAdapterNode.ts
rename to packages/react-native-audio-api/src/mobile/sources/RecorderAdapterNode.ts
index 75c194944..8487ecabc 100644
--- a/packages/react-native-audio-api/src/core/RecorderAdapterNode.ts
+++ b/packages/react-native-audio-api/src/mobile/sources/RecorderAdapterNode.ts
@@ -1,5 +1,5 @@
import { IRecorderAdapterNode } from '../interfaces';
-import AudioNode from './AudioNode';
+import AudioNode from '../core/AudioNode';
export default class RecorderAdapterNode extends AudioNode {
/** @internal */
diff --git a/packages/react-native-audio-api/src/system/AudioManager.ts b/packages/react-native-audio-api/src/mobile/system/AudioManager.ts
similarity index 98%
rename from packages/react-native-audio-api/src/system/AudioManager.ts
rename to packages/react-native-audio-api/src/mobile/system/AudioManager.ts
index 70a116ee4..d8d9dea20 100644
--- a/packages/react-native-audio-api/src/system/AudioManager.ts
+++ b/packages/react-native-audio-api/src/mobile/system/AudioManager.ts
@@ -9,7 +9,7 @@ import {
SystemEventCallback,
RemoteCommandEventName,
} from '../events/types';
-import { NativeAudioAPIModule } from '../specs';
+import { NativeAudioAPIModule } from '../../specs';
import { AudioEventEmitter, AudioEventSubscription } from '../events';
if (global.AudioEventEmitter == null) {
diff --git a/packages/react-native-audio-api/src/system/index.ts b/packages/react-native-audio-api/src/mobile/system/index.ts
similarity index 100%
rename from packages/react-native-audio-api/src/system/index.ts
rename to packages/react-native-audio-api/src/mobile/system/index.ts
diff --git a/packages/react-native-audio-api/src/system/types.ts b/packages/react-native-audio-api/src/mobile/system/types.ts
similarity index 100%
rename from packages/react-native-audio-api/src/system/types.ts
rename to packages/react-native-audio-api/src/mobile/system/types.ts
diff --git a/packages/react-native-audio-api/src/specs/NativeAudioAPIModule.ts b/packages/react-native-audio-api/src/specs/NativeAudioAPIModule.ts
index 6bab1ba39..f8edf54c2 100644
--- a/packages/react-native-audio-api/src/specs/NativeAudioAPIModule.ts
+++ b/packages/react-native-audio-api/src/specs/NativeAudioAPIModule.ts
@@ -1,7 +1,7 @@
'use strict';
import { TurboModuleRegistry } from 'react-native';
import type { TurboModule } from 'react-native';
-import { PermissionStatus, AudioDevicesInfo } from '../system/types';
+import { PermissionStatus, AudioDevicesInfo } from '../mobile/system/types';
interface Spec extends TurboModule {
install(): boolean;
diff --git a/packages/react-native-audio-api/src/web-core/BaseAudioContext.tsx b/packages/react-native-audio-api/src/web-core/BaseAudioContext.tsx
deleted file mode 100644
index 5cafcee77..000000000
--- a/packages/react-native-audio-api/src/web-core/BaseAudioContext.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { ContextState, PeriodicWaveConstraints } from '../types';
-import AnalyserNode from './AnalyserNode';
-import AudioDestinationNode from './AudioDestinationNode';
-import AudioBuffer from './AudioBuffer';
-import AudioBufferSourceNode from './AudioBufferSourceNode';
-import BiquadFilterNode from './BiquadFilterNode';
-import GainNode from './GainNode';
-import OscillatorNode from './OscillatorNode';
-import PeriodicWave from './PeriodicWave';
-import StereoPannerNode from './StereoPannerNode';
-
-export default interface BaseAudioContext {
- readonly context: globalThis.BaseAudioContext;
-
- readonly destination: AudioDestinationNode;
- readonly sampleRate: number;
-
- get currentTime(): number;
- get state(): ContextState;
- createOscillator(): OscillatorNode;
- createGain(): GainNode;
- createStereoPanner(): StereoPannerNode;
- createBiquadFilter(): BiquadFilterNode;
- createBufferSource(): Promise;
- createBuffer(
- numOfChannels: number,
- length: number,
- sampleRate: number
- ): AudioBuffer;
- createPeriodicWave(
- real: Float32Array,
- imag: Float32Array,
- constraints?: PeriodicWaveConstraints
- ): PeriodicWave;
- createAnalyser(): AnalyserNode;
- decodeAudioDataSource(source: string): Promise;
- decodeAudioData(arrayBuffer: ArrayBuffer): Promise;
-}
diff --git a/packages/react-native-audio-api/src/web-core/OfflineAudioContext.tsx b/packages/react-native-audio-api/src/web-core/OfflineAudioContext.tsx
deleted file mode 100644
index b4c6f95aa..000000000
--- a/packages/react-native-audio-api/src/web-core/OfflineAudioContext.tsx
+++ /dev/null
@@ -1,163 +0,0 @@
-import {
- ContextState,
- PeriodicWaveConstraints,
- OfflineAudioContextOptions,
- AudioBufferSourceNodeOptions,
-} from '../types';
-import { InvalidAccessError, NotSupportedError } from '../errors';
-import BaseAudioContext from './BaseAudioContext';
-import AnalyserNode from './AnalyserNode';
-import AudioDestinationNode from './AudioDestinationNode';
-import AudioBuffer from './AudioBuffer';
-import AudioBufferSourceNode from './AudioBufferSourceNode';
-import BiquadFilterNode from './BiquadFilterNode';
-import GainNode from './GainNode';
-import OscillatorNode from './OscillatorNode';
-import PeriodicWave from './PeriodicWave';
-import StereoPannerNode from './StereoPannerNode';
-
-import { globalWasmPromise, globalTag } from './custom/LoadCustomWasm';
-
-export default class OfflineAudioContext implements BaseAudioContext {
- readonly context: globalThis.OfflineAudioContext;
-
- readonly destination: AudioDestinationNode;
- readonly sampleRate: number;
-
- constructor(options: OfflineAudioContextOptions);
- constructor(numberOfChannels: number, length: number, sampleRate: number);
- constructor(
- arg0: OfflineAudioContextOptions | number,
- arg1?: number,
- arg2?: number
- ) {
- if (typeof arg0 === 'object') {
- this.context = new window.OfflineAudioContext(arg0);
- } else if (
- typeof arg0 === 'number' &&
- typeof arg1 === 'number' &&
- typeof arg2 === 'number'
- ) {
- this.context = new window.OfflineAudioContext(arg0, arg1, arg2);
- } else {
- throw new NotSupportedError('Invalid constructor arguments');
- }
-
- this.sampleRate = this.context.sampleRate;
- this.destination = new AudioDestinationNode(this, this.context.destination);
- }
-
- public get currentTime(): number {
- return this.context.currentTime;
- }
-
- public get state(): ContextState {
- return this.context.state as ContextState;
- }
-
- createOscillator(): OscillatorNode {
- return new OscillatorNode(this, this.context.createOscillator());
- }
-
- createGain(): GainNode {
- return new GainNode(this, this.context.createGain());
- }
-
- createStereoPanner(): StereoPannerNode {
- return new StereoPannerNode(this, this.context.createStereoPanner());
- }
-
- createBiquadFilter(): BiquadFilterNode {
- return new BiquadFilterNode(this, this.context.createBiquadFilter());
- }
-
- async createBufferSource(
- options?: AudioBufferSourceNodeOptions
- ): Promise {
- if (!options || !options.pitchCorrection) {
- return new AudioBufferSourceNode(
- this,
- this.context.createBufferSource(),
- false
- );
- }
-
- await globalWasmPromise;
-
- const wasmStretch = await window[globalTag](this.context);
-
- return new AudioBufferSourceNode(this, wasmStretch, true);
- }
-
- createBuffer(
- numOfChannels: number,
- length: number,
- sampleRate: number
- ): AudioBuffer {
- if (numOfChannels < 1 || numOfChannels >= 32) {
- throw new NotSupportedError(
- `The number of channels provided (${numOfChannels}) is outside the range [1, 32]`
- );
- }
-
- if (length <= 0) {
- throw new NotSupportedError(
- `The number of frames provided (${length}) is less than or equal to the minimum bound (0)`
- );
- }
-
- if (sampleRate < 8000 || sampleRate > 96000) {
- throw new NotSupportedError(
- `The sample rate provided (${sampleRate}) is outside the range [8000, 96000]`
- );
- }
-
- return new AudioBuffer(
- this.context.createBuffer(numOfChannels, 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.context.createPeriodicWave(real, imag, constraints)
- );
- }
-
- createAnalyser(): AnalyserNode {
- return new AnalyserNode(this, this.context.createAnalyser());
- }
-
- async decodeAudioDataSource(source: string): Promise {
- const arrayBuffer = await fetch(source).then((response) =>
- response.arrayBuffer()
- );
-
- return this.decodeAudioData(arrayBuffer);
- }
-
- async decodeAudioData(arrayBuffer: ArrayBuffer): Promise {
- return new AudioBuffer(await this.context.decodeAudioData(arrayBuffer));
- }
-
- async startRendering(): Promise {
- return new AudioBuffer(await this.context.startRendering());
- }
-
- async resume(): Promise {
- await this.context.resume();
- }
-
- async suspend(suspendTime: number): Promise {
- await this.context.suspend(suspendTime);
- }
-}
diff --git a/packages/react-native-audio-api/src/web-core/AnalyserNode.tsx b/packages/react-native-audio-api/src/web/analysis/AnalyserNode.tsx
similarity index 79%
rename from packages/react-native-audio-api/src/web-core/AnalyserNode.tsx
rename to packages/react-native-audio-api/src/web/analysis/AnalyserNode.tsx
index c74b67e05..7b7e193a1 100644
--- a/packages/react-native-audio-api/src/web-core/AnalyserNode.tsx
+++ b/packages/react-native-audio-api/src/web/analysis/AnalyserNode.tsx
@@ -1,6 +1,6 @@
-import AudioNode from './AudioNode';
-import { WindowType } from '../types';
-import BaseAudioContext from './BaseAudioContext';
+import AudioNode from '../core/AudioNode';
+import BaseAudioContext from '../core/BaseAudioContext';
+import { WindowType } from '../../types';
export default class AnalyserNode extends AudioNode {
fftSize: number;
@@ -20,13 +20,12 @@ export default class AnalyserNode extends AudioNode {
}
public get window(): WindowType {
+ console.warn('React Native Audio API: window prop is not supported on web');
return 'blackman';
}
public set window(value: WindowType) {
- console.log(
- 'React Native Audio API: setting window is not supported on web'
- );
+ console.warn('React Native Audio API: window prop is not supported on web');
}
public getByteFrequencyData(array: Uint8Array): void {
diff --git a/packages/react-native-audio-api/src/web/core/AudioContext.tsx b/packages/react-native-audio-api/src/web/core/AudioContext.tsx
new file mode 100644
index 000000000..063258c40
--- /dev/null
+++ b/packages/react-native-audio-api/src/web/core/AudioContext.tsx
@@ -0,0 +1,31 @@
+import { AudioContextOptions } from '../../types';
+import { NotSupportedError } from '../../errors';
+import BaseAudioContext from './BaseAudioContext';
+
+export default class AudioContext extends BaseAudioContext {
+ constructor(options?: AudioContextOptions, _initSuspended: boolean = false) {
+ if (
+ options &&
+ options.sampleRate &&
+ (options.sampleRate < 8000 || options.sampleRate > 96000)
+ ) {
+ throw new NotSupportedError(
+ `The provided sampleRate is not supported: ${options.sampleRate}`
+ );
+ }
+
+ super(new window.AudioContext({ sampleRate: options?.sampleRate }));
+ }
+
+ async close(): Promise {
+ await (this.context as globalThis.AudioContext).close();
+ }
+
+ async resume(): Promise {
+ await (this.context as globalThis.AudioContext).resume();
+ }
+
+ async suspend(): Promise {
+ await (this.context as globalThis.AudioContext).suspend();
+ }
+}
diff --git a/packages/react-native-audio-api/src/web-core/AudioNode.tsx b/packages/react-native-audio-api/src/web/core/AudioNode.tsx
similarity index 71%
rename from packages/react-native-audio-api/src/web-core/AudioNode.tsx
rename to packages/react-native-audio-api/src/web/core/AudioNode.tsx
index a66113f1f..2921ceddf 100644
--- a/packages/react-native-audio-api/src/web-core/AudioNode.tsx
+++ b/packages/react-native-audio-api/src/web/core/AudioNode.tsx
@@ -1,6 +1,7 @@
import BaseAudioContext from './BaseAudioContext';
-import { ChannelCountMode, ChannelInterpretation } from '../types';
+import { ChannelCountMode, ChannelInterpretation } from '../../types';
import AudioParam from './AudioParam';
+import { InvalidAccessError } from '../../errors';
export default class AudioNode {
readonly context: BaseAudioContext;
@@ -24,13 +25,13 @@ export default class AudioNode {
public connect(destination: AudioNode | AudioParam): AudioNode | AudioParam {
if (this.context !== destination.context) {
- throw new Error(
+ throw new InvalidAccessError(
'Source and destination are from different BaseAudioContexts'
);
}
if (destination instanceof AudioParam) {
- this.node.connect(destination.param);
+ this.node.connect(destination.audioParam);
} else {
this.node.connect(destination.node);
}
@@ -38,12 +39,13 @@ export default class AudioNode {
return destination;
}
- public disconnect(destination?: AudioNode): void {
- if (destination === undefined) {
+ public disconnect(destination?: AudioNode | AudioParam): void {
+ if (destination instanceof AudioParam) {
+ this.node.disconnect(destination.audioParam);
+ } else if (destination instanceof AudioNode) {
+ this.node.disconnect(destination.node);
+ } else {
this.node.disconnect();
- return;
}
-
- this.node.disconnect(destination.node);
}
}
diff --git a/packages/react-native-audio-api/src/web-core/AudioParam.tsx b/packages/react-native-audio-api/src/web/core/AudioParam.tsx
similarity index 74%
rename from packages/react-native-audio-api/src/web-core/AudioParam.tsx
rename to packages/react-native-audio-api/src/web/core/AudioParam.tsx
index 341f59e55..e8ce67ef4 100644
--- a/packages/react-native-audio-api/src/web-core/AudioParam.tsx
+++ b/packages/react-native-audio-api/src/web/core/AudioParam.tsx
@@ -1,4 +1,4 @@
-import { RangeError, InvalidStateError } from '../errors';
+import { RangeError, InvalidStateError } from '../../errors';
import BaseAudioContext from './BaseAudioContext';
export default class AudioParam {
@@ -7,22 +7,22 @@ export default class AudioParam {
readonly maxValue: number;
readonly context: BaseAudioContext;
- readonly param: globalThis.AudioParam;
+ readonly audioParam: globalThis.AudioParam;
- constructor(param: globalThis.AudioParam, context: BaseAudioContext) {
- this.param = param;
- this.defaultValue = param.defaultValue;
- this.minValue = param.minValue;
- this.maxValue = param.maxValue;
+ constructor(audioParam: globalThis.AudioParam, context: BaseAudioContext) {
+ this.audioParam = audioParam;
+ this.defaultValue = audioParam.defaultValue;
+ this.minValue = audioParam.minValue;
+ this.maxValue = audioParam.maxValue;
this.context = context;
}
public get value(): number {
- return this.param.value;
+ return this.audioParam.value;
}
public set value(value: number) {
- this.param.value = value;
+ this.audioParam.value = value;
}
public setValueAtTime(value: number, startTime: number): AudioParam {
@@ -32,7 +32,7 @@ export default class AudioParam {
);
}
- this.param.setValueAtTime(value, startTime);
+ this.audioParam.setValueAtTime(value, startTime);
return this;
}
@@ -44,7 +44,7 @@ export default class AudioParam {
);
}
- this.param.linearRampToValueAtTime(value, endTime);
+ this.audioParam.linearRampToValueAtTime(value, endTime);
return this;
}
@@ -59,7 +59,7 @@ export default class AudioParam {
);
}
- this.param.exponentialRampToValueAtTime(value, endTime);
+ this.audioParam.exponentialRampToValueAtTime(value, endTime);
return this;
}
@@ -81,7 +81,7 @@ export default class AudioParam {
);
}
- this.param.setTargetAtTime(target, startTime, timeConstant);
+ this.audioParam.setTargetAtTime(target, startTime, timeConstant);
return this;
}
@@ -107,7 +107,7 @@ export default class AudioParam {
throw new InvalidStateError(`values must contain at least two values`);
}
- this.param.setValueCurveAtTime(values, startTime, duration);
+ this.audioParam.setValueCurveAtTime(values, startTime, duration);
return this;
}
@@ -119,7 +119,7 @@ export default class AudioParam {
);
}
- this.param.cancelScheduledValues(cancelTime);
+ this.audioParam.cancelScheduledValues(cancelTime);
return this;
}
@@ -131,7 +131,7 @@ export default class AudioParam {
);
}
- this.param.cancelAndHoldAtTime(cancelTime);
+ this.audioParam.cancelAndHoldAtTime(cancelTime);
return this;
}
diff --git a/packages/react-native-audio-api/src/web-core/AudioContext.tsx b/packages/react-native-audio-api/src/web/core/BaseAudioContext.tsx
similarity index 68%
rename from packages/react-native-audio-api/src/web-core/AudioContext.tsx
rename to packages/react-native-audio-api/src/web/core/BaseAudioContext.tsx
index 78ada7bf1..e87e056cb 100644
--- a/packages/react-native-audio-api/src/web-core/AudioContext.tsx
+++ b/packages/react-native-audio-api/src/web/core/BaseAudioContext.tsx
@@ -1,44 +1,30 @@
import {
ContextState,
PeriodicWaveConstraints,
- AudioContextOptions,
AudioBufferSourceNodeOptions,
-} from '../types';
-import { InvalidAccessError, NotSupportedError } from '../errors';
-import BaseAudioContext from './BaseAudioContext';
-import AnalyserNode from './AnalyserNode';
-import AudioDestinationNode from './AudioDestinationNode';
-import AudioBuffer from './AudioBuffer';
-import AudioBufferSourceNode from './AudioBufferSourceNode';
-import BiquadFilterNode from './BiquadFilterNode';
-import GainNode from './GainNode';
-import OscillatorNode from './OscillatorNode';
-import PeriodicWave from './PeriodicWave';
-import StereoPannerNode from './StereoPannerNode';
-
-import { globalWasmPromise, globalTag } from './custom/LoadCustomWasm';
-
-export default class AudioContext implements BaseAudioContext {
- readonly context: globalThis.AudioContext;
-
+} from '../../types';
+import AudioDestinationNode from '../destinations/AudioDestinationNode';
+import OscillatorNode from '../sources/OscillatorNode';
+import GainNode from '../effects/GainNode';
+import StereoPannerNode from '../effects/StereoPannerNode';
+import BiquadFilterNode from '../effects/BiquadFilterNode';
+import AudioBufferSourceNode from '../sources/AudioBufferSourceNode';
+import AudioBuffer from '../sources/AudioBuffer';
+import PeriodicWave from '../effects/PeriodicWave';
+import AnalyserNode from '../analysis/AnalyserNode';
+import { InvalidAccessError, NotSupportedError } from '../../errors';
+
+import { globalWasmPromise, globalTag } from '../custom/LoadCustomWasm';
+
+export default class BaseAudioContext {
+ protected readonly context: globalThis.BaseAudioContext;
readonly destination: AudioDestinationNode;
readonly sampleRate: number;
- constructor(options?: AudioContextOptions, _initSuspended: boolean = false) {
- if (
- options &&
- options.sampleRate &&
- (options.sampleRate < 8000 || options.sampleRate > 96000)
- ) {
- throw new NotSupportedError(
- `The provided sampleRate is not supported: ${options.sampleRate}`
- );
- }
-
- this.context = new window.AudioContext({ sampleRate: options?.sampleRate });
-
- this.sampleRate = this.context.sampleRate;
+ constructor(context: globalThis.BaseAudioContext) {
+ this.context = context;
this.destination = new AudioDestinationNode(this, this.context.destination);
+ this.sampleRate = this.context.sampleRate;
}
public get currentTime(): number {
@@ -65,6 +51,7 @@ export default class AudioContext implements BaseAudioContext {
return new BiquadFilterNode(this, this.context.createBiquadFilter());
}
+ // UNIFIED IT SOMEHOW
async createBufferSource(
options?: AudioBufferSourceNodeOptions
): Promise {
@@ -143,15 +130,15 @@ export default class AudioContext implements BaseAudioContext {
return new AudioBuffer(await this.context.decodeAudioData(arrayBuffer));
}
- async close(): Promise {
- await this.context.close();
- }
-
- async resume(): Promise {
- await this.context.resume();
- }
+ // TODO: IMPLEMENT IT
+ // eslint-disable-next-line @typescript-eslint/require-await
+ async decodePCMInBase64Data(
+ base64: string,
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ playbackRate: number = 1.0
+ ): Promise {
+ console.warn('decodePCMInBase64Data does not work on web');
- async suspend(): Promise {
- await this.context.suspend();
+ return this.createBuffer(2, 48000, this.sampleRate);
}
}
diff --git a/packages/react-native-audio-api/src/web/core/OfflineAudioContext.tsx b/packages/react-native-audio-api/src/web/core/OfflineAudioContext.tsx
new file mode 100644
index 000000000..741ab1f3a
--- /dev/null
+++ b/packages/react-native-audio-api/src/web/core/OfflineAudioContext.tsx
@@ -0,0 +1,93 @@
+import { OfflineAudioContextOptions } from '../../types';
+import { NotSupportedError, InvalidStateError } from '../../errors';
+import BaseAudioContext from './BaseAudioContext';
+import AudioBuffer from '../sources/AudioBuffer';
+
+export default class OfflineAudioContext extends BaseAudioContext {
+ private isSuspended: boolean;
+ private isRendering: boolean;
+ private duration: number;
+
+ constructor(options: OfflineAudioContextOptions);
+ constructor(numberOfChannels: number, length: number, sampleRate: number);
+ constructor(
+ arg0: OfflineAudioContextOptions | number,
+ arg1?: number,
+ arg2?: number
+ ) {
+ if (typeof arg0 === 'object') {
+ const { numberOfChannels, length, sampleRate } = arg0;
+ super(
+ new window.OfflineAudioContext(numberOfChannels, length, sampleRate)
+ );
+
+ this.duration = length / sampleRate;
+ } else if (
+ typeof arg0 === 'number' &&
+ typeof arg1 === 'number' &&
+ typeof arg2 === 'number'
+ ) {
+ super(new window.OfflineAudioContext(arg0, arg1, arg2));
+ this.duration = arg1 / arg2;
+ } else {
+ throw new NotSupportedError('Invalid constructor arguments');
+ }
+
+ this.isSuspended = false;
+ this.isRendering = false;
+ }
+
+ async resume(): Promise {
+ if (!this.isRendering) {
+ throw new InvalidStateError(
+ 'Cannot resume an OfflineAudioContext while rendering'
+ );
+ }
+
+ if (!this.isSuspended) {
+ throw new InvalidStateError(
+ 'Cannot resume an OfflineAudioContext that is not suspended'
+ );
+ }
+
+ this.isSuspended = false;
+
+ await (this.context as globalThis.OfflineAudioContext).resume();
+ }
+
+ async suspend(suspendTime: number): Promise {
+ if (suspendTime < 0) {
+ throw new InvalidStateError('suspendTime must be a non-negative number');
+ }
+
+ if (suspendTime < this.context.currentTime) {
+ throw new InvalidStateError(
+ `suspendTime must be greater than the current time: ${suspendTime}`
+ );
+ }
+
+ if (suspendTime > this.duration) {
+ throw new InvalidStateError(
+ `suspendTime must be less than the duration of the context: ${suspendTime}`
+ );
+ }
+
+ this.isSuspended = true;
+
+ await (this.context as globalThis.OfflineAudioContext).suspend(suspendTime);
+ }
+
+ async startRendering(): Promise {
+ if (this.isRendering) {
+ throw new InvalidStateError('OfflineAudioContext is already rendering');
+ }
+
+ this.isRendering = true;
+
+ const audioBuffer = await (
+ this.context as globalThis.OfflineAudioContext
+ ).startRendering();
+
+ return new AudioBuffer(audioBuffer);
+ }
+}
diff --git a/packages/react-native-audio-api/src/web-core/custom/LoadCustomWasm.ts b/packages/react-native-audio-api/src/web/custom/LoadCustomWasm.ts
similarity index 100%
rename from packages/react-native-audio-api/src/web-core/custom/LoadCustomWasm.ts
rename to packages/react-native-audio-api/src/web/custom/LoadCustomWasm.ts
diff --git a/packages/react-native-audio-api/src/web-core/custom/index.ts b/packages/react-native-audio-api/src/web/custom/index.ts
similarity index 100%
rename from packages/react-native-audio-api/src/web-core/custom/index.ts
rename to packages/react-native-audio-api/src/web/custom/index.ts
diff --git a/packages/react-native-audio-api/src/web-core/custom/signalsmithStretch/LICENSE.txt b/packages/react-native-audio-api/src/web/custom/signalsmithStretch/LICENSE.txt
similarity index 100%
rename from packages/react-native-audio-api/src/web-core/custom/signalsmithStretch/LICENSE.txt
rename to packages/react-native-audio-api/src/web/custom/signalsmithStretch/LICENSE.txt
diff --git a/packages/react-native-audio-api/src/web-core/custom/signalsmithStretch/README.md b/packages/react-native-audio-api/src/web/custom/signalsmithStretch/README.md
similarity index 100%
rename from packages/react-native-audio-api/src/web-core/custom/signalsmithStretch/README.md
rename to packages/react-native-audio-api/src/web/custom/signalsmithStretch/README.md
diff --git a/packages/react-native-audio-api/src/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs b/packages/react-native-audio-api/src/web/custom/signalsmithStretch/SignalsmithStretch.mjs
similarity index 100%
rename from packages/react-native-audio-api/src/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs
rename to packages/react-native-audio-api/src/web/custom/signalsmithStretch/SignalsmithStretch.mjs
diff --git a/packages/react-native-audio-api/src/web-core/AudioDestinationNode.tsx b/packages/react-native-audio-api/src/web/destinations/AudioDestinationNode.tsx
similarity index 59%
rename from packages/react-native-audio-api/src/web-core/AudioDestinationNode.tsx
rename to packages/react-native-audio-api/src/web/destinations/AudioDestinationNode.tsx
index f1d850e90..ed658d83d 100644
--- a/packages/react-native-audio-api/src/web-core/AudioDestinationNode.tsx
+++ b/packages/react-native-audio-api/src/web/destinations/AudioDestinationNode.tsx
@@ -1,3 +1,3 @@
-import AudioNode from './AudioNode';
+import AudioNode from '../core/AudioNode';
export default class AudioDestinationNode extends AudioNode {}
diff --git a/packages/react-native-audio-api/src/web-core/BiquadFilterNode.tsx b/packages/react-native-audio-api/src/web/effects/BiquadFilterNode.tsx
similarity index 85%
rename from packages/react-native-audio-api/src/web-core/BiquadFilterNode.tsx
rename to packages/react-native-audio-api/src/web/effects/BiquadFilterNode.tsx
index 4a8a4df21..c9e9a32d8 100644
--- a/packages/react-native-audio-api/src/web-core/BiquadFilterNode.tsx
+++ b/packages/react-native-audio-api/src/web/effects/BiquadFilterNode.tsx
@@ -1,8 +1,8 @@
-import AudioParam from './AudioParam';
-import AudioNode from './AudioNode';
-import BaseAudioContext from './BaseAudioContext';
-import { BiquadFilterType } from '../types';
-import { InvalidAccessError } from '../errors';
+import AudioParam from '../core/AudioParam';
+import AudioNode from '../core/AudioNode';
+import BaseAudioContext from '../core/BaseAudioContext';
+import { BiquadFilterType } from '../../types';
+import { InvalidAccessError } from '../../errors';
export default class BiquadFilterNode extends AudioNode {
readonly frequency: AudioParam;
diff --git a/packages/react-native-audio-api/src/web-core/GainNode.tsx b/packages/react-native-audio-api/src/web/effects/GainNode.tsx
similarity index 61%
rename from packages/react-native-audio-api/src/web-core/GainNode.tsx
rename to packages/react-native-audio-api/src/web/effects/GainNode.tsx
index 601de5920..d524dd067 100644
--- a/packages/react-native-audio-api/src/web-core/GainNode.tsx
+++ b/packages/react-native-audio-api/src/web/effects/GainNode.tsx
@@ -1,6 +1,6 @@
-import BaseAudioContext from './BaseAudioContext';
-import AudioNode from './AudioNode';
-import AudioParam from './AudioParam';
+import AudioParam from '../core/AudioParam';
+import AudioNode from '../core/AudioNode';
+import BaseAudioContext from '../core/BaseAudioContext';
export default class GainNode extends AudioNode {
readonly gain: AudioParam;
diff --git a/packages/react-native-audio-api/src/web-core/PeriodicWave.tsx b/packages/react-native-audio-api/src/web/effects/PeriodicWave.tsx
similarity index 100%
rename from packages/react-native-audio-api/src/web-core/PeriodicWave.tsx
rename to packages/react-native-audio-api/src/web/effects/PeriodicWave.tsx
diff --git a/packages/react-native-audio-api/src/web-core/StereoPannerNode.tsx b/packages/react-native-audio-api/src/web/effects/StereoPannerNode.tsx
similarity index 62%
rename from packages/react-native-audio-api/src/web-core/StereoPannerNode.tsx
rename to packages/react-native-audio-api/src/web/effects/StereoPannerNode.tsx
index 2d468a205..1ab12ce3c 100644
--- a/packages/react-native-audio-api/src/web-core/StereoPannerNode.tsx
+++ b/packages/react-native-audio-api/src/web/effects/StereoPannerNode.tsx
@@ -1,6 +1,6 @@
-import BaseAudioContext from './BaseAudioContext';
-import AudioNode from './AudioNode';
-import AudioParam from './AudioParam';
+import AudioParam from '../core/AudioParam';
+import AudioNode from '../core/AudioNode';
+import BaseAudioContext from '../core/BaseAudioContext';
export default class StereoPannerNode extends AudioNode {
readonly pan: AudioParam;
diff --git a/packages/react-native-audio-api/src/web-core/AudioBuffer.tsx b/packages/react-native-audio-api/src/web/sources/AudioBuffer.tsx
similarity index 97%
rename from packages/react-native-audio-api/src/web-core/AudioBuffer.tsx
rename to packages/react-native-audio-api/src/web/sources/AudioBuffer.tsx
index d007a6dd4..f71cb3b16 100644
--- a/packages/react-native-audio-api/src/web-core/AudioBuffer.tsx
+++ b/packages/react-native-audio-api/src/web/sources/AudioBuffer.tsx
@@ -1,4 +1,4 @@
-import { IndexSizeError } from '../errors';
+import { IndexSizeError } from '../../errors';
export default class AudioBuffer {
readonly length: number;
diff --git a/packages/react-native-audio-api/src/web-core/AudioBufferSourceNode.tsx b/packages/react-native-audio-api/src/web/sources/AudioBufferSourceNode.tsx
similarity index 93%
rename from packages/react-native-audio-api/src/web-core/AudioBufferSourceNode.tsx
rename to packages/react-native-audio-api/src/web/sources/AudioBufferSourceNode.tsx
index 71c749848..25d047010 100644
--- a/packages/react-native-audio-api/src/web-core/AudioBufferSourceNode.tsx
+++ b/packages/react-native-audio-api/src/web/sources/AudioBufferSourceNode.tsx
@@ -1,12 +1,12 @@
-import { InvalidStateError, RangeError } from '../errors';
+import { InvalidStateError, RangeError } from '../../errors';
-import AudioParam from './AudioParam';
+import AudioParam from '../core/AudioParam';
import AudioBuffer from './AudioBuffer';
-import BaseAudioContext from './BaseAudioContext';
+import BaseAudioContext from '../core/BaseAudioContext';
import AudioScheduledSourceNode from './AudioScheduledSourceNode';
-import { clamp } from '../utils';
-import { globalTag } from './custom/LoadCustomWasm';
+import { clamp } from '../../utils';
+import { globalTag } from '../custom/LoadCustomWasm';
interface ScheduleOptions {
rate?: number;
@@ -26,7 +26,7 @@ interface IStretcherNode extends globalThis.AudioNode {
numberOfInputs: number;
numberOfOutputs: number;
- onended:
+ onEnded:
| ((this: globalThis.AudioScheduledSourceNode, ev: Event) => unknown)
| null;
addEventListener: (
@@ -193,6 +193,7 @@ export default class AudioBufferSourceNode<
private _loop: boolean = false;
private _loopStart: number = -1;
private _loopEnd: number = -1;
+ private _loopSkip: boolean = false;
private _buffer: AudioBuffer | null = null;
@@ -319,6 +320,24 @@ export default class AudioBufferSourceNode<
return this.asBufferSource().loop;
}
+ public set loopSkip(value: boolean) {
+ console.warn('loopSkip does not work on web');
+
+ if (this.isStretcherNode()) {
+ this._loop = value;
+ }
+ }
+
+ public get loopSkip(): boolean {
+ console.warn('loopSkip does not work on web');
+
+ if (this.isStretcherNode()) {
+ return this._loopSkip;
+ }
+
+ return false;
+ }
+
public set loop(value: boolean) {
if (this.isStretcherNode()) {
this._loop = value;
diff --git a/packages/react-native-audio-api/src/web-core/AudioScheduledSourceNode.tsx b/packages/react-native-audio-api/src/web/sources/AudioScheduledSourceNode.tsx
similarity index 66%
rename from packages/react-native-audio-api/src/web-core/AudioScheduledSourceNode.tsx
rename to packages/react-native-audio-api/src/web/sources/AudioScheduledSourceNode.tsx
index 89566c3ae..8005c9fa0 100644
--- a/packages/react-native-audio-api/src/web-core/AudioScheduledSourceNode.tsx
+++ b/packages/react-native-audio-api/src/web/sources/AudioScheduledSourceNode.tsx
@@ -1,10 +1,11 @@
-import AudioNode from './AudioNode';
-import { EventEmptyType } from '../events/types';
-import { RangeError, InvalidStateError } from '../errors';
+import AudioNode from '../core/AudioNode';
+import { RangeError, InvalidStateError } from '../../errors';
export default class AudioScheduledSourceNode extends AudioNode {
protected hasBeenStarted: boolean = false;
+ private onEndedCallback?: () => void;
+
public start(when: number = 0): void {
if (when < 0) {
throw new RangeError(
@@ -36,8 +37,18 @@ export default class AudioScheduledSourceNode extends AudioNode {
(this.node as globalThis.AudioScheduledSourceNode).stop(when);
}
- // eslint-disable-next-line accessor-pairs
- public set onended(callback: (event: EventEmptyType) => void) {
+ public get onEnded(): (() => void) | undefined {
+ return this.onEndedCallback;
+ }
+
+ public set onEnded(callback: (() => void) | null) {
+ if (!callback) {
+ (this.node as globalThis.AudioScheduledSourceNode).onended = null;
+ this.onEndedCallback = undefined;
+ return;
+ }
+
+ this.onEndedCallback = callback;
(this.node as globalThis.AudioScheduledSourceNode).onended = callback;
}
}
diff --git a/packages/react-native-audio-api/src/web-core/OscillatorNode.tsx b/packages/react-native-audio-api/src/web/sources/OscillatorNode.tsx
similarity index 79%
rename from packages/react-native-audio-api/src/web-core/OscillatorNode.tsx
rename to packages/react-native-audio-api/src/web/sources/OscillatorNode.tsx
index 612cdd9f6..905fb2a60 100644
--- a/packages/react-native-audio-api/src/web-core/OscillatorNode.tsx
+++ b/packages/react-native-audio-api/src/web/sources/OscillatorNode.tsx
@@ -1,9 +1,9 @@
-import { OscillatorType } from '../types';
-import { InvalidStateError } from '../errors';
+import { OscillatorType } from '../../types';
+import { InvalidStateError } from '../../errors';
import AudioScheduledSourceNode from './AudioScheduledSourceNode';
-import BaseAudioContext from './BaseAudioContext';
-import AudioParam from './AudioParam';
-import PeriodicWave from './PeriodicWave';
+import BaseAudioContext from '../core/BaseAudioContext';
+import AudioParam from '../core/AudioParam';
+import PeriodicWave from '../effects/PeriodicWave';
export default class OscillatorNode extends AudioScheduledSourceNode {
readonly frequency: AudioParam;