Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 29 additions & 0 deletions packages/react-native-audio-api/.clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Full clang-tidy configuration for react-native-audio-api C++.
# See: https://clang.llvm.org/extra/clang-tidy/checks/list.html
# Tweak checks in .clangd (Diagnostics.ClangTidy.Remove) to disable noisy ones.

Checks: '-*,
bugprone-*,
-bugprone-easily-swappable-parameters,
modernize-*,
-modernize-use-trailing-return-type,
performance-*,
readability-*,
-readability-uppercase-literal-suffix,
-readability-math-missing-parentheses,
-readability-isolate-declaration,
-readability-identifier-length,
cppcoreguidelines-*,
-cppcoreguidelines-non-private-member-variables-in-classes,
-cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-init-variables,
concurrency-*'

HeaderFilterRegex: '.*/(audioapi|common/cpp|src/main/cpp)/.*'

FormatStyle: file
10 changes: 10 additions & 0 deletions packages/react-native-audio-api/.clangd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Documentation:
CommentFormat: Doxygen

CompileFlags:
Add:
- -std=c++20

Diagnostics:
ClangTidy:
FastCheckFilter: Loose
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ AndroidAudioRecorder::~AndroidAudioRecorder() {

if (isConnected()) {
isConnected_.store(false, std::memory_order_release);
adapterNode_->cleanup();
adapterNode_->adapterCleanup();
}
}

Expand Down Expand Up @@ -198,7 +198,7 @@ Result<std::tuple<std::string, double, double>, std::string> AndroidAudioRecorde
}

if (isConnected()) {
adapterNode_->cleanup();
adapterNode_->adapterCleanup();
}

