diff --git a/apps/common-app/src/examples/AudioVisualizer/AudioVisualizer.tsx b/apps/common-app/src/examples/AudioVisualizer/AudioVisualizer.tsx
index 638239b00..9a11f9af2 100644
--- a/apps/common-app/src/examples/AudioVisualizer/AudioVisualizer.tsx
+++ b/apps/common-app/src/examples/AudioVisualizer/AudioVisualizer.tsx
@@ -105,10 +105,7 @@ const AudioVisualizer: React.FC = () => {
}
if (!analyserRef.current) {
- analyserRef.current = audioContextRef.current.createAnalyser();
- analyserRef.current.fftSize = FFT_SIZE;
- analyserRef.current.smoothingTimeConstant = 0.2;
-
+ analyserRef.current = new AnalyserNode(audioContextRef.current, { fftSize: FFT_SIZE, smoothingTimeConstant: 0.2 });
analyserRef.current.connect(audioContextRef.current.destination);
}
diff --git a/packages/audiodocs/docs/core/audio-node.mdx b/packages/audiodocs/docs/core/audio-node.mdx
index 26aa21223..b6db096bc 100644
--- a/packages/audiodocs/docs/core/audio-node.mdx
+++ b/packages/audiodocs/docs/core/audio-node.mdx
@@ -111,6 +111,18 @@ If no arguments provided node disconnects from all outgoing connections.
#### Returns `undefined`.
+### `AudioNodeOptions`
+
+It is used to constructing majority of all `AudioNodes`.
+
+| Parameter | Type | Default | Description |
+| :---: | :---: | :----: | :---- |
+| `channelCount` | `number` | 2 | Indicates number of channels used in mixing of node. |
+| `channelCountMode` | [`ChannelCountMode`](/docs/types/channel-count-mode) | `max` | Determines how the number of input channels affects the number of output channels in an audio node. |
+| `channelInterpretation` | [`ChannelInterpretation`](/docs/types/channel-interpretation) | `speakers` | Specifies how input channels are mapped out to output channels when the number of them are different. |
+
+If any of these values are not provided, default values are used.
+
## Remarks
#### `numberOfInputs`
diff --git a/packages/audiodocs/docs/effects/gain-node.mdx b/packages/audiodocs/docs/effects/gain-node.mdx
index 42fb43d57..adfa4eb19 100644
--- a/packages/audiodocs/docs/effects/gain-node.mdx
+++ b/packages/audiodocs/docs/effects/gain-node.mdx
@@ -3,7 +3,7 @@ sidebar_position: 2
---
import AudioNodePropsTable from "@site/src/components/AudioNodePropsTable"
-import { ReadOnly } from '@site/src/components/Badges';
+import { Optional, ReadOnly } from '@site/src/components/Badges';
import { useGainAdsrPlayground } from '@site/src/components/InteractivePlayground/GainAdsrExample/useGainAdsrPlayground';
import InteractivePlayground from '@site/src/components/InteractivePlayground';
@@ -43,6 +43,19 @@ You can read more about envelopes and ADSR on [Wikipedia]( | `number` | 1.0 | Number representing gain value |
+
+Or by using `BaseAudioContext` factory method:
[`BaseAudioContext.createGain()`](/docs/core/base-audio-context#creategain)
## Properties
diff --git a/packages/audiodocs/docs/effects/stereo-panner-node.mdx b/packages/audiodocs/docs/effects/stereo-panner-node.mdx
index 438feff59..64438ff33 100644
--- a/packages/audiodocs/docs/effects/stereo-panner-node.mdx
+++ b/packages/audiodocs/docs/effects/stereo-panner-node.mdx
@@ -3,7 +3,7 @@ sidebar_position: 4
---
import AudioNodePropsTable from "@site/src/components/AudioNodePropsTable"
-import { ReadOnly } from '@site/src/components/Badges';
+import { Optional, ReadOnly } from '@site/src/components/Badges';
# StereoPannerNode
@@ -15,6 +15,19 @@ The `StereoPannerNode` interface represents the change in ratio between two outp
## Constructor
+```tsx
+constructor(context: BaseAudioContext, stereoPannerOptions?: StereoPannerOptions)
+```
+
+### `StereoPannerOptions`
+
+Inherits all properties from [`AudioNodeOptions`](/docs/core/audio-node#audionodeoptions)
+
+| Parameter | Type | Default | Description |
+| :---: | :---: | :----: | :---- |
+| `pan` | `number` | 0.0 | Number representing pan value |
+
+Or by using `BaseAudioContext` factory method:
[`BaseAudioContext.createStereoPanner()`](/docs/core/base-audio-context#createstereopanner)
## Properties
diff --git a/packages/audiodocs/docs/sources/streamer-node.mdx b/packages/audiodocs/docs/sources/streamer-node.mdx
index 0d22e0e62..479da9f02 100644
--- a/packages/audiodocs/docs/sources/streamer-node.mdx
+++ b/packages/audiodocs/docs/sources/streamer-node.mdx
@@ -45,18 +45,21 @@ function App() {
## Properties
-`StreamerNode` does not define any additional properties.
It inherits all properties from [`AudioScheduledSourceNode`](/docs/sources/audio-scheduled-source-node#properties).
+| Name | Type | Description |
+| :----: | :----: | :------- |
+| `streamPath` | `string` | String value representing url to stream. |
+
## Methods
It inherits all methods from [`AudioScheduledSourceNode`](/docs/sources/audio-scheduled-source-node#methods).
### `initialize`
-Initializes the streamer with a link to an external HLS source.
+Initializes the streamer with a link to an external source.
| Parameter | Type | Description |
| :---: | :---: | :---- |
-| `streamPath` | `string` | Link pointing to an external HLS source |
+| `streamPath` | `string` | Link pointing to an external source |
#### Returns `boolean` indicating if setup of streaming has worked.
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp
index e61d01bc1..b2ff7449c 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp
@@ -19,6 +19,7 @@
#include
#include
+#include
#include
#include
@@ -153,13 +154,21 @@ JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createRecorderAdapter) {
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createOscillator) {
- auto oscillator = context_->createOscillator();
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr oscillatorOptions =
+ audioapi::option_parser::parseOscillatorOptions(runtime, options);
+ auto oscillator = context_->createOscillator(oscillatorOptions);
auto oscillatorHostObject = std::make_shared(oscillator);
return jsi::Object::createFromHostObject(runtime, oscillatorHostObject);
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createStreamer) {
- auto streamer = context_->createStreamer();
+ std::shared_ptr streamerOptions = std::make_shared();
+ if (!args[0].isUndefined()) {
+ auto options = args[0].asObject(runtime);
+ streamerOptions = audioapi::option_parser::parseStreamerOptions(runtime, options);
+ }
+ auto streamer = context_->createStreamer(streamerOptions);
auto streamerHostObject = std::make_shared(streamer);
auto object = jsi::Object::createFromHostObject(runtime, streamerHostObject);
object.setExternalMemoryPressure(runtime, StreamerNodeHostObject::getSizeInBytes());
@@ -167,39 +176,55 @@ JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createStreamer) {
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createConstantSource) {
- auto constantSource = context_->createConstantSource();
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr constantSourceOptions =
+ audioapi::option_parser::parseConstantSourceOptions(runtime, options);
+ auto constantSource = context_->createConstantSource(constantSourceOptions);
auto constantSourceHostObject = std::make_shared(constantSource);
return jsi::Object::createFromHostObject(runtime, constantSourceHostObject);
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createGain) {
- auto gain = context_->createGain();
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr gainOptions =
+ audioapi::option_parser::parseGainOptions(runtime, options);
+ auto gain = context_->createGain(gainOptions);
auto gainHostObject = std::make_shared(gain);
return jsi::Object::createFromHostObject(runtime, gainHostObject);
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createStereoPanner) {
- auto stereoPanner = context_->createStereoPanner();
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr stereoPannerOptions =
+ audioapi::option_parser::parseStereoPannerOptions(runtime, options);
+ auto stereoPanner = context_->createStereoPanner(stereoPannerOptions);
auto stereoPannerHostObject = std::make_shared(stereoPanner);
return jsi::Object::createFromHostObject(runtime, stereoPannerHostObject);
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createBiquadFilter) {
- auto biquadFilter = context_->createBiquadFilter();
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr biquadFilterOptions =
+ audioapi::option_parser::parseBiquadFilterOptions(runtime, options);
+ auto biquadFilter = context_->createBiquadFilter(biquadFilterOptions);
auto biquadFilterHostObject = std::make_shared(biquadFilter);
return jsi::Object::createFromHostObject(runtime, biquadFilterHostObject);
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createBufferSource) {
- auto pitchCorrection = args[0].asBool();
- auto bufferSource = context_->createBufferSource(pitchCorrection);
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr audioBufferSourceOptions =
+ audioapi::option_parser::parseAudioBufferSourceOptions(runtime, options);
+ auto bufferSource = context_->createBufferSource(audioBufferSourceOptions);
auto bufferSourceHostObject = std::make_shared(bufferSource);
return jsi::Object::createFromHostObject(runtime, bufferSourceHostObject);
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createBufferQueueSource) {
- auto pitchCorrection = args[0].asBool();
- auto bufferSource = context_->createBufferQueueSource(pitchCorrection);
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr baseAudioBufferSourceOptions =
+ audioapi::option_parser::parseBaseAudioBufferSourceOptions(runtime, options);
+ auto bufferSource = context_->createBufferQueueSource(baseAudioBufferSourceOptions);
auto bufferStreamSourceHostObject =
std::make_shared(bufferSource);
return jsi::Object::createFromHostObject(runtime, bufferStreamSourceHostObject);
@@ -243,20 +268,19 @@ JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createPeriodicWave) {
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createAnalyser) {
- auto analyser = context_->createAnalyser();
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr analyserOptions =
+ audioapi::option_parser::parseAnalyserOptions(runtime, options);
+ auto analyser = context_->createAnalyser(analyserOptions);
auto analyserHostObject = std::make_shared(analyser);
return jsi::Object::createFromHostObject(runtime, analyserHostObject);
}
JSI_HOST_FUNCTION_IMPL(BaseAudioContextHostObject, createConvolver) {
- auto disableNormalization = args[1].getBool();
- std::shared_ptr convolver;
- if (args[0].isUndefined()) {
- convolver = context_->createConvolver(nullptr, disableNormalization);
- } else {
- auto bufferHostObject = args[0].getObject(runtime).asHostObject(runtime);
- convolver = context_->createConvolver(bufferHostObject->audioBuffer_, disableNormalization);
- }
+ auto options = args[0].asObject(runtime);
+ std::shared_ptr convolverOptions =
+ audioapi::option_parser::parseConvolverOptions(runtime, options);
+ auto convolver = context_->createConvolver(convolverOptions);
auto convolverHostObject = std::make_shared(convolver);
auto jsiObject = jsi::Object::createFromHostObject(runtime, convolverHostObject);
if (!args[0].isUndefined()) {
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.cpp b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.cpp
index bee7fc82e..6da7c85e1 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.cpp
@@ -10,6 +10,12 @@ namespace audioapi {
StreamerNodeHostObject::StreamerNodeHostObject(const std::shared_ptr &node)
: AudioScheduledSourceNodeHostObject(node) {
addFunctions(JSI_EXPORT_FUNCTION(StreamerNodeHostObject, initialize));
+ addGetters(JSI_EXPORT_PROPERTY_GETTER(StreamerNodeHostObject, streamPath));
+}
+
+JSI_PROPERTY_GETTER_IMPL(StreamerNodeHostObject, streamPath) {
+ auto streamerNode = std::static_pointer_cast(node_);
+ return jsi::String::createFromUtf8(runtime, streamerNode->getStreamPath());
}
JSI_HOST_FUNCTION_IMPL(StreamerNodeHostObject, initialize) {
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.h b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.h
index 33e691679..43118bc0e 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.h
+++ b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.h
@@ -19,6 +19,7 @@ class StreamerNodeHostObject : public AudioScheduledSourceNodeHostObject {
return SIZE;
}
+ JSI_PROPERTY_GETTER_DECL(streamPath);
JSI_HOST_FUNCTION_DECL(initialize);
private:
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/utils/NodeOptions.h b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/utils/NodeOptions.h
new file mode 100644
index 000000000..fc05192a9
--- /dev/null
+++ b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/utils/NodeOptions.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace audioapi {
+struct AudioNodeOptions {
+ int channelCount = 2;
+ ChannelCountMode channelCountMode = ChannelCountMode::MAX;
+ ChannelInterpretation channelInterpretation = ChannelInterpretation::SPEAKERS;
+};
+
+struct GainOptions : AudioNodeOptions {
+ float gain = 1.0f;
+};
+
+struct StereoPannerOptions : AudioNodeOptions {
+ float pan = 0.0f;
+};
+
+struct ConvolverOptions : AudioNodeOptions {
+ std::shared_ptr bus = nullptr;
+ bool disableNormalization = false;
+};
+
+struct ConstantSourceOptions {
+ float offset = 1.0f;
+};
+
+struct AnalyserOptions : AudioNodeOptions {
+ int fftSize = 2048;
+ float minDecibels = -100.0f;
+ float maxDecibels = -30.0f;
+ float smoothingTimeConstant = 0.8f;
+};
+
+struct BiquadFilterOptions : AudioNodeOptions {
+ BiquadFilterType type = BiquadFilterType::LOWPASS;
+ float frequency = 350.0f;
+ float detune = 0.0f;
+ float Q = 1.0f;
+ float gain = 0.0f;
+};
+
+struct OscillatorOptions {
+ std::shared_ptr periodicWave = nullptr;
+ float frequency = 440.0f;
+ float detune = 0.0f;
+ OscillatorType type = OscillatorType::SINE;
+};
+
+struct BaseAudioBufferSourceOptions {
+ float detune = 0.0f;
+ bool pitchCorrection = false;
+ float playbackRate = 1.0f;
+};
+
+struct AudioBufferSourceOptions : BaseAudioBufferSourceOptions {
+ std::shared_ptr buffer = nullptr;
+ bool loop = false;
+ float loopStart = 0.0f;
+ float loopEnd = 0.0f;
+};
+
+struct StreamerOptions {
+ std::string streamPath = "";
+};
+
+} // namespace audioapi
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/utils/NodeOptionsParser.h b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/utils/NodeOptionsParser.h
new file mode 100644
index 000000000..e51f47c6e
--- /dev/null
+++ b/packages/react-native-audio-api/common/cpp/audioapi/HostObjects/utils/NodeOptionsParser.h
@@ -0,0 +1,213 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+namespace audioapi::option_parser {
+std::shared_ptr parseAudioNodeOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ AudioNodeOptions options;
+
+ options.channelCount =
+ static_cast(optionsObject.getProperty(runtime, "channelCount").getNumber());
+
+ auto channelCountModeStr =
+ optionsObject.getProperty(runtime, "channelCountMode").asString(runtime).utf8(runtime);
+
+ if (channelCountModeStr == "max") {
+ options.channelCountMode = ChannelCountMode::MAX;
+ } else if (channelCountModeStr == "clamped-max") {
+ options.channelCountMode = ChannelCountMode::CLAMPED_MAX;
+ } else if (channelCountModeStr == "explicit") {
+ options.channelCountMode = ChannelCountMode::EXPLICIT;
+ }
+
+ auto channelInterpretationStr =
+ optionsObject.getProperty(runtime, "channelInterpretation").asString(runtime).utf8(runtime);
+
+ if (channelInterpretationStr == "speakers") {
+ options.channelInterpretation = ChannelInterpretation::SPEAKERS;
+ } else if (channelInterpretationStr == "discrete") {
+ options.channelInterpretation = ChannelInterpretation::DISCRETE;
+ }
+
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseGainOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ std::shared_ptr nodeOptions = parseAudioNodeOptions(runtime, optionsObject);
+ GainOptions options(*nodeOptions.get());
+ options.gain = static_cast(optionsObject.getProperty(runtime, "gain").getNumber());
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseStereoPannerOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ std::shared_ptr nodeOptions = parseAudioNodeOptions(runtime, optionsObject);
+ StereoPannerOptions options(*nodeOptions.get());
+ options.pan = static_cast(optionsObject.getProperty(runtime, "pan").getNumber());
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseConvolverOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ std::shared_ptr nodeOptions = parseAudioNodeOptions(runtime, optionsObject);
+ ConvolverOptions options(*nodeOptions.get());
+ options.disableNormalization =
+ static_cast(optionsObject.getProperty(runtime, "disableNormalization").getNumber());
+ if (optionsObject.hasProperty(runtime, "buffer")) {
+ auto bufferHostObject = optionsObject.getProperty(runtime, "buffer")
+ .getObject(runtime)
+ .asHostObject(runtime);
+ options.bus = bufferHostObject->audioBuffer_;
+ }
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseConstantSourceOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ ConstantSourceOptions options;
+ options.offset = static_cast(optionsObject.getProperty(runtime, "offset").getNumber());
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseAnalyserOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ std::shared_ptr nodeOptions = parseAudioNodeOptions(runtime, optionsObject);
+ AnalyserOptions options(*nodeOptions.get());
+ options.fftSize = static_cast(optionsObject.getProperty(runtime, "fftSize").getNumber());
+ options.minDecibels =
+ static_cast(optionsObject.getProperty(runtime, "minDecibels").getNumber());
+ options.maxDecibels =
+ static_cast(optionsObject.getProperty(runtime, "maxDecibels").getNumber());
+ options.smoothingTimeConstant =
+ static_cast(optionsObject.getProperty(runtime, "smoothingTimeConstant").getNumber());
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseBiquadFilterOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ std::shared_ptr nodeOptions = parseAudioNodeOptions(runtime, optionsObject);
+ BiquadFilterOptions options(*nodeOptions.get());
+
+ auto typeStr = optionsObject.getProperty(runtime, "type").asString(runtime).utf8(runtime);
+
+ if (typeStr == "lowpass") {
+ options.type = BiquadFilterType::LOWPASS;
+ } else if (typeStr == "highpass") {
+ options.type = BiquadFilterType::HIGHPASS;
+ } else if (typeStr == "bandpass") {
+ options.type = BiquadFilterType::BANDPASS;
+ } else if (typeStr == "lowshelf") {
+ options.type = BiquadFilterType::LOWSHELF;
+ } else if (typeStr == "highshelf") {
+ options.type = BiquadFilterType::HIGHSHELF;
+ } else if (typeStr == "peaking") {
+ options.type = BiquadFilterType::PEAKING;
+ } else if (typeStr == "notch") {
+ options.type = BiquadFilterType::NOTCH;
+ } else if (typeStr == "allpass") {
+ options.type = BiquadFilterType::ALLPASS;
+ }
+
+ options.frequency =
+ static_cast(optionsObject.getProperty(runtime, "frequency").getNumber());
+ options.detune = static_cast(optionsObject.getProperty(runtime, "detune").getNumber());
+ options.Q = static_cast(optionsObject.getProperty(runtime, "Q").getNumber());
+ options.gain = static_cast(optionsObject.getProperty(runtime, "gain").getNumber());
+
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseOscillatorOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ std::shared_ptr nodeOptions = parseAudioNodeOptions(runtime, optionsObject);
+ OscillatorOptions options;
+
+ auto typeStr = optionsObject.getProperty(runtime, "type").asString(runtime).utf8(runtime);
+
+ if (typeStr == "sine") {
+ options.type = OscillatorType::SINE;
+ } else if (typeStr == "square") {
+ options.type = OscillatorType::SQUARE;
+ } else if (typeStr == "sawtooth") {
+ options.type = OscillatorType::SAWTOOTH;
+ } else if (typeStr == "triangle") {
+ options.type = OscillatorType::TRIANGLE;
+ } else if (typeStr == "custom") {
+ options.type = OscillatorType::CUSTOM;
+ }
+
+ options.frequency =
+ static_cast(optionsObject.getProperty(runtime, "frequency").getNumber());
+ options.detune = static_cast(optionsObject.getProperty(runtime, "detune").getNumber());
+
+ if (optionsObject.hasProperty(runtime, "periodicWave")) {
+ auto periodicWaveHostObject = optionsObject.getProperty(runtime, "periodicWave")
+ .getObject(runtime)
+ .asHostObject(runtime);
+ options.periodicWave = periodicWaveHostObject->periodicWave_;
+ }
+
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseBaseAudioBufferSourceOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ BaseAudioBufferSourceOptions options;
+ options.detune = static_cast(optionsObject.getProperty(runtime, "detune").getNumber());
+ options.playbackRate =
+ static_cast(optionsObject.getProperty(runtime, "playbackRate").getNumber());
+ options.pitchCorrection =
+ static_cast(optionsObject.getProperty(runtime, "pitchCorrection").getNumber());
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseAudioBufferSourceOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ std::shared_ptr baseOptions =
+ parseBaseAudioBufferSourceOptions(runtime, optionsObject);
+ AudioBufferSourceOptions options(*baseOptions.get());
+ if (optionsObject.hasProperty(runtime, "buffer")) {
+ auto bufferHostObject = optionsObject.getProperty(runtime, "buffer")
+ .getObject(runtime)
+ .asHostObject(runtime);
+ options.buffer = bufferHostObject->audioBuffer_;
+ }
+ options.loop = static_cast(optionsObject.getProperty(runtime, "loop").getNumber());
+ options.loopStart =
+ static_cast(optionsObject.getProperty(runtime, "loopStart").getNumber());
+ options.loopEnd = static_cast(optionsObject.getProperty(runtime, "loopEnd").getNumber());
+ return std::make_shared(options);
+}
+
+std::shared_ptr parseStreamerOptions(
+ jsi::Runtime &runtime,
+ const jsi::Object &optionsObject) {
+ auto options = StreamerOptions();
+ if (optionsObject.hasProperty(runtime, "streamPath")) {
+ options.streamPath =
+ optionsObject.getProperty(runtime, "streamPath").asString(runtime).utf8(runtime);
+ }
+ return std::make_shared(options);
+}
+} // namespace audioapi::option_parser
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/AudioNode.cpp b/packages/react-native-audio-api/common/cpp/audioapi/core/AudioNode.cpp
index 9035ab02a..fc47670a6 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/AudioNode.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/AudioNode.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
#include
@@ -10,7 +11,13 @@
namespace audioapi {
-AudioNode::AudioNode(BaseAudioContext *context) : context_(context) {
+AudioNode::AudioNode(BaseAudioContext *context, std::shared_ptr options)
+ : context_(context) {
+ if (options != nullptr) {
+ channelCount_ = options->channelCount;
+ channelCountMode_ = options->channelCountMode;
+ channelInterpretation_ = options->channelInterpretation;
+ }
audioBus_ =
std::make_shared(RENDER_QUANTUM_SIZE, channelCount_, context->getSampleRate());
}
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/AudioNode.h b/packages/react-native-audio-api/common/cpp/audioapi/core/AudioNode.h
index 3673fd81e..02d9227d8 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/AudioNode.h
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/AudioNode.h
@@ -16,10 +16,13 @@ namespace audioapi {
class AudioBus;
class BaseAudioContext;
class AudioParam;
+class AudioNodeOptions;
class AudioNode : public std::enable_shared_from_this {
public:
- explicit AudioNode(BaseAudioContext *context);
+ explicit AudioNode(
+ BaseAudioContext *context,
+ std::shared_ptr options = nullptr);
virtual ~AudioNode();
int getNumberOfInputs() const;
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/BaseAudioContext.cpp b/packages/react-native-audio-api/common/cpp/audioapi/core/BaseAudioContext.cpp
index a3c941216..38e2735f1 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/BaseAudioContext.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/BaseAudioContext.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
#include
@@ -65,7 +66,7 @@ double BaseAudioContext::getCurrentTime() const {
return destination_->getCurrentTime();
}
-std::shared_ptr BaseAudioContext::getDestination() {
+std::shared_ptr BaseAudioContext::getDestination() const {
return destination_;
}
@@ -109,53 +110,59 @@ std::shared_ptr BaseAudioContext::createRecorderAdapter() {
return recorderAdapter;
}
-std::shared_ptr BaseAudioContext::createOscillator() {
- auto oscillator = std::make_shared(this);
+std::shared_ptr BaseAudioContext::createOscillator(
+ std::shared_ptr options) {
+ auto oscillator = std::make_shared(this, options);
nodeManager_->addSourceNode(oscillator);
return oscillator;
}
-std::shared_ptr BaseAudioContext::createConstantSource() {
- auto constantSource = std::make_shared(this);
+std::shared_ptr BaseAudioContext::createConstantSource(
+ std::shared_ptr options) {
+ auto constantSource = std::make_shared(this, options);
nodeManager_->addSourceNode(constantSource);
return constantSource;
}
#ifndef AUDIO_API_TEST_SUITE
-std::shared_ptr BaseAudioContext::createStreamer() {
- auto streamer = std::make_shared(this);
+std::shared_ptr BaseAudioContext::createStreamer(
+ std::shared_ptr options) {
+ auto streamer = std::make_shared(this, options);
nodeManager_->addSourceNode(streamer);
return streamer;
}
#endif
-std::shared_ptr BaseAudioContext::createGain() {
- auto gain = std::make_shared(this);
+std::shared_ptr BaseAudioContext::createGain(std::shared_ptr options) {
+ auto gain = std::make_shared(this, options);
nodeManager_->addProcessingNode(gain);
return gain;
}
-std::shared_ptr BaseAudioContext::createStereoPanner() {
- auto stereoPanner = std::make_shared(this);
+std::shared_ptr BaseAudioContext::createStereoPanner(
+ std::shared_ptr options) {
+ auto stereoPanner = std::make_shared(this, options);
nodeManager_->addProcessingNode(stereoPanner);
return stereoPanner;
}
-std::shared_ptr BaseAudioContext::createBiquadFilter() {
- auto biquadFilter = std::make_shared(this);
+std::shared_ptr BaseAudioContext::createBiquadFilter(
+ std::shared_ptr options) {
+ auto biquadFilter = std::make_shared(this, options);
nodeManager_->addProcessingNode(biquadFilter);
return biquadFilter;
}
-std::shared_ptr BaseAudioContext::createBufferSource(bool pitchCorrection) {
- auto bufferSource = std::make_shared(this, pitchCorrection);
+std::shared_ptr BaseAudioContext::createBufferSource(
+ std::shared_ptr options) {
+ auto bufferSource = std::make_shared(this, options);
nodeManager_->addSourceNode(bufferSource);
return bufferSource;
}
std::shared_ptr BaseAudioContext::createBufferQueueSource(
- bool pitchCorrection) {
- auto bufferSource = std::make_shared(this, pitchCorrection);
+ std::shared_ptr options) {
+ auto bufferSource = std::make_shared(this, options);
nodeManager_->addSourceNode(bufferSource);
return bufferSource;
}
@@ -172,16 +179,16 @@ std::shared_ptr BaseAudioContext::createPeriodicWave(
return std::make_shared(sampleRate_, complexData, length, disableNormalization);
}
-std::shared_ptr BaseAudioContext::createAnalyser() {
- auto analyser = std::make_shared(this);
+std::shared_ptr BaseAudioContext::createAnalyser(
+ std::shared_ptr options) {
+ auto analyser = std::make_shared(this, options);
nodeManager_->addProcessingNode(analyser);
return analyser;
}
std::shared_ptr BaseAudioContext::createConvolver(
- std::shared_ptr buffer,
- bool disableNormalization) {
- auto convolver = std::make_shared(this, buffer, disableNormalization);
+ std::shared_ptr options) {
+ auto convolver = std::make_shared(this, options);
nodeManager_->addProcessingNode(convolver);
return convolver;
}
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/BaseAudioContext.h b/packages/react-native-audio-api/common/cpp/audioapi/core/BaseAudioContext.h
index 713d4082c..2032142aa 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/BaseAudioContext.h
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/BaseAudioContext.h
@@ -35,6 +35,16 @@ class WorkletSourceNode;
class WorkletNode;
class WorkletProcessingNode;
class StreamerNode;
+class GainOptions;
+class StereoPannerOptions;
+class ConvolverOptions;
+class ConstantSourceOptions;
+class AnalyserOptions;
+class BiquadFilterOptions;
+class OscillatorOptions;
+class BaseAudioBufferSourceOptions;
+class AudioBufferSourceOptions;
+class StreamerOptions;
class BaseAudioContext {
public:
@@ -47,7 +57,7 @@ class BaseAudioContext {
[[nodiscard]] float getSampleRate() const;
[[nodiscard]] double getCurrentTime() const;
[[nodiscard]] std::size_t getCurrentSampleFrame() const;
- std::shared_ptr getDestination();
+ std::shared_ptr getDestination() const;
std::shared_ptr createRecorderAdapter();
std::shared_ptr createWorkletSourceNode(
@@ -64,24 +74,27 @@ class BaseAudioContext {
std::shared_ptr &shareableWorklet,
std::weak_ptr runtime,
bool shouldLockRuntime = true);
- std::shared_ptr createOscillator();
- std::shared_ptr createConstantSource();
- std::shared_ptr createStreamer();
- std::shared_ptr createGain();
- std::shared_ptr createStereoPanner();
- std::shared_ptr createBiquadFilter();
- std::shared_ptr createBufferSource(bool pitchCorrection);
- std::shared_ptr createBufferQueueSource(bool pitchCorrection);
+ std::shared_ptr createOscillator(std::shared_ptr options);
+ std::shared_ptr createConstantSource(
+ std::shared_ptr options);
+ std::shared_ptr createStreamer(std::shared_ptr options);
+ std::shared_ptr createGain(std::shared_ptr options);
+ std::shared_ptr createStereoPanner(
+ std::shared_ptr options);
+ std::shared_ptr createBiquadFilter(
+ std::shared_ptr options);
+ std::shared_ptr createBufferSource(
+ std::shared_ptr options);
+ std::shared_ptr createBufferQueueSource(
+ std::shared_ptr options);
static std::shared_ptr
createBuffer(int numberOfChannels, size_t length, float sampleRate);
std::shared_ptr createPeriodicWave(
const std::vector> &complexData,
bool disableNormalization,
int length);
- std::shared_ptr createAnalyser();
- std::shared_ptr createConvolver(
- std::shared_ptr buffer,
- bool disableNormalization);
+ std::shared_ptr createAnalyser(std::shared_ptr options);
+ std::shared_ptr createConvolver(std::shared_ptr options);
std::shared_ptr getBasicWaveForm(OscillatorType type);
[[nodiscard]] float getNyquistFrequency() const;
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/analysis/AnalyserNode.cpp b/packages/react-native-audio-api/common/cpp/audioapi/core/analysis/AnalyserNode.cpp
index c01d3f5bd..860ae0636 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/analysis/AnalyserNode.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/analysis/AnalyserNode.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
#include
@@ -12,12 +13,14 @@
#include
namespace audioapi {
-AnalyserNode::AnalyserNode(audioapi::BaseAudioContext *context)
- : AudioNode(context),
- fftSize_(2048),
- minDecibels_(-100),
- maxDecibels_(-30),
- smoothingTimeConstant_(0.8),
+AnalyserNode::AnalyserNode(
+ audioapi::BaseAudioContext *context,
+ std::shared_ptr options)
+ : AudioNode(context, options),
+ fftSize_(options->fftSize),
+ minDecibels_(options->minDecibels),
+ maxDecibels_(options->maxDecibels),
+ smoothingTimeConstant_(options->smoothingTimeConstant),
windowType_(WindowType::BLACKMAN) {
inputBuffer_ = std::make_unique(MAX_FFT_SIZE * 2);
tempBuffer_ = std::make_unique(fftSize_);
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/analysis/AnalyserNode.h b/packages/react-native-audio-api/common/cpp/audioapi/core/analysis/AnalyserNode.h
index b62d0058a..d8dc2691b 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/analysis/AnalyserNode.h
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/analysis/AnalyserNode.h
@@ -15,11 +15,12 @@ namespace audioapi {
class AudioBus;
class AudioArray;
class CircularAudioArray;
+class AnalyserOptions;
class AnalyserNode : public AudioNode {
public:
enum class WindowType { BLACKMAN, HANN };
- explicit AnalyserNode(BaseAudioContext *context);
+ explicit AnalyserNode(BaseAudioContext *context, std::shared_ptr options);
int getFftSize() const;
int getFrequencyBinCount() const;
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp
index 33f1f3aaa..b502e2cca 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp
@@ -26,6 +26,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include
#include
#include
#include
@@ -38,21 +39,23 @@
namespace audioapi {
-BiquadFilterNode::BiquadFilterNode(BaseAudioContext *context) : AudioNode(context) {
- frequencyParam_ =
- std::make_shared(350.0, 0.0f, context->getNyquistFrequency(), context);
+BiquadFilterNode::BiquadFilterNode(
+ BaseAudioContext *context,
+ std::shared_ptr options)
+ : AudioNode(context, options) {
+ frequencyParam_ = std::make_shared(
+ options->frequency, 0.0f, context->getNyquistFrequency(), context);
detuneParam_ = std::make_shared(
- 0.0f,
+ options->detune,
-1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT,
1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT,
context);
QParam_ = std::make_shared(
- 1.0f, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
+ options->Q, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
gainParam_ = std::make_shared(
- 0.0f, MOST_NEGATIVE_SINGLE_FLOAT, 40 * LOG10_MOST_POSITIVE_SINGLE_FLOAT, context);
- type_ = BiquadFilterType::LOWPASS;
+ options->gain, MOST_NEGATIVE_SINGLE_FLOAT, 40 * LOG10_MOST_POSITIVE_SINGLE_FLOAT, context);
+ type_ = options->type;
isInitialized_ = true;
- channelCountMode_ = ChannelCountMode::MAX;
}
std::string BiquadFilterNode::getType() {
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/BiquadFilterNode.h b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/BiquadFilterNode.h
index 6a7a606d1..3d48377ad 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/BiquadFilterNode.h
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/BiquadFilterNode.h
@@ -46,6 +46,7 @@
namespace audioapi {
class AudioBus;
+class BiquadFilterOptions;
class BiquadFilterNode : public AudioNode {
#ifdef AUDIO_API_TEST_SUITE
@@ -54,7 +55,9 @@ class BiquadFilterNode : public AudioNode {
#endif
public:
- explicit BiquadFilterNode(BaseAudioContext *context);
+ explicit BiquadFilterNode(
+ BaseAudioContext *context,
+ std::shared_ptr options);
[[nodiscard]] std::string getType();
void setType(const std::string &type);
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/ConvolverNode.cpp b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/ConvolverNode.cpp
index a09bc0ced..e27e1c7b7 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/ConvolverNode.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/ConvolverNode.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
#include
@@ -13,9 +14,8 @@
namespace audioapi {
ConvolverNode::ConvolverNode(
BaseAudioContext *context,
- const std::shared_ptr &buffer,
- bool disableNormalization)
- : AudioNode(context),
+ const std::shared_ptr options)
+ : AudioNode(context, options),
remainingSegments_(0),
internalBufferIndex_(0),
signalledToStop_(false),
@@ -23,11 +23,9 @@ ConvolverNode::ConvolverNode(
intermediateBus_(nullptr),
buffer_(nullptr),
internalBuffer_(nullptr) {
- channelCount_ = 2;
- channelCountMode_ = ChannelCountMode::CLAMPED_MAX;
- normalize_ = !disableNormalization;
+ normalize_ = !options->disableNormalization;
gainCalibrationSampleRate_ = context->getSampleRate();
- setBuffer(buffer);
+ setBuffer(options->bus);
audioBus_ =
std::make_shared(RENDER_QUANTUM_SIZE, channelCount_, context->getSampleRate());
isInitialized_ = true;
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/ConvolverNode.h b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/ConvolverNode.h
index 92a45d609..006be093b 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/ConvolverNode.h
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/ConvolverNode.h
@@ -17,13 +17,13 @@ namespace audioapi {
class AudioBus;
class AudioBuffer;
+class ConvolverOptions;
class ConvolverNode : public AudioNode {
public:
explicit ConvolverNode(
BaseAudioContext *context,
- const std::shared_ptr &buffer,
- bool disableNormalization);
+ const std::shared_ptr options);
[[nodiscard]] bool getNormalize_() const;
[[nodiscard]] const std::shared_ptr &getBuffer() const;
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/GainNode.cpp b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/GainNode.cpp
index 6e1c01d45..33bb716fd 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/GainNode.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/GainNode.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
#include
@@ -7,9 +8,10 @@
namespace audioapi {
-GainNode::GainNode(BaseAudioContext *context) : AudioNode(context) {
+GainNode::GainNode(BaseAudioContext *context, std::shared_ptr options)
+ : AudioNode(context, options) {
gainParam_ = std::make_shared(
- 1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
+ options->gain, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
isInitialized_ = true;
}
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/GainNode.h b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/GainNode.h
index de3b0d7b0..361dffe5a 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/GainNode.h
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/GainNode.h
@@ -8,10 +8,11 @@
namespace audioapi {
class AudioBus;
+class GainOptions;
class GainNode : public AudioNode {
public:
- explicit GainNode(BaseAudioContext *context);
+ explicit GainNode(BaseAudioContext *context, const std::shared_ptr options);
[[nodiscard]] std::shared_ptr getGainParam() const;
diff --git a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/StereoPannerNode.cpp b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/StereoPannerNode.cpp
index 5a362a180..1bfc4a58f 100644
--- a/packages/react-native-audio-api/common/cpp/audioapi/core/effects/StereoPannerNode.cpp
+++ b/packages/react-native-audio-api/common/cpp/audioapi/core/effects/StereoPannerNode.cpp
@@ -1,3 +1,4 @@
+#include
#include
#include
#include
@@ -9,9 +10,11 @@
namespace audioapi {
-StereoPannerNode::StereoPannerNode(BaseAudioContext *context) : AudioNode(context) {
- channelCountMode_ = ChannelCountMode::CLAMPED_MAX;
- panParam_ = std::make_shared(0.0, -1.0f, 1.0f, context);
+StereoPannerNode::StereoPannerNode(
+ BaseAudioContext *context,
+ const std::shared_ptr options)
+ : AudioNode(context, options) {
+ panParam_ = std::make_shared