Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
43fed07
refactor: audio array
Feb 2, 2026
6ad3a2b
feat: audio bus
Feb 2, 2026
f32a9f7
chore: added docs for both utils
Feb 2, 2026
91503c4
ci: lint
Feb 2, 2026
456b139
refactor: audio array and fft
Feb 2, 2026
8f439a6
chore: requested changes
Feb 3, 2026
e74317f
refactor: next part for audio bus and audio array
Feb 3, 2026
d1dede6
refactor: wip
Feb 3, 2026
1eca174
Merge branch 'main' into refactor/internal-tools
Feb 3, 2026
55bb04b
fix: a few fixes
Feb 3, 2026
e3b937c
fix: lint
Feb 3, 2026
83e8fdd
fix: fixed tests
Feb 3, 2026
122b9e0
fix: todos
Feb 4, 2026
a87f2f7
refactor: nits
Feb 4, 2026
58471e4
fix: nitpick
Feb 4, 2026
1b51ce6
refactor: added copyWithin - memmove to audio array
Feb 4, 2026
8127fa2
fix: memmove
Feb 4, 2026
2b01ac3
chore: updated custom processor template
Feb 4, 2026
dd2bf6b
refactor: optimized interleaveTo function
Feb 4, 2026
40d3ce7
refactor: renaming
Feb 4, 2026
7703767
refactor: renaming
Feb 4, 2026
a39e955
refactor: renaming
Feb 4, 2026
f9a3ac2
refactor: doxygen for AudioBuffer
Feb 4, 2026
a92bbf9
refactor: deinterleave audio data using AudioBuffer method
Feb 5, 2026
49537d0
refactor: broader support for circular data structures operations and…
Feb 5, 2026
7a13612
chore: requuested changes from code review
Feb 5, 2026
8587663
fix: nits
Feb 5, 2026
2e7538a
Merge branch 'main' into refactor/internal-tools
Feb 6, 2026
a033e12
ci: lint
Feb 6, 2026
e43d34b
refactor: fat function
Feb 6, 2026
ae6b384
refactor: audio param
Feb 6, 2026
6c55954
refactor: audio node
Feb 6, 2026
7e67258
ci: lint
Feb 6, 2026
9b8d15c
refactor: destination
Feb 6, 2026
592139a
refactor: audio scheduled source node
Feb 6, 2026
af56e5e
refactor: make isInitialized atomic variable
Feb 6, 2026
03e2d07
refactor: streamer node
Feb 6, 2026
a3547b1
refactor: oscillator and constant source node
Feb 6, 2026
14b377e
refactor: buffer base source node
Feb 6, 2026
269f56a
fix: nitpicks
Feb 6, 2026
f7f063e
refactor: gain, delay, stereo panner nodes
Feb 6, 2026
ff82771
ci: lint
Feb 6, 2026
60eb11e
refactor: audio buffer source node and related cleanups
Feb 7, 2026
1612d47
refactor: audio buffer queue source node
Feb 7, 2026
699f75a
fix: nitpicks
Feb 7, 2026
9c65120
refactor: wave shaper node
Feb 7, 2026
1375a9b
refactor: iir filter node
Feb 7, 2026
0298c33
refactor: biquad filter node
Feb 7, 2026
1ca5d4c
refactor: convolver node
Feb 7, 2026
3def7d7
refactor: part of analyser node
Feb 9, 2026
56719b0
Merge branch 'main' into refactor/communication-between-audio-and-js-…
Feb 9, 2026
40f2f43
fix: nitpicks
Feb 9, 2026
7f84ecf
ci: lint
Feb 9, 2026
7d07947
fix: nitpicks
Feb 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions apps/common-app/src/examples/Streaming/Streaming.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@ const Streaming: FC = () => {
console.error('StreamerNode is already initialized');
return;
}
streamerRef.current = aCtxRef.current.createStreamer();
streamerRef.current = aCtxRef.current.createStreamer('https://liveradio.timesa.pl/2980-1.aac/playlist.m3u8');