filePath_ = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, setTargetAtTime) {
JSI_HOST_FUNCTION_IMPL(AudioParamHostObject, setValueCurveAtTime) {
auto arrayBuffer =
args[0].getObject(runtime).getPropertyAsObject(runtime, "buffer").getArrayBuffer(runtime);
auto rawValues = reinterpret_cast<float *>(arrayBuffer.data(runtime));
auto *rawValues = reinterpret_cast<float *>(arrayBuffer.data(runtime));
auto length = static_cast<int>(arrayBuffer.size(runtime) / sizeof(float));
auto values = std::make_shared<AudioArray>(rawValues, length);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
namespace audioapi {

AudioEventHandlerRegistryHostObject::AudioEventHandlerRegistryHostObject(
const std::shared_ptr<AudioEventHandlerRegistry> &eventHandlerRegistry) {
eventHandlerRegistry_ = eventHandlerRegistry;

const std::shared_ptr<AudioEventHandlerRegistry> &eventHandlerRegistry)
: eventHandlerRegistry_(eventHandlerRegistry) {
addFunctions(
JSI_EXPORT_FUNCTION(AudioEventHandlerRegistryHostObject, addAudioEventListener),
JSI_EXPORT_FUNCTION(AudioEventHandlerRegistryHostObject, removeAudioEventListener));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ JSI_HOST_FUNCTION_IMPL(AudioBufferHostObject, getChannelData) {
JSI_HOST_FUNCTION_IMPL(AudioBufferHostObject, copyFromChannel) {
auto arrayBuffer =
args[0].getObject(runtime).getPropertyAsObject(runtime, "buffer").getArrayBuffer(runtime);
auto destination = reinterpret_cast<float *>(arrayBuffer.data(runtime));
auto *destination = reinterpret_cast<float *>(arrayBuffer.data(runtime));
auto length = arrayBuffer.size(runtime) / sizeof(float);
auto channelNumber = static_cast<int>(args[1].getNumber());
auto startInChannel = static_cast<size_t>(args[2].getNumber());
Expand All @@ -69,7 +69,7 @@ JSI_HOST_FUNCTION_IMPL(AudioBufferHostObject, copyFromChannel) {
JSI_HOST_FUNCTION_IMPL(AudioBufferHostObject, copyToChannel) {
auto arrayBuffer =
args[0].getObject(runtime).getPropertyAsObject(runtime, "buffer").getArrayBuffer(runtime);
auto source = reinterpret_cast<float *>(arrayBuffer.data(runtime));
auto *source = reinterpret_cast<float *>(arrayBuffer.data(runtime));
auto length = arrayBuffer.size(runtime) / sizeof(float);
auto channelNumber = static_cast<int>(args[1].getNumber());
auto startInChannel = static_cast<size_t>(args[2].getNumber());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class AudioBufferHostObject : public JsiHostObject {
return *this;
}

[[nodiscard]] inline size_t getSizeInBytes() const {
~AudioBufferHostObject() override = default;

[[nodiscard]] size_t getSizeInBytes() const {
// *2 because every time buffer is passed we create a copy of it.
return audioBuffer_->getSize() * audioBuffer_->getNumberOfChannels() * sizeof(float) * 2;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ JSI_HOST_FUNCTION_IMPL(AudioBufferQueueSourceNodeHostObject, enqueueBuffer) {
std::shared_ptr<AudioBuffer> tailBuffer = nullptr;

if (pitchCorrection_ && !stretchHasBeenInit_) {
initStretch(copiedBuffer->getNumberOfChannels(), copiedBuffer->getSampleRate());
int extraTailFrames =
initStretch(
static_cast<int>(copiedBuffer->getNumberOfChannels()), copiedBuffer->getSampleRate());
auto extraTailFrames =
static_cast<size_t>((inputLatency_ + outputLatency_) * copiedBuffer->getSampleRate());
tailBuffer = std::make_shared<AudioBuffer>(
copiedBuffer->getNumberOfChannels(), extraTailFrames, copiedBuffer->getSampleRate());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void AudioBufferSourceNodeHostObject::setBuffer(const std::shared_ptr<AudioBuffe
} else {
if (pitchCorrection_) {
initStretch(static_cast<int>(buffer->getNumberOfChannels()), buffer->getSampleRate());
int extraTailFrames =
auto extraTailFrames =
static_cast<size_t>((inputLatency_ + outputLatency_) * buffer->getSampleRate());
size_t totalSize = buffer->getSize() + extraTailFrames;
copiedBuffer = std::make_shared<AudioBuffer>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class StreamerNodeHostObject : public AudioScheduledSourceNodeHostObject {
const StreamerOptions &options)
: AudioScheduledSourceNodeHostObject(context->createStreamer(options), options) {}

[[nodiscard]] static inline size_t getSizeInBytes() {
[[nodiscard]] static size_t getSizeInBytes() {
return SIZE;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ AudioDecoderHostObject::AudioDecoderHostObject(
JSI_HOST_FUNCTION_IMPL(AudioDecoderHostObject, decodeWithMemoryBlock) {
auto arrayBuffer =
args[0].getObject(runtime).getPropertyAsObject(runtime, "buffer").getArrayBuffer(runtime);
auto data = arrayBuffer.data(runtime);
auto *data = arrayBuffer.data(runtime);
auto size = static_cast<int>(arrayBuffer.size(runtime));

auto sampleRate = args[1].getNumber();
auto sampleRate = static_cast<float>(args[1].getNumber());

auto promise = promiseVendor_->createAsyncPromise([data, size, sampleRate]() -> PromiseResolver {
auto result = AudioDecoder::decodeWithMemoryBlock(data, size, sampleRate);
Expand All @@ -51,7 +51,7 @@ JSI_HOST_FUNCTION_IMPL(AudioDecoderHostObject, decodeWithMemoryBlock) {

JSI_HOST_FUNCTION_IMPL(AudioDecoderHostObject, decodeWithFilePath) {
auto sourcePath = args[0].getString(runtime).utf8(runtime);
auto sampleRate = args[1].getNumber();
auto sampleRate = static_cast<float>(args[1].getNumber());

auto promise = promiseVendor_->createAsyncPromise([sourcePath, sampleRate]() -> PromiseResolver {
auto result = AudioDecoder::decodeWithFilePath(sourcePath, sampleRate);
Expand All @@ -78,8 +78,8 @@ JSI_HOST_FUNCTION_IMPL(AudioDecoderHostObject, decodeWithFilePath) {

JSI_HOST_FUNCTION_IMPL(AudioDecoderHostObject, decodeWithPCMInBase64) {
auto b64 = args[0].getString(runtime).utf8(runtime);
auto inputSampleRate = args[1].getNumber();
auto inputChannelCount = args[2].getNumber();
auto inputSampleRate = static_cast<float>(args[1].getNumber());
auto inputChannelCount = static_cast<int>(args[2].getNumber());
auto interleaved = args[3].getBool();

auto promise = promiseVendor_->createAsyncPromise(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

namespace audioapi::js_enum_parser {

// NOLINTBEGIN(readability-braces-around-statements)

BiquadFilterType filterTypeFromString(const std::string &type) {
if (type == "lowpass")
return BiquadFilterType::LOWPASS;
Expand Down Expand Up @@ -187,3 +189,5 @@ std::string channelInterpretationToString(ChannelInterpretation interpretation)
}
}
} // namespace audioapi::js_enum_parser

// NOLINTEND(readability-braces-around-statements)
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ inline BaseAudioBufferSourceOptions parseBaseAudioBufferSourceOptions(

auto pitchCorrectionValue = optionsObject.getProperty(runtime, "pitchCorrection");
if (pitchCorrectionValue.isBool()) {
options.pitchCorrection = static_cast<bool>(pitchCorrectionValue.getBool());
options.pitchCorrection = pitchCorrectionValue.getBool();
}

return options;
Expand All @@ -258,7 +258,7 @@ inline AudioBufferSourceOptions parseAudioBufferSourceOptions(

auto loopValue = optionsObject.getProperty(runtime, "loop");
if (loopValue.isBool()) {
options.loop = static_cast<bool>(loopValue.getBool());
options.loop = loopValue.getBool();
}

auto loopStartValue = optionsObject.getProperty(runtime, "loopStart");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <audioapi/core/BaseAudioContext.h>
#include <audioapi/core/utils/Macros.h>
#include <audioapi/core/utils/worklets/SafeIncludes.h>
#include <audioapi/utils/AudioBuffer.hpp>

Expand All @@ -21,6 +22,7 @@ class AudioContext : public BaseAudioContext {
const std::shared_ptr<IAudioEventHandlerRegistry> &audioEventHandlerRegistry,
const RuntimeRegistry &runtimeRegistry);
~AudioContext() override;
DELETE_COPY_AND_MOVE(AudioContext);

void close();
bool resume();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ AudioNode::AudioNode(
const std::shared_ptr<BaseAudioContext> &context,
const AudioNodeOptions &options)
: context_(context),
audioBuffer_(nullptr),
numberOfInputs_(options.numberOfInputs),
numberOfOutputs_(options.numberOfOutputs),
channelCount_(options.channelCount),
Expand All @@ -37,35 +38,43 @@ size_t AudioNode::getChannelCount() const {
return channelCount_;
}

void AudioNode::connect(const std::shared_ptr<AudioNode> &node) {
void AudioNode::connect(
const std::shared_ptr<AudioNode>
&node) { // NOLINT(readability-convert-member-functions-to-static)
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
context->getGraphManager()->addPendingNodeConnection(
shared_from_this(), node, AudioGraphManager::ConnectionType::CONNECT);
}
}

void AudioNode::connect(const std::shared_ptr<AudioParam> &param) {
void AudioNode::connect(
const std::shared_ptr<AudioParam>
&param) { // NOLINT(readability-convert-member-functions-to-static)
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
context->getGraphManager()->addPendingParamConnection(
shared_from_this(), param, AudioGraphManager::ConnectionType::CONNECT);
}
}

void AudioNode::disconnect() {
void AudioNode::disconnect() { // NOLINT(readability-convert-member-functions-to-static)
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
context->getGraphManager()->addPendingNodeConnection(
shared_from_this(), nullptr, AudioGraphManager::ConnectionType::DISCONNECT_ALL);
}
}

void AudioNode::disconnect(const std::shared_ptr<AudioNode> &node) {
void AudioNode::disconnect(
const std::shared_ptr<AudioNode>
&node) { // NOLINT(readability-convert-member-functions-to-static)
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
context->getGraphManager()->addPendingNodeConnection(
shared_from_this(), node, AudioGraphManager::ConnectionType::DISCONNECT);
}
}

void AudioNode::disconnect(const std::shared_ptr<AudioParam> &param) {
void AudioNode::disconnect(
const std::shared_ptr<AudioParam>
&param) { // NOLINT(readability-convert-member-functions-to-static)
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
context->getGraphManager()->addPendingParamConnection(
shared_from_this(), param, AudioGraphManager::ConnectionType::DISCONNECT);
Expand Down Expand Up @@ -131,7 +140,7 @@ std::shared_ptr<DSPAudioBuffer> AudioNode::processAudio(
return processNode(processingBuffer, framesToProcess);
}

bool AudioNode::isAlreadyProcessed() {
bool AudioNode::isAlreadyProcessed() { // NOLINT(readability-convert-member-functions-to-static)
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
std::size_t currentSampleFrame = context->getCurrentSampleFrame();

Expand All @@ -147,19 +156,18 @@ bool AudioNode::isAlreadyProcessed() {
}

// If context is invalid, consider it as already processed to avoid processing
return true;
return true; // NOLINT(readability-simplify-boolean-expr)
}

std::shared_ptr<DSPAudioBuffer> AudioNode::processInputs(
const std::shared_ptr<DSPAudioBuffer> &outputBuffer,
int framesToProcess,
bool checkIsAlreadyProcessed) {
bool checkIsAlreadyProcessed) { // NOLINT(readability-convert-member-functions-to-static)
auto processingBuffer = audioBuffer_;
processingBuffer->zero();

size_t maxNumberOfChannels = 0;
for (auto it = inputNodes_.begin(), end = inputNodes_.end(); it != end; ++it) {
auto inputNode = *it;
for (auto *inputNode : inputNodes_) {
assert(inputNode != nullptr);

if (!inputNode->isEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <audioapi/core/types/ChannelCountMode.h>
#include <audioapi/core/types/ChannelInterpretation.h>
#include <audioapi/core/utils/Constants.h>
#include <audioapi/core/utils/Macros.h>
#include <audioapi/types/NodeOptions.h>
#include <audioapi/utils/AudioBuffer.hpp>

Expand All @@ -25,7 +26,9 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {
const AudioNodeOptions &options = AudioNodeOptions());
virtual ~AudioNode();

size_t getChannelCount() const;
DELETE_COPY_AND_MOVE(AudioNode);

[[nodiscard]] size_t getChannelCount() const;
void connect(const std::shared_ptr<AudioNode> &node);
void connect(const std::shared_ptr<AudioParam> &param);
void disconnect();
Expand All @@ -36,25 +39,27 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {
int framesToProcess,
bool checkIsAlreadyProcessed);

float getContextSampleRate() const {
[[nodiscard]] float getContextSampleRate()
const { // NOLINT(readability-convert-member-functions-to-static)
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
return context->getSampleRate();
}

return DEFAULT_SAMPLE_RATE;
}

float getNyquistFrequency() const {
return getContextSampleRate() / 2.0f;
[[nodiscard]] float getNyquistFrequency() const {
constexpr float kNyquistDivisor = 2.0f;
return getContextSampleRate() / kNyquistDivisor;
}

/// @note JS Thread only
bool isEnabled() const;
[[nodiscard]] bool isEnabled() const;
/// @note JS Thread only
bool requiresTailProcessing() const;
[[nodiscard]] bool requiresTailProcessing() const;

template <typename F>
bool inline scheduleAudioEvent(F &&event) noexcept {
bool scheduleAudioEvent(F &&event) noexcept {
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
return context->scheduleAudioEvent(std::forward<F>(event));
}
Expand All @@ -75,14 +80,14 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {

const int numberOfInputs_ = 1;
const int numberOfOutputs_ = 1;
size_t channelCount_ = 2;
int channelCount_ = 2;
const ChannelCountMode channelCountMode_ = ChannelCountMode::MAX;
const ChannelInterpretation channelInterpretation_ = ChannelInterpretation::SPEAKERS;
const bool requiresTailProcessing_;

std::unordered_set<AudioNode *> inputNodes_ = {};
std::unordered_set<std::shared_ptr<AudioNode>> outputNodes_ = {};
std::unordered_set<std::shared_ptr<AudioParam>> outputParams_ = {};
std::unordered_set<AudioNode *> inputNodes_;
std::unordered_set<std::shared_ptr<AudioNode>> outputNodes_;
std::unordered_set<std::shared_ptr<AudioParam>> outputParams_;

int numberOfEnabledInputNodes_ = 0;
std::atomic<bool> isInitialized_ = false;
Expand All @@ -94,7 +99,7 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {

private:
bool isEnabled_ = true;
std::vector<std::shared_ptr<DSPAudioBuffer>> inputBuffers_ = {};
std::vector<std::shared_ptr<DSPAudioBuffer>> inputBuffers_;

virtual std::shared_ptr<DSPAudioBuffer> processInputs(
const std::shared_ptr<DSPAudioBuffer> &outputBuffer,
Expand Down
Loading
Loading