react-native-audio-api 0.8.3-nightly-d178688-20250925 → 0.8.3-nightly-2295d0d-20250926

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.
Files changed (136) hide show
  1. package/RNAudioAPI.podspec +8 -5
  2. package/android/build.gradle +44 -4
  3. package/android/src/main/cpp/audioapi/CMakeLists.txt +65 -0
  4. package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +29 -1
  5. package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +14 -0
  6. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +7 -1
  7. package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +6 -1
  8. package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +1 -1
  9. package/android/src/main/cpp/audioapi/android/core/NativeAudioRecorder.hpp +36 -0
  10. package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +11 -1
  11. package/android/src/main/java/com/swmansion/audioapi/core/NativeAudioRecorder.kt +24 -0
  12. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +15 -2
  13. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +31 -13
  14. package/common/cpp/audioapi/HostObjects/AudioContextHostObject.cpp +57 -0
  15. package/common/cpp/audioapi/HostObjects/AudioContextHostObject.h +6 -46
  16. package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.cpp +70 -6
  17. package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h +10 -66
  18. package/common/cpp/audioapi/HostObjects/AudioParamHostObject.cpp +105 -0
  19. package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +17 -91
  20. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +292 -6
  21. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +26 -242
  22. package/common/cpp/audioapi/HostObjects/OfflineAudioContextHostObject.cpp +70 -0
  23. package/common/cpp/audioapi/HostObjects/OfflineAudioContextHostObject.h +6 -50
  24. package/common/cpp/audioapi/HostObjects/WorkletNodeHostObject.h +18 -0
  25. package/common/cpp/audioapi/HostObjects/analysis/AnalyserNodeHostObject.cpp +148 -0
  26. package/common/cpp/audioapi/HostObjects/analysis/AnalyserNodeHostObject.h +37 -0
  27. package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.cpp +92 -0
  28. package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.h +29 -0
  29. package/common/cpp/audioapi/HostObjects/effects/GainNodeHostObject.cpp +20 -0
  30. package/common/cpp/audioapi/HostObjects/effects/GainNodeHostObject.h +19 -0
  31. package/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.cpp +21 -0
  32. package/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.h +21 -0
  33. package/common/cpp/audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.cpp +41 -0
  34. package/common/cpp/audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.h +28 -0
  35. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +69 -0
  36. package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +33 -0
  37. package/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.cpp +73 -0
  38. package/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.h +29 -0
  39. package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.cpp +94 -0
  40. package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.h +46 -0
  41. package/common/cpp/audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.cpp +60 -0
  42. package/common/cpp/audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.h +25 -0
  43. package/common/cpp/audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.cpp +133 -0
  44. package/common/cpp/audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.h +34 -0
  45. package/common/cpp/audioapi/HostObjects/sources/AudioScheduledSourceNodeHostObject.cpp +52 -0
  46. package/common/cpp/audioapi/HostObjects/sources/AudioScheduledSourceNodeHostObject.h +25 -0
  47. package/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.cpp +55 -0
  48. package/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.h +27 -0
  49. package/common/cpp/audioapi/HostObjects/{RecorderAdapterNodeHostObject.h → sources/RecorderAdapterNodeHostObject.h} +1 -2
  50. package/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.cpp +22 -0
  51. package/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.h +28 -0
  52. package/common/cpp/audioapi/core/AudioContext.cpp +3 -2
  53. package/common/cpp/audioapi/core/AudioContext.h +2 -1
  54. package/common/cpp/audioapi/core/AudioNode.h +1 -1
  55. package/common/cpp/audioapi/core/AudioParam.h +1 -1
  56. package/common/cpp/audioapi/core/BaseAudioContext.cpp +15 -1
  57. package/common/cpp/audioapi/core/BaseAudioContext.h +7 -3
  58. package/common/cpp/audioapi/core/OfflineAudioContext.cpp +4 -3
  59. package/common/cpp/audioapi/core/OfflineAudioContext.h +2 -1
  60. package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +1 -1
  61. package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +1 -1
  62. package/common/cpp/audioapi/core/effects/WorkletNode.cpp +86 -0
  63. package/common/cpp/audioapi/core/effects/WorkletNode.h +64 -0
  64. package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +1 -1
  65. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +2 -2
  66. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +1 -1
  67. package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +1 -1
  68. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +1 -1
  69. package/common/cpp/audioapi/core/sources/StreamerNode.h +0 -8
  70. package/common/cpp/audioapi/core/{AudioParamEventQueue.cpp → utils/AudioParamEventQueue.cpp} +1 -1
  71. package/common/cpp/audioapi/core/utils/worklets/SafeIncludes.h +45 -0
  72. package/common/cpp/audioapi/core/utils/worklets/UiWorkletsRunner.cpp +9 -0
  73. package/common/cpp/audioapi/core/utils/worklets/UiWorkletsRunner.h +73 -0
  74. package/common/cpp/audioapi/dsp/Windows.cpp +1 -1
  75. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +1 -1
  76. package/common/cpp/audioapi/jsi/AudioArrayBuffer.h +14 -1
  77. package/common/cpp/audioapi/jsi/JsiHostObject.h +6 -12
  78. package/common/cpp/audioapi/utils/AudioBus.cpp +1 -1
  79. package/common/cpp/test/CMakeLists.txt +8 -3
  80. package/common/cpp/test/GainTest.cpp +1 -1
  81. package/common/cpp/test/OscillatorTest.cpp +1 -1
  82. package/ios/audioapi/ios/AudioAPIModule.mm +32 -5
  83. package/ios/audioapi/ios/core/IOSAudioPlayer.mm +1 -1
  84. package/ios/audioapi/ios/core/IOSAudioRecorder.h +1 -2
  85. package/ios/audioapi/ios/core/IOSAudioRecorder.mm +1 -1
  86. package/lib/commonjs/api.js +7 -0
  87. package/lib/commonjs/api.js.map +1 -1
  88. package/lib/commonjs/core/BaseAudioContext.js +29 -0
  89. package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
  90. package/lib/commonjs/core/WorkletNode.js +11 -0
  91. package/lib/commonjs/core/WorkletNode.js.map +1 -0
  92. package/lib/commonjs/utils/index.js +9 -0
  93. package/lib/commonjs/utils/index.js.map +1 -1
  94. package/lib/module/api.js +1 -0
  95. package/lib/module/api.js.map +1 -1
  96. package/lib/module/core/BaseAudioContext.js +29 -0
  97. package/lib/module/core/BaseAudioContext.js.map +1 -1
  98. package/lib/module/core/WorkletNode.js +5 -0
  99. package/lib/module/core/WorkletNode.js.map +1 -0
  100. package/lib/module/utils/index.js +8 -0
  101. package/lib/module/utils/index.js.map +1 -1
  102. package/lib/typescript/api.d.ts +1 -0
  103. package/lib/typescript/api.d.ts.map +1 -1
  104. package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
  105. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  106. package/lib/typescript/core/WorkletNode.d.ts +4 -0
  107. package/lib/typescript/core/WorkletNode.d.ts.map +1 -0
  108. package/lib/typescript/interfaces.d.ts +3 -0
  109. package/lib/typescript/interfaces.d.ts.map +1 -1
  110. package/lib/typescript/utils/index.d.ts +2 -0
  111. package/lib/typescript/utils/index.d.ts.map +1 -1
  112. package/package.json +3 -2
  113. package/src/api.ts +1 -0
  114. package/src/core/BaseAudioContext.ts +51 -0
  115. package/src/core/WorkletNode.ts +3 -0
  116. package/src/interfaces.ts +7 -0
  117. package/src/utils/index.ts +10 -0
  118. package/common/cpp/audioapi/HostObjects/AnalyserNodeHostObject.h +0 -149
  119. package/common/cpp/audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h +0 -76
  120. package/common/cpp/audioapi/HostObjects/AudioBufferHostObject.h +0 -120
  121. package/common/cpp/audioapi/HostObjects/AudioBufferQueueSourceNodeHostObject.h +0 -67
  122. package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +0 -142
  123. package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +0 -86
  124. package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +0 -56
  125. package/common/cpp/audioapi/HostObjects/BiquadFilterNodeHostObject.h +0 -89
  126. package/common/cpp/audioapi/HostObjects/GainNodeHostObject.h +0 -27
  127. package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +0 -65
  128. package/common/cpp/audioapi/HostObjects/StereoPannerNodeHostObject.h +0 -29
  129. package/common/cpp/audioapi/HostObjects/StreamerNodeHostObject.h +0 -30
  130. package/common/cpp/audioapi/events/AudioEventHandlerRegistryHostObject.h +0 -48
  131. package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.h +0 -7
  132. package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.mm +0 -12
  133. /package/common/cpp/audioapi/HostObjects/{AudioDestinationNodeHostObject.h → destinations/AudioDestinationNodeHostObject.h} +0 -0
  134. /package/common/cpp/audioapi/HostObjects/{PeriodicWaveHostObject.h → effects/PeriodicWaveHostObject.h} +0 -0
  135. /package/common/cpp/audioapi/core/{AudioParamEventQueue.h → utils/AudioParamEventQueue.h} +0 -0
  136. /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
