react-native-audio-api 0.1.0 → 0.3.0-rc1

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 (217) hide show
  1. package/README.md +10 -8
  2. package/RNAudioAPI.podspec +5 -0
  3. package/android/CMakeLists.txt +21 -10
  4. package/android/libs/fftw3/arm64-v8a/libfftw3.a +0 -0
  5. package/android/libs/fftw3/armeabi-v7a/libfftw3.a +0 -0
  6. package/android/libs/fftw3/x86/libfftw3.a +0 -0
  7. package/android/libs/fftw3/x86_64/libfftw3.a +0 -0
  8. package/android/libs/include/fftw3/fftw3.h +413 -0
  9. package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +32 -2
  10. package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +6 -2
  11. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +5 -3
  12. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +5 -1
  13. package/common/cpp/HostObjects/AudioBufferHostObject.cpp +6 -0
  14. package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +13 -1
  15. package/common/cpp/HostObjects/AudioContextHostObject.cpp +12 -149
  16. package/common/cpp/HostObjects/AudioContextHostObject.h +8 -14
  17. package/common/cpp/HostObjects/AudioNodeHostObject.cpp +0 -6
  18. package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +240 -0
  19. package/common/cpp/HostObjects/BaseAudioContextHostObject.h +41 -0
  20. package/common/cpp/HostObjects/BiquadFilterNodeHostObject.cpp +44 -0
  21. package/common/cpp/HostObjects/OscillatorNodeHostObject.cpp +21 -0
  22. package/common/cpp/HostObjects/OscillatorNodeHostObject.h +1 -0
  23. package/common/cpp/HostObjects/PeriodicWaveHostObject.cpp +33 -0
  24. package/common/cpp/HostObjects/PeriodicWaveHostObject.h +33 -0
  25. package/common/cpp/core/AudioArray.cpp +117 -0
  26. package/common/cpp/core/AudioArray.h +48 -0
  27. package/common/cpp/core/AudioBuffer.cpp +23 -80
  28. package/common/cpp/core/AudioBuffer.h +12 -13
  29. package/common/cpp/core/AudioBufferSourceNode.cpp +112 -25
  30. package/common/cpp/core/AudioBufferSourceNode.h +10 -6
  31. package/common/cpp/core/AudioBus.cpp +518 -0
  32. package/common/cpp/core/AudioBus.h +83 -0
  33. package/common/cpp/core/AudioContext.cpp +7 -77
  34. package/common/cpp/core/AudioContext.h +3 -60
  35. package/common/cpp/core/AudioDestinationNode.cpp +27 -15
  36. package/common/cpp/core/AudioDestinationNode.h +13 -5
  37. package/common/cpp/core/AudioNode.cpp +184 -22
  38. package/common/cpp/core/AudioNode.h +37 -37
  39. package/common/cpp/core/AudioNodeManager.cpp +75 -0
  40. package/common/cpp/core/AudioNodeManager.h +42 -0
  41. package/common/cpp/core/AudioParam.cpp +8 -11
  42. package/common/cpp/core/AudioParam.h +8 -8
  43. package/common/cpp/core/AudioScheduledSourceNode.cpp +19 -5
  44. package/common/cpp/core/AudioScheduledSourceNode.h +6 -2
  45. package/common/cpp/core/BaseAudioContext.cpp +191 -0
  46. package/common/cpp/core/BaseAudioContext.h +87 -0
  47. package/common/cpp/core/BiquadFilterNode.cpp +92 -69
  48. package/common/cpp/core/BiquadFilterNode.h +53 -57
  49. package/common/cpp/core/GainNode.cpp +12 -12
  50. package/common/cpp/core/GainNode.h +5 -3
  51. package/common/cpp/core/OscillatorNode.cpp +38 -29
  52. package/common/cpp/core/OscillatorNode.h +29 -69
  53. package/common/cpp/core/ParamChange.h +6 -6
  54. package/common/cpp/core/PeriodicWave.cpp +362 -0
  55. package/common/cpp/core/PeriodicWave.h +119 -0
  56. package/common/cpp/core/StereoPannerNode.cpp +31 -30
  57. package/common/cpp/core/StereoPannerNode.h +6 -6
  58. package/common/cpp/types/BiquadFilterType.h +19 -0
  59. package/common/cpp/types/ChannelCountMode.h +10 -0
  60. package/common/cpp/types/ChannelInterpretation.h +10 -0
  61. package/common/cpp/types/ContextState.h +10 -0
  62. package/common/cpp/types/OscillatorType.h +11 -0
  63. package/common/cpp/utils/FFTFrame.h +67 -0
  64. package/common/cpp/utils/JsiPromise.cpp +59 -0
  65. package/common/cpp/utils/JsiPromise.h +42 -0
  66. package/common/cpp/utils/Locker.h +49 -0
  67. package/common/cpp/utils/VectorMath.cpp +88 -3
  68. package/common/cpp/utils/VectorMath.h +7 -1
  69. package/common/cpp/utils/android/FFTFrame.cpp +23 -0
  70. package/common/cpp/utils/ios/FFTFrame.cpp +29 -0
  71. package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.cpp +10 -0
  72. package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.h +3 -2
  73. package/common/cpp/wrappers/AudioBufferWrapper.h +5 -5
  74. package/common/cpp/wrappers/AudioContextWrapper.cpp +7 -60
  75. package/common/cpp/wrappers/AudioContextWrapper.h +5 -26
  76. package/common/cpp/wrappers/AudioNodeWrapper.h +5 -5
  77. package/common/cpp/wrappers/AudioParamWrapper.h +4 -4
  78. package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +83 -0
  79. package/common/cpp/wrappers/BaseAudioContextWrapper.h +50 -0
  80. package/common/cpp/wrappers/BiquadFilterNodeWrapper.cpp +9 -0
  81. package/common/cpp/wrappers/BiquadFilterNodeWrapper.h +9 -4
  82. package/common/cpp/wrappers/GainNodeWrapper.h +1 -1
  83. package/common/cpp/wrappers/OscillatorNodeWrapper.cpp +6 -0
  84. package/common/cpp/wrappers/OscillatorNodeWrapper.h +5 -2
  85. package/common/cpp/wrappers/PeriodicWaveWrapper.h +17 -0
  86. package/common/cpp/wrappers/StereoPannerNodeWrapper.h +1 -1
  87. package/ios/AudioAPIModule.h +20 -1
  88. package/ios/AudioAPIModule.mm +6 -4
  89. package/ios/AudioDecoder/AudioDecoder.h +17 -0
  90. package/ios/AudioDecoder/AudioDecoder.m +167 -0
  91. package/ios/AudioDecoder/IOSAudioDecoder.h +26 -0
  92. package/ios/AudioDecoder/IOSAudioDecoder.mm +40 -0
  93. package/ios/AudioPlayer/AudioPlayer.h +3 -2
  94. package/ios/AudioPlayer/AudioPlayer.m +14 -17
  95. package/ios/AudioPlayer/IOSAudioPlayer.h +7 -3
  96. package/ios/AudioPlayer/IOSAudioPlayer.mm +31 -7
  97. package/lib/module/core/AudioBuffer.js +37 -0
  98. package/lib/module/core/AudioBuffer.js.map +1 -0
  99. package/lib/module/core/AudioBufferSourceNode.js +28 -0
  100. package/lib/module/core/AudioBufferSourceNode.js.map +1 -0
  101. package/lib/module/core/AudioContext.js +10 -0
  102. package/lib/module/core/AudioContext.js.map +1 -0
  103. package/lib/module/core/AudioDestinationNode.js +7 -0
  104. package/lib/module/core/AudioDestinationNode.js.map +1 -0
  105. package/lib/module/core/AudioNode.js +22 -0
  106. package/lib/module/core/AudioNode.js.map +1 -0
  107. package/lib/module/core/AudioParam.js +35 -0
  108. package/lib/module/core/AudioParam.js.map +1 -0
  109. package/lib/module/core/AudioScheduledSourceNode.js +28 -0
  110. package/lib/module/core/AudioScheduledSourceNode.js.map +1 -0
  111. package/lib/module/core/BaseAudioContext.js +62 -0
  112. package/lib/module/core/BaseAudioContext.js.map +1 -0
  113. package/lib/module/core/BiquadFilterNode.js +25 -0
  114. package/lib/module/core/BiquadFilterNode.js.map +1 -0
  115. package/lib/module/core/GainNode.js +9 -0
  116. package/lib/module/core/GainNode.js.map +1 -0
  117. package/lib/module/core/OscillatorNode.js +24 -0
  118. package/lib/module/core/OscillatorNode.js.map +1 -0
  119. package/lib/module/core/PeriodicWave.js +8 -0
  120. package/lib/module/core/PeriodicWave.js.map +1 -0
  121. package/lib/module/core/StereoPannerNode.js +9 -0
  122. package/lib/module/core/StereoPannerNode.js.map +1 -0
  123. package/lib/module/core/types.js.map +1 -0
  124. package/lib/module/errors/IndexSizeError.js +8 -0
  125. package/lib/module/errors/IndexSizeError.js.map +1 -0
  126. package/lib/module/errors/InvalidAccessError.js +8 -0
  127. package/lib/module/errors/InvalidAccessError.js.map +1 -0
  128. package/lib/module/errors/InvalidStateError.js +8 -0
  129. package/lib/module/errors/InvalidStateError.js.map +1 -0
  130. package/lib/module/errors/RangeError.js +8 -0
  131. package/lib/module/errors/RangeError.js.map +1 -0
  132. package/lib/module/errors/index.js +5 -0
  133. package/lib/module/errors/index.js.map +1 -0
  134. package/lib/module/index.js +212 -15
  135. package/lib/module/index.js.map +1 -1
  136. package/lib/module/index.native.js +18 -0
  137. package/lib/module/index.native.js.map +1 -0
  138. package/lib/module/interfaces.js +2 -0
  139. package/lib/module/interfaces.js.map +1 -0
  140. package/lib/module/utils/resolveAudioSource.js +10 -0
  141. package/lib/module/utils/resolveAudioSource.js.map +1 -0
  142. package/lib/typescript/core/AudioBuffer.d.ts +12 -0
  143. package/lib/typescript/core/AudioBuffer.d.ts.map +1 -0
  144. package/lib/typescript/core/AudioBufferSourceNode.d.ts +12 -0
  145. package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -0
  146. package/lib/typescript/core/AudioContext.d.ts +6 -0
  147. package/lib/typescript/core/AudioContext.d.ts.map +1 -0
  148. package/lib/typescript/core/AudioDestinationNode.d.ts +7 -0
  149. package/lib/typescript/core/AudioDestinationNode.d.ts.map +1 -0
  150. package/lib/typescript/core/AudioNode.d.ts +16 -0
  151. package/lib/typescript/core/AudioNode.d.ts.map +1 -0
  152. package/lib/typescript/core/AudioParam.d.ts +14 -0
  153. package/lib/typescript/core/AudioParam.d.ts.map +1 -0
  154. package/lib/typescript/core/AudioScheduledSourceNode.d.ts +10 -0
  155. package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -0
  156. package/lib/typescript/core/BaseAudioContext.d.ts +27 -0
  157. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -0
  158. package/lib/typescript/core/BiquadFilterNode.d.ts +16 -0
  159. package/lib/typescript/core/BiquadFilterNode.d.ts.map +1 -0
  160. package/lib/typescript/core/GainNode.d.ts +9 -0
  161. package/lib/typescript/core/GainNode.d.ts.map +1 -0
  162. package/lib/typescript/core/OscillatorNode.d.ts +15 -0
  163. package/lib/typescript/core/OscillatorNode.d.ts.map +1 -0
  164. package/lib/typescript/core/PeriodicWave.d.ts +5 -0
  165. package/lib/typescript/core/PeriodicWave.d.ts.map +1 -0
  166. package/lib/typescript/core/StereoPannerNode.d.ts +9 -0
  167. package/lib/typescript/core/StereoPannerNode.d.ts.map +1 -0
  168. package/lib/typescript/core/types.d.ts +15 -0
  169. package/lib/typescript/core/types.d.ts.map +1 -0
  170. package/lib/typescript/errors/IndexSizeError.d.ts +5 -0
  171. package/lib/typescript/errors/IndexSizeError.d.ts.map +1 -0
  172. package/lib/typescript/errors/InvalidAccessError.d.ts +5 -0
  173. package/lib/typescript/errors/InvalidAccessError.d.ts.map +1 -0
  174. package/lib/typescript/errors/InvalidStateError.d.ts +5 -0
  175. package/lib/typescript/errors/InvalidStateError.d.ts.map +1 -0
  176. package/lib/typescript/errors/RangeError.d.ts +5 -0
  177. package/lib/typescript/errors/RangeError.d.ts.map +1 -0
  178. package/lib/typescript/errors/index.d.ts +5 -0
  179. package/lib/typescript/errors/index.d.ts.map +1 -0
  180. package/lib/typescript/index.d.ts +88 -5
  181. package/lib/typescript/index.d.ts.map +1 -1
  182. package/lib/typescript/index.native.d.ts +14 -0
  183. package/lib/typescript/index.native.d.ts.map +1 -0
  184. package/lib/typescript/interfaces.d.ts +79 -0
  185. package/lib/typescript/interfaces.d.ts.map +1 -0
  186. package/lib/typescript/utils/resolveAudioSource.d.ts +3 -0
  187. package/lib/typescript/utils/resolveAudioSource.d.ts.map +1 -0
  188. package/package.json +4 -2
  189. package/src/core/AudioBuffer.ts +68 -0
  190. package/src/core/AudioBufferSourceNode.ts +35 -0
  191. package/src/core/AudioContext.ts +12 -0
  192. package/src/core/AudioDestinationNode.ts +9 -0
  193. package/src/core/AudioNode.ts +38 -0
  194. package/src/core/AudioParam.ts +55 -0
  195. package/src/core/AudioScheduledSourceNode.ts +43 -0
  196. package/src/core/BaseAudioContext.ts +108 -0
  197. package/src/core/BiquadFilterNode.ts +49 -0
  198. package/src/core/GainNode.ts +13 -0
  199. package/src/core/OscillatorNode.ts +37 -0
  200. package/src/core/PeriodicWave.ts +10 -0
  201. package/src/core/StereoPannerNode.ts +13 -0
  202. package/src/core/types.ts +33 -0
  203. package/src/errors/IndexSizeError.ts +8 -0
  204. package/src/errors/InvalidAccessError.ts +8 -0
  205. package/src/errors/InvalidStateError.ts +8 -0
  206. package/src/errors/RangeError.ts +8 -0
  207. package/src/errors/index.ts +4 -0
  208. package/src/index.native.ts +25 -0
  209. package/src/index.ts +380 -40
  210. package/src/interfaces.ts +121 -0
  211. package/src/modules/global.d.ts +3 -3
  212. package/src/utils/resolveAudioSource.ts +14 -0
  213. package/lib/module/types.js.map +0 -1
  214. package/lib/typescript/types.d.ts +0 -76
  215. package/lib/typescript/types.d.ts.map +0 -1
  216. package/src/types.ts +0 -108
  217. /package/lib/module/{types.js → core/types.js} +0 -0
