react-native-audio-api 0.8.3-nightly-d178688-20250925 → 0.8.3-nightly-cae1f96-20250927
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/RNAudioAPI.podspec +8 -5
- package/android/build.gradle +44 -4
- package/android/src/main/cpp/audioapi/CMakeLists.txt +65 -0
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +29 -1
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +14 -0
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +7 -1
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +6 -1
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +1 -1
- package/android/src/main/cpp/audioapi/android/core/NativeAudioRecorder.hpp +36 -0
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +11 -1
- package/android/src/main/java/com/swmansion/audioapi/core/NativeAudioRecorder.kt +24 -0
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +15 -2
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +31 -13
- package/common/cpp/audioapi/HostObjects/AudioContextHostObject.cpp +57 -0
- package/common/cpp/audioapi/HostObjects/AudioContextHostObject.h +6 -46
- package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.cpp +70 -6
- package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h +10 -66
- package/common/cpp/audioapi/HostObjects/AudioParamHostObject.cpp +105 -0
- package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +17 -91
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +292 -6
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +26 -242
- package/common/cpp/audioapi/HostObjects/OfflineAudioContextHostObject.cpp +70 -0
- package/common/cpp/audioapi/HostObjects/OfflineAudioContextHostObject.h +6 -50
- package/common/cpp/audioapi/HostObjects/WorkletNodeHostObject.h +18 -0
- package/common/cpp/audioapi/HostObjects/analysis/AnalyserNodeHostObject.cpp +148 -0
- package/common/cpp/audioapi/HostObjects/analysis/AnalyserNodeHostObject.h +37 -0
- package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.cpp +92 -0
- package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.h +29 -0
- package/common/cpp/audioapi/HostObjects/effects/GainNodeHostObject.cpp +20 -0
- package/common/cpp/audioapi/HostObjects/effects/GainNodeHostObject.h +19 -0
- package/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.cpp +21 -0
- package/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.h +21 -0
- package/common/cpp/audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.cpp +41 -0
- package/common/cpp/audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.h +28 -0
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +69 -0
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +33 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.cpp +73 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.h +29 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.cpp +94 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.h +46 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.cpp +60 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.h +25 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.cpp +133 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.h +34 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioScheduledSourceNodeHostObject.cpp +52 -0
- package/common/cpp/audioapi/HostObjects/sources/AudioScheduledSourceNodeHostObject.h +25 -0
- package/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.cpp +55 -0
- package/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.h +27 -0
- package/common/cpp/audioapi/HostObjects/{RecorderAdapterNodeHostObject.h → sources/RecorderAdapterNodeHostObject.h} +1 -2
- package/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.cpp +22 -0
- package/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.h +28 -0
- package/common/cpp/audioapi/core/AudioContext.cpp +3 -2
- package/common/cpp/audioapi/core/AudioContext.h +2 -1
- package/common/cpp/audioapi/core/AudioNode.h +1 -1
- package/common/cpp/audioapi/core/AudioParam.h +1 -1
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +15 -1
- package/common/cpp/audioapi/core/BaseAudioContext.h +7 -3
- package/common/cpp/audioapi/core/OfflineAudioContext.cpp +4 -3
- package/common/cpp/audioapi/core/OfflineAudioContext.h +2 -1
- package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +1 -1
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +1 -1
- package/common/cpp/audioapi/core/effects/WorkletNode.cpp +86 -0
- package/common/cpp/audioapi/core/effects/WorkletNode.h +64 -0
- package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +1 -1
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +2 -2
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +1 -1
- package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +1 -1
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +1 -1
- package/common/cpp/audioapi/core/sources/StreamerNode.h +0 -8
- package/common/cpp/audioapi/core/{AudioParamEventQueue.cpp → utils/AudioParamEventQueue.cpp} +1 -1
- package/common/cpp/audioapi/core/utils/worklets/SafeIncludes.h +45 -0
- package/common/cpp/audioapi/core/utils/worklets/UiWorkletsRunner.cpp +9 -0
- package/common/cpp/audioapi/core/utils/worklets/UiWorkletsRunner.h +73 -0
- package/common/cpp/audioapi/dsp/Windows.cpp +1 -1
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +1 -1
- package/common/cpp/audioapi/jsi/AudioArrayBuffer.h +14 -1
- package/common/cpp/audioapi/jsi/JsiHostObject.h +6 -12
- package/common/cpp/audioapi/utils/AudioBus.cpp +1 -1
- package/common/cpp/test/CMakeLists.txt +8 -3
- package/common/cpp/test/GainTest.cpp +1 -1
- package/common/cpp/test/OscillatorTest.cpp +1 -1
- package/ios/audioapi/ios/AudioAPIModule.mm +32 -5
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +1 -1
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +1 -2
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +1 -1
- package/lib/commonjs/api.js +7 -0
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/BaseAudioContext.js +29 -0
- package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
- package/lib/commonjs/core/WorkletNode.js +11 -0
- package/lib/commonjs/core/WorkletNode.js.map +1 -0
- package/lib/commonjs/utils/index.js +9 -0
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/module/api.js +1 -0
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +29 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/core/WorkletNode.js +5 -0
- package/lib/module/core/WorkletNode.js.map +1 -0
- package/lib/module/utils/index.js +8 -0
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/api.d.ts +1 -0
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/core/WorkletNode.d.ts +4 -0
- package/lib/typescript/core/WorkletNode.d.ts.map +1 -0
- package/lib/typescript/interfaces.d.ts +3 -0
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/utils/index.d.ts +2 -0
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/api.ts +1 -0
- package/src/core/BaseAudioContext.ts +51 -0
- package/src/core/WorkletNode.ts +3 -0
- package/src/interfaces.ts +7 -0
- package/src/utils/index.ts +10 -0
- package/common/cpp/audioapi/HostObjects/AnalyserNodeHostObject.h +0 -149
- package/common/cpp/audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h +0 -76
- package/common/cpp/audioapi/HostObjects/AudioBufferHostObject.h +0 -120
- package/common/cpp/audioapi/HostObjects/AudioBufferQueueSourceNodeHostObject.h +0 -67
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +0 -142
- package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +0 -86
- package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +0 -56
- package/common/cpp/audioapi/HostObjects/BiquadFilterNodeHostObject.h +0 -89
- package/common/cpp/audioapi/HostObjects/GainNodeHostObject.h +0 -27
- package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +0 -65
- package/common/cpp/audioapi/HostObjects/StereoPannerNodeHostObject.h +0 -29
- package/common/cpp/audioapi/HostObjects/StreamerNodeHostObject.h +0 -30
- package/common/cpp/audioapi/events/AudioEventHandlerRegistryHostObject.h +0 -48
- package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.h +0 -7
- package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.mm +0 -12
- /package/common/cpp/audioapi/HostObjects/{AudioDestinationNodeHostObject.h → destinations/AudioDestinationNodeHostObject.h} +0 -0
- /package/common/cpp/audioapi/HostObjects/{PeriodicWaveHostObject.h → effects/PeriodicWaveHostObject.h} +0 -0
- /package/common/cpp/audioapi/core/{AudioParamEventQueue.h → utils/AudioParamEventQueue.h} +0 -0
- /package/common/cpp/audioapi/core/{Constants.h → utils/Constants.h} +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#include <audioapi/HostObjects/sources/StreamerNodeHostObject.h>
|
|
2
|
+
|
|
3
|
+
#include <audioapi/HostObjects/AudioParamHostObject.h>
|
|
4
|
+
#include <audioapi/HostObjects/effects/PeriodicWaveHostObject.h>
|
|
5
|
+
#include <audioapi/core/sources/StreamerNode.h>
|
|
6
|
+
|
|
7
|
+
namespace audioapi {
|
|
8
|
+
|
|
9
|
+
StreamerNodeHostObject::StreamerNodeHostObject(
|
|
10
|
+
const std::shared_ptr<StreamerNode> &node)
|
|
11
|
+
: AudioScheduledSourceNodeHostObject(node) {
|
|
12
|
+
addFunctions(JSI_EXPORT_FUNCTION(StreamerNodeHostObject, initialize));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
JSI_HOST_FUNCTION_IMPL(StreamerNodeHostObject, initialize) {
|
|
16
|
+
auto streamerNode = std::static_pointer_cast<StreamerNode>(node_);
|
|
17
|
+
auto path = args[0].getString(runtime).utf8(runtime);
|
|
18
|
+
auto result = streamerNode->initialize(path);
|
|
19
|
+
return {result};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <audioapi/HostObjects/sources/AudioScheduledSourceNodeHostObject.h>
|
|
4
|
+
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
namespace audioapi {
|
|
10
|
+
using namespace facebook;
|
|
11
|
+
|
|
12
|
+
class StreamerNode;
|
|
13
|
+
|
|
14
|
+
class StreamerNodeHostObject : public AudioScheduledSourceNodeHostObject {
|
|
15
|
+
public:
|
|
16
|
+
explicit StreamerNodeHostObject(
|
|
17
|
+
const std::shared_ptr<StreamerNode> &node);
|
|
18
|
+
|
|
19
|
+
[[nodiscard]] static inline size_t getSizeInBytes() {
|
|
20
|
+
return SIZE;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
JSI_HOST_FUNCTION_DECL(initialize);
|
|
24
|
+
|
|
25
|
+
private:
|
|
26
|
+
static constexpr size_t SIZE = 4'000'000; // 4MB
|
|
27
|
+
};
|
|
28
|
+
} // namespace audioapi
|
|
@@ -14,8 +14,9 @@ AudioContext::AudioContext(
|
|
|
14
14
|
float sampleRate,
|
|
15
15
|
bool initSuspended,
|
|
16
16
|
const std::shared_ptr<IAudioEventHandlerRegistry>
|
|
17
|
-
&audioEventHandlerRegistry
|
|
18
|
-
|
|
17
|
+
&audioEventHandlerRegistry,
|
|
18
|
+
const std::shared_ptr<UiWorkletsRunner> &workletRunner)
|
|
19
|
+
: BaseAudioContext(audioEventHandlerRegistry, workletRunner) {
|
|
19
20
|
#ifdef ANDROID
|
|
20
21
|
audioPlayer_ = std::make_shared<AudioPlayer>(
|
|
21
22
|
this->renderAudio(), sampleRate, destination_->getChannelCount());
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include <audioapi/core/BaseAudioContext.h>
|
|
4
|
+
#include <audioapi/core/utils/worklets/UiWorkletsRunner.h>
|
|
4
5
|
|
|
5
6
|
#include <memory>
|
|
6
7
|
#include <functional>
|
|
@@ -14,7 +15,7 @@ class IOSAudioPlayer;
|
|
|
14
15
|
|
|
15
16
|
class AudioContext : public BaseAudioContext {
|
|
16
17
|
public:
|
|
17
|
-
explicit AudioContext(float sampleRate, bool initSuspended, const std::shared_ptr<IAudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
18
|
+
explicit AudioContext(float sampleRate, bool initSuspended, const std::shared_ptr<IAudioEventHandlerRegistry> &audioEventHandlerRegistry, const std::shared_ptr<UiWorkletsRunner> &workletRunner);
|
|
18
19
|
~AudioContext() override;
|
|
19
20
|
|
|
20
21
|
void close();
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
#include <audioapi/core/utils/ParamChangeEvent.h>
|
|
5
5
|
#include <audioapi/utils/AudioBus.h>
|
|
6
6
|
#include <audioapi/core/AudioNode.h>
|
|
7
|
-
#include <audioapi/core/AudioParamEventQueue.h>
|
|
7
|
+
#include <audioapi/core/utils/AudioParamEventQueue.h>
|
|
8
8
|
|
|
9
9
|
#include <cstddef>
|
|
10
10
|
#include <utility>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#include <audioapi/core/effects/BiquadFilterNode.h>
|
|
5
5
|
#include <audioapi/core/effects/GainNode.h>
|
|
6
6
|
#include <audioapi/core/effects/StereoPannerNode.h>
|
|
7
|
+
#include <audioapi/core/effects/WorkletNode.h>
|
|
7
8
|
#include <audioapi/core/sources/AudioBuffer.h>
|
|
8
9
|
#include <audioapi/core/sources/AudioBufferQueueSourceNode.h>
|
|
9
10
|
#include <audioapi/core/sources/AudioBufferSourceNode.h>
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
#include <audioapi/core/sources/StreamerNode.h>
|
|
13
14
|
#include <audioapi/core/utils/AudioDecoder.h>
|
|
14
15
|
#include <audioapi/core/utils/AudioNodeManager.h>
|
|
16
|
+
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
15
17
|
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
16
18
|
#include <audioapi/utils/AudioArray.h>
|
|
17
19
|
#include <audioapi/utils/AudioBus.h>
|
|
@@ -21,11 +23,13 @@ namespace audioapi {
|
|
|
21
23
|
|
|
22
24
|
BaseAudioContext::BaseAudioContext(
|
|
23
25
|
const std::shared_ptr<IAudioEventHandlerRegistry>
|
|
24
|
-
&audioEventHandlerRegistry
|
|
26
|
+
&audioEventHandlerRegistry,
|
|
27
|
+
const std::shared_ptr<UiWorkletsRunner> &workletRunner) {
|
|
25
28
|
nodeManager_ = std::make_shared<AudioNodeManager>();
|
|
26
29
|
destination_ = std::make_shared<AudioDestinationNode>(this);
|
|
27
30
|
|
|
28
31
|
audioEventHandlerRegistry_ = audioEventHandlerRegistry;
|
|
32
|
+
workletRunner_ = workletRunner;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
std::string BaseAudioContext::getState() {
|
|
@@ -58,6 +62,16 @@ std::shared_ptr<AudioDestinationNode> BaseAudioContext::getDestination() {
|
|
|
58
62
|
return destination_;
|
|
59
63
|
}
|
|
60
64
|
|
|
65
|
+
std::shared_ptr<WorkletNode> BaseAudioContext::createWorkletNode(
|
|
66
|
+
std::shared_ptr<worklets::SerializableWorklet> &shareableWorklet,
|
|
67
|
+
size_t bufferLength,
|
|
68
|
+
size_t inputChannelCount) {
|
|
69
|
+
auto workletNode = std::make_shared<WorkletNode>(
|
|
70
|
+
this, shareableWorklet, bufferLength, inputChannelCount);
|
|
71
|
+
nodeManager_->addProcessingNode(workletNode);
|
|
72
|
+
return workletNode;
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
std::shared_ptr<RecorderAdapterNode> BaseAudioContext::createRecorderAdapter() {
|
|
62
76
|
auto recorderAdapter = std::make_shared<RecorderAdapterNode>(this);
|
|
63
77
|
nodeManager_->addProcessingNode(recorderAdapter);
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
#include <audioapi/core/types/ContextState.h>
|
|
4
4
|
#include <audioapi/core/types/OscillatorType.h>
|
|
5
|
-
|
|
5
|
+
#include <audioapi/core/utils/worklets/UiWorkletsRunner.h>
|
|
6
|
+
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
6
7
|
|
|
7
8
|
#include <functional>
|
|
8
9
|
#include <memory>
|
|
@@ -31,11 +32,12 @@ class AnalyserNode;
|
|
|
31
32
|
class AudioEventHandlerRegistry;
|
|
32
33
|
class IAudioEventHandlerRegistry;
|
|
33
34
|
class RecorderAdapterNode;
|
|
35
|
+
class WorkletNode;
|
|
34
36
|
class StreamerNode;
|
|
35
37
|
|
|
36
38
|
class BaseAudioContext {
|
|
37
39
|
public:
|
|
38
|
-
explicit BaseAudioContext(const std::shared_ptr<IAudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
40
|
+
explicit BaseAudioContext(const std::shared_ptr<IAudioEventHandlerRegistry> &audioEventHandlerRegistry, const std::shared_ptr<UiWorkletsRunner> &workletRunner);
|
|
39
41
|
virtual ~BaseAudioContext() = default;
|
|
40
42
|
|
|
41
43
|
std::string getState();
|
|
@@ -45,6 +47,7 @@ class BaseAudioContext {
|
|
|
45
47
|
std::shared_ptr<AudioDestinationNode> getDestination();
|
|
46
48
|
|
|
47
49
|
std::shared_ptr<RecorderAdapterNode> createRecorderAdapter();
|
|
50
|
+
std::shared_ptr<WorkletNode> createWorkletNode(std::shared_ptr<worklets::SerializableWorklet> &shareableWorklet, size_t bufferLength, size_t inputChannelCount);
|
|
48
51
|
std::shared_ptr<OscillatorNode> createOscillator();
|
|
49
52
|
std::shared_ptr<StreamerNode> createStreamer();
|
|
50
53
|
std::shared_ptr<GainNode> createGain();
|
|
@@ -89,10 +92,11 @@ class BaseAudioContext {
|
|
|
89
92
|
std::shared_ptr<PeriodicWave> cachedSawtoothWave_ = nullptr;
|
|
90
93
|
std::shared_ptr<PeriodicWave> cachedTriangleWave_ = nullptr;
|
|
91
94
|
|
|
92
|
-
virtual bool isDriverRunning() const = 0;
|
|
95
|
+
[[nodiscard]] virtual bool isDriverRunning() const = 0;
|
|
93
96
|
|
|
94
97
|
public:
|
|
95
98
|
std::shared_ptr<IAudioEventHandlerRegistry> audioEventHandlerRegistry_;
|
|
99
|
+
std::shared_ptr<UiWorkletsRunner> workletRunner_;
|
|
96
100
|
};
|
|
97
101
|
|
|
98
102
|
} // namespace audioapi
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#include "OfflineAudioContext.h"
|
|
2
2
|
|
|
3
3
|
#include <audioapi/core/AudioContext.h>
|
|
4
|
-
#include <audioapi/core/Constants.h>
|
|
5
4
|
#include <audioapi/core/destinations/AudioDestinationNode.h>
|
|
6
5
|
#include <audioapi/core/sources/AudioBuffer.h>
|
|
7
6
|
#include <audioapi/core/utils/AudioDecoder.h>
|
|
8
7
|
#include <audioapi/core/utils/AudioNodeManager.h>
|
|
8
|
+
#include <audioapi/core/utils/Constants.h>
|
|
9
9
|
#include <audioapi/core/utils/Locker.h>
|
|
10
10
|
#include <audioapi/utils/AudioArray.h>
|
|
11
11
|
#include <audioapi/utils/AudioBus.h>
|
|
@@ -23,8 +23,9 @@ OfflineAudioContext::OfflineAudioContext(
|
|
|
23
23
|
size_t length,
|
|
24
24
|
float sampleRate,
|
|
25
25
|
const std::shared_ptr<IAudioEventHandlerRegistry>
|
|
26
|
-
&audioEventHandlerRegistry
|
|
27
|
-
|
|
26
|
+
&audioEventHandlerRegistry,
|
|
27
|
+
const std::shared_ptr<UiWorkletsRunner> &workletRunner)
|
|
28
|
+
: BaseAudioContext(audioEventHandlerRegistry, workletRunner),
|
|
28
29
|
length_(length),
|
|
29
30
|
numberOfChannels_(numberOfChannels),
|
|
30
31
|
currentSampleFrame_(0) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include "BaseAudioContext.h"
|
|
4
|
+
#include <audioapi/core/utils/worklets/UiWorkletsRunner.h>
|
|
4
5
|
|
|
5
6
|
#include <mutex>
|
|
6
7
|
#include <map>
|
|
@@ -14,7 +15,7 @@ using OfflineAudioContextResultCallback = std::function<void(std::shared_ptr<Aud
|
|
|
14
15
|
|
|
15
16
|
class OfflineAudioContext : public BaseAudioContext {
|
|
16
17
|
public:
|
|
17
|
-
explicit OfflineAudioContext(int numberOfChannels, size_t length, float sampleRate, const std::shared_ptr<IAudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
18
|
+
explicit OfflineAudioContext(int numberOfChannels, size_t length, float sampleRate, const std::shared_ptr<IAudioEventHandlerRegistry> &audioEventHandlerRegistry, const std::shared_ptr<UiWorkletsRunner> &workletRunner);
|
|
18
19
|
~OfflineAudioContext() override;
|
|
19
20
|
|
|
20
21
|
void resume();
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
#include <audioapi/core/Constants.h>
|
|
30
29
|
#include <audioapi/core/effects/PeriodicWave.h>
|
|
30
|
+
#include <audioapi/core/utils/Constants.h>
|
|
31
31
|
#include <audioapi/dsp/VectorMath.h>
|
|
32
32
|
|
|
33
33
|
constexpr unsigned NumberOfOctaveBands = 3;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#include <audioapi/core/effects/WorkletNode.h>
|
|
2
|
+
|
|
3
|
+
namespace audioapi {
|
|
4
|
+
|
|
5
|
+
WorkletNode::WorkletNode(
|
|
6
|
+
BaseAudioContext *context,
|
|
7
|
+
std::shared_ptr<worklets::SerializableWorklet> &worklet,
|
|
8
|
+
size_t bufferLength,
|
|
9
|
+
size_t inputChannelCount)
|
|
10
|
+
: AudioNode(context),
|
|
11
|
+
buffRealLength_(bufferLength * sizeof(float)),
|
|
12
|
+
bufferLength_(bufferLength),
|
|
13
|
+
workletRunner_(context->workletRunner_),
|
|
14
|
+
shareableWorklet_(worklet),
|
|
15
|
+
inputChannelCount_(inputChannelCount),
|
|
16
|
+
curBuffIndex_(0) {
|
|
17
|
+
buffs_.reserve(inputChannelCount_);
|
|
18
|
+
for (size_t i = 0; i < inputChannelCount_; ++i) {
|
|
19
|
+
buffs_.emplace_back(new uint8_t[buffRealLength_]);
|
|
20
|
+
}
|
|
21
|
+
isInitialized_ = true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
WorkletNode::~WorkletNode() {
|
|
25
|
+
for (auto &buff : buffs_) {
|
|
26
|
+
delete[] buff;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void WorkletNode::processNode(
|
|
31
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
32
|
+
int framesToProcess) {
|
|
33
|
+
size_t processed = 0;
|
|
34
|
+
size_t channelCount_ = std::min(
|
|
35
|
+
inputChannelCount_,
|
|
36
|
+
static_cast<size_t>(processingBus->getNumberOfChannels()));
|
|
37
|
+
while (processed < framesToProcess) {
|
|
38
|
+
size_t framesToWorkletInvoke = bufferLength_ - curBuffIndex_;
|
|
39
|
+
size_t needsToProcess = framesToProcess - processed;
|
|
40
|
+
size_t shouldProcess = std::min(framesToWorkletInvoke, needsToProcess);
|
|
41
|
+
|
|
42
|
+
for (size_t ch = 0; ch < channelCount_; ch++) {
|
|
43
|
+
/// here we copy
|
|
44
|
+
/// to uint8_t* [curBuffIndex_, curBuffIndex_ + shouldProcess]
|
|
45
|
+
/// from float* [processed, processed + shouldProcess]
|
|
46
|
+
/// so as the we need to copy shouldProcess * sizeof(float) bytes
|
|
47
|
+
auto channelData = processingBus->getChannel(ch)->getData();
|
|
48
|
+
std::memcpy(
|
|
49
|
+
/* dest */ buffs_[ch] + curBuffIndex_ * sizeof(float),
|
|
50
|
+
/* src */ reinterpret_cast<const uint8_t *>(channelData + processed),
|
|
51
|
+
/* size */ shouldProcess * sizeof(float));
|
|
52
|
+
}
|
|
53
|
+
processed += shouldProcess;
|
|
54
|
+
curBuffIndex_ += shouldProcess;
|
|
55
|
+
|
|
56
|
+
/// If we filled the entire buffer, we need to execute the worklet
|
|
57
|
+
if (curBuffIndex_ == bufferLength_) {
|
|
58
|
+
// Reset buffer index, channel buffers and execute worklet
|
|
59
|
+
curBuffIndex_ = 0;
|
|
60
|
+
workletRunner_->executeOnRuntimeGuardedSync(
|
|
61
|
+
[this, channelCount_](jsi::Runtime &uiRuntimeRaw) {
|
|
62
|
+
/// Arguments preparation
|
|
63
|
+
auto jsArray = jsi::Array(uiRuntimeRaw, channelCount_);
|
|
64
|
+
for (size_t ch = 0; ch < channelCount_; ch++) {
|
|
65
|
+
uint8_t *buffPtr = buffs_[ch];
|
|
66
|
+
buffs_[ch] = new uint8_t[buffRealLength_];
|
|
67
|
+
auto sharedAudioArray =
|
|
68
|
+
std::make_shared<AudioArrayBuffer>(buffPtr, buffRealLength_);
|
|
69
|
+
auto arrayBuffer =
|
|
70
|
+
jsi::ArrayBuffer(uiRuntimeRaw, std::move(sharedAudioArray));
|
|
71
|
+
jsArray.setValueAtIndex(uiRuntimeRaw, ch, std::move(arrayBuffer));
|
|
72
|
+
}
|
|
73
|
+
jsArray.setExternalMemoryPressure(
|
|
74
|
+
uiRuntimeRaw, channelCount_ * buffRealLength_);
|
|
75
|
+
|
|
76
|
+
workletRunner_->executeWorklet(
|
|
77
|
+
shareableWorklet_,
|
|
78
|
+
std::move(jsArray),
|
|
79
|
+
jsi::Value(uiRuntimeRaw, static_cast<int>(channelCount_)));
|
|
80
|
+
return jsi::Value::undefined();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#include <jsi/jsi.h>
|
|
5
|
+
#include <audioapi/core/utils/worklets/UiWorkletsRunner.h>
|
|
6
|
+
#include <audioapi/core/AudioNode.h>
|
|
7
|
+
#include <audioapi/core/BaseAudioContext.h>
|
|
8
|
+
#include <audioapi/utils/AudioBus.h>
|
|
9
|
+
#include <audioapi/utils/AudioArray.h>
|
|
10
|
+
#include <audioapi/jsi/AudioArrayBuffer.h>
|
|
11
|
+
|
|
12
|
+
#include <memory>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
namespace audioapi {
|
|
16
|
+
|
|
17
|
+
#if RN_AUDIO_API_TEST
|
|
18
|
+
class WorkletNode : public AudioNode {
|
|
19
|
+
public:
|
|
20
|
+
explicit WorkletNode(
|
|
21
|
+
BaseAudioContext *context,
|
|
22
|
+
std::shared_ptr<worklets::SerializableWorklet> &worklet,
|
|
23
|
+
size_t bufferLength,
|
|
24
|
+
size_t inputChannelCount
|
|
25
|
+
) : AudioNode(context) {}
|
|
26
|
+
~WorkletNode() override = default;
|
|
27
|
+
|
|
28
|
+
protected:
|
|
29
|
+
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override {}
|
|
30
|
+
};
|
|
31
|
+
#else
|
|
32
|
+
|
|
33
|
+
using namespace facebook;
|
|
34
|
+
|
|
35
|
+
class WorkletNode : public AudioNode {
|
|
36
|
+
public:
|
|
37
|
+
explicit WorkletNode(
|
|
38
|
+
BaseAudioContext *context,
|
|
39
|
+
std::shared_ptr<worklets::SerializableWorklet> &worklet,
|
|
40
|
+
size_t bufferLength,
|
|
41
|
+
size_t inputChannelCount
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
~WorkletNode() override;
|
|
45
|
+
|
|
46
|
+
protected:
|
|
47
|
+
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
private:
|
|
51
|
+
std::shared_ptr<UiWorkletsRunner> workletRunner_;
|
|
52
|
+
std::shared_ptr<worklets::SerializableWorklet> shareableWorklet_;
|
|
53
|
+
std::vector<uint8_t*> buffs_;
|
|
54
|
+
|
|
55
|
+
/// @brief Length of the byte buffer that will be passed to the AudioArrayBuffer
|
|
56
|
+
size_t buffRealLength_;
|
|
57
|
+
size_t bufferLength_;
|
|
58
|
+
size_t inputChannelCount_;
|
|
59
|
+
size_t curBuffIndex_;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
#endif // RN_AUDIO_API_TEST
|
|
63
|
+
|
|
64
|
+
} // namespace audioapi
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#include <audioapi/HostObjects/AudioBufferHostObject.h>
|
|
1
|
+
#include <audioapi/HostObjects/sources/AudioBufferHostObject.h>
|
|
2
2
|
#include <audioapi/core/inputs/AudioRecorder.h>
|
|
3
3
|
#include <audioapi/core/sources/AudioBuffer.h>
|
|
4
4
|
#include <audioapi/core/sources/RecorderAdapterNode.h>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#include <audioapi/core/AudioParam.h>
|
|
2
2
|
#include <audioapi/core/BaseAudioContext.h>
|
|
3
|
-
#include <audioapi/core/Constants.h>
|
|
4
3
|
#include <audioapi/core/sources/AudioBufferBaseSourceNode.h>
|
|
4
|
+
#include <audioapi/core/utils/Constants.h>
|
|
5
5
|
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
6
6
|
#include <audioapi/utils/AudioArray.h>
|
|
7
7
|
#include <audioapi/utils/AudioBus.h>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#include <audioapi/core/AudioParam.h>
|
|
2
2
|
#include <audioapi/core/BaseAudioContext.h>
|
|
3
|
-
#include <audioapi/core/Constants.h>
|
|
4
3
|
#include <audioapi/core/sources/AudioBufferQueueSourceNode.h>
|
|
4
|
+
#include <audioapi/core/utils/Constants.h>
|
|
5
5
|
#include <audioapi/core/utils/Locker.h>
|
|
6
6
|
#include <audioapi/dsp/AudioUtils.h>
|
|
7
7
|
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#include <audioapi/core/AudioParam.h>
|
|
2
2
|
#include <audioapi/core/BaseAudioContext.h>
|
|
3
|
-
#include <audioapi/core/Constants.h>
|
|
4
3
|
#include <audioapi/core/sources/AudioBufferSourceNode.h>
|
|
4
|
+
#include <audioapi/core/utils/Constants.h>
|
|
5
5
|
#include <audioapi/core/utils/Locker.h>
|
|
6
6
|
#include <audioapi/dsp/AudioUtils.h>
|
|
7
7
|
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
@@ -43,14 +43,6 @@ class StreamerNode : public AudioScheduledSourceNode {
|
|
|
43
43
|
bool initialize(const std::string& inputUrl);
|
|
44
44
|
void stop(double when) override;
|
|
45
45
|
|
|
46
|
-
private:
|
|
47
|
-
static constexpr int SIZE = 4'000'000; // 4MB
|
|
48
|
-
|
|
49
|
-
public:
|
|
50
|
-
static constexpr int getEstimatedSize() {
|
|
51
|
-
return StreamerNode::SIZE;
|
|
52
|
-
} // in bytes
|
|
53
|
-
|
|
54
46
|
protected:
|
|
55
47
|
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
56
48
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
|
|
5
|
+
#include <string>
|
|
6
|
+
#include <memory>
|
|
7
|
+
|
|
8
|
+
#ifdef __APPLE__
|
|
9
|
+
/// We cannot make any conditional logic inside podspec but it should automatically compile those files
|
|
10
|
+
/// they should be accessible if someone has react-native-worklets in node_modules
|
|
11
|
+
#if __has_include(<worklets/WorkletRuntime/WorkletRuntime.h>)
|
|
12
|
+
#define RN_AUDIO_API_ENABLE_WORKLETS 1
|
|
13
|
+
#else
|
|
14
|
+
#define RN_AUDIO_API_ENABLE_WORKLETS 0
|
|
15
|
+
#endif
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
#ifndef RN_AUDIO_API_TEST
|
|
19
|
+
#define RN_AUDIO_API_TEST 0
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
#if RN_AUDIO_API_ENABLE_WORKLETS
|
|
23
|
+
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
|
24
|
+
#include <worklets/SharedItems/Serializable.h>
|
|
25
|
+
#include <worklets/NativeModules/WorkletsModuleProxy.h>
|
|
26
|
+
#if ANDROID
|
|
27
|
+
#include <worklets/android/WorkletsModule.h>
|
|
28
|
+
#endif
|
|
29
|
+
#else
|
|
30
|
+
/// @brief Dummy implementation of worklets for non-worklet builds they should do nothing and mock necessary methods
|
|
31
|
+
/// @note It helps to reduce compile time branching across codebase
|
|
32
|
+
/// @note If you need to base some c++ implementation on if the worklets are enabled use `#if RN_AUDIO_API_ENABLE_WORKLETS`
|
|
33
|
+
namespace worklets {
|
|
34
|
+
|
|
35
|
+
using namespace facebook;
|
|
36
|
+
class MessageQueueThread {};
|
|
37
|
+
class WorkletsModuleProxy {};
|
|
38
|
+
class WorkletRuntime {
|
|
39
|
+
explicit WorkletRuntime(uint64_t, const std::shared_ptr<MessageQueueThread> &, const std::string &, const bool);
|
|
40
|
+
};
|
|
41
|
+
class SerializableWorklet {
|
|
42
|
+
SerializableWorklet(jsi::Runtime*, const jsi::Object &);
|
|
43
|
+
};
|
|
44
|
+
} // namespace worklets
|
|
45
|
+
#endif
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#include <audioapi/core/utils/worklets/UiWorkletsRunner.h>
|
|
2
|
+
|
|
3
|
+
namespace audioapi {
|
|
4
|
+
|
|
5
|
+
UiWorkletsRunner::UiWorkletsRunner(
|
|
6
|
+
std::weak_ptr<worklets::WorkletRuntime> weakUiRuntime) noexcept
|
|
7
|
+
: weakUiRuntime_(std::move(weakUiRuntime)) {}
|
|
8
|
+
|
|
9
|
+
}; // namespace audioapi
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
5
|
+
|
|
6
|
+
#include <functional>
|
|
7
|
+
#include <atomic>
|
|
8
|
+
#include <memory>
|
|
9
|
+
#include <utility>
|
|
10
|
+
#include <optional>
|
|
11
|
+
|
|
12
|
+
namespace audioapi {
|
|
13
|
+
using namespace facebook;
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* # How to extract worklet from JavaScript argument
|
|
17
|
+
*
|
|
18
|
+
* To extract a shareable worklet from a JavaScript argument, use the following code:
|
|
19
|
+
*
|
|
20
|
+
* ```cpp
|
|
21
|
+
* auto worklet = worklets::extractSerializableWorkletFromArg(runtime, args[0]);
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* This will return a shared pointer to the extracted worklet, or throw an error if the argument is invalid.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
class UiWorkletsRunner {
|
|
28
|
+
public:
|
|
29
|
+
explicit UiWorkletsRunner(std::weak_ptr<worklets::WorkletRuntime> weakUiRuntime) noexcept;
|
|
30
|
+
|
|
31
|
+
/// @brief Execute a job on the UI runtime safely.
|
|
32
|
+
/// @param job
|
|
33
|
+
/// @return nullopt if the runtime is not available or the result of the job execution
|
|
34
|
+
/// @note Execution is synchronous
|
|
35
|
+
std::optional<jsi::Value> executeOnRuntimeGuardedSync(const std::function<jsi::Value(jsi::Runtime&)>&& job) const noexcept(noexcept(job)) {
|
|
36
|
+
auto strongRuntime = weakUiRuntime_.lock();
|
|
37
|
+
if (strongRuntime == nullptr) {
|
|
38
|
+
return std::nullopt;
|
|
39
|
+
}
|
|
40
|
+
#if RN_AUDIO_API_ENABLE_WORKLETS
|
|
41
|
+
return strongRuntime->executeSync(std::move(job));
|
|
42
|
+
#else
|
|
43
|
+
return std::nullopt;
|
|
44
|
+
#endif
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// @brief Execute a worklet with the given arguments.
|
|
48
|
+
/// @tparam ...Args
|
|
49
|
+
/// @param shareableWorklet
|
|
50
|
+
/// @param ...args
|
|
51
|
+
/// @note Execution is synchronous, this method can be used in `executeOnRuntimeGuardedSync` and `...Async` methods arguments
|
|
52
|
+
/// @return nullopt if the runtime is not available or the result of the worklet execution
|
|
53
|
+
template<typename... Args>
|
|
54
|
+
std::optional<jsi::Value> executeWorklet(const std::shared_ptr<worklets::SerializableWorklet>& shareableWorklet, Args&&... args) {
|
|
55
|
+
auto strongRuntime = weakUiRuntime_.lock();
|
|
56
|
+
if (strongRuntime == nullptr) {
|
|
57
|
+
return std::nullopt;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
#if RN_AUDIO_API_ENABLE_WORKLETS
|
|
61
|
+
|
|
62
|
+
return strongRuntime->runGuarded(shareableWorklet, std::forward<Args>(args)...);
|
|
63
|
+
|
|
64
|
+
#else
|
|
65
|
+
return std::nullopt;
|
|
66
|
+
#endif
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private:
|
|
70
|
+
std::weak_ptr<worklets::WorkletRuntime> weakUiRuntime_;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
} // namespace audioapi
|
|
@@ -9,7 +9,20 @@ using namespace facebook;
|
|
|
9
9
|
class AudioArrayBuffer : public jsi::MutableBuffer {
|
|
10
10
|
public:
|
|
11
11
|
AudioArrayBuffer(uint8_t *data, size_t size): data_(data), size_(size) {}
|
|
12
|
-
~AudioArrayBuffer() override
|
|
12
|
+
~AudioArrayBuffer() override {
|
|
13
|
+
if (data_ == nullptr) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
delete[] data_;
|
|
17
|
+
}
|
|
18
|
+
AudioArrayBuffer(AudioArrayBuffer &&other) noexcept
|
|
19
|
+
: data_(other.data_), size_(other.size_) {
|
|
20
|
+
other.data_ = nullptr;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
AudioArrayBuffer(const AudioArrayBuffer &) = delete;
|
|
24
|
+
AudioArrayBuffer &operator=(const AudioArrayBuffer &) = delete;
|
|
25
|
+
AudioArrayBuffer &operator=(AudioArrayBuffer &&other) = delete;
|
|
13
26
|
|
|
14
27
|
[[nodiscard]] size_t size() const override;
|
|
15
28
|
uint8_t *data() override;
|