react-native-audio-api 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/jniLibs/arm64-v8a/libavcodec.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libavformat.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libavutil.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libswresample.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavcodec.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavformat.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavutil.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libswresample.so +0 -0
- package/android/src/main/jniLibs/x86/libavcodec.so +0 -0
- package/android/src/main/jniLibs/x86/libavformat.so +0 -0
- package/android/src/main/jniLibs/x86/libavutil.so +0 -0
- package/android/src/main/jniLibs/x86/libswresample.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavcodec.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavformat.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavutil.so +0 -0
- package/android/src/main/jniLibs/x86_64/libswresample.so +0 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.cpp +3 -8
- package/common/cpp/audioapi/core/effects/WorkletNode.cpp +16 -28
- package/common/cpp/audioapi/core/effects/WorkletNode.h +2 -3
- package/common/cpp/audioapi/core/effects/WorkletProcessingNode.cpp +5 -6
- package/common/cpp/audioapi/core/sources/AudioBuffer.h +1 -0
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +0 -4
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +0 -1
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +0 -2
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +0 -4
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +0 -1
- package/common/cpp/audioapi/core/sources/StreamerNode.cpp +16 -6
- package/common/cpp/audioapi/core/sources/StreamerNode.h +3 -1
- package/common/cpp/audioapi/core/sources/WorkletSourceNode.cpp +2 -3
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +5 -1
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64/libavcodec.framework/libavcodec +0 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64_x86_64-simulator/libavcodec.framework/libavcodec +0 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/Info.plist +5 -5
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64/libavformat.framework/libavformat +0 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64_x86_64-simulator/libavformat.framework/libavformat +0 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64/libavutil.framework/libavutil +0 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64_x86_64-simulator/libavutil.framework/libavutil +0 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/Info.plist +5 -5
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64/libswresample.framework/libswresample +0 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64_x86_64-simulator/libswresample.framework/libswresample +0 -0
- package/common/cpp/audioapi/jsi/AudioArrayBuffer.cpp +2 -2
- package/common/cpp/audioapi/jsi/AudioArrayBuffer.h +10 -11
- package/common/cpp/audioapi/libs/ffmpeg/ffmpeg_setup.sh +1 -1
- package/common/cpp/audioapi/utils/AudioBus.cpp +4 -0
- package/common/cpp/audioapi/utils/AudioBus.h +1 -0
- package/common/cpp/test/CMakeLists.txt +7 -4
- package/common/cpp/test/RunTests.sh +2 -2
- package/common/cpp/test/{AudioParamTest.cpp → src/AudioParamTest.cpp} +1 -1
- package/common/cpp/test/src/ConstantSourceTest.cpp +64 -0
- package/common/cpp/test/{GainTest.cpp → src/GainTest.cpp} +11 -10
- package/common/cpp/test/{MockAudioEventHandlerRegistry.h → src/MockAudioEventHandlerRegistry.h} +4 -2
- package/common/cpp/test/{OscillatorTest.cpp → src/OscillatorTest.cpp} +6 -4
- package/common/cpp/test/{StereoPannerTest.cpp → src/StereoPannerTest.cpp} +1 -1
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#include <audioapi/HostObjects/sources/AudioBufferHostObject.h>
|
|
2
2
|
|
|
3
3
|
#include <audioapi/jsi/AudioArrayBuffer.h>
|
|
4
|
+
#include <audioapi/utils/AudioBus.h>
|
|
4
5
|
|
|
5
6
|
namespace audioapi {
|
|
6
7
|
|
|
@@ -42,14 +43,8 @@ JSI_PROPERTY_GETTER_IMPL(AudioBufferHostObject, numberOfChannels) {
|
|
|
42
43
|
|
|
43
44
|
JSI_HOST_FUNCTION_IMPL(AudioBufferHostObject, getChannelData) {
|
|
44
45
|
auto channel = static_cast<int>(args[0].getNumber());
|
|
45
|
-
auto
|
|
46
|
-
|
|
47
|
-
auto length = static_cast<int>(audioBuffer_->getLength());
|
|
48
|
-
auto size = static_cast<int>(length * sizeof(float));
|
|
49
|
-
|
|
50
|
-
// reading or writing from this ArrayBuffer could cause a crash
|
|
51
|
-
// if underlying channelData is deallocated
|
|
52
|
-
auto audioArrayBuffer = std::make_shared<AudioArrayBuffer>(channelData, size);
|
|
46
|
+
auto audioArrayBuffer = std::make_shared<AudioArrayBuffer>(
|
|
47
|
+
audioBuffer_->bus_->getSharedChannel(channel));
|
|
53
48
|
auto arrayBuffer = jsi::ArrayBuffer(runtime, audioArrayBuffer);
|
|
54
49
|
|
|
55
50
|
auto float32ArrayCtor =
|
|
@@ -9,25 +9,16 @@ WorkletNode::WorkletNode(
|
|
|
9
9
|
size_t bufferLength,
|
|
10
10
|
size_t inputChannelCount)
|
|
11
11
|
: AudioNode(context),
|
|
12
|
-
buffRealLength_(bufferLength * sizeof(float)),
|
|
13
|
-
bufferLength_(bufferLength),
|
|
14
12
|
workletRunner_(runtime),
|
|
15
13
|
shareableWorklet_(worklet),
|
|
14
|
+
bufferLength_(bufferLength),
|
|
16
15
|
inputChannelCount_(inputChannelCount),
|
|
17
16
|
curBuffIndex_(0) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
buffs_.emplace_back(new uint8_t[buffRealLength_]);
|
|
21
|
-
}
|
|
17
|
+
bus_ = std::make_shared<AudioBus>(
|
|
18
|
+
bufferLength, inputChannelCount, context->getSampleRate());
|
|
22
19
|
isInitialized_ = true;
|
|
23
20
|
}
|
|
24
21
|
|
|
25
|
-
WorkletNode::~WorkletNode() {
|
|
26
|
-
for (auto &buff : buffs_) {
|
|
27
|
-
delete[] buff;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
22
|
std::shared_ptr<AudioBus> WorkletNode::processNode(
|
|
32
23
|
const std::shared_ptr<AudioBus> &processingBus,
|
|
33
24
|
int framesToProcess) {
|
|
@@ -40,17 +31,11 @@ std::shared_ptr<AudioBus> WorkletNode::processNode(
|
|
|
40
31
|
size_t needsToProcess = framesToProcess - processed;
|
|
41
32
|
size_t shouldProcess = std::min(framesToWorkletInvoke, needsToProcess);
|
|
42
33
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
auto channelData = processingBus->getChannel(ch)->getData();
|
|
49
|
-
std::memcpy(
|
|
50
|
-
/* dest */ buffs_[ch] + curBuffIndex_ * sizeof(float),
|
|
51
|
-
/* src */ reinterpret_cast<const uint8_t *>(channelData + processed),
|
|
52
|
-
/* size */ shouldProcess * sizeof(float));
|
|
53
|
-
}
|
|
34
|
+
/// here we copy
|
|
35
|
+
/// to [curBuffIndex_, curBuffIndex_ + shouldProcess]
|
|
36
|
+
/// from [processed, processed + shouldProcess]
|
|
37
|
+
bus_->copy(processingBus.get(), processed, curBuffIndex_, shouldProcess);
|
|
38
|
+
|
|
54
39
|
processed += shouldProcess;
|
|
55
40
|
curBuffIndex_ += shouldProcess;
|
|
56
41
|
|
|
@@ -63,16 +48,19 @@ std::shared_ptr<AudioBus> WorkletNode::processNode(
|
|
|
63
48
|
/// Arguments preparation
|
|
64
49
|
auto jsArray = jsi::Array(uiRuntimeRaw, channelCount_);
|
|
65
50
|
for (size_t ch = 0; ch < channelCount_; ch++) {
|
|
66
|
-
|
|
67
|
-
|
|
51
|
+
auto audioArray = std::make_shared<AudioArray>(bufferLength_);
|
|
52
|
+
audioArray->copy(bus_->getChannel(ch));
|
|
68
53
|
auto sharedAudioArray =
|
|
69
|
-
std::make_shared<AudioArrayBuffer>(
|
|
54
|
+
std::make_shared<AudioArrayBuffer>(audioArray);
|
|
55
|
+
auto sharedAudioArraySize = sharedAudioArray->size();
|
|
70
56
|
auto arrayBuffer =
|
|
71
57
|
jsi::ArrayBuffer(uiRuntimeRaw, std::move(sharedAudioArray));
|
|
58
|
+
arrayBuffer.setExternalMemoryPressure(
|
|
59
|
+
uiRuntimeRaw, sharedAudioArraySize);
|
|
72
60
|
jsArray.setValueAtIndex(uiRuntimeRaw, ch, std::move(arrayBuffer));
|
|
73
61
|
}
|
|
74
|
-
|
|
75
|
-
|
|
62
|
+
|
|
63
|
+
bus_->zero();
|
|
76
64
|
|
|
77
65
|
workletRunner_.executeWorklet(
|
|
78
66
|
shareableWorklet_,
|
|
@@ -42,7 +42,7 @@ class WorkletNode : public AudioNode {
|
|
|
42
42
|
size_t inputChannelCount
|
|
43
43
|
);
|
|
44
44
|
|
|
45
|
-
~WorkletNode() override;
|
|
45
|
+
~WorkletNode() override = default;
|
|
46
46
|
|
|
47
47
|
protected:
|
|
48
48
|
std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
@@ -51,10 +51,9 @@ class WorkletNode : public AudioNode {
|
|
|
51
51
|
private:
|
|
52
52
|
WorkletsRunner workletRunner_;
|
|
53
53
|
std::shared_ptr<worklets::SerializableWorklet> shareableWorklet_;
|
|
54
|
-
std::
|
|
54
|
+
std::shared_ptr<AudioBus> bus_;
|
|
55
55
|
|
|
56
56
|
/// @brief Length of the byte buffer that will be passed to the AudioArrayBuffer
|
|
57
|
-
size_t buffRealLength_;
|
|
58
57
|
size_t bufferLength_;
|
|
59
58
|
size_t inputChannelCount_;
|
|
60
59
|
size_t curBuffIndex_;
|
|
@@ -16,13 +16,12 @@ WorkletProcessingNode::WorkletProcessingNode(
|
|
|
16
16
|
outputBuffsHandles_.resize(maxChannelCount);
|
|
17
17
|
|
|
18
18
|
for (size_t i = 0; i < maxChannelCount; ++i) {
|
|
19
|
-
auto
|
|
20
|
-
inputBuffsHandles_[i] = std::make_shared<AudioArrayBuffer>(
|
|
21
|
-
inputBuff, RENDER_QUANTUM_SIZE * sizeof(float));
|
|
19
|
+
auto inputAudioArray = std::make_shared<AudioArray>(RENDER_QUANTUM_SIZE);
|
|
20
|
+
inputBuffsHandles_[i] = std::make_shared<AudioArrayBuffer>(inputAudioArray);
|
|
22
21
|
|
|
23
|
-
auto
|
|
24
|
-
outputBuffsHandles_[i] =
|
|
25
|
-
|
|
22
|
+
auto outputAudioArray = std::make_shared<AudioArray>(RENDER_QUANTUM_SIZE);
|
|
23
|
+
outputBuffsHandles_[i] =
|
|
24
|
+
std::make_shared<AudioArrayBuffer>(outputAudioArray);
|
|
26
25
|
}
|
|
27
26
|
}
|
|
28
27
|
|
|
@@ -27,10 +27,6 @@ AudioBufferBaseSourceNode::AudioBufferBaseSourceNode(
|
|
|
27
27
|
std::make_shared<signalsmith::stretch::SignalsmithStretch<float>>();
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
AudioBufferBaseSourceNode::~AudioBufferBaseSourceNode() {
|
|
31
|
-
clearOnPositionChangedCallback();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
30
|
std::shared_ptr<AudioParam> AudioBufferBaseSourceNode::getDetuneParam() const {
|
|
35
31
|
return detuneParam_;
|
|
36
32
|
}
|
|
@@ -15,7 +15,6 @@ class AudioParam;
|
|
|
15
15
|
class AudioBufferBaseSourceNode : public AudioScheduledSourceNode {
|
|
16
16
|
public:
|
|
17
17
|
explicit AudioBufferBaseSourceNode(BaseAudioContext *context, bool pitchCorrection);
|
|
18
|
-
~AudioBufferBaseSourceNode() override;
|
|
19
18
|
|
|
20
19
|
[[nodiscard]] std::shared_ptr<AudioParam> getDetuneParam() const;
|
|
21
20
|
[[nodiscard]] std::shared_ptr<AudioParam> getPlaybackRateParam() const;
|
|
@@ -16,10 +16,6 @@ AudioScheduledSourceNode::AudioScheduledSourceNode(BaseAudioContext *context)
|
|
|
16
16
|
numberOfInputs_ = 0;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
AudioScheduledSourceNode::~AudioScheduledSourceNode() {
|
|
20
|
-
clearOnEndedCallback();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
19
|
void AudioScheduledSourceNode::start(double when) {
|
|
24
20
|
playbackState_ = PlaybackState::SCHEDULED;
|
|
25
21
|
startTime_ = when;
|
|
@@ -27,7 +27,6 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
27
27
|
// FINISHED: The node has finished playing.
|
|
28
28
|
enum class PlaybackState { UNSCHEDULED, SCHEDULED, PLAYING, STOP_SCHEDULED, FINISHED };
|
|
29
29
|
explicit AudioScheduledSourceNode(BaseAudioContext *context);
|
|
30
|
-
~AudioScheduledSourceNode() override;
|
|
31
30
|
|
|
32
31
|
void start(double when);
|
|
33
32
|
virtual void stop(double when);
|
|
@@ -44,10 +44,14 @@ bool StreamerNode::initialize(const std::string &input_url) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (!openInput(input_url)) {
|
|
47
|
+
if (VERBOSE)
|
|
48
|
+
printf("Failed to open input\n");
|
|
47
49
|
return false;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
if (!findAudioStream() || !setupDecoder() || !setupResampler()) {
|
|
53
|
+
if (VERBOSE)
|
|
54
|
+
printf("Failed to find/setup audio stream\n");
|
|
51
55
|
cleanup();
|
|
52
56
|
return false;
|
|
53
57
|
}
|
|
@@ -56,6 +60,8 @@ bool StreamerNode::initialize(const std::string &input_url) {
|
|
|
56
60
|
frame_ = av_frame_alloc();
|
|
57
61
|
|
|
58
62
|
if (pkt_ == nullptr || frame_ == nullptr) {
|
|
63
|
+
if (VERBOSE)
|
|
64
|
+
printf("Failed to allocate packet or frame\n");
|
|
59
65
|
cleanup();
|
|
60
66
|
return false;
|
|
61
67
|
}
|
|
@@ -119,29 +125,24 @@ void StreamerNode::streamAudio() {
|
|
|
119
125
|
while (streamFlag.load()) {
|
|
120
126
|
if (pendingFrame_ != nullptr) {
|
|
121
127
|
if (!processFrameWithResampler(pendingFrame_)) {
|
|
122
|
-
cleanup();
|
|
123
128
|
return;
|
|
124
129
|
}
|
|
125
130
|
} else {
|
|
126
131
|
if (av_read_frame(fmtCtx_, pkt_) < 0) {
|
|
127
|
-
cleanup();
|
|
128
132
|
return;
|
|
129
133
|
}
|
|
130
134
|
if (pkt_->stream_index == audio_stream_index_) {
|
|
131
135
|
if (avcodec_send_packet(codecCtx_, pkt_) != 0) {
|
|
132
|
-
cleanup();
|
|
133
136
|
return;
|
|
134
137
|
}
|
|
135
138
|
if (avcodec_receive_frame(codecCtx_, frame_) != 0) {
|
|
136
|
-
cleanup();
|
|
137
139
|
return;
|
|
138
140
|
}
|
|
139
141
|
if (!processFrameWithResampler(frame_)) {
|
|
140
|
-
cleanup();
|
|
141
142
|
return;
|
|
142
143
|
}
|
|
143
|
-
av_packet_unref(pkt_);
|
|
144
144
|
}
|
|
145
|
+
av_packet_unref(pkt_);
|
|
145
146
|
}
|
|
146
147
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
147
148
|
}
|
|
@@ -174,6 +175,13 @@ std::shared_ptr<AudioBus> StreamerNode::processNode(
|
|
|
174
175
|
(maxBufferSize_ - offsetLength) * sizeof(float));
|
|
175
176
|
}
|
|
176
177
|
bufferedBusIndex_ -= offsetLength;
|
|
178
|
+
} else {
|
|
179
|
+
if (VERBOSE)
|
|
180
|
+
printf(
|
|
181
|
+
"Buffer underrun: have %zu, need %zu\n",
|
|
182
|
+
bufferedBusIndex_,
|
|
183
|
+
(size_t)framesToProcess);
|
|
184
|
+
processingBus->zero();
|
|
177
185
|
}
|
|
178
186
|
|
|
179
187
|
return processingBus;
|
|
@@ -273,6 +281,8 @@ bool StreamerNode::setupDecoder() {
|
|
|
273
281
|
|
|
274
282
|
void StreamerNode::cleanup() {
|
|
275
283
|
streamFlag.store(false);
|
|
284
|
+
// cleanup cannot be called from the streaming thread so there is no need to
|
|
285
|
+
// check if we are in the same thread
|
|
276
286
|
streamingThread_.join();
|
|
277
287
|
if (swrCtx_ != nullptr) {
|
|
278
288
|
swr_free(&swrCtx_);
|
|
@@ -28,6 +28,8 @@ extern "C" {
|
|
|
28
28
|
#include <string>
|
|
29
29
|
#include <atomic>
|
|
30
30
|
|
|
31
|
+
static bool constexpr VERBOSE = false;
|
|
32
|
+
|
|
31
33
|
namespace audioapi {
|
|
32
34
|
|
|
33
35
|
class AudioBus;
|
|
@@ -94,7 +96,7 @@ class StreamerNode : public AudioScheduledSourceNode {
|
|
|
94
96
|
|
|
95
97
|
/**
|
|
96
98
|
* @brief Open the input stream
|
|
97
|
-
* @param
|
|
99
|
+
* @param inputUrl The URL of the input stream
|
|
98
100
|
* @return true if successful, false otherwise
|
|
99
101
|
* @note This function initializes the FFmpeg libraries and opens the input stream
|
|
100
102
|
*/
|
|
@@ -16,9 +16,8 @@ WorkletSourceNode::WorkletSourceNode(
|
|
|
16
16
|
size_t outputChannelCount = this->getChannelCount();
|
|
17
17
|
outputBuffsHandles_.resize(outputChannelCount);
|
|
18
18
|
for (size_t i = 0; i < outputChannelCount; ++i) {
|
|
19
|
-
auto
|
|
20
|
-
outputBuffsHandles_[i] = std::make_shared<AudioArrayBuffer>(
|
|
21
|
-
buff, RENDER_QUANTUM_SIZE * sizeof(float));
|
|
19
|
+
auto audioArray = std::make_shared<AudioArray>(RENDER_QUANTUM_SIZE);
|
|
20
|
+
outputBuffsHandles_[i] = std::make_shared<AudioArrayBuffer>(audioArray);
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
|
|
@@ -156,8 +156,12 @@ void AudioEventHandlerRegistry::invokeHandlerWithEventBody(
|
|
|
156
156
|
|
|
157
157
|
// In case of debugging this, please increment the hours spent counter
|
|
158
158
|
|
|
159
|
-
// Hours spent on this:
|
|
159
|
+
// Hours spent on this: 8
|
|
160
160
|
try {
|
|
161
|
+
if (!handlerIt->second || !handlerIt->second->isFunction(*runtime_)) {
|
|
162
|
+
// If the handler is not valid, we can skip it
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
161
165
|
jsi::Object eventObject(*runtime_);
|
|
162
166
|
// handle special logic for microphone, because we pass audio buffer which
|
|
163
167
|
// has significant size
|
|
Binary file
|
|
Binary file
|
|
@@ -8,32 +8,32 @@
|
|
|
8
8
|
<key>BinaryPath</key>
|
|
9
9
|
<string>libavformat.framework/libavformat</string>
|
|
10
10
|
<key>LibraryIdentifier</key>
|
|
11
|
-
<string>ios-
|
|
11
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
12
12
|
<key>LibraryPath</key>
|
|
13
13
|
<string>libavformat.framework</string>
|
|
14
14
|
<key>SupportedArchitectures</key>
|
|
15
15
|
<array>
|
|
16
16
|
<string>arm64</string>
|
|
17
|
+
<string>x86_64</string>
|
|
17
18
|
</array>
|
|
18
19
|
<key>SupportedPlatform</key>
|
|
19
20
|
<string>ios</string>
|
|
21
|
+
<key>SupportedPlatformVariant</key>
|
|
22
|
+
<string>simulator</string>
|
|
20
23
|
</dict>
|
|
21
24
|
<dict>
|
|
22
25
|
<key>BinaryPath</key>
|
|
23
26
|
<string>libavformat.framework/libavformat</string>
|
|
24
27
|
<key>LibraryIdentifier</key>
|
|
25
|
-
<string>ios-
|
|
28
|
+
<string>ios-arm64</string>
|
|
26
29
|
<key>LibraryPath</key>
|
|
27
30
|
<string>libavformat.framework</string>
|
|
28
31
|
<key>SupportedArchitectures</key>
|
|
29
32
|
<array>
|
|
30
33
|
<string>arm64</string>
|
|
31
|
-
<string>x86_64</string>
|
|
32
34
|
</array>
|
|
33
35
|
<key>SupportedPlatform</key>
|
|
34
36
|
<string>ios</string>
|
|
35
|
-
<key>SupportedPlatformVariant</key>
|
|
36
|
-
<string>simulator</string>
|
|
37
37
|
</dict>
|
|
38
38
|
</array>
|
|
39
39
|
<key>CFBundlePackageType</key>
|
|
Binary file
|
|
Binary file
|
package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64/libavutil.framework/libavutil
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -8,32 +8,32 @@
|
|
|
8
8
|
<key>BinaryPath</key>
|
|
9
9
|
<string>libswresample.framework/libswresample</string>
|
|
10
10
|
<key>LibraryIdentifier</key>
|
|
11
|
-
<string>ios-
|
|
11
|
+
<string>ios-arm64</string>
|
|
12
12
|
<key>LibraryPath</key>
|
|
13
13
|
<string>libswresample.framework</string>
|
|
14
14
|
<key>SupportedArchitectures</key>
|
|
15
15
|
<array>
|
|
16
16
|
<string>arm64</string>
|
|
17
|
-
<string>x86_64</string>
|
|
18
17
|
</array>
|
|
19
18
|
<key>SupportedPlatform</key>
|
|
20
19
|
<string>ios</string>
|
|
21
|
-
<key>SupportedPlatformVariant</key>
|
|
22
|
-
<string>simulator</string>
|
|
23
20
|
</dict>
|
|
24
21
|
<dict>
|
|
25
22
|
<key>BinaryPath</key>
|
|
26
23
|
<string>libswresample.framework/libswresample</string>
|
|
27
24
|
<key>LibraryIdentifier</key>
|
|
28
|
-
<string>ios-
|
|
25
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
29
26
|
<key>LibraryPath</key>
|
|
30
27
|
<string>libswresample.framework</string>
|
|
31
28
|
<key>SupportedArchitectures</key>
|
|
32
29
|
<array>
|
|
33
30
|
<string>arm64</string>
|
|
31
|
+
<string>x86_64</string>
|
|
34
32
|
</array>
|
|
35
33
|
<key>SupportedPlatform</key>
|
|
36
34
|
<string>ios</string>
|
|
35
|
+
<key>SupportedPlatformVariant</key>
|
|
36
|
+
<string>simulator</string>
|
|
37
37
|
</dict>
|
|
38
38
|
</array>
|
|
39
39
|
<key>CFBundlePackageType</key>
|
|
Binary file
|
|
Binary file
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
namespace audioapi {
|
|
4
4
|
|
|
5
5
|
size_t AudioArrayBuffer::size() const {
|
|
6
|
-
return
|
|
6
|
+
return audioArray_->getSize() * sizeof(float);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
uint8_t *AudioArrayBuffer::data() {
|
|
10
|
-
return
|
|
10
|
+
return reinterpret_cast<uint8_t *>(audioArray_->getData());
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
} // namespace audioapi
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include <jsi/jsi.h>
|
|
4
|
+
#include <audioapi/utils/AudioArray.h>
|
|
5
|
+
|
|
6
|
+
#include <memory>
|
|
7
|
+
#include <utility>
|
|
4
8
|
|
|
5
9
|
namespace audioapi {
|
|
6
10
|
|
|
@@ -8,16 +12,12 @@ using namespace facebook;
|
|
|
8
12
|
|
|
9
13
|
class AudioArrayBuffer : public jsi::MutableBuffer {
|
|
10
14
|
public:
|
|
11
|
-
AudioArrayBuffer(
|
|
12
|
-
~AudioArrayBuffer() override
|
|
13
|
-
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
delete[] data_;
|
|
17
|
-
}
|
|
15
|
+
explicit AudioArrayBuffer(const std::shared_ptr<AudioArray> &audioArray): audioArray_(audioArray) {}
|
|
16
|
+
~AudioArrayBuffer() override = default;
|
|
17
|
+
|
|
18
18
|
AudioArrayBuffer(AudioArrayBuffer &&other) noexcept
|
|
19
|
-
:
|
|
20
|
-
other.
|
|
19
|
+
: audioArray_(std::move(other.audioArray_)) {
|
|
20
|
+
other.audioArray_ = nullptr;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
AudioArrayBuffer(const AudioArrayBuffer &) = delete;
|
|
@@ -28,8 +28,7 @@ class AudioArrayBuffer : public jsi::MutableBuffer {
|
|
|
28
28
|
uint8_t *data() override;
|
|
29
29
|
|
|
30
30
|
private:
|
|
31
|
-
|
|
32
|
-
const size_t size_;
|
|
31
|
+
std::shared_ptr<AudioArray> audioArray_;
|
|
33
32
|
};
|
|
34
33
|
|
|
35
34
|
} // namespace audioapi
|
|
@@ -128,6 +128,10 @@ AudioArray *AudioBus::getChannelByType(int channelType) const {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
std::shared_ptr<AudioArray> AudioBus::getSharedChannel(int index) const {
|
|
132
|
+
return channels_[index];
|
|
133
|
+
}
|
|
134
|
+
|
|
131
135
|
AudioArray &AudioBus::operator[](size_t index) {
|
|
132
136
|
return *channels_[index];
|
|
133
137
|
}
|
|
@@ -34,6 +34,7 @@ class AudioBus {
|
|
|
34
34
|
[[nodiscard]] size_t getSize() const;
|
|
35
35
|
[[nodiscard]] AudioArray *getChannel(int index) const;
|
|
36
36
|
[[nodiscard]] AudioArray *getChannelByType(int channelType) const;
|
|
37
|
+
[[nodiscard]] std::shared_ptr<AudioArray> getSharedChannel(int index) const;
|
|
37
38
|
|
|
38
39
|
AudioArray &operator[](size_t index);
|
|
39
40
|
const AudioArray &operator[](size_t index) const;
|
|
@@ -62,12 +62,15 @@ target_include_directories(rnaudioapi PUBLIC
|
|
|
62
62
|
target_include_directories(rnaudioapi_libs PUBLIC
|
|
63
63
|
${ROOT}/packages/react-native-audio-api/common/cpp
|
|
64
64
|
)
|
|
65
|
+
|
|
66
|
+
file(GLOB_RECURSE test_src
|
|
67
|
+
CONFIGURE_DEPENDS
|
|
68
|
+
"src/*.cpp"
|
|
69
|
+
)
|
|
70
|
+
|
|
65
71
|
add_executable(
|
|
66
72
|
tests
|
|
67
|
-
|
|
68
|
-
GainTest.cpp
|
|
69
|
-
AudioParamTest.cpp
|
|
70
|
-
StereoPannerTest.cpp
|
|
73
|
+
${test_src}
|
|
71
74
|
)
|
|
72
75
|
|
|
73
76
|
add_compile_definitions(AUDIO_API_TEST_SUITE)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#include <audioapi/core/OfflineAudioContext.h>
|
|
2
|
+
#include <audioapi/core/sources/ConstantSourceNode.h>
|
|
3
|
+
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
4
|
+
#include <audioapi/utils/AudioArray.h>
|
|
5
|
+
#include <audioapi/utils/AudioBus.h>
|
|
6
|
+
#include <gtest/gtest.h>
|
|
7
|
+
#include <test/src/MockAudioEventHandlerRegistry.h>
|
|
8
|
+
|
|
9
|
+
using namespace audioapi;
|
|
10
|
+
|
|
11
|
+
class ConstantSourceTest : public ::testing::Test {
|
|
12
|
+
protected:
|
|
13
|
+
std::shared_ptr<IAudioEventHandlerRegistry> eventRegistry;
|
|
14
|
+
std::unique_ptr<OfflineAudioContext> context;
|
|
15
|
+
static constexpr int sampleRate = 44100;
|
|
16
|
+
|
|
17
|
+
void SetUp() override {
|
|
18
|
+
eventRegistry = std::make_shared<MockAudioEventHandlerRegistry>();
|
|
19
|
+
context = std::make_unique<OfflineAudioContext>(
|
|
20
|
+
2, 5 * sampleRate, sampleRate, eventRegistry, RuntimeRegistry{});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
class TestableConstantSourceNode : public ConstantSourceNode {
|
|
25
|
+
public:
|
|
26
|
+
explicit TestableConstantSourceNode(BaseAudioContext *context)
|
|
27
|
+
: ConstantSourceNode(context) {}
|
|
28
|
+
|
|
29
|
+
void setOffsetParam(float value) {
|
|
30
|
+
getOffsetParam()->setValue(value);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
std::shared_ptr<AudioBus> processNode(
|
|
34
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
35
|
+
int framesToProcess) override {
|
|
36
|
+
return ConstantSourceNode::processNode(processingBus, framesToProcess);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
TEST_F(ConstantSourceTest, ConstantSourceCanBeCreated) {
|
|
41
|
+
auto constantSource = context->createConstantSource();
|
|
42
|
+
ASSERT_NE(constantSource, nullptr);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
TEST_F(ConstantSourceTest, ConstantSourceOutputsConstantValue) {
|
|
46
|
+
static constexpr int FRAMES_TO_PROCESS = 4;
|
|
47
|
+
|
|
48
|
+
auto bus =
|
|
49
|
+
std::make_shared<audioapi::AudioBus>(FRAMES_TO_PROCESS, 1, sampleRate);
|
|
50
|
+
auto constantSource =
|
|
51
|
+
std::make_shared<TestableConstantSourceNode>(context.get());
|
|
52
|
+
constantSource->start(context->getCurrentTime());
|
|
53
|
+
auto resultBus = constantSource->processNode(bus, FRAMES_TO_PROCESS);
|
|
54
|
+
|
|
55
|
+
for (int i = 0; i < FRAMES_TO_PROCESS; ++i) {
|
|
56
|
+
EXPECT_FLOAT_EQ((*resultBus->getChannel(0))[i], 1.0f);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
constantSource->setOffsetParam(0.5f);
|
|
60
|
+
resultBus = constantSource->processNode(bus, FRAMES_TO_PROCESS);
|
|
61
|
+
for (int i = 0; i < FRAMES_TO_PROCESS; ++i) {
|
|
62
|
+
EXPECT_FLOAT_EQ((*resultBus->getChannel(0))[i], 0.5f);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -4,34 +4,35 @@
|
|
|
4
4
|
#include <audioapi/utils/AudioArray.h>
|
|
5
5
|
#include <audioapi/utils/AudioBus.h>
|
|
6
6
|
#include <gtest/gtest.h>
|
|
7
|
-
#include
|
|
7
|
+
#include <test/src/MockAudioEventHandlerRegistry.h>
|
|
8
|
+
|
|
9
|
+
using namespace audioapi;
|
|
8
10
|
|
|
9
11
|
class GainTest : public ::testing::Test {
|
|
10
12
|
protected:
|
|
11
|
-
std::shared_ptr<
|
|
12
|
-
std::unique_ptr<
|
|
13
|
+
std::shared_ptr<IAudioEventHandlerRegistry> eventRegistry;
|
|
14
|
+
std::unique_ptr<OfflineAudioContext> context;
|
|
13
15
|
static constexpr int sampleRate = 44100;
|
|
14
16
|
|
|
15
17
|
void SetUp() override {
|
|
16
18
|
eventRegistry = std::make_shared<MockAudioEventHandlerRegistry>();
|
|
17
|
-
context = std::make_unique<
|
|
19
|
+
context = std::make_unique<OfflineAudioContext>(
|
|
18
20
|
2, 5 * sampleRate, sampleRate, eventRegistry, RuntimeRegistry{});
|
|
19
21
|
}
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
class TestableGainNode : public
|
|
24
|
+
class TestableGainNode : public GainNode {
|
|
23
25
|
public:
|
|
24
|
-
explicit TestableGainNode(
|
|
25
|
-
: audioapi::GainNode(context) {}
|
|
26
|
+
explicit TestableGainNode(BaseAudioContext *context) : GainNode(context) {}
|
|
26
27
|
|
|
27
28
|
void setGainParam(float value) {
|
|
28
29
|
getGainParam()->setValue(value);
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
std::shared_ptr<
|
|
32
|
-
const std::shared_ptr<
|
|
32
|
+
std::shared_ptr<AudioBus> processNode(
|
|
33
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
33
34
|
int framesToProcess) override {
|
|
34
|
-
return
|
|
35
|
+
return GainNode::processNode(processingBus, framesToProcess);
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
38
|
|
package/common/cpp/test/{MockAudioEventHandlerRegistry.h → src/MockAudioEventHandlerRegistry.h}
RENAMED
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
#include <string>
|
|
7
7
|
#include <memory>
|
|
8
8
|
|
|
9
|
-
using
|
|
9
|
+
using namespace audioapi;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
using EventMap = std::unordered_map<std::string, EventValue>;
|
|
12
|
+
|
|
13
|
+
class MockAudioEventHandlerRegistry : public IAudioEventHandlerRegistry {
|
|
12
14
|
public:
|
|
13
15
|
MOCK_METHOD(uint64_t, registerHandler,
|
|
14
16
|
(const std::string &eventName, const std::shared_ptr<facebook::jsi::Function> &handler), (override));
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
#include <audioapi/core/sources/OscillatorNode.h>
|
|
3
3
|
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
4
4
|
#include <gtest/gtest.h>
|
|
5
|
-
#include
|
|
5
|
+
#include <test/src/MockAudioEventHandlerRegistry.h>
|
|
6
|
+
|
|
7
|
+
using namespace audioapi;
|
|
6
8
|
|
|
7
9
|
class OscillatorTest : public ::testing::Test {
|
|
8
10
|
protected:
|
|
9
|
-
std::shared_ptr<
|
|
10
|
-
std::unique_ptr<
|
|
11
|
+
std::shared_ptr<IAudioEventHandlerRegistry> eventRegistry;
|
|
12
|
+
std::unique_ptr<OfflineAudioContext> context;
|
|
11
13
|
static constexpr int sampleRate = 44100;
|
|
12
14
|
|
|
13
15
|
void SetUp() override {
|
|
14
16
|
eventRegistry = std::make_shared<MockAudioEventHandlerRegistry>();
|
|
15
|
-
context = std::make_unique<
|
|
17
|
+
context = std::make_unique<OfflineAudioContext>(
|
|
16
18
|
2, 5 * sampleRate, sampleRate, eventRegistry, RuntimeRegistry{});
|
|
17
19
|
}
|
|
18
20
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-audio-api",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification",
|
|
5
5
|
"bin": {
|
|
6
6
|
"setup-rn-audio-api-web": "./scripts/setup-rn-audio-api-web.js"
|