@@ -0,0 +1,83 @@
1
+ #include "BaseAudioContextWrapper.h"
2
+
3
+ namespace audioapi {
4
+
5
+ BaseAudioContextWrapper::BaseAudioContextWrapper(
6
+ const std::shared_ptr<BaseAudioContext> &context)
7
+ : context_(context) {
8
+ auto destination = context_->getDestination();
9
+ destination_ = std::make_shared<AudioDestinationNodeWrapper>(destination);
10
+ }
11
+
12
+ std::shared_ptr<AudioDestinationNodeWrapper>
13
+ BaseAudioContextWrapper::getDestination() const {
14
+ return destination_;
15
+ }
16
+
17
+ std::string BaseAudioContextWrapper::getState() const {
18
+ return context_->getState();
19
+ }
20
+
21
+ int BaseAudioContextWrapper::getSampleRate() const {
22
+ return context_->getSampleRate();
23
+ }
24
+
25
+ double BaseAudioContextWrapper::getCurrentTime() const {
26
+ return context_->getCurrentTime();
27
+ }
28
+
29
+ std::shared_ptr<OscillatorNodeWrapper>
30
+ BaseAudioContextWrapper::createOscillator() const {
31
+ auto oscillator = context_->createOscillator();
32
+ return std::make_shared<OscillatorNodeWrapper>(oscillator);
33
+ }
34
+
35
+ std::shared_ptr<GainNodeWrapper> BaseAudioContextWrapper::createGain() const {
36
+ auto gain = context_->createGain();
37
+ return std::make_shared<GainNodeWrapper>(gain);
38
+ }
39
+
40
+ std::shared_ptr<StereoPannerNodeWrapper>
41
+ BaseAudioContextWrapper::createStereoPanner() const {
42
+ auto panner = context_->createStereoPanner();
43
+ return std::make_shared<StereoPannerNodeWrapper>(panner);
44
+ }
45
+
46
+ std::shared_ptr<BiquadFilterNodeWrapper>
47
+ BaseAudioContextWrapper::createBiquadFilter() const {
48
+ auto filter = context_->createBiquadFilter();
49
+ return std::make_shared<BiquadFilterNodeWrapper>(filter);
50
+ }
51
+
52
+ std::shared_ptr<AudioBufferSourceNodeWrapper>
53
+ BaseAudioContextWrapper::createBufferSource() const {
54
+ auto bufferSource = context_->createBufferSource();
55
+ return std::make_shared<AudioBufferSourceNodeWrapper>(bufferSource);
56
+ }
57
+
58
+ std::shared_ptr<AudioBufferWrapper> BaseAudioContextWrapper::createBuffer(
59
+ int numberOfChannels,
60
+ int length,
61
+ int sampleRate) const {
62
+ auto buffer = context_->createBuffer(numberOfChannels, length, sampleRate);
63
+ return std::make_shared<AudioBufferWrapper>(buffer);
64
+ }
65
+
66
+ std::shared_ptr<PeriodicWaveWrapper>
67
+ BaseAudioContextWrapper::createPeriodicWave(
68
+ float *real,
69
+ float *imag,
70
+ bool disableNormalization,
71
+ int length) {
72
+ auto periodicWave =
73
+ context_->createPeriodicWave(real, imag, disableNormalization, length);
74
+ return std::make_shared<PeriodicWaveWrapper>(periodicWave);
75
+ }
76
+
77
+ std::shared_ptr<AudioBufferWrapper>
78
+ BaseAudioContextWrapper::decodeAudioDataSource(const std::string &source) {
79
+ return std::make_shared<AudioBufferWrapper>(
80
+ context_->decodeAudioDataSource(source));
81
+ }
82
+
83
+ } // namespace audioapi
@@ -0,0 +1,50 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <string>
5
+ #include <utility>
6
+
7
+ #include "AudioBufferSourceNodeWrapper.h"
8
+ #include "AudioBufferWrapper.h"
9
+ #include "AudioDestinationNodeWrapper.h"
10
+ #include "BaseAudioContext.h"
11
+ #include "BiquadFilterNodeWrapper.h"
12
+ #include "GainNodeWrapper.h"
13
+ #include "OscillatorNodeWrapper.h"
14
+ #include "PeriodicWaveWrapper.h"
15
+ #include "StereoPannerNodeWrapper.h"
16
+
17
+ namespace audioapi {
18
+
19
+ class BaseAudioContextWrapper {
20
+ public:
21
+ explicit BaseAudioContextWrapper(
22
+ const std::shared_ptr<BaseAudioContext> &context);
23
+
24
+ [[nodiscard]] std::shared_ptr<AudioDestinationNodeWrapper> getDestination()
25
+ const;
26
+ [[nodiscard]] std::string getState() const;
27
+ [[nodiscard]] int getSampleRate() const;
28
+ [[nodiscard]] double getCurrentTime() const;
29
+ [[nodiscard]] std::shared_ptr<OscillatorNodeWrapper> createOscillator() const;
30
+ [[nodiscard]] std::shared_ptr<GainNodeWrapper> createGain() const;
31
+ [[nodiscard]] std::shared_ptr<StereoPannerNodeWrapper> createStereoPanner()
32
+ const;
33
+ [[nodiscard]] std::shared_ptr<BiquadFilterNodeWrapper> createBiquadFilter()
34
+ const;
35
+ [[nodiscard]] std::shared_ptr<AudioBufferSourceNodeWrapper>
36
+ createBufferSource() const;
37
+ [[nodiscard]] std::shared_ptr<AudioBufferWrapper>
38
+ createBuffer(int numberOfChannels, int length, int sampleRate) const;
39
+ [[nodiscard]] std::shared_ptr<PeriodicWaveWrapper> createPeriodicWave(
40
+ float *real,
41
+ float *imag,
42
+ bool disableNormalization,
43
+ int length);
44
+ std::shared_ptr<AudioBufferWrapper> decodeAudioDataSource(const std::string &source);
45
+
46
+ protected:
47
+ std::shared_ptr<AudioDestinationNodeWrapper> destination_;
48
+ std::shared_ptr<BaseAudioContext> context_;
49
+ };
50
+ } // namespace audioapi
@@ -48,4 +48,13 @@ void BiquadFilterNodeWrapper::setType(const std::string &filterType) {
48
48
  auto biquadFilterNode_ = getBiquadFilterNodeFromAudioNode();
49
49
  biquadFilterNode_->setType(filterType);
50
50
  }