- : BaseAudioContext(audioEventHandlerRegistry) {
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();
@@ -2,7 +2,7 @@
2
2
 
3
3
  #include <audioapi/core/types/ChannelCountMode.h>
4
4
  #include <audioapi/core/types/ChannelInterpretation.h>
5
- #include <audioapi/core/Constants.h>
5
+ #include <audioapi/core/utils/Constants.h>
6
6
 
7
7
  #include <memory>
8
8
  #include <string>
@@ -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
- : BaseAudioContext(audioEventHandlerRegistry),
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;
@@ -1,6 +1,6 @@
1
1
  #include <audioapi/core/BaseAudioContext.h>
2
- #include <audioapi/core/Constants.h>
3
2
  #include <audioapi/core/effects/StereoPannerNode.h>
3
+ #include <audioapi/core/utils/Constants.h>
4
4
  #include <audioapi/utils/AudioArray.h>
5
5
  #include <audioapi/utils/AudioBus.h>
6
6
 
@@ -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,11 +1,11 @@
1
1
  #pragma once
2
2
 
3
-
4
3
  #include <memory>
5
- #include <mutex>
6
4
  #include <atomic>
5
+ #include <mutex>
7
6
 
8
7
  namespace audioapi {
8
+
9
9
  class RecorderAdapterNode;
10
10
  class AudioBus;
11
11
  class CircularAudioArray;
@@ -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
 
@@ -1,4 +1,4 @@
1
- #include <audioapi/core/AudioParamEventQueue.h>
1
+ #include <audioapi/core/utils/AudioParamEventQueue.h>
2
2
 
3
3
  namespace audioapi {
4
4
 
@@ -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
@@ -1,4 +1,4 @@
1
- #include <audioapi/core/Constants.h>
1
+ #include <audioapi/core/utils/Constants.h>
2
2
  #include <audioapi/dsp/Windows.h>
3
3
 
4
4
  namespace audioapi::dsp {
@@ -1,4 +1,4 @@
1
- #include <audioapi/HostObjects/AudioBufferHostObject.h>
1
+ #include <audioapi/HostObjects/sources/AudioBufferHostObject.h>
2
2
  #include <audioapi/events/AudioEventHandlerRegistry.h>
3
3
 
4
4
  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 = default;
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;