streamerRef.current.initialize(
'https://liveradio.timesa.pl/2980-1.aac/playlist.m3u8'
);
streamerRef.current.connect(gainRef.current);
gainRef.current.connect(aCtxRef.current.destination);
streamerRef.current.start(aCtxRef.current.currentTime);
Expand Down
2 changes: 1 addition & 1 deletion packages/audiodocs/docs/guides/create-your-own-effect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ namespace audioapi {
MyProcessorNode::MyProcessorNode(const std::shared_ptr<BaseAudioContext> &context)
//highlight-next-line
: AudioNode(context), gain(0.5) {
isInitialized_ = true;
isInitialized_.store(true, std::memory_order_release);
}

std::shared_ptr<AudioBuffer> MyProcessorNode::processNode(const std::shared_ptr<AudioBuffer> &buffer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace audioapi {
MyProcessorNode::MyProcessorNode(
const std::shared_ptr<BaseAudioContext> &context, )
: AudioNode(context) {
isInitialized_ = true;
isInitialized_.store(true, std::memory_order_release);
}

std::shared_ptr<AudioBuffer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
namespace audioapi {

AudioNodeHostObject::AudioNodeHostObject(const std::shared_ptr<AudioNode> &node,
const AudioNodeOptions &options) : node_(node) {
const AudioNodeOptions &options)
: node_(node),
numberOfInputs_(options.numberOfInputs),
numberOfOutputs_(options.numberOfOutputs),
channelCount_(options.channelCount),
channelCountMode_(options.channelCountMode),
channelInterpretation_(options.channelInterpretation) {
addGetters(
JSI_EXPORT_PROPERTY_GETTER(AudioNodeHostObject, numberOfInputs),
JSI_EXPORT_PROPERTY_GETTER(AudioNodeHostObject, numberOfOutputs),
Expand All @@ -28,23 +34,23 @@ AudioNodeHostObject::AudioNodeHostObject(const std::shared_ptr<AudioNode> &node,
AudioNodeHostObject::~AudioNodeHostObject() = default;

JSI_PROPERTY_GETTER_IMPL(AudioNodeHostObject, numberOfInputs) {
return {node_->getNumberOfInputs()};
return {numberOfInputs_};
}

JSI_PROPERTY_GETTER_IMPL(AudioNodeHostObject, numberOfOutputs) {
return {node_->getNumberOfOutputs()};
return {numberOfOutputs_};
}

JSI_PROPERTY_GETTER_IMPL(AudioNodeHostObject, channelCount) {
return {static_cast<int>(node_->getChannelCount())};
return {static_cast<int>(channelCount_)};
}

JSI_PROPERTY_GETTER_IMPL(AudioNodeHostObject, channelCountMode) {
return jsi::String::createFromUtf8(runtime, js_enum_parser::channelCountModeToString(node_->getChannelCountMode()));
return jsi::String::createFromUtf8(runtime, js_enum_parser::channelCountModeToString(channelCountMode_));
}

JSI_PROPERTY_GETTER_IMPL(AudioNodeHostObject, channelInterpretation) {
return jsi::String::createFromUtf8(runtime, js_enum_parser::channelInterpretationToString(node_->getChannelInterpretation()));
return jsi::String::createFromUtf8(runtime, js_enum_parser::channelInterpretationToString(channelInterpretation_));
}

JSI_HOST_FUNCTION_IMPL(AudioNodeHostObject, connect) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <audioapi/core/types/ChannelCountMode.h>
#include <audioapi/core/types/ChannelInterpretation.h>
#include <audioapi/jsi/JsiHostObject.h>
#include <audioapi/types/NodeOptions.h>

Expand Down Expand Up @@ -30,5 +32,11 @@ class AudioNodeHostObject : public JsiHostObject {

protected:
std::shared_ptr<AudioNode> node_;

const int numberOfInputs_;
const int numberOfOutputs_;
size_t channelCount_;
const ChannelCountMode channelCountMode_;
const ChannelInterpretation channelInterpretation_;
};
} // namespace audioapi
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace audioapi {

AudioParamHostObject::AudioParamHostObject(const std::shared_ptr<AudioParam> &param)
: param_(param) {
: param_(param), defaultValue_(param->getDefaultValue()), minValue_(param->getMinValue()), maxValue_(param->getMaxValue()) {
addGetters(
JSI_EXPORT_PROPERTY_GETTER(AudioParamHostObject, value),
JSI_EXPORT_PROPERTY_GETTER(AudioParamHostObject, defaultValue),
Expand All @@ -33,47 +33,58 @@ JSI_PROPERTY_GETTER_IMPL(AudioParamHostObject, value) {
}

JSI_PROPERTY_GETTER_IMPL(AudioParamHostObject, defaultValue) {
return {param_->getDefaultValue()};
return {defaultValue_};
}

JSI_PROPERTY_GETTER_IMPL(AudioParamHostObject, minValue) {
return {param_->getMinValue()};
return {minValue_};
}

JSI_PROPERTY_GETTER_IMPL(AudioParamHostObject, maxValue) {
return {param_->getMaxValue()};
return {maxValue_};
}

JSI_PROPERTY_SETTER_IMPL(AudioParamHostObject, value) {
param_->setValue(static_cast<float>(value.getNumber()));
auto event = [param = param_, value = static_cast<float>(value.getNumber())](BaseAudioContext &) {
param->setValue(value);
};

param_->scheduleAudioEvent(std::move(event));
}

JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, setValueAtTime) {
auto value = static_cast<float>(args[0].getNumber());
double startTime = args[1].getNumber();
param_->setValueAtTime(value, startTime);
auto event = [param = param_, value = static_cast<float>(args[0].getNumber()), startTime = args[1].getNumber()](BaseAudioContext &) {
param->setValueAtTime(value, startTime);
};

param_->scheduleAudioEvent(std::move(event));
return jsi::Value::undefined();
}

JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, linearRampToValueAtTime) {
auto value = static_cast<float>(args[0].getNumber());
double endTime = args[1].getNumber();
param_->linearRampToValueAtTime(value, endTime);
auto event = [param = param_, value = static_cast<float>(args[0].getNumber()), endTime = args[1].getNumber()](BaseAudioContext &) {
param->linearRampToValueAtTime(value, endTime);
};

param_->scheduleAudioEvent(std::move(event));
return jsi::Value::undefined();
}

JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, exponentialRampToValueAtTime) {
auto value = static_cast<float>(args[0].getNumber());
double endTime = args[1].getNumber();
param_->exponentialRampToValueAtTime(value, endTime);
auto event = [param = param_, value = static_cast<float>(args[0].getNumber()), endTime = args[1].getNumber()](BaseAudioContext &) {
param->exponentialRampToValueAtTime(value, endTime);
};

param_->scheduleAudioEvent(std::move(event));
return jsi::Value::undefined();
}

JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, setTargetAtTime) {
auto target = static_cast<float>(args[0].getNumber());
double startTime = args[1].getNumber();
double timeConstant = args[2].getNumber();
param_->setTargetAtTime(target, startTime, timeConstant);
auto event = [param = param_, target = static_cast<float>(args[0].getNumber()), startTime = args[1].getNumber(), timeConstant = args[2].getNumber()](BaseAudioContext &) {
param->setTargetAtTime(target, startTime, timeConstant);
};

param_->scheduleAudioEvent(std::move(event));
return jsi::Value::undefined();
}

Expand All @@ -82,23 +93,31 @@ JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, setValueCurveAtTime) {
args[0].getObject(runtime).getPropertyAsObject(runtime, "buffer").getArrayBuffer(runtime);
auto rawValues = reinterpret_cast<float *>(arrayBuffer.data(runtime));
auto length = static_cast<int>(arrayBuffer.size(runtime));
auto values = std::make_unique<AudioArray>(rawValues, length);
auto values = std::make_shared<AudioArray>(rawValues, length);

auto event = [param = param_, values, length, startTime = args[1].getNumber(), duration = args[2].getNumber()](BaseAudioContext &) {
param->setValueCurveAtTime(values, length, startTime, duration);
};

double startTime = args[1].getNumber();
double duration = args[2].getNumber();
param_->setValueCurveAtTime(std::move(values), length, startTime, duration);
param_->scheduleAudioEvent(std::move(event));
return jsi::Value::undefined();
}

JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, cancelScheduledValues) {
double cancelTime = args[0].getNumber();
param_->cancelScheduledValues(cancelTime);
auto event = [param = param_, cancelTime = args[0].getNumber()](BaseAudioContext &) {
param->cancelScheduledValues(cancelTime);
};

param_->scheduleAudioEvent(std::move(event));
return jsi::Value::undefined();
}

JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, cancelAndHoldAtTime) {
double cancelTime = args[0].getNumber();
param_->cancelAndHoldAtTime(cancelTime);
auto event = [param = param_, cancelTime = args[0].getNumber()](BaseAudioContext &) {
param->cancelAndHoldAtTime(cancelTime);
};

param_->scheduleAudioEvent(std::move(event));
return jsi::Value::undefined();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,8 @@ class AudioParamHostObject : public JsiHostObject {
friend class AudioNodeHostObject;

std::shared_ptr<AudioParam> param_;
float defaultValue_;
float minValue_;
float maxValue_;
};
} // namespace audioapi
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@
#include <audioapi/core/analysis/AnalyserNode.h>

#include <memory>
#include <utility>

namespace audioapi {

AnalyserNodeHostObject::AnalyserNodeHostObject(const std::shared_ptr<BaseAudioContext>& context, const AnalyserOptions &options)
: AudioNodeHostObject(context->createAnalyser(options), options) {
: AudioNodeHostObject(context->createAnalyser(options), options),
fftSize_(options.fftSize),
minDecibels_(options.minDecibels),
maxDecibels_(options.maxDecibels),
smoothingTimeConstant_(options.smoothingTimeConstant),
windowType_(options.windowType) {
addGetters(
JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, fftSize),
JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, frequencyBinCount),
JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, minDecibels),
JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, maxDecibels),
JSI_EXPORT_PROPERTY_GETTER(AnalyserNodeHostObject, smoothingTimeConstant),
Expand All @@ -33,64 +38,74 @@ AnalyserNodeHostObject::AnalyserNodeHostObject(const std::shared_ptr<BaseAudioCo
}

JSI_PROPERTY_GETTER_IMPL(AnalyserNodeHostObject, fftSize) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
return {static_cast<int>(analyserNode->getFftSize())};
}

JSI_PROPERTY_GETTER_IMPL(AnalyserNodeHostObject, frequencyBinCount) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
return {static_cast<int>(analyserNode->getFrequencyBinCount())};
return {fftSize_};
}

JSI_PROPERTY_GETTER_IMPL(AnalyserNodeHostObject, minDecibels) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
return {analyserNode->getMinDecibels()};
return {minDecibels_};
}