51
+
52
+ void BiquadFilterNodeWrapper::getFrequencyResponse(
53
+ const std::vector<float> &frequencyArray,
54
+ std::vector<float> &magResponseOutput,
55
+ std::vector<float> &phaseResponseOutput) {
56
+ auto biquadFilterNode_ = getBiquadFilterNodeFromAudioNode();
57
+ biquadFilterNode_->getFrequencyResponse(
58
+ frequencyArray, magResponseOutput, phaseResponseOutput);
59
+ }
51
60
  } // namespace audioapi
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include <memory>
4
4
  #include <string>
5
+ #include <vector>
5
6
 
6
7
  #include "AudioNodeWrapper.h"
7
8
  #include "AudioParamWrapper.h"
@@ -14,12 +15,16 @@ class BiquadFilterNodeWrapper : public AudioNodeWrapper {
14
15
  explicit BiquadFilterNodeWrapper(
15
16
  const std::shared_ptr<BiquadFilterNode> &biquadFilterNode);
16
17
 
17
- std::shared_ptr<AudioParamWrapper> getFrequencyParam() const;
18
- std::shared_ptr<AudioParamWrapper> getDetuneParam() const;
19
- std::shared_ptr<AudioParamWrapper> getQParam() const;
20
- std::shared_ptr<AudioParamWrapper> getGainParam() const;
18
+ [[nodiscard]] std::shared_ptr<AudioParamWrapper> getFrequencyParam() const;
19
+ [[nodiscard]] std::shared_ptr<AudioParamWrapper> getDetuneParam() const;
20
+ [[nodiscard]] std::shared_ptr<AudioParamWrapper> getQParam() const;
21
+ [[nodiscard]] std::shared_ptr<AudioParamWrapper> getGainParam() const;
21
22
  std::string getType();
22
23
  void setType(const std::string &filterType);
24
+ void getFrequencyResponse(
25
+ const std::vector<float> &frequencyArray,
26
+ std::vector<float> &magResponseOutput,
27
+ std::vector<float> &phaseResponseOutput);
23
28
 
24
29
  private:
25
30
  std::shared_ptr<AudioParamWrapper> frequencyParam_;
@@ -12,7 +12,7 @@ class GainNodeWrapper : public AudioNodeWrapper {
12
12
  public:
13
13
  explicit GainNodeWrapper(const std::shared_ptr<GainNode> &gainNode);
14
14
 
15
- std::shared_ptr<AudioParamWrapper> getGainParam() const;
15
+ [[nodiscard]] std::shared_ptr<AudioParamWrapper> getGainParam() const;
16
16
 
17
17
  private:
18
18
  std::shared_ptr<AudioParamWrapper> gainParam_;
@@ -35,4 +35,10 @@ void OscillatorNodeWrapper::setType(const std::string &type) {
35
35
  auto oscillatorNode_ = getOscillatorNodeFromAudioNode();
36
36
  oscillatorNode_->setType(type);
37
37
  }
38
+
39
+ void OscillatorNodeWrapper::setPeriodicWave(
40
+ const std::shared_ptr<PeriodicWaveWrapper> &periodicWave) {
41
+ auto oscillatorNode_ = getOscillatorNodeFromAudioNode();
42
+ oscillatorNode_->setPeriodicWave(periodicWave->periodicWave_);
43
+ }
38
44
  } // namespace audioapi
@@ -6,6 +6,7 @@
6
6
  #include "AudioParamWrapper.h"
7
7
  #include "AudioScheduledSourceNodeWrapper.h"
8
8
  #include "OscillatorNode.h"
9
+ #include "PeriodicWaveWrapper.h"
9
10
 
10
11
  namespace audioapi {
11
12
 
@@ -14,10 +15,12 @@ class OscillatorNodeWrapper : public AudioScheduledSourceNodeWrapper {
14
15
  explicit OscillatorNodeWrapper(
15
16
  const std::shared_ptr<OscillatorNode> &oscillatorNode);
16
17
 
17
- std::shared_ptr<AudioParamWrapper> getFrequencyParam() const;
18
- std::shared_ptr<AudioParamWrapper> getDetuneParam() const;
18
+ [[nodiscard]] std::shared_ptr<AudioParamWrapper> getFrequencyParam() const;
19
+ [[nodiscard]] std::shared_ptr<AudioParamWrapper> getDetuneParam() const;
19
20
  std::string getType();
20
21
  void setType(const std::string &type);
22
+ void setPeriodicWave(
23
+ const std::shared_ptr<PeriodicWaveWrapper> &periodicWave);
21
24
 
22
25
  private:
23
26
  std::shared_ptr<AudioParamWrapper> frequencyParam_;
@@ -0,0 +1,17 @@
1
+ #pragma once
2
+
3
+ #include <memory>
4
+
5
+ #include "PeriodicWave.h"
6
+
7
+ namespace audioapi {
8
+
9
+ class PeriodicWaveWrapper {
10
+ public:
11
+ explicit PeriodicWaveWrapper(
12
+ const std::shared_ptr<PeriodicWave> &periodicWave)
13
+ : periodicWave_(periodicWave) {}
14
+
15
+ std::shared_ptr<PeriodicWave> periodicWave_;
16
+ };
17
+ } // namespace audioapi
@@ -13,7 +13,7 @@ class StereoPannerNodeWrapper : public AudioNodeWrapper {
13
13
  explicit StereoPannerNodeWrapper(
14
14
  const std::shared_ptr<StereoPannerNode> &stereoPannerNode);
15
15
 
16
- std::shared_ptr<AudioParamWrapper> getPanParam() const;
16
+ [[nodiscard]] std::shared_ptr<AudioParamWrapper> getPanParam() const;
17
17
 
18
18
  private:
19
19
  std::shared_ptr<AudioParamWrapper> panParam_;
@@ -1,5 +1,24 @@
1
+ #ifdef RCT_NEW_ARCH_ENABLED
2
+ #import <React/RCTInitializing.h>
3
+ #if REACT_NATIVE_MINOR_VERSION >= 74
4
+ #import <React/RCTRuntimeExecutorModule.h>
5
+ #import <ReactCommon/RCTRuntimeExecutor.h>
6
+ #endif // REACT_NATIVE_MINOR_VERSION >= 74
7
+ #else // RCT_NEW_ARCH_ENABLED
1
8
  #import <React/RCTBridgeModule.h>
9
+ #endif // RCT_NEW_ARCH_ENABLED
2
10
 
3
- @interface AudioAPIModule : NSObject <RCTBridgeModule>
11
+ #import <React/RCTEventEmitter.h>
4
12
 
13
+ @interface AudioAPIModule : RCTEventEmitter
14
+ #ifdef RCT_NEW_ARCH_ENABLED
15
+ <RCTInitializing
16
+ #if REACT_NATIVE_MINOR_VERSION >= 74
17
+ ,
18
+ RCTRuntimeExecutorModule
19
+ #endif // REACT_NATIVE_MINOR_VERSION >= 74
20
+ #else
21
+ <RCTBridgeModule
22
+ #endif // RCT_NEW_ARCH_ENABLED
23
+ >
5
24
  @end
@@ -1,11 +1,13 @@
1
1
  #import "AudioAPIModule.h"
2
2
 
3
+ #import <ReactCommon/RCTTurboModule.h>
3
4
  #import <React/RCTBridge+Private.h>
5
+ #import <React/RCTBridge.h>
4
6
  #import <React/RCTUtils.h>
5
7
  #import <jsi/jsi.h>
6
8
 
7
- #import "../common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h"
8
- #import "../common/cpp/AudioAPIInstaller/AudioAPIInstallerWrapper.h"
9
+ #import "AudioAPIInstallerHostObject.h"
10
+ #import "AudioAPIInstallerWrapper.h"
9
11
 
10
12
  @implementation AudioAPIModule
11
13
 
@@ -14,7 +16,7 @@ RCT_EXPORT_MODULE(AudioAPIModule)
14
16
  RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
15
17
  {
16
18
  NSLog(@"Installing JSI bindings for react-native-audio-api...");
17
- RCTCxxBridge *cxxBridge = (RCTCxxBridge *)[RCTBridge currentBridge];
19
+ RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
18
20
 
19
21
  if (cxxBridge == nil) {
20
22
  NSLog(@"Error during getting bridge!");
@@ -33,7 +35,7 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
33
35
  auto &runtime = *jsRuntime;
34
36
 
35
37
  auto wrapper = std::make_shared<audioapi::AudioAPIInstallerWrapper>();
36
- auto hostObject = std::make_shared<audioapi::AudioAPIInstallerHostObject>(wrapper);
38
+ auto hostObject = std::make_shared<audioapi::AudioAPIInstallerHostObject>(wrapper, jsRuntime, cxxBridge.jsCallInvoker);
37
39
  auto object = jsi::Object::createFromHostObject(runtime, hostObject);
38
40
  runtime.global().setProperty(runtime, "__AudioAPIInstaller", std::move(object));
39
41
 
@@ -0,0 +1,17 @@
1
+ #pragma once
2
+
3
+ #import <AVFoundation/AVFoundation.h>
4
+ #import <Foundation/Foundation.h>
5
+
6
+ @interface AudioDecoder : NSObject
7
+
8
+ @property (nonatomic, strong) AVAudioPCMBuffer *buffer;
9
+ @property (nonatomic, assign) int sampleRate;
10
+
11
+ - (instancetype)initWithSampleRate:(int)sampleRate;
12
+
13
+ - (const AudioBufferList *)decode:(NSString *)pathOrURL;
14
+
15
+ - (void)cleanup;
16
+
17
+ @end
@@ -0,0 +1,167 @@
1
+ #import <AudioDecoder.h>
2
+
3
+ @implementation AudioDecoder
4
+
5
+ - (instancetype)initWithSampleRate:(int)sampleRate
6
+ {
7
+ if (self = [super init]) {
8
+ self.sampleRate = sampleRate;
9
+ }
10
+ return self;
11
+ }
12
+
13
+ - (const AudioBufferList *)decode:(NSString *)pathOrURL
14
+ {
15
+ // check if the input is a URL or a local file path
16
+ NSURL *url = [NSURL URLWithString:pathOrURL];
17
+
18
+ if (url && url.scheme) {
19
+ self.buffer = [self decodeWithURL:url];
20
+ } else {
21
+ self.buffer = [self decodeWithFilePath:pathOrURL];
22
+ }
23
+
24
+ return self.buffer.audioBufferList;
25
+ }
26
+
27
+ - (AVAudioPCMBuffer *)decodeWithFilePath:(NSString *)path
28
+ {
29
+ NSError *error = nil;
30
+ NSURL *fileURL = [NSURL fileURLWithPath:path];
31
+ AVAudioFile *audioFile = [[AVAudioFile alloc] initForReading:fileURL error:&error];
32
+
33
+ if (error) {
34
+ NSLog(@"Error occurred while opening the audio file: %@", [error localizedDescription]);
35
+ return nil;
36
+ }
37
+ AVAudioPCMBuffer *buffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:[audioFile processingFormat]
38
+ frameCapacity:[audioFile length]];
39
+
40
+ AVAudioFormat *format = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32
41
+ sampleRate:self.sampleRate
42
+ channels:buffer.audioBufferList->mNumberBuffers
43
+ interleaved:NO];
44
+
45
+ [audioFile readIntoBuffer:buffer error:&error];
46
+ if (error) {
47
+ NSLog(@"Error occurred while reading the audio file: %@", [error localizedDescription]);
48
+ return nil;
49
+ }
50
+
51
+ if (self.sampleRate != audioFile.processingFormat.sampleRate) {
52
+ return [self convertBuffer:buffer ToFormat:format];
53
+ }
54
+
55
+ return buffer;
56
+ }
57
+
58
+ - (AVAudioPCMBuffer *)decodeWithURL:(NSURL *)url
59
+ {
60
+ __block NSURL *tempFileURL = nil;
61
+
62
+ dispatch_group_t group = dispatch_group_create();
63
+
64
+ dispatch_group_enter(group);
65
+
66
+ [self downloadFileFromURL:url
67
+ completion:^(NSURL *downloadedFileURL, NSError *downloadError) {
68
+ if (downloadError) {
69
+ NSLog(@"Error downloading file: %@", downloadError.localizedDescription);
70
+ tempFileURL = nil;
71
+ } else {
72
+ tempFileURL = downloadedFileURL;
73
+ }
74
+
75
+ dispatch_group_leave(group);
76
+ }];
77
+
78
+ dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
79
+
80
+ if (!tempFileURL) {
81
+ NSLog(@"Cannot process given url");
82
+ return nil;
83
+ }
84
+
85
+ return [self decodeWithFilePath:tempFileURL.path];
86
+ }
87
+
88
+ - (void)downloadFileFromURL:(NSURL *)url completion:(void (^)(NSURL *tempFileURL, NSError *error))completion
89
+ {
90
+ // get unique file path in temporary dir
91
+ NSString *tempDirectory = NSTemporaryDirectory();
92
+ NSString *timestamp = [NSString stringWithFormat:@"_%@", @((long long)[[NSDate date] timeIntervalSince1970])];
93
+ NSString *fileNameWithTimestamp = [url.lastPathComponent stringByDeletingPathExtension];
94
+ fileNameWithTimestamp = [fileNameWithTimestamp stringByAppendingString:timestamp];
95
+ NSString *fileExtension =
96
+ [url.pathExtension length] > 0 ? [NSString stringWithFormat:@".%@", url.pathExtension] : @"";
97
+ NSString *tempFilePath =
98
+ [tempDirectory stringByAppendingPathComponent:[fileNameWithTimestamp stringByAppendingString:fileExtension]];
99
+ NSURL *tempFileURL = [NSURL fileURLWithPath:tempFilePath];
100
+
101
+ // download file
102
+ NSURLSession *session = [NSURLSession sharedSession];
103
+ NSURLSessionDownloadTask *downloadTask = [session
104
+ downloadTaskWithURL:url
105
+ completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
106
+ if (error) {
107
+ NSLog(@"Error downloading file: %@", error.localizedDescription);
108
+ if (completion) {
109
+ completion(nil, error);
110
+ }
111
+ return;
112
+ }
113
+
114
+ // move to generated file path in temporary dir
115
+ NSError *fileError = nil;
116
+ BOOL success = [[NSFileManager defaultManager] moveItemAtURL:location toURL:tempFileURL error:&fileError];
117
+ if (success) {
118
+ NSLog(@"File downloaded successfully to %@", tempFileURL.path);
119
+ if (completion) {
120
+ completion(tempFileURL, nil);
121
+ }
122
+ } else {
123
+ NSLog(@"Error moving downloaded file: %@", fileError.localizedDescription);
124
+ if (completion) {
125
+ completion(nil, fileError);
126
+ }
127
+ }
128
+ }];
129
+
130
+ [downloadTask resume];
131
+ }
132
+
133
+ - (AVAudioPCMBuffer *)convertBuffer:(AVAudioPCMBuffer *)buffer ToFormat:(AVAudioFormat *)format
134
+ {
135
+ NSError *error = nil;
136
+ AVAudioConverter *converter = [[AVAudioConverter alloc] initFromFormat:buffer.format toFormat:format];
137
+ AVAudioPCMBuffer *convertedBuffer =
138
+ [[AVAudioPCMBuffer alloc] initWithPCMFormat:format frameCapacity:(AVAudioFrameCount)buffer.frameCapacity];
139
+
140
+ AVAudioConverterInputBlock inputBlock =
141
+ ^AVAudioBuffer *(AVAudioPacketCount inNumberOfPackets, AVAudioConverterInputStatus *outStatus)
142
+ {
143
+ if (buffer.frameLength > 0) {
144
+ *outStatus = AVAudioConverterInputStatus_HaveData;
145
+ return buffer;
146
+ } else {
147
+ *outStatus = AVAudioConverterInputStatus_NoDataNow;
148
+ return nil;
149
+ }
150
+ };
151
+
152
+ [converter convertToBuffer:convertedBuffer error:&error withInputFromBlock:inputBlock];
153
+
154
+ if (error) {
155
+ NSLog(@"Error occurred while converting the audio file: %@", [error localizedDescription]);
156
+ return nil;
157
+ }
158
+
159
+ return convertedBuffer;
160
+ }
161
+
162
+ - (void)cleanup
163
+ {
164
+ self.buffer = nil;
165
+ }
166
+
167
+ @end
@@ -0,0 +1,26 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ #ifdef __OBJC__ // when compiled as Objective-C++
6
+ #import <AudioDecoder.h>
7
+ #else // when compiled as C++
8
+ typedef struct objc_object AudioDecoder;
9
+ #endif // __OBJC__
10
+
11
+ namespace audioapi {
12
+
13
+ class AudioBus;
14
+
15
+ class IOSAudioDecoder {
16
+ protected:
17
+ AudioDecoder *audioDecoder_;
18
+ int sampleRate_;
19
+
20
+ public:
21
+ IOSAudioDecoder(int sampleRate);
22
+ ~IOSAudioDecoder();
23
+
24
+ AudioBus *decodeWithFilePath(const std::string &path);
25
+ };
26
+ } // namespace audioapi
@@ -0,0 +1,40 @@
1
+ #import <AVFoundation/AVFoundation.h>
2
+
3
+ #include <AudioArray.h>
4
+ #include <AudioBus.h>
5
+ #include <IOSAudioDecoder.h>
6
+
7
+ namespace audioapi {
8
+
9
+ IOSAudioDecoder::IOSAudioDecoder(int sampleRate) : sampleRate_(sampleRate)
10
+ {
11
+ audioDecoder_ = [[AudioDecoder alloc] initWithSampleRate:sampleRate_];
12
+ }
13
+
14
+ IOSAudioDecoder::~IOSAudioDecoder()
15
+ {
16
+ [audioDecoder_ cleanup];
17
+ audioDecoder_ = nullptr;
18
+ }
19
+
20
+ AudioBus *IOSAudioDecoder::decodeWithFilePath(const std::string &path)
21
+ {
22
+ auto bufferList = [audioDecoder_ decode:[NSString stringWithUTF8String:path.c_str()]];
23
+ AudioBus *audioBus;
24
+ if (bufferList) {
25
+ auto numberOfChannels = bufferList->mNumberBuffers;
26
+ auto size = bufferList->mBuffers[0].mDataByteSize / sizeof(float);
27
+
28
+ audioBus = new AudioBus(sampleRate_, size, numberOfChannels);
29
+
30
+ for (int i = 0; i < numberOfChannels; i++) {
31
+ float *data = (float *)bufferList->mBuffers[i].mData;
32
+ memcpy(audioBus->getChannel(i)->getData(), data, sizeof(float) * size);
33
+ }
34
+ } else {
35
+ audioBus = new AudioBus(sampleRate_, 1, 1);
36
+ }
37
+
38
+ return audioBus;
39
+ }
40
+ } // namespace audioapi
@@ -3,7 +3,7 @@
3
3
  #import <AVFoundation/AVFoundation.h>
4
4
  #import <Foundation/Foundation.h>
5
5
 
6
- typedef void (^RenderAudioBlock)(float *audioData, int numFrames);
6
+ typedef void (^RenderAudioBlock)(AudioBufferList *outputBuffer, int numFrames);
7
7
 
8
8
  @interface AudioPlayer : NSObject
9
9
 
@@ -12,12 +12,13 @@ typedef void (^RenderAudioBlock)(float *audioData, int numFrames);
12
12
  @property (nonatomic, strong) AVAudioFormat *format;
13
13
  @property (nonatomic, strong) AVAudioSourceNode *sourceNode;
14
14
  @property (nonatomic, copy) RenderAudioBlock renderAudio;
15
- @property (nonatomic, assign) float *buffer;
16
15
 
17
16
  - (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio;
18
17
 
19
18
  - (int)getSampleRate;
20
19
 
20
+ - (int)getBufferSizeInFrames;
21
+
21
22
  - (void)start;
22
23
 
23
24
  - (void)stop;
@@ -42,8 +42,6 @@
42
42
  frameCount:frameCount
43
43
  outputData:outputData];
44
44
  }];
45
-
46
- self.buffer = nil;
47
45
  }
