Skip to content

Commit 3c924bf

Browse files
authored
[#201] [Core] AudioBus - support for multiple node connections and mixed amount of channels (#206)
* feat: working on new buffer structure * feat: more work * feat: channel mixer * feat: add some comments * fix: spellchecker howling * fix: linter howling * fix: linter howling part 1.27 * fix: politely obey to false-positive linter check * feat: working on AudioPlayer implementation using AudioBus * feat: processNode implementations * feat: self-abuse * feat: migrate gain node * feat: audio bus & audio array range operators * feat: audio buffer source node - rewrite to use audio bus and complicate the matter * fix: some memory alloc fixes * fix: get back to previous scheduling impl * fix: cleanup logs * feat: update translations * fix: uncomment all oscilator example params * fix: more fixes * feat: locker + audio node manager wip * fix: remove silencer + add post and preproc * feat: working on decontruction * feat: something is working * fix: hi-hat sound * feat: proper deconstruction * fix: unused variable, android player pointer usage * fix: linter * fix: linter2 - the return of the explicit? * Update packages/react-native-audio-api/common/cpp/core/AudioBus.cpp * Update packages/react-native-audio-api/common/cpp/core/AudioBus.cpp * fix: cleanup * fix: redundant HAVE_ACCELERATE directive
1 parent 4199cef commit 3c924bf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1484
-363
lines changed

.github/actions/spelling/allow.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ rnaa
2828

2929
tada
3030
vec
31+
rnaa
3132

apps/common-app/src/examples/SharedUtils/soundEngines/Clap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Clap implements SoundEngine {
2020
}
2121

2222
createNoiseBuffer() {
23-
const bufferSize = this.audioContext.sampleRate / 10;
23+
const bufferSize = this.audioContext.sampleRate / 5;
2424
const buffer = this.audioContext.createBuffer(
2525
1,
2626
bufferSize,

apps/common-app/src/examples/SharedUtils/soundEngines/HiHat.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class HiHat implements SoundEngine {
2626
const oscillator = this.audioContext.createOscillator();
2727
oscillator.type = 'square';
2828
oscillator.frequency.value = this.tone * ratio;
29+
2930
const bandpassFilter = this.audioContext.createBiquadFilter();
3031
const highpassFilter = this.audioContext.createBiquadFilter();
3132
const gain = this.audioContext.createGain();
@@ -46,6 +47,7 @@ class HiHat implements SoundEngine {
4647
bandpassFilter.connect(highpassFilter);
4748
highpassFilter.connect(gain);
4849
gain.connect(this.audioContext.destination!);
50+
4951
oscillator.start(time);
5052
oscillator.stop(time + this.decay);
5153
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>

apps/fabric-example/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,8 +2063,8 @@ SPEC CHECKSUMS:
20632063
RNReanimated: 77242c6d67416988a2fd9f5cf574bb3e60016362
20642064
RNScreens: e389d6a6a66a4f0d3662924ecae803073ccce8ec
20652065
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
2066-
Yoga: f8ec45ce98bba1bc93dd28f2ee37215180e6d2b6
2066+
Yoga: 1d66db49f38fd9e576a1d7c3b081e46ab4c28b9e
20672067

20682068
PODFILE CHECKSUM: 75ad38075e71875257a2590065853ea6a608b897
20692069

2070-
COCOAPODS: 1.15.2
2070+
COCOAPODS: 1.16.2

packages/react-native-audio-api/android/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ project(react-native-audio-api)
44
set(CMAKE_VERBOSE_MAKEFILE ON)
55
set(CMAKE_CXX_STANDARD 20)
66

7-
# Detect the operating system
8-
if(APPLE)
9-
set(HAVE_ACCELERATE TRUE)
10-
endif()
11-
127
# Detect the processor and SIMD support
138
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
149
set(HAVE_ARM_NEON_INTRINSICS TRUE)

packages/react-native-audio-api/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
2+
#include "AudioBus.h"
3+
#include "Constants.h"
4+
#include "AudioArray.h"
15
#include "AudioPlayer.h"
26
#include "AudioContext.h"
37

48
namespace audioapi {
5-
AudioPlayer::AudioPlayer(const std::function<void(float *, int)> &renderAudio)
9+
10+
AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
611
: renderAudio_(renderAudio) {
712
AudioStreamBuilder builder;
13+
814
builder.setSharingMode(SharingMode::Exclusive)
915
->setFormat(AudioFormat::Float)
1016
->setFormatConversionAllowed(true)
@@ -13,12 +19,18 @@ AudioPlayer::AudioPlayer(const std::function<void(float *, int)> &renderAudio)
1319
->setSampleRateConversionQuality(SampleRateConversionQuality::Medium)
1420
->setDataCallback(this)
1521
->openStream(mStream_);
22+
23+
mBus_ = std::make_shared<AudioBus>(getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
1624
}
1725

1826
int AudioPlayer::getSampleRate() const {
1927
return mStream_->getSampleRate();
2028
}
2129

30+
int AudioPlayer::getBufferSizeInFrames() const {
31+
return mStream_->getBufferSizeInFrames();
32+
}
33+
2234
void AudioPlayer::start() {
2335
if (mStream_) {
2436
mStream_->requestStart();
@@ -38,8 +50,17 @@ DataCallbackResult AudioPlayer::onAudioReady(
3850
void *audioData,
3951
int32_t numFrames) {
4052
auto buffer = static_cast<float *>(audioData);
41-
renderAudio_(buffer, numFrames);
53+
54+
renderAudio_(mBus_.get(), numFrames);
55+
56+
// TODO: optimize this with SIMD?
57+
for (int32_t i = 0; i < numFrames; i += 1) {
58+
for (int channel = 0; channel < CHANNEL_COUNT; channel += 1) {
59+
buffer[i * CHANNEL_COUNT + channel] = mBus_->getChannel(channel)->getData()[i];
60+
}
61+
}
4262

4363
return DataCallbackResult::Continue;
4464
}
65+
4566
} // namespace audioapi

packages/react-native-audio-api/android/src/main/cpp/AudioPlayer/AudioPlayer.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ namespace audioapi {
88
using namespace oboe;
99

1010
class AudioContext;
11+
class AudioBus;
1112

1213
class AudioPlayer : public AudioStreamDataCallback {
1314
public:
14-
explicit AudioPlayer(const std::function<void(float *, int)> &renderAudio);
15+
explicit AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio);
1516

1617
int getSampleRate() const;
18+
int getBufferSizeInFrames() const;
1719
void start();
1820
void stop();
1921

@@ -23,8 +25,9 @@ class AudioPlayer : public AudioStreamDataCallback {
2325
int32_t numFrames) override;
2426

2527
private:
26-
std::function<void(float *, int)> renderAudio_;
28+
std::function<void(AudioBus*, int)> renderAudio_;
2729
std::shared_ptr<AudioStream> mStream_;
30+
std::shared_ptr<AudioBus> mBus_;
2831
};
2932

3033
} // namespace audioapi
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include <algorithm>
2+
3+
#include "AudioArray.h"
4+
#include "VectorMath.h"
5+
6+
namespace audioapi {
7+
8+
AudioArray::AudioArray(int size) : size_(size), data_(0) {
9+
resize(size);
10+
}
11+
12+
AudioArray::~AudioArray() {
13+
if (data_) {
14+
delete[] data_;
15+
data_ = 0;
16+
}
17+
}
18+
19+
int AudioArray::getSize() const {
20+
return size_;
21+
}
22+
23+
float* AudioArray::getData() const {
24+
return data_;
25+
}
26+
27+
float& AudioArray::operator[](int index) {
28+
return data_[index];
29+
}
30+
31+
const float& AudioArray::operator[](int index) const {
32+
return data_[index];
33+
}
34+
35+
void AudioArray::normalize() {
36+
float maxAbsValue = getMaxAbsValue();
37+
38+
if (maxAbsValue == 0.0f || maxAbsValue == 1.0f) {
39+
return;
40+
}
41+
42+
VectorMath::multiplyByScalar(data_, 1.0f / maxAbsValue, data_, size_);
43+
}
44+
45+
void AudioArray::resize(int size) {
46+
if (size == size_) {
47+
if (!data_) {
48+
data_ = new float[size];
49+
}
50+
51+
zero(0, size);
52+
return;
53+
}
54+
55+
delete[] data_;
56+
size_ = size;
57+
data_ = new float[size_];
58+
59+
zero(0, size_);
60+
}
61+
62+
void AudioArray::scale(float value) {
63+
VectorMath::multiplyByScalar(data_, value, data_, size_);
64+
}
65+
66+
float AudioArray::getMaxAbsValue() const {
67+
return VectorMath::maximumMagnitude(data_, size_);
68+
}
69+
70+
void AudioArray::zero() {
71+
zero(0, size_);
72+
}
73+
74+
void AudioArray::zero(int start, int length) {
75+
memset(data_ + start, 0, length * sizeof(float));
76+
}
77+
78+
void AudioArray::sum(const AudioArray* source) {
79+
sum(source, 0, 0, size_);
80+
}
81+
82+
void AudioArray::sum(const AudioArray* source, int start, int length) {
83+
sum(source, start, start, length);
84+
}
85+
86+
void AudioArray::sum(const AudioArray* source, int sourceStart, int destinationStart, int length) {
87+
VectorMath::add(data_ + destinationStart, source->getData() + sourceStart, data_ + destinationStart, length);
88+
}
89+
90+
void AudioArray::copy(const AudioArray* source) {
91+
copy(source, 0, size_);
92+
}
93+
94+
void AudioArray::copy(const AudioArray* source, int start, int length) {
95+
copy(source, start, start, length);
96+
}
97+
98+
void AudioArray::copy(const AudioArray* source, int sourceStart, int destinationStart, int length) {
99+
memcpy(data_ + destinationStart, source->getData() + sourceStart, length * sizeof(float));
100+
}
101+
102+
} // namespace audioapi
103+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#pragma once
2+
3+
#include <memory>
4+
#include <algorithm>
5+
6+
namespace audioapi {
7+
8+
class AudioArray {
9+
public:
10+
explicit AudioArray(int size);
11+
~AudioArray();
12+
13+
[[nodiscard]] int getSize() const;
14+
float* getData() const;
15+
16+
17+
float& operator[](int index);
18+
const float& operator[](int index) const;
19+
20+
void normalize();
21+
void resize(int size);
22+
void scale(float value);
23+
float getMaxAbsValue() const;
24+
25+
void zero();
26+
void zero(int start, int length);
27+
28+
void sum(const AudioArray* source);
29+
void sum(const AudioArray* source, int start, int length);
30+
void sum(const AudioArray* source, int sourceStart, int destinationStart, int length);
31+
32+
void copy(const AudioArray* source);
33+
void copy(const AudioArray* source, int start, int length);
34+
void copy(const AudioArray* source, int sourceStart, int destinationStart, int length);
35+
36+
37+
private:
38+
float *data_;
39+
int size_;
40+
};
41+
42+
} // namespace audioapi

0 commit comments

Comments
 (0)