JSI_PROPERTY_GETTER_IMPL(AnalyserNodeHostObject, maxDecibels) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
return {analyserNode->getMaxDecibels()};
return {maxDecibels_};
}

JSI_PROPERTY_GETTER_IMPL(AnalyserNodeHostObject, smoothingTimeConstant) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
return {analyserNode->getSmoothingTimeConstant()};
return {smoothingTimeConstant_};
}

JSI_PROPERTY_GETTER_IMPL(AnalyserNodeHostObject, window) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
auto windowType = analyserNode->getWindowType();
return jsi::String::createFromUtf8(runtime, js_enum_parser::windowTypeToString(windowType));
return jsi::String::createFromUtf8(runtime, js_enum_parser::windowTypeToString(windowType_));
}

JSI_PROPERTY_SETTER_IMPL(AnalyserNodeHostObject, fftSize) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);

auto fftSize = static_cast<int>(value.getNumber());
analyserNode->setFftSize(fftSize);
auto event = [analyserNode, fftSize](BaseAudioContext&) {
analyserNode->setFftSize(fftSize);
};
analyserNode->scheduleAudioEvent(std::move(event));
fftSize_ = fftSize;
}

JSI_PROPERTY_SETTER_IMPL(AnalyserNodeHostObject, minDecibels) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
auto minDecibels = static_cast<float>(value.getNumber());
analyserNode->setMinDecibels(minDecibels);
auto event = [analyserNode, minDecibels](BaseAudioContext&) {
analyserNode->setMinDecibels(minDecibels);
};
analyserNode->scheduleAudioEvent(std::move(event));
minDecibels_ = minDecibels;
}