48
46
 
49
47
  return self;
@@ -54,6 +52,19 @@
54
52
  return [self.audioSession sampleRate];
55
53
  }
56
54
 
55
+ - (int)getBufferSizeInFrames
56
+ {
57
+ // Note: might be important in the future.
58
+ // For some reason audioSession.IOBufferDuration is always 0.01, which for sample rate of 48k
59
+ // gives exactly 480 frames, while at the same time frameCount requested by AVAudioSourceEngine
60
+ // might vary f.e. between 555-560.
61
+ // preferredIOBufferDuration seems to be double the value (resulting in 960 frames),
62
+ // which is safer to base our internal AudioBus sizes.
63
+ // Buut no documentation => no guarantee :)
64
+ // If something is crackling when it should play silence, start here 📻
65
+ return (int)(self.audioSession.preferredIOBufferDuration * self.audioSession.sampleRate);
66
+ }
67
+
57
68
  - (void)start
58
69
  {
59
70
  [self.audioEngine attachNode:self.sourceNode];
@@ -88,8 +99,6 @@
88
99
  self.audioEngine = nil;
89
100
  self.audioSession = nil;
90
101
  self.renderAudio = nil;
91
-
92
- free(_buffer);
93
102
  }
94
103
 
95
104
  - (OSStatus)renderCallbackWithIsSilence:(BOOL *)isSilence
