From 147e724503a2299f826c4d94d5cf169441a18899 Mon Sep 17 00:00:00 2001 From: Maciej Makowski <120780663+maciejmakowski2003@users.noreply.github.com> Date: Fri, 31 Jan 2025 15:13:53 +0100 Subject: [PATCH] Refactor/constants and types (#278) * refactor: refactored types and constants in AudioArray * refactor: refactored types and constants in AnalyserNode * refactor: refactored types and constants in AudioBus * fix: added necessary include * refactor: refactored types and constants in AudioBuffer * refactor: refactored types and constants in AudioBufferSourceNode * refactor: refactored types and constants in BaseAudioContext * refactor: refactored types and constants in AudioContext * refactor: refactored types and constants in AudioDecoder and AudioDestinationNode * refactor: refactored types and constants in AudioNode * refactor: refactored types and constants in AudioNodeManager * refactor: refactored types and constants in AudioParam * refactor: refactored types and constants in AudioScheduledSourceNode * refactor: refactored types and constants in BiquadFilterNode * refactor: refactored types and constants in GainNode * refactor: refactored types and constants in OscillatorNode * refactor: refactored types and constants in StereoPannerNode * refactor: refactored types and constants in PeriodicWave * refactor: refactored types in utils * ci: yarn format * fix: fixed analyser types * refactor: host objects --------- Co-authored-by: Maciej Makowski --- apps/fabric-example/ios/Podfile.lock | 4 +- .../android/src/main/cpp/core/AudioPlayer.cpp | 8 +-- .../android/src/main/cpp/core/AudioPlayer.h | 6 +- .../HostObjects/AudioAPIInstallerHostObject.h | 2 +- .../cpp/HostObjects/AudioBufferHostObject.h | 11 ++-- .../cpp/HostObjects/AudioParamHostObject.h | 3 +- .../HostObjects/BaseAudioContextHostObject.h | 7 ++- .../common/cpp/core/AnalyserNode.cpp | 58 +++++++++---------- .../common/cpp/core/AnalyserNode.h | 39 +++++++------ .../common/cpp/core/AudioArray.cpp | 28 ++++----- .../common/cpp/core/AudioArray.h | 31 +++++----- .../common/cpp/core/AudioBuffer.cpp | 21 ++++--- .../common/cpp/core/AudioBuffer.h | 17 +++--- .../common/cpp/core/AudioBufferSourceNode.cpp | 38 ++++++------ .../common/cpp/core/AudioBufferSourceNode.h | 1 + .../common/cpp/core/AudioBus.cpp | 48 +++++++-------- .../common/cpp/core/AudioBus.h | 48 +++++++-------- .../common/cpp/core/AudioContext.cpp | 2 +- .../common/cpp/core/AudioContext.h | 2 +- .../common/cpp/core/AudioDecoder.h | 4 +- .../common/cpp/core/AudioDestinationNode.cpp | 2 +- .../common/cpp/core/AudioDestinationNode.h | 3 +- .../common/cpp/core/AudioNode.cpp | 12 ++-- .../common/cpp/core/AudioNode.h | 19 +++--- .../common/cpp/core/AudioNodeManager.cpp | 4 +- .../common/cpp/core/AudioNodeManager.h | 2 +- .../common/cpp/core/AudioParam.cpp | 9 ++- .../common/cpp/core/AudioParam.h | 3 +- .../cpp/core/AudioScheduledSourceNode.cpp | 2 +- .../cpp/core/AudioScheduledSourceNode.h | 1 + .../common/cpp/core/BaseAudioContext.cpp | 10 +++- .../common/cpp/core/BaseAudioContext.h | 10 ++-- .../common/cpp/core/BiquadFilterNode.cpp | 12 ++-- .../common/cpp/core/Constants.h | 37 ++++++++---- .../common/cpp/core/GainNode.cpp | 2 +- .../common/cpp/core/OscillatorNode.cpp | 7 ++- .../common/cpp/core/PeriodicWave.cpp | 13 +++-- .../common/cpp/core/PeriodicWave.h | 8 +-- .../common/cpp/core/StereoPannerNode.cpp | 8 +-- .../common/cpp/utils/AudioUtils.cpp | 4 +- .../common/cpp/utils/AudioUtils.h | 4 +- .../common/cpp/utils/Locker.h | 4 +- 42 files changed, 294 insertions(+), 260 deletions(-) diff --git a/apps/fabric-example/ios/Podfile.lock b/apps/fabric-example/ios/Podfile.lock index f9da416c..1728adeb 100644 --- a/apps/fabric-example/ios/Podfile.lock +++ b/apps/fabric-example/ios/Podfile.lock @@ -1656,7 +1656,7 @@ PODS: - React-logger (= 0.76.5) - React-perflogger (= 0.76.5) - React-utils (= 0.76.5) - - RNAudioAPI (0.4.0): + - RNAudioAPI (0.4.1): - DoubleConversion - glog - hermes-engine @@ -2152,7 +2152,7 @@ SPEC CHECKSUMS: React-utils: f584a494ac233c7857bab176416b0c49cb4037ba ReactCodegen: 1f59af46efc9351f27046d90d9ceb5e99385f623 ReactCommon: 5809a8ee421b7219221a475b78180f8f34b5c5ec - RNAudioAPI: 8a98b4d1149f55f3815919576d50520fbab125f9 + RNAudioAPI: 15bc66d49cd9ea130a0139ed44ed5bb87aeb441b RNGestureHandler: e1dcb274c17ca0680a04d7ff357e35e37c384185 RNReanimated: 270e2df37d3a18e8270a9c461d9f90a374a97d04 RNScreens: 351f431ef2a042a1887d4d90e1c1024b8ae9d123 diff --git a/packages/react-native-audio-api/android/src/main/cpp/core/AudioPlayer.cpp b/packages/react-native-audio-api/android/src/main/cpp/core/AudioPlayer.cpp index 2c3287bd..3225d3db 100644 --- a/packages/react-native-audio-api/android/src/main/cpp/core/AudioPlayer.cpp +++ b/packages/react-native-audio-api/android/src/main/cpp/core/AudioPlayer.cpp @@ -21,7 +21,7 @@ AudioPlayer::AudioPlayer( ->setDataCallback(this) ->openStream(mStream_); - sampleRate_ = mStream_->getSampleRate(); + sampleRate_ = static_cast(mStream_->getSampleRate()); mBus_ = std::make_shared( sampleRate_, RENDER_QUANTUM_SIZE, CHANNEL_COUNT); isInitialized_ = true; @@ -29,7 +29,7 @@ AudioPlayer::AudioPlayer( AudioPlayer::AudioPlayer( const std::function &renderAudio, - int sampleRate) + float sampleRate) : renderAudio_(renderAudio) { AudioStreamBuilder builder; @@ -40,7 +40,7 @@ AudioPlayer::AudioPlayer( ->setChannelCount(CHANNEL_COUNT) ->setSampleRateConversionQuality(SampleRateConversionQuality::Medium) ->setDataCallback(this) - ->setSampleRate(sampleRate) + ->setSampleRate(static_cast(sampleRate)) ->openStream(mStream_); sampleRate_ = sampleRate; @@ -49,7 +49,7 @@ AudioPlayer::AudioPlayer( isInitialized_ = true; } -int AudioPlayer::getSampleRate() const { +float AudioPlayer::getSampleRate() const { return sampleRate_; } diff --git a/packages/react-native-audio-api/android/src/main/cpp/core/AudioPlayer.h b/packages/react-native-audio-api/android/src/main/cpp/core/AudioPlayer.h index 3c63c664..c5abcc10 100644 --- a/packages/react-native-audio-api/android/src/main/cpp/core/AudioPlayer.h +++ b/packages/react-native-audio-api/android/src/main/cpp/core/AudioPlayer.h @@ -16,9 +16,9 @@ class AudioPlayer : public AudioStreamDataCallback { explicit AudioPlayer(const std::function &renderAudio); AudioPlayer( const std::function &renderAudio, - int sampleRate); + float sampleRate); - [[nodiscard]] int getSampleRate() const; + [[nodiscard]] float getSampleRate() const; void start(); void stop(); @@ -32,7 +32,7 @@ class AudioPlayer : public AudioStreamDataCallback { std::shared_ptr mStream_; std::shared_ptr mBus_; bool isInitialized_ = false; - int sampleRate_; + float sampleRate_; }; } // namespace audioapi diff --git a/packages/react-native-audio-api/common/cpp/HostObjects/AudioAPIInstallerHostObject.h b/packages/react-native-audio-api/common/cpp/HostObjects/AudioAPIInstallerHostObject.h index 5b6d6efb..afc41a5a 100644 --- a/packages/react-native-audio-api/common/cpp/HostObjects/AudioAPIInstallerHostObject.h +++ b/packages/react-native-audio-api/common/cpp/HostObjects/AudioAPIInstallerHostObject.h @@ -39,7 +39,7 @@ class AudioAPIInstallerHostObject if (args[0].isUndefined()) { audioContext = std::make_shared(); } else { - int sampleRate = static_cast(args[0].getNumber()); + auto sampleRate = static_cast(args[0].getNumber()); audioContext = std::make_shared(sampleRate); } diff --git a/packages/react-native-audio-api/common/cpp/HostObjects/AudioBufferHostObject.h b/packages/react-native-audio-api/common/cpp/HostObjects/AudioBufferHostObject.h index e38fc7c5..cef0274e 100644 --- a/packages/react-native-audio-api/common/cpp/HostObjects/AudioBufferHostObject.h +++ b/packages/react-native-audio-api/common/cpp/HostObjects/AudioBufferHostObject.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "AudioBuffer.h" @@ -34,7 +35,7 @@ class AudioBufferHostObject : public JsiHostObject { } JSI_PROPERTY_GETTER(length) { - return {audioBuffer_->getLength()}; + return {static_cast(audioBuffer_->getLength())}; } JSI_PROPERTY_GETTER(duration) { @@ -60,9 +61,9 @@ class AudioBufferHostObject : public JsiHostObject { JSI_HOST_FUNCTION(copyFromChannel) { auto destination = args[0].getObject(runtime).asArray(runtime); auto destinationLength = - static_cast(destination.getProperty(runtime, "length").asNumber()); + static_cast(destination.getProperty(runtime, "length").asNumber()); auto channelNumber = static_cast(args[1].getNumber()); - auto startInChannel = static_cast(args[2].getNumber()); + auto startInChannel = static_cast(args[2].getNumber()); auto *destinationData = new float[destinationLength]; @@ -79,9 +80,9 @@ class AudioBufferHostObject : public JsiHostObject { JSI_HOST_FUNCTION(copyToChannel) { auto source = args[0].getObject(runtime).asArray(runtime); auto sourceLength = - static_cast(source.getProperty(runtime, "length").asNumber()); + static_cast(source.getProperty(runtime, "length").asNumber()); auto channelNumber = static_cast(args[1].getNumber()); - auto startInChannel = static_cast(args[2].getNumber()); + auto startInChannel = static_cast(args[2].getNumber()); auto *sourceData = new float[sourceLength]; diff --git a/packages/react-native-audio-api/common/cpp/HostObjects/AudioParamHostObject.h b/packages/react-native-audio-api/common/cpp/HostObjects/AudioParamHostObject.h index d2a2b1e9..ecb5191a 100644 --- a/packages/react-native-audio-api/common/cpp/HostObjects/AudioParamHostObject.h +++ b/packages/react-native-audio-api/common/cpp/HostObjects/AudioParamHostObject.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "AudioParam.h" @@ -79,7 +80,7 @@ class AudioParamHostObject : public JsiHostObject { JSI_HOST_FUNCTION(setValueCurveAtTime) { auto values = args[0].getObject(runtime).asArray(runtime); - auto length = static_cast(values.length(runtime)); + auto length = static_cast(values.length(runtime)); auto valuesData = new float[length]; for (size_t i = 0; i < values.length(runtime); i++) { valuesData[i] = diff --git a/packages/react-native-audio-api/common/cpp/HostObjects/BaseAudioContextHostObject.h b/packages/react-native-audio-api/common/cpp/HostObjects/BaseAudioContextHostObject.h index 403f4d47..b19df16e 100644 --- a/packages/react-native-audio-api/common/cpp/HostObjects/BaseAudioContextHostObject.h +++ b/packages/react-native-audio-api/common/cpp/HostObjects/BaseAudioContextHostObject.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -100,9 +101,9 @@ class BaseAudioContextHostObject : public JsiHostObject { JSI_HOST_FUNCTION(createBuffer) { auto numberOfChannels = static_cast(args[0].getNumber()); - auto length = static_cast(args[1].getNumber()); - auto sampleRate = static_cast(args[2].getNumber()); - auto buffer = context_->createBuffer(numberOfChannels, length, sampleRate); + auto length = static_cast(args[1].getNumber()); + auto sampleRate = static_cast(args[2].getNumber()); + auto buffer = BaseAudioContext::createBuffer(numberOfChannels, length, sampleRate); auto bufferHostObject = std::make_shared(buffer); return jsi::Object::createFromHostObject(runtime, bufferHostObject); } diff --git a/packages/react-native-audio-api/common/cpp/core/AnalyserNode.cpp b/packages/react-native-audio-api/common/cpp/core/AnalyserNode.cpp index ce7c6159..27456f51 100644 --- a/packages/react-native-audio-api/common/cpp/core/AnalyserNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AnalyserNode.cpp @@ -18,32 +18,36 @@ AnalyserNode::AnalyserNode(audioapi::BaseAudioContext *context) smoothingTimeConstant_(DEFAULT_SMOOTHING_TIME_CONSTANT), vWriteIndex_(0) { inputBuffer_ = std::make_unique(MAX_FFT_SIZE * 2); - fftFrame_ = std::make_unique(fftSize_); magnitudeBuffer_ = std::make_unique(fftSize_ / 2); + downMixBus_ = std::make_unique( + context_->getSampleRate(), RENDER_QUANTUM_SIZE, 1); + + fftFrame_ = std::make_unique(fftSize_); + isInitialized_ = true; } -size_t AnalyserNode::getFftSize() const { +int AnalyserNode::getFftSize() const { return fftSize_; } -size_t AnalyserNode::getFrequencyBinCount() const { +int AnalyserNode::getFrequencyBinCount() const { return fftSize_ / 2; } -double AnalyserNode::getMinDecibels() const { +float AnalyserNode::getMinDecibels() const { return minDecibels_; } -double AnalyserNode::getMaxDecibels() const { +float AnalyserNode::getMaxDecibels() const { return maxDecibels_; } -double AnalyserNode::getSmoothingTimeConstant() const { +float AnalyserNode::getSmoothingTimeConstant() const { return smoothingTimeConstant_; } -void AnalyserNode::setFftSize(size_t fftSize) { +void AnalyserNode::setFftSize(int fftSize) { if (fftSize_ == fftSize) { return; } @@ -53,35 +57,35 @@ void AnalyserNode::setFftSize(size_t fftSize) { magnitudeBuffer_ = std::make_unique(fftSize_ / 2); } -void AnalyserNode::setMinDecibels(double minDecibels) { +void AnalyserNode::setMinDecibels(float minDecibels) { minDecibels_ = minDecibels; } -void AnalyserNode::setMaxDecibels(double maxDecibels) { +void AnalyserNode::setMaxDecibels(float maxDecibels) { maxDecibels_ = maxDecibels; } -void AnalyserNode::setSmoothingTimeConstant(double smoothingTimeConstant) { +void AnalyserNode::setSmoothingTimeConstant(float smoothingTimeConstant) { smoothingTimeConstant_ = smoothingTimeConstant; } -void AnalyserNode::getFloatFrequencyData(float *data, size_t length) { +void AnalyserNode::getFloatFrequencyData(float *data, int length) { doFFTAnalysis(); - length = std::min(magnitudeBuffer_->getSize(), length); + length = std::min(static_cast(magnitudeBuffer_->getSize()), length); VectorMath::linearToDecibels(magnitudeBuffer_->getData(), data, length); } -void AnalyserNode::getByteFrequencyData(uint8_t *data, size_t length) { +void AnalyserNode::getByteFrequencyData(uint8_t *data, int length) { doFFTAnalysis(); auto magnitudeBufferData = magnitudeBuffer_->getData(); - length = std::min(magnitudeBuffer_->getSize(), length); + length = std::min(static_cast(magnitudeBuffer_->getSize()), length); const auto rangeScaleFactor = maxDecibels_ == minDecibels_ ? 1 : 1 / (maxDecibels_ - minDecibels_); - for (size_t i = 0; i < length; i++) { + for (int i = 0; i < length; i++) { auto dbMag = magnitudeBufferData[i] == 0 ? minDecibels_ : AudioUtils::linearToDecibels(magnitudeBufferData[i]); @@ -98,20 +102,20 @@ void AnalyserNode::getByteFrequencyData(uint8_t *data, size_t length) { } } -void AnalyserNode::getFloatTimeDomainData(float *data, size_t length) { - auto size = std::min(fftSize_, length); +void AnalyserNode::getFloatTimeDomainData(float *data, int length) { + auto size = fftSize_ ? fftSize_ < length : length; - for (size_t i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { data[i] = inputBuffer_->getData() [(vWriteIndex_ + i - fftSize_ + inputBuffer_->getSize()) % inputBuffer_->getSize()]; } } -void AnalyserNode::getByteTimeDomainData(uint8_t *data, size_t length) { - auto size = std::min(fftSize_, length); +void AnalyserNode::getByteTimeDomainData(uint8_t *data, int length) { + auto size = fftSize_ ? fftSize_ < length : length; - for (size_t i = 0; i < size; i++) { + for (int i = 0; i < size; i++) { auto value = inputBuffer_->getData() [(vWriteIndex_ + i - fftSize_ + inputBuffer_->getSize()) % inputBuffer_->getSize()]; @@ -140,15 +144,11 @@ void AnalyserNode::processNode( // Analyser should behave like a sniffer node, it should not modify the // processingBus but instead copy the data to its own input buffer. - if (downMixBus_ == nullptr) { - downMixBus_ = std::make_unique( - context_->getSampleRate(), processingBus->getSize(), 1); - } - downMixBus_->copy(processingBus); if (vWriteIndex_ + framesToProcess > inputBuffer_->getSize()) { - auto framesToCopy = inputBuffer_->getSize() - vWriteIndex_; + auto framesToCopy = + static_cast(inputBuffer_->getSize() - vWriteIndex_); memcpy( inputBuffer_->getData() + vWriteIndex_, downMixBus_->getChannel(0)->getData(), @@ -211,7 +211,7 @@ void AnalyserNode::doFFTAnalysis() { const float magnitudeScale = 1.0f / static_cast(fftSize_); auto magnitudeBufferData = magnitudeBuffer_->getData(); - for (size_t i = 0; i < magnitudeBuffer_->getSize(); i++) { + for (int i = 0; i < magnitudeBuffer_->getSize(); i++) { std::complex c(realFFTFrameData[i], imaginaryFFTFrameData[i]); auto scalarMagnitude = std::abs(c) * magnitudeScale; magnitudeBufferData[i] = static_cast( @@ -220,7 +220,7 @@ void AnalyserNode::doFFTAnalysis() { } } -void AnalyserNode::applyWindow(float *data, size_t length) { +void AnalyserNode::applyWindow(float *data, int length) { // https://www.sciencedirect.com/topics/engineering/blackman-window auto alpha = 0.16f; auto a0 = 0.5f * (1 - alpha); diff --git a/packages/react-native-audio-api/common/cpp/core/AnalyserNode.h b/packages/react-native-audio-api/common/cpp/core/AnalyserNode.h index 10574d6b..365c37f1 100644 --- a/packages/react-native-audio-api/common/cpp/core/AnalyserNode.h +++ b/packages/react-native-audio-api/common/cpp/core/AnalyserNode.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "AudioNode.h" @@ -14,30 +15,30 @@ class AnalyserNode : public AudioNode { public: explicit AnalyserNode(BaseAudioContext *context); - size_t getFftSize() const; - size_t getFrequencyBinCount() const; - double getMinDecibels() const; - double getMaxDecibels() const; + int getFftSize() const; + int getFrequencyBinCount() const; + float getMinDecibels() const; + float getMaxDecibels() const; - double getSmoothingTimeConstant() const; - void setFftSize(size_t fftSize); - void setMinDecibels(double minDecibels); - void setMaxDecibels(double maxDecibels); - void setSmoothingTimeConstant(double smoothingTimeConstant); + float getSmoothingTimeConstant() const; + void setFftSize(int fftSize); + void setMinDecibels(float minDecibels); + void setMaxDecibels(float maxDecibels); + void setSmoothingTimeConstant(float smoothingTimeConstant); - void getFloatFrequencyData(float *data, size_t length); - void getByteFrequencyData(uint8_t *data, size_t length); - void getFloatTimeDomainData(float *data, size_t length); - void getByteTimeDomainData(uint8_t *data, size_t length); + void getFloatFrequencyData(float *data, int length); + void getByteFrequencyData(uint8_t *data, int length); + void getFloatTimeDomainData(float *data, int length); + void getByteTimeDomainData(uint8_t *data, int length); protected: void processNode(AudioBus *processingBus, int framesToProcess) override; private: - size_t fftSize_; - double minDecibels_; - double maxDecibels_; - double smoothingTimeConstant_; + int fftSize_; + float minDecibels_; + float maxDecibels_; + float smoothingTimeConstant_; std::unique_ptr inputBuffer_; std::unique_ptr downMixBus_; @@ -47,8 +48,8 @@ class AnalyserNode : public AudioNode { std::unique_ptr magnitudeBuffer_; bool shouldDoFFTAnalysis_ { true }; - void doFFTAnalysis(); - static void applyWindow(float *data, size_t length); + void doFFTAnalysis(); + static void applyWindow(float *data, int length); }; } // namespace audioapi diff --git a/packages/react-native-audio-api/common/cpp/core/AudioArray.cpp b/packages/react-native-audio-api/common/cpp/core/AudioArray.cpp index 2115e8ed..7ea21247 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioArray.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioArray.cpp @@ -5,7 +5,7 @@ namespace audioapi { -AudioArray::AudioArray(int size) : data_(nullptr), size_(size) { +AudioArray::AudioArray(size_t size) : data_(nullptr), size_(size) { resize(size); } @@ -16,7 +16,7 @@ AudioArray::~AudioArray() { } } -int AudioArray::getSize() const { +size_t AudioArray::getSize() const { return size_; } @@ -24,11 +24,11 @@ float *AudioArray::getData() const { return data_; } -float &AudioArray::operator[](int index) { +float &AudioArray::operator[](size_t index) { return data_[index]; } -const float &AudioArray::operator[](int index) const { +const float &AudioArray::operator[](size_t index) const { return data_[index]; } @@ -42,7 +42,7 @@ void AudioArray::normalize() { VectorMath::multiplyByScalar(data_, 1.0f / maxAbsValue, data_, size_); } -void AudioArray::resize(int size) { +void AudioArray::resize(size_t size) { if (size == size_) { if (!data_) { data_ = new float[size]; @@ -71,7 +71,7 @@ void AudioArray::zero() { zero(0, size_); } -void AudioArray::zero(int start, int length) { +void AudioArray::zero(size_t start, size_t length) { memset(data_ + start, 0, length * sizeof(float)); } @@ -79,15 +79,15 @@ void AudioArray::sum(const AudioArray *source) { sum(source, 0, 0, size_); } -void AudioArray::sum(const AudioArray *source, int start, int length) { +void AudioArray::sum(const AudioArray *source, size_t start, size_t length) { sum(source, start, start, length); } void AudioArray::sum( const AudioArray *source, - int sourceStart, - int destinationStart, - int length) { + size_t sourceStart, + size_t destinationStart, + size_t length) { VectorMath::add( data_ + destinationStart, source->getData() + sourceStart, @@ -99,15 +99,15 @@ void AudioArray::copy(const AudioArray *source) { copy(source, 0, size_); } -void AudioArray::copy(const AudioArray *source, int start, int length) { +void AudioArray::copy(const AudioArray *source, size_t start, size_t length) { copy(source, start, start, length); } void AudioArray::copy( const AudioArray *source, - int sourceStart, - int destinationStart, - int length) { + size_t sourceStart, + size_t destinationStart, + size_t length) { memcpy( data_ + destinationStart, source->getData() + sourceStart, diff --git a/packages/react-native-audio-api/common/cpp/core/AudioArray.h b/packages/react-native-audio-api/common/cpp/core/AudioArray.h index f86b5d11..109f700a 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioArray.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioArray.h @@ -2,47 +2,48 @@ #include #include +#include namespace audioapi { class AudioArray { public: - explicit AudioArray(int size); + explicit AudioArray(size_t size); ~AudioArray(); - [[nodiscard]] int getSize() const; + [[nodiscard]] size_t getSize() const; [[nodiscard]] float *getData() const; - float &operator[](int index); - const float &operator[](int index) const; + float &operator[](size_t index); + const float &operator[](size_t index) const; void normalize(); - void resize(int size); + void resize(size_t size); void scale(float value); [[nodiscard]] float getMaxAbsValue() const; void zero(); - void zero(int start, int length); + void zero(size_t start, size_t length); void sum(const AudioArray *source); - void sum(const AudioArray *source, int start, int length); + void sum(const AudioArray *source, size_t start, size_t length); void sum( const AudioArray *source, - int sourceStart, - int destinationStart, - int length); + size_t sourceStart, + size_t destinationStart, + size_t length); void copy(const AudioArray *source); - void copy(const AudioArray *source, int start, int length); + void copy(const AudioArray *source, size_t start, size_t length); void copy( const AudioArray *source, - int sourceStart, - int destinationStart, - int length); + size_t sourceStart, + size_t destinationStart, + size_t length); private: float *data_; - int size_; + size_t size_; }; } // namespace audioapi diff --git a/packages/react-native-audio-api/common/cpp/core/AudioBuffer.cpp b/packages/react-native-audio-api/common/cpp/core/AudioBuffer.cpp index cd19ace0..8b6b0b5f 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioBuffer.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioBuffer.cpp @@ -4,7 +4,10 @@ namespace audioapi { -AudioBuffer::AudioBuffer(int numberOfChannels, int length, int sampleRate) { +AudioBuffer::AudioBuffer( + int numberOfChannels, + size_t length, + float sampleRate) { bus_ = std::make_shared(sampleRate, length, numberOfChannels); } @@ -12,7 +15,7 @@ AudioBuffer::AudioBuffer(AudioBus *bus) { bus_ = std::shared_ptr(bus); } -int AudioBuffer::getLength() const { +size_t AudioBuffer::getLength() const { return bus_->getSize(); } @@ -20,12 +23,12 @@ int AudioBuffer::getNumberOfChannels() const { return bus_->getNumberOfChannels(); } -int AudioBuffer::getSampleRate() const { +float AudioBuffer::getSampleRate() const { return bus_->getSampleRate(); } -double AudioBuffer::getDuration() const { - return static_cast(getLength()) / getSampleRate(); +float AudioBuffer::getDuration() const { + return static_cast(getLength()) / getSampleRate(); } float *AudioBuffer::getChannelData(int channel) const { @@ -34,9 +37,9 @@ float *AudioBuffer::getChannelData(int channel) const { void AudioBuffer::copyFromChannel( float *destination, - int destinationLength, + size_t destinationLength, int channelNumber, - int startInChannel) const { + size_t startInChannel) const { memcpy( destination, bus_->getChannel(channelNumber)->getData() + startInChannel, @@ -46,9 +49,9 @@ void AudioBuffer::copyFromChannel( void AudioBuffer::copyToChannel( const float *source, - int sourceLength, + size_t sourceLength, int channelNumber, - int startInChannel) { + size_t startInChannel) { memcpy( bus_->getChannel(channelNumber)->getData() + startInChannel, source, diff --git a/packages/react-native-audio-api/common/cpp/core/AudioBuffer.h b/packages/react-native-audio-api/common/cpp/core/AudioBuffer.h index f03dcbf8..61166b4a 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioBuffer.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioBuffer.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace audioapi { @@ -11,26 +12,26 @@ class AudioBus; class AudioBuffer : public std::enable_shared_from_this { public: - explicit AudioBuffer(int numberOfChannels, int length, int sampleRate); + explicit AudioBuffer(int numberOfChannels, size_t length, float sampleRate); explicit AudioBuffer(AudioBus *bus); - [[nodiscard]] int getLength() const; - [[nodiscard]] int getSampleRate() const; - [[nodiscard]] double getDuration() const; + [[nodiscard]] size_t getLength() const; + [[nodiscard]] float getSampleRate() const; + [[nodiscard]] float getDuration() const; [[nodiscard]] int getNumberOfChannels() const; [[nodiscard]] float *getChannelData(int channel) const; void copyFromChannel( float *destination, - int destinationLength, + size_t destinationLength, int channelNumber, - int startInChannel) const; + size_t startInChannel) const; void copyToChannel( const float *source, - int sourceLength, + size_t sourceLength, int channelNumber, - int startInChannel); + size_t startInChannel); private: std::shared_ptr bus_; diff --git a/packages/react-native-audio-api/common/cpp/core/AudioBufferSourceNode.cpp b/packages/react-native-audio-api/common/cpp/core/AudioBufferSourceNode.cpp index 20e2b81e..a343e1eb 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioBufferSourceNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioBufferSourceNode.cpp @@ -16,10 +16,9 @@ AudioBufferSourceNode::AudioBufferSourceNode(BaseAudioContext *context) loopStart_(0), loopEnd_(0), vReadIndex_(0.0) { - numberOfInputs_ = 0; buffer_ = std::shared_ptr(nullptr); - detuneParam_ = std::make_shared(0.0, -MAX_DETUNE, MAX_DETUNE); + detuneParam_ = std::make_shared(0.0, MIN_DETUNE, MAX_DETUNE); playbackRateParam_ = std::make_shared( 1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT); @@ -73,7 +72,9 @@ void AudioBufferSourceNode::setBuffer( buffer_ = buffer; alignedBus_ = std::make_shared( - context_->getSampleRate(), buffer_->getLength()); + context_->getSampleRate(), + buffer_->getLength(), + buffer_->getNumberOfChannels()); alignedBus_->zero(); alignedBus_->sum(buffer_->bus_.get()); @@ -90,7 +91,7 @@ void AudioBufferSourceNode::processNode( // No audio data to fill, zero the output and return. if (!isPlaying() || !alignedBus_ || alignedBus_->getSize() == 0 || - !playbackRate) { + playbackRate == 0.0f) { processingBus->zero(); return; } @@ -115,7 +116,7 @@ void AudioBufferSourceNode::processWithoutInterpolation( size_t startOffset, size_t offsetLength, float playbackRate) { - size_t direction = playbackRate < 0 ? -1 : 1; + size_t direction = playbackRate < 0.0f ? -1 : 1; auto readIndex = static_cast(vReadIndex_); size_t writeIndex = startOffset; @@ -165,7 +166,7 @@ void AudioBufferSourceNode::processWithoutInterpolation( } // update reading index for next render quantum - vReadIndex_ = readIndex; + vReadIndex_ = static_cast(readIndex); } void AudioBufferSourceNode::processWithInterpolation( @@ -173,13 +174,13 @@ void AudioBufferSourceNode::processWithInterpolation( size_t startOffset, size_t offsetLength, float playbackRate) { - size_t direction = playbackRate < 0 ? -1 : 1; + size_t direction = playbackRate < 0.0f ? -1 : 1; size_t writeIndex = startOffset; - double vFrameStart = getVirtualStartFrame(); - double vFrameEnd = getVirtualEndFrame(); - double vFrameDelta = vFrameEnd - vFrameStart; + auto vFrameStart = getVirtualStartFrame(); + auto vFrameEnd = getVirtualEndFrame(); + auto vFrameDelta = vFrameEnd - vFrameStart; auto frameStart = static_cast(vFrameStart); auto frameEnd = static_cast(vFrameEnd); @@ -195,7 +196,8 @@ void AudioBufferSourceNode::processWithInterpolation( while (framesLeft > 0) { auto readIndex = static_cast(vReadIndex_); size_t nextReadIndex = readIndex + 1; - float factor = vReadIndex_ - readIndex; + auto factor = + static_cast(vReadIndex_ - static_cast(readIndex)); if (nextReadIndex >= frameEnd) { nextReadIndex = loop_ ? frameStart : readIndex; @@ -210,11 +212,11 @@ void AudioBufferSourceNode::processWithInterpolation( } writeIndex += 1; - vReadIndex_ += playbackRate * direction; + vReadIndex_ += playbackRate * static_cast(direction); framesLeft -= 1; if (vReadIndex_ < vFrameStart || vReadIndex_ >= vFrameEnd) { - vReadIndex_ -= direction * vFrameDelta; + vReadIndex_ -= static_cast(direction) * vFrameDelta; if (!loop_) { processingBus->zero(writeIndex, framesLeft); @@ -227,23 +229,23 @@ void AudioBufferSourceNode::processWithInterpolation( } float AudioBufferSourceNode::getPlaybackRateValue(size_t &startOffset) { - double time = - context_->getCurrentTime() + startOffset / context_->getSampleRate(); + auto time = context_->getCurrentTime() + + static_cast(startOffset) / context_->getSampleRate(); return playbackRateParam_->getValueAtTime(time) * std::pow(2.0f, detuneParam_->getValueAtTime(time) / 1200.0f); } double AudioBufferSourceNode::getVirtualStartFrame() { - double loopStartFrame = loopStart_ * context_->getSampleRate(); + auto loopStartFrame = loopStart_ * context_->getSampleRate(); return loop_ && loopStartFrame >= 0 && loopStart_ < loopEnd_ ? loopStartFrame : 0.0; } double AudioBufferSourceNode::getVirtualEndFrame() { - double inputBufferLength = alignedBus_->getSize(); - double loopEndFrame = loopEnd_ * context_->getSampleRate(); + auto inputBufferLength = static_cast(alignedBus_->getSize()); + auto loopEndFrame = loopEnd_ * context_->getSampleRate(); return loop_ && loopEndFrame > 0 && loopStart_ < loopEnd_ ? std::min(loopEndFrame, inputBufferLength) diff --git a/packages/react-native-audio-api/common/cpp/core/AudioBufferSourceNode.h b/packages/react-native-audio-api/common/cpp/core/AudioBufferSourceNode.h index 1a3e6d54..6e458260 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioBufferSourceNode.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioBufferSourceNode.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "AudioBuffer.h" #include "AudioScheduledSourceNode.h" diff --git a/packages/react-native-audio-api/common/cpp/core/AudioBus.cpp b/packages/react-native-audio-api/common/cpp/core/AudioBus.cpp index c7e30e73..784438ea 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioBus.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioBus.cpp @@ -17,12 +17,8 @@ namespace audioapi { /** * Public interfaces - memory management */ -AudioBus::AudioBus(int sampleRate, int size) - : numberOfChannels_(CHANNEL_COUNT), sampleRate_(sampleRate), size_(size) { - createChannels(); -} -AudioBus::AudioBus(int sampleRate, int size, int numberOfChannels) +AudioBus::AudioBus(float sampleRate, size_t size, int numberOfChannels) : numberOfChannels_(numberOfChannels), sampleRate_(sampleRate), size_(size) { @@ -41,11 +37,11 @@ int AudioBus::getNumberOfChannels() const { return numberOfChannels_; } -int AudioBus::getSampleRate() const { +float AudioBus::getSampleRate() const { return sampleRate_; } -int AudioBus::getSize() const { +size_t AudioBus::getSize() const { return size_; } @@ -56,7 +52,7 @@ AudioArray *AudioBus::getChannel(int index) const { AudioArray *AudioBus::getChannelByType(int channelType) const { switch (getNumberOfChannels()) { case 1: // mono - if (channelType == ChannelMono || channelType == ChannelLeft) { + if (channelType == ChannelMono) { return getChannel(0); } return nullptr; @@ -131,7 +127,7 @@ void AudioBus::zero() { zero(0, getSize()); } -void AudioBus::zero(int start, int length) { +void AudioBus::zero(size_t start, size_t length) { for (auto it = channels_.begin(); it != channels_.end(); it += 1) { it->get()->zero(start, length); } @@ -169,15 +165,15 @@ void AudioBus::sum(const AudioBus *source) { sum(source, 0, 0, getSize()); } -void AudioBus::sum(const AudioBus *source, int start, int length) { +void AudioBus::sum(const AudioBus *source, size_t start, size_t length) { sum(source, start, start, length); } void AudioBus::sum( const AudioBus *source, - int sourceStart, - int destinationStart, - int length) { + size_t sourceStart, + size_t destinationStart, + size_t length) { if (source == this) { return; } @@ -210,15 +206,15 @@ void AudioBus::copy(const AudioBus *source) { copy(source, 0, 0, getSize()); } -void AudioBus::copy(const AudioBus *source, int start, int length) { +void AudioBus::copy(const AudioBus *source, size_t start, size_t length) { copy(source, start, start, length); } void AudioBus::copy( const AudioBus *source, - int sourceStart, - int destinationStart, - int length) { + size_t sourceStart, + size_t destinationStart, + size_t length) { if (source == this) { return; } @@ -255,9 +251,9 @@ void AudioBus::createChannels() { void AudioBus::discreteSum( const AudioBus *source, - int sourceStart, - int destinationStart, - int length) const { + size_t sourceStart, + size_t destinationStart, + size_t length) const { int numberOfChannels = std::min(getNumberOfChannels(), source->getNumberOfChannels()); @@ -272,9 +268,9 @@ void AudioBus::discreteSum( void AudioBus::sumByUpMixing( const AudioBus *source, - int sourceStart, - int destinationStart, - int length) { + size_t sourceStart, + size_t destinationStart, + size_t length) { int numberOfSourceChannels = source->getNumberOfChannels(); int numberOfChannels = getNumberOfChannels(); @@ -351,9 +347,9 @@ void AudioBus::sumByUpMixing( void AudioBus::sumByDownMixing( const AudioBus *source, - int sourceStart, - int destinationStart, - int length) { + size_t sourceStart, + size_t destinationStart, + size_t length) { int numberOfSourceChannels = source->getNumberOfChannels(); int numberOfChannels = getNumberOfChannels(); diff --git a/packages/react-native-audio-api/common/cpp/core/AudioBus.h b/packages/react-native-audio-api/common/cpp/core/AudioBus.h index 723a6f4e..3163ff9f 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioBus.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioBus.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace audioapi { @@ -21,14 +22,13 @@ class AudioBus { ChannelSurroundRight = 5, }; - explicit AudioBus(int sampleRate, int size); - explicit AudioBus(int sampleRate, int size, int numberOfChannels); + explicit AudioBus(float sampleRate, size_t size, int numberOfChannels); ~AudioBus(); [[nodiscard]] int getNumberOfChannels() const; - [[nodiscard]] int getSampleRate() const; - [[nodiscard]] int getSize() const; + [[nodiscard]] float getSampleRate() const; + [[nodiscard]] size_t getSize() const; [[nodiscard]] AudioArray *getChannel(int index) const; [[nodiscard]] AudioArray *getChannelByType(int channelType) const; @@ -37,47 +37,47 @@ class AudioBus { [[nodiscard]] float maxAbsValue() const; void zero(); - void zero(int start, int length); + void zero(size_t start, size_t length); void sum(const AudioBus *source); - void sum(const AudioBus *source, int start, int length); + void sum(const AudioBus *source, size_t start, size_t length); void sum( const AudioBus *source, - int sourceStart, - int destinationStart, - int length); + size_t sourceStart, + size_t destinationStart, + size_t length); void copy(const AudioBus *source); - void copy(const AudioBus *source, int start, int length); + void copy(const AudioBus *source, size_t start, size_t length); void copy( const AudioBus *source, - int sourceStart, - int destinationStart, - int length); + size_t sourceStart, + size_t destinationStart, + size_t length); private: std::vector> channels_; int numberOfChannels_; - int sampleRate_; - int size_; + float sampleRate_; + size_t size_; void createChannels(); void discreteSum( const AudioBus *source, - int sourceStart, - int destinationStart, - int length) const; + size_t sourceStart, + size_t destinationStart, + size_t length) const; void sumByUpMixing( const AudioBus *source, - int sourceStart, - int destinationStart, - int length); + size_t sourceStart, + size_t destinationStart, + size_t length); void sumByDownMixing( const AudioBus *source, - int sourceStart, - int destinationStart, - int length); + size_t sourceStart, + size_t destinationStart, + size_t length); }; } // namespace audioapi diff --git a/packages/react-native-audio-api/common/cpp/core/AudioContext.cpp b/packages/react-native-audio-api/common/cpp/core/AudioContext.cpp index 5bc9fcfd..0138f1e8 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioContext.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioContext.cpp @@ -21,7 +21,7 @@ AudioContext::AudioContext() : BaseAudioContext() { audioPlayer_->start(); } -AudioContext::AudioContext(int sampleRate) : BaseAudioContext() { +AudioContext::AudioContext(float sampleRate) : BaseAudioContext() { #ifdef ANDROID audioPlayer_ = std::make_shared(this->renderAudio(), sampleRate); #else diff --git a/packages/react-native-audio-api/common/cpp/core/AudioContext.h b/packages/react-native-audio-api/common/cpp/core/AudioContext.h index 1f8a8723..6e83fb17 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioContext.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioContext.h @@ -15,7 +15,7 @@ class IOSAudioPlayer; class AudioContext : public BaseAudioContext { public: AudioContext(); - explicit AudioContext(int sampleRate); + explicit AudioContext(float sampleRate); ~AudioContext() override; void close(); diff --git a/packages/react-native-audio-api/common/cpp/core/AudioDecoder.h b/packages/react-native-audio-api/common/cpp/core/AudioDecoder.h index 0eca59c5..3f6aa5b7 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioDecoder.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioDecoder.h @@ -8,12 +8,12 @@ class AudioBus; class AudioDecoder { public: - explicit AudioDecoder(int sampleRate) : sampleRate_(sampleRate) {} + explicit AudioDecoder(float sampleRate) : sampleRate_(sampleRate) {} [[nodiscard]] AudioBus *decodeWithFilePath(const std::string &path) const; private: - int sampleRate_; + float sampleRate_; }; } // namespace audioapi diff --git a/packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.cpp b/packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.cpp index 0ef82dd2..438afefa 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.cpp @@ -25,7 +25,7 @@ double AudioDestinationNode::getCurrentTime() const { void AudioDestinationNode::renderAudio( AudioBus *destinationBus, - int32_t numFrames) { + int numFrames) { if (!numFrames || !destinationBus || !isInitialized_) { return; } diff --git a/packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.h b/packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.h index c8ff0a90..d4c74e6f 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioDestinationNode.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "AudioNode.h" @@ -15,7 +16,7 @@ class AudioDestinationNode : public AudioNode { public: explicit AudioDestinationNode(BaseAudioContext *context); - void renderAudio(AudioBus *audioData, int32_t numFrames); + void renderAudio(AudioBus *audioData, int numFrames); std::size_t getCurrentSampleFrame() const; double getCurrentTime() const; diff --git a/packages/react-native-audio-api/common/cpp/core/AudioNode.cpp b/packages/react-native-audio-api/common/cpp/core/AudioNode.cpp index 593039ce..8ead0ac5 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioNode.cpp @@ -75,16 +75,16 @@ bool AudioNode::isEnabled() const { void AudioNode::enable() { isEnabled_ = true; - for (auto it = outputNodes_.begin(); it != outputNodes_.end(); ++it) { - it->get()->onInputEnabled(); + for (auto &outputNode : outputNodes_) { + outputNode->onInputEnabled(); } } void AudioNode::disable() { isEnabled_ = false; - for (auto it = outputNodes_.begin(); it != outputNodes_.end(); ++it) { - it->get()->onInputDisabled(); + for (auto &outputNode : outputNodes_) { + outputNode->onInputDisabled(); } } @@ -166,12 +166,14 @@ AudioBus *AudioNode::processAudio(AudioBus *outputBus, int framesToProcess) { AudioBus *inputBus = (*it)->processAudio(processingBus, framesToProcess); if (inputBus != processingBus) { + // add assert processingBus->sum(inputBus); } } else { // Enforce the summing to be done using the internal bus. - AudioBus *inputBus = (*it)->processAudio(0, framesToProcess); + AudioBus *inputBus = (*it)->processAudio(nullptr, framesToProcess); if (inputBus) { + // add assert processingBus->sum(inputBus); } } diff --git a/packages/react-native-audio-api/common/cpp/core/AudioNode.h b/packages/react-native-audio-api/common/cpp/core/AudioNode.h index 7f75b652..06ac4f7b 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioNode.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioNode.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "ChannelCountMode.h" #include "ChannelInterpretation.h" @@ -37,24 +38,22 @@ class AudioNode : public std::enable_shared_from_this { BaseAudioContext *context_; std::shared_ptr audioBus_; - int channelCount_ = CHANNEL_COUNT; - int numberOfInputs_ = 1; int numberOfOutputs_ = 1; - int numberOfEnabledInputNodes_ = 0; + int channelCount_ = 2; + ChannelCountMode channelCountMode_ = ChannelCountMode::MAX; + ChannelInterpretation channelInterpretation_ = + ChannelInterpretation::SPEAKERS; + + std::vector inputNodes_ = {}; + std::vector> outputNodes_ = {}; + int numberOfEnabledInputNodes_ = 0; bool isInitialized_ = false; bool isEnabled_ = true; std::size_t lastRenderedFrame_{SIZE_MAX}; - ChannelCountMode channelCountMode_ = ChannelCountMode::MAX; - ChannelInterpretation channelInterpretation_ = - ChannelInterpretation::SPEAKERS; - - std::vector inputNodes_ = {}; - std::vector> outputNodes_ = {}; - private: static std::string toString(ChannelCountMode mode); static std::string toString(ChannelInterpretation interpretation); diff --git a/packages/react-native-audio-api/common/cpp/core/AudioNodeManager.cpp b/packages/react-native-audio-api/common/cpp/core/AudioNodeManager.cpp index 2b1a1e74..8876296f 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioNodeManager.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioNodeManager.cpp @@ -5,8 +5,6 @@ namespace audioapi { -AudioNodeManager::AudioNodeManager() {} - AudioNodeManager::~AudioNodeManager() { audioNodesToConnect_.clear(); sourceNodes_.clear(); @@ -18,7 +16,7 @@ void AudioNodeManager::addPendingConnection( ConnectionType type) { Locker lock(getGraphLock()); - audioNodesToConnect_.push_back(std::make_tuple(from, to, type)); + audioNodesToConnect_.emplace_back(from, to, type); } void AudioNodeManager::addSourceNode(const std::shared_ptr &node) { diff --git a/packages/react-native-audio-api/common/cpp/core/AudioNodeManager.h b/packages/react-native-audio-api/common/cpp/core/AudioNodeManager.h index 6b7b825d..f373b929 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioNodeManager.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioNodeManager.h @@ -12,7 +12,7 @@ class AudioNode; class AudioNodeManager { public: enum class ConnectionType { CONNECT, DISCONNECT }; - AudioNodeManager(); + AudioNodeManager() = default; ~AudioNodeManager(); void preProcessGraph(); diff --git a/packages/react-native-audio-api/common/cpp/core/AudioParam.cpp b/packages/react-native-audio-api/common/cpp/core/AudioParam.cpp index 08884450..0d6d3dc2 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioParam.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioParam.cpp @@ -181,7 +181,7 @@ void AudioParam::setTargetAtTime( void AudioParam::setValueCurveAtTime( const float *values, - int length, + size_t length, double startTime, double duration) { if (startTime <= getQueueEndTime()) { @@ -200,9 +200,12 @@ void AudioParam::setValueCurveAtTime( if (time < endTime) { auto k = static_cast(std::floor( - (length - 1) / (endTime - startTime) * (time - startTime))); + static_cast(length - 1) / (endTime - startTime) * + (time - startTime))); auto factor = static_cast( - k - (time - startTime) * (length - 1) / (endTime - startTime)); + k - + (time - startTime) * static_cast(length - 1) / + (endTime - startTime)); return AudioUtils::linearInterpolate(values, k, k + 1, factor); } diff --git a/packages/react-native-audio-api/common/cpp/core/AudioParam.h b/packages/react-native-audio-api/common/cpp/core/AudioParam.h index ed55d7f9..cdc251eb 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioParam.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioParam.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "ParamChangeEvent.h" #include "ParamChangeEventType.h" @@ -27,7 +28,7 @@ class AudioParam { void setTargetAtTime(float target, double startTime, double timeConstant); void setValueCurveAtTime( const float *values, - int length, + size_t length, double startTime, double duration); void cancelScheduledValues(double cancelTime); diff --git a/packages/react-native-audio-api/common/cpp/core/AudioScheduledSourceNode.cpp b/packages/react-native-audio-api/common/cpp/core/AudioScheduledSourceNode.cpp index 0779a0fc..c583332a 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioScheduledSourceNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/AudioScheduledSourceNode.cpp @@ -53,7 +53,7 @@ void AudioScheduledSourceNode::updatePlaybackInfo( return; } - int sampleRate = context_->getSampleRate(); + auto sampleRate = context_->getSampleRate(); size_t firstFrame = context_->getCurrentSampleFrame(); size_t lastFrame = firstFrame + framesToProcess; diff --git a/packages/react-native-audio-api/common/cpp/core/AudioScheduledSourceNode.h b/packages/react-native-audio-api/common/cpp/core/AudioScheduledSourceNode.h index ef21bc6a..4d069280 100644 --- a/packages/react-native-audio-api/common/cpp/core/AudioScheduledSourceNode.h +++ b/packages/react-native-audio-api/common/cpp/core/AudioScheduledSourceNode.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "AudioNode.h" diff --git a/packages/react-native-audio-api/common/cpp/core/BaseAudioContext.cpp b/packages/react-native-audio-api/common/cpp/core/BaseAudioContext.cpp index c95fbb6f..3419e22f 100644 --- a/packages/react-native-audio-api/common/cpp/core/BaseAudioContext.cpp +++ b/packages/react-native-audio-api/common/cpp/core/BaseAudioContext.cpp @@ -25,7 +25,7 @@ std::string BaseAudioContext::getState() { return BaseAudioContext::toString(state_); } -int BaseAudioContext::getSampleRate() const { +float BaseAudioContext::getSampleRate() const { return sampleRate_; } @@ -63,8 +63,8 @@ std::shared_ptr BaseAudioContext::createBufferSource() { std::shared_ptr BaseAudioContext::createBuffer( int numberOfChannels, - int length, - int sampleRate) { + size_t length, + float sampleRate) { return std::make_shared(numberOfChannels, length, sampleRate); } @@ -99,6 +99,10 @@ bool BaseAudioContext::isClosed() const { return state_ == ContextState::CLOSED; } +float BaseAudioContext::getNyquistFrequency() const { + return sampleRate_ / 2.0f; +} + std::string BaseAudioContext::toString(ContextState state) { switch (state) { case ContextState::SUSPENDED: diff --git a/packages/react-native-audio-api/common/cpp/core/BaseAudioContext.h b/packages/react-native-audio-api/common/cpp/core/BaseAudioContext.h index f53b766f..00eb108d 100644 --- a/packages/react-native-audio-api/common/cpp/core/BaseAudioContext.h +++ b/packages/react-native-audio-api/common/cpp/core/BaseAudioContext.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "ContextState.h" #include "OscillatorType.h" @@ -30,7 +31,7 @@ class BaseAudioContext { virtual ~BaseAudioContext() = default; std::string getState(); - [[nodiscard]] int getSampleRate() const; + [[nodiscard]] float getSampleRate() const; [[nodiscard]] double getCurrentTime() const; [[nodiscard]] std::size_t getCurrentSampleFrame() const; std::shared_ptr getDestination(); @@ -41,19 +42,20 @@ class BaseAudioContext { std::shared_ptr createBiquadFilter(); std::shared_ptr createBufferSource(); static std::shared_ptr - createBuffer(int numberOfChannels, int length, int sampleRate); + createBuffer(int numberOfChannels, size_t length, float sampleRate); std::shared_ptr createPeriodicWave( float *real, float *imag, bool disableNormalization, int length); std::shared_ptr createAnalyser(); - std::shared_ptr decodeAudioDataSource(const std::string &path); + std::shared_ptr getBasicWaveForm(OscillatorType type); AudioNodeManager *getNodeManager(); [[nodiscard]] bool isRunning() const; [[nodiscard]] bool isClosed() const; + [[nodiscard]] float getNyquistFrequency() const; protected: static std::string toString(ContextState state); @@ -62,7 +64,7 @@ class BaseAudioContext { std::shared_ptr audioDecoder_ {}; // init in AudioContext or OfflineContext constructor - int sampleRate_ {}; + float sampleRate_ {}; ContextState state_ = ContextState::RUNNING; std::shared_ptr nodeManager_; diff --git a/packages/react-native-audio-api/common/cpp/core/BiquadFilterNode.cpp b/packages/react-native-audio-api/common/cpp/core/BiquadFilterNode.cpp index a79e3bb7..6bbcf920 100644 --- a/packages/react-native-audio-api/common/cpp/core/BiquadFilterNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/BiquadFilterNode.cpp @@ -11,9 +11,9 @@ namespace audioapi { BiquadFilterNode::BiquadFilterNode(BaseAudioContext *context) : AudioNode(context) { frequencyParam_ = std::make_shared( - 350.0, MIN_FILTER_FREQUENCY, MAX_FILTER_FREQUENCY); + 350.0, MIN_FILTER_FREQUENCY, context->getNyquistFrequency()); detuneParam_ = std::make_shared(0.0, -MAX_DETUNE, MAX_DETUNE); - QParam_ = std::make_shared(1.0, -MAX_FILTER_Q, MAX_FILTER_Q); + QParam_ = std::make_shared(1.0, MIN_FILTER_Q, MAX_FILTER_Q); gainParam_ = std::make_shared(0.0, MIN_FILTER_GAIN, MAX_FILTER_GAIN); type_ = BiquadFilterType::LOWPASS; @@ -67,8 +67,8 @@ void BiquadFilterNode::getFrequencyResponse( float a2 = a2_; for (size_t i = 0; i < frequencyArraySize; i++) { - auto omega = - static_cast(M_PI) * frequencyArray[i] / NYQUIST_FREQUENCY; + auto omega = static_cast(M_PI) * frequencyArray[i] / + context_->getNyquistFrequency(); auto z = std::complex(cos(omega), sin(omega)); auto response = ((b0 * z + b1) * z + b2) / ((z + a1) * z + a2); magResponseOutput[i] = static_cast(abs(response)); @@ -302,8 +302,8 @@ void BiquadFilterNode::setAllpassCoefficients(float frequency, float Q) { void BiquadFilterNode::applyFilter() { double currentTime = context_->getCurrentTime(); - float normalizedFrequency = - frequencyParam_->getValueAtTime(currentTime) / NYQUIST_FREQUENCY; + float normalizedFrequency = frequencyParam_->getValueAtTime(currentTime) / + context_->getNyquistFrequency(); float detuneValue = detuneParam_->getValueAtTime(currentTime); if (detuneValue != 0.0) { diff --git a/packages/react-native-audio-api/common/cpp/core/Constants.h b/packages/react-native-audio-api/common/cpp/core/Constants.h index 259cb912..50830679 100644 --- a/packages/react-native-audio-api/common/cpp/core/Constants.h +++ b/packages/react-native-audio-api/common/cpp/core/Constants.h @@ -6,26 +6,39 @@ // https://webaudio.github.io/web-audio-api/ namespace audioapi { -constexpr int DEFAULT_SAMPLE_RATE = 48000; +// context constexpr int RENDER_QUANTUM_SIZE = 128; constexpr int CHANNEL_COUNT = 2; +// general constexpr float MOST_POSITIVE_SINGLE_FLOAT = static_cast(std::numeric_limits::max()); constexpr float MOST_NEGATIVE_SINGLE_FLOAT = static_cast(std::numeric_limits::lowest()); +constexpr float PI = static_cast(M_PI); -constexpr float NYQUIST_FREQUENCY = DEFAULT_SAMPLE_RATE / 2.0; -static float MAX_DETUNE = 1200 * std::log2(MOST_POSITIVE_SINGLE_FLOAT); -constexpr float MAX_GAIN = MOST_POSITIVE_SINGLE_FLOAT; +// pan constexpr float MAX_PAN = 1.0; -constexpr float MAX_FILTER_Q = MOST_POSITIVE_SINGLE_FLOAT; -constexpr float MAX_FILTER_FREQUENCY = NYQUIST_FREQUENCY; +constexpr float MIN_PAN = -1.0; + +// gain +constexpr float MAX_GAIN = MOST_POSITIVE_SINGLE_FLOAT; +constexpr float MIN_GAIN = -MAX_GAIN; + +// biquad filter constexpr float MIN_FILTER_FREQUENCY = 0.0; static float MAX_FILTER_GAIN = 40 * std::log10(MOST_POSITIVE_SINGLE_FLOAT); -constexpr float MIN_FILTER_GAIN = -MAX_GAIN; +static float MIN_FILTER_GAIN = -MAX_GAIN; +constexpr float MAX_FILTER_Q = MOST_POSITIVE_SINGLE_FLOAT; +constexpr float MIN_FILTER_Q = -MAX_FILTER_Q; + +//detune +static float MAX_DETUNE = 1200 * std::log2(MOST_POSITIVE_SINGLE_FLOAT); +static float MIN_DETUNE = -MAX_DETUNE; -constexpr int MAX_FFT_SIZE = 32768; -constexpr int DEFAULT_FFT_SIZE = 2048; -constexpr double DEFAULT_MAX_DECIBELS = -30; -constexpr double DEFAULT_MIN_DECIBELS = -100; -const double DEFAULT_SMOOTHING_TIME_CONSTANT = 0.8; +// analyser node +constexpr size_t MAX_FFT_SIZE = 32768; +constexpr size_t MIN_FFT_SIZE = 32; +constexpr size_t DEFAULT_FFT_SIZE = 2048; +constexpr float DEFAULT_MAX_DECIBELS = -30; +constexpr float DEFAULT_MIN_DECIBELS = -100; +const float DEFAULT_SMOOTHING_TIME_CONSTANT = 0.8; } // namespace audioapi diff --git a/packages/react-native-audio-api/common/cpp/core/GainNode.cpp b/packages/react-native-audio-api/common/cpp/core/GainNode.cpp index baffdebd..52e1658f 100644 --- a/packages/react-native-audio-api/common/cpp/core/GainNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/GainNode.cpp @@ -6,7 +6,7 @@ namespace audioapi { GainNode::GainNode(BaseAudioContext *context) : AudioNode(context) { - gainParam_ = std::make_shared(1.0, -MAX_GAIN, MAX_GAIN); + gainParam_ = std::make_shared(1.0, MIN_GAIN, MAX_GAIN); isInitialized_ = true; } diff --git a/packages/react-native-audio-api/common/cpp/core/OscillatorNode.cpp b/packages/react-native-audio-api/common/cpp/core/OscillatorNode.cpp index 2b2bed37..96ea177c 100644 --- a/packages/react-native-audio-api/common/cpp/core/OscillatorNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/OscillatorNode.cpp @@ -8,7 +8,7 @@ namespace audioapi { OscillatorNode::OscillatorNode(BaseAudioContext *context) : AudioScheduledSourceNode(context) { frequencyParam_ = std::make_shared( - 444.0, -NYQUIST_FREQUENCY, NYQUIST_FREQUENCY); + 444.0, -context_->getNyquistFrequency(), context_->getNyquistFrequency()); detuneParam_ = std::make_shared(0.0, -MAX_DETUNE, MAX_DETUNE); type_ = OscillatorType::SINE; periodicWave_ = context_->getBasicWaveForm(type_); @@ -49,8 +49,9 @@ void OscillatorNode::processNode(AudioBus *processingBus, int framesToProcess) { return; } - double deltaTime = 1.0 / context_->getSampleRate(); - double time = context_->getCurrentTime() + startOffset * deltaTime; + auto deltaTime = 1.0 / context_->getSampleRate(); + auto time = + context_->getCurrentTime() + static_cast(startOffset) * deltaTime; for (size_t i = startOffset; i < offsetLength; i += 1) { auto detuneRatio = diff --git a/packages/react-native-audio-api/common/cpp/core/PeriodicWave.cpp b/packages/react-native-audio-api/common/cpp/core/PeriodicWave.cpp index 69f49410..d1aa1bdc 100644 --- a/packages/react-native-audio-api/common/cpp/core/PeriodicWave.cpp +++ b/packages/react-native-audio-api/common/cpp/core/PeriodicWave.cpp @@ -27,6 +27,7 @@ */ #include "PeriodicWave.h" +#include "Constants.h" constexpr unsigned NumberOfOctaveBands = 3; constexpr float CentsPerRange = 1200.0f / NumberOfOctaveBands; @@ -34,10 +35,10 @@ constexpr float interpolate2Point = 0.3; constexpr float interpolate3Point = 0.16; namespace audioapi { -PeriodicWave::PeriodicWave(int sampleRate, bool disableNormalization) +PeriodicWave::PeriodicWave(float sampleRate, bool disableNormalization) : sampleRate_(sampleRate), disableNormalization_(disableNormalization) { - numberOfRanges_ = lround( - NumberOfOctaveBands * log2f(static_cast(getPeriodicWaveSize()))); + numberOfRanges_ = static_cast(round( + NumberOfOctaveBands * log2f(static_cast(getPeriodicWaveSize())))); auto nyquistFrequency = sampleRate_ / 2; lowestFundamentalFrequency_ = static_cast(nyquistFrequency) / static_cast(getMaxNumberOfPartials()); @@ -47,7 +48,7 @@ PeriodicWave::PeriodicWave(int sampleRate, bool disableNormalization) } PeriodicWave::PeriodicWave( - int sampleRate, + float sampleRate, audioapi::OscillatorType type, bool disableNormalization) : PeriodicWave(sampleRate, disableNormalization) { @@ -55,7 +56,7 @@ PeriodicWave::PeriodicWave( } PeriodicWave::PeriodicWave( - int sampleRate, + float sampleRate, float *real, float *imaginary, int length, @@ -147,7 +148,7 @@ void PeriodicWave::generateBasicWaveForm(OscillatorType type) { // Coefficient for sin() float b; - auto piFactor = static_cast(1.0f / (i * M_PI)); + auto piFactor = 1.0f / (PI * static_cast(i)); switch (type) { case OscillatorType::SINE: diff --git a/packages/react-native-audio-api/common/cpp/core/PeriodicWave.h b/packages/react-native-audio-api/common/cpp/core/PeriodicWave.h index 620179f5..4aac6a31 100644 --- a/packages/react-native-audio-api/common/cpp/core/PeriodicWave.h +++ b/packages/react-native-audio-api/common/cpp/core/PeriodicWave.h @@ -40,11 +40,11 @@ namespace audioapi { class PeriodicWave { public: explicit PeriodicWave( - int sampleRate, + float sampleRate, OscillatorType type, bool disableNormalization); explicit PeriodicWave( - int sampleRate, + float sampleRate, float *real, float *imaginary, int length, @@ -57,7 +57,7 @@ class PeriodicWave { getSample(float fundamentalFrequency, float phase, float phaseIncrement); private: - explicit PeriodicWave(int sampleRate, bool disableNormalization); + explicit PeriodicWave(float sampleRate, bool disableNormalization); // Partial is any frequency component of a sound. // Both harmonics(fundamentalFrequency * k) and overtones are partials. @@ -102,7 +102,7 @@ class PeriodicWave { const float *higherWaveData) const; // determines the time resolution of the waveform. - int sampleRate_; + float sampleRate_; // determines number of frequency segments (or bands) the signal is divided. int numberOfRanges_; // the lowest frequency (in hertz) where playback will include all of the diff --git a/packages/react-native-audio-api/common/cpp/core/StereoPannerNode.cpp b/packages/react-native-audio-api/common/cpp/core/StereoPannerNode.cpp index 08dc123f..f2308be4 100644 --- a/packages/react-native-audio-api/common/cpp/core/StereoPannerNode.cpp +++ b/packages/react-native-audio-api/common/cpp/core/StereoPannerNode.cpp @@ -11,7 +11,7 @@ namespace audioapi { StereoPannerNode::StereoPannerNode(BaseAudioContext *context) : AudioNode(context) { channelCountMode_ = ChannelCountMode::CLAMPED_MAX; - panParam_ = std::make_shared(0.0, -MAX_PAN, MAX_PAN); + panParam_ = std::make_shared(0.0, MIN_PAN, MAX_PAN); isInitialized_ = true; } @@ -36,10 +36,10 @@ void StereoPannerNode::processNode( for (int i = 0; i < framesToProcess; i += 1) { float pan = panParam_->getValueAtTime(time); - float x = (pan <= 0 ? pan + 1 : pan) * M_PI / 2; + float x = (pan <= 0 ? pan + 1 : pan) * PI / 2; - float gainL = static_cast(cos(x)); - float gainR = static_cast(sin(x)); + auto gainL = static_cast(cos(x)); + auto gainR = static_cast(sin(x)); float inputL = (*left)[i]; float inputR = (*right)[i]; diff --git a/packages/react-native-audio-api/common/cpp/utils/AudioUtils.cpp b/packages/react-native-audio-api/common/cpp/utils/AudioUtils.cpp index 577f742e..7246a95f 100644 --- a/packages/react-native-audio-api/common/cpp/utils/AudioUtils.cpp +++ b/packages/react-native-audio-api/common/cpp/utils/AudioUtils.cpp @@ -1,11 +1,11 @@ #include "AudioUtils.h" namespace audioapi::AudioUtils { -size_t timeToSampleFrame(double time, int sampleRate) { +size_t timeToSampleFrame(double time, float sampleRate) { return static_cast(time * sampleRate); } -double sampleFrameToTime(int sampleFrame, int sampleRate) { +double sampleFrameToTime(int sampleFrame, float sampleRate) { return static_cast(sampleFrame) / sampleRate; } diff --git a/packages/react-native-audio-api/common/cpp/utils/AudioUtils.h b/packages/react-native-audio-api/common/cpp/utils/AudioUtils.h index 3eab4c56..01f38b31 100644 --- a/packages/react-native-audio-api/common/cpp/utils/AudioUtils.h +++ b/packages/react-native-audio-api/common/cpp/utils/AudioUtils.h @@ -6,8 +6,8 @@ namespace audioapi::AudioUtils { -size_t timeToSampleFrame(double time, int sampleRate); -double sampleFrameToTime(int sampleFrame, int sampleRate); +size_t timeToSampleFrame(double time, float sampleRate); +double sampleFrameToTime(int sampleFrame, float sampleRate); float linearInterpolate(const float *source, size_t firstIndex, size_t secondIndex, float factor); diff --git a/packages/react-native-audio-api/common/cpp/utils/Locker.h b/packages/react-native-audio-api/common/cpp/utils/Locker.h index ae7a17e4..36fa7780 100644 --- a/packages/react-native-audio-api/common/cpp/utils/Locker.h +++ b/packages/react-native-audio-api/common/cpp/utils/Locker.h @@ -7,7 +7,7 @@ namespace audioapi { // Small easy interface to manage locking class Locker { public: - Locker() : lockPtr_(0) {} + Locker() : lockPtr_(nullptr) {} explicit Locker(std::mutex &lockPtr) : lockPtr_(&lockPtr) { lock(); } @@ -17,7 +17,7 @@ class Locker { } explicit operator bool() const { - return !!lockPtr_; + return lockPtr_ != nullptr; } void lock() {