JSI_PROPERTY_SETTER_IMPL(AnalyserNodeHostObject, maxDecibels) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
auto maxDecibels = static_cast<float>(value.getNumber());
analyserNode->setMaxDecibels(maxDecibels);
auto event = [analyserNode, maxDecibels](BaseAudioContext&) {
analyserNode->setMaxDecibels(maxDecibels);
};
analyserNode->scheduleAudioEvent(std::move(event));
maxDecibels_ = maxDecibels;
}

JSI_PROPERTY_SETTER_IMPL(AnalyserNodeHostObject, smoothingTimeConstant) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
auto smoothingTimeConstant = static_cast<float>(value.getNumber());
analyserNode->setSmoothingTimeConstant(smoothingTimeConstant);
auto event = [analyserNode, smoothingTimeConstant](BaseAudioContext&) {
analyserNode->setSmoothingTimeConstant(smoothingTimeConstant);
};
analyserNode->scheduleAudioEvent(std::move(event));
smoothingTimeConstant_ = smoothingTimeConstant;
}

JSI_PROPERTY_SETTER_IMPL(AnalyserNodeHostObject, window) {
auto analyserNode = std::static_pointer_cast<AnalyserNode>(node_);
auto type = value.asString(runtime).utf8(runtime);
analyserNode->setWindowType(js_enum_parser::windowTypeFromString(type));
auto windowType = js_enum_parser::windowTypeFromString(value.asString(runtime).utf8(runtime));
auto event = [analyserNode, windowType](BaseAudioContext&) {
analyserNode->setWindowType(windowType);
};
analyserNode->scheduleAudioEvent(std::move(event));
windowType_ = windowType;
}