@@ -101,19 +110,7 @@
101
110
  return noErr; // Ensure we have stereo output
102
111
  }
103
112
 
104
- if (!self.buffer) {
105
- self.buffer = malloc(frameCount * 2 * sizeof(float));
106
- }
107
-
108
- float *leftBuffer = (float *)outputData->mBuffers[0].mData;
109
- float *rightBuffer = (float *)outputData->mBuffers[1].mData;
110
-
111
- self.renderAudio(self.buffer, frameCount);
112
-
113
- for (int frame = 0; frame < frameCount; frame += 1) {
114
- leftBuffer[frame] = self.buffer[frame * 2];
115
- rightBuffer[frame] = self.buffer[frame * 2 + 1];
116
- }
113
+ self.renderAudio(outputData, frameCount);
117
114
 
118
115
  return noErr;
119
116
  }
@@ -11,19 +11,23 @@ typedef struct objc_object AudioPlayer;
11
11
  namespace audioapi {
12
12
 
13
13
  class AudioContext;
14
+ class AudioBus;
14
15
 
15
16
  class IOSAudioPlayer {
16
17
  protected:
18
+ AudioBus *audioBus_;
17
19
  AudioPlayer *audioPlayer_;
18
- std::function<void(float *, int)> renderAudio_;
20
+ std::function<void(AudioBus *, int)> renderAudio_;
19
21
 
20
22
  public:
21
- explicit IOSAudioPlayer(const std::function<void(float *, int)> &renderAudio);
23
+ explicit IOSAudioPlayer(
24
+ const std::function<void(AudioBus *, int)> &renderAudio);
22
25
  ~IOSAudioPlayer();
23
26
 
24
27
  int getSampleRate() const;
28
+ int getBufferSizeInFrames() const;
29
+
25
30
  void start();
26
31
  void stop();
27
- void renderAudio(float *audioData, int32_t numFrames);
28
32
  };
29
33
  } // namespace audioapi