JSI_HOST_FUNCTION_IMPL(AnalyserNodeHostObject, getFloatFrequencyData) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#pragma once

#include <audioapi/HostObjects/AudioNodeHostObject.h>
#include <audioapi/core/types/WindowType.h>

#include <memory>
#include <string>
#include <vector>

namespace audioapi {
using namespace facebook;
Expand All @@ -19,7 +19,6 @@ class AnalyserNodeHostObject : public AudioNodeHostObject {
const AnalyserOptions &options);

JSI_PROPERTY_GETTER_DECL(fftSize);
JSI_PROPERTY_GETTER_DECL(frequencyBinCount);
JSI_PROPERTY_GETTER_DECL(minDecibels);
JSI_PROPERTY_GETTER_DECL(maxDecibels);
JSI_PROPERTY_GETTER_DECL(smoothingTimeConstant);
Expand All @@ -35,6 +34,13 @@ class AnalyserNodeHostObject : public AudioNodeHostObject {
JSI_HOST_FUNCTION_DECL(getByteFrequencyData);
JSI_HOST_FUNCTION_DECL(getFloatTimeDomainData);
JSI_HOST_FUNCTION_DECL(getByteTimeDomainData);

private:
int fftSize_;
float minDecibels_;
float maxDecibels_;
float smoothingTimeConstant_;
WindowType windowType_;
};

} // namespace audioapi
Loading