react-native-audio-api 0.2.0 → 0.3.0-rc2

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 (84) hide show
  1. package/android/CMakeLists.txt +2 -2
  2. package/android/build.gradle +1 -3
  3. package/android/libs/include/miniaudio.h +92621 -0
  4. package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.cpp +8 -4
  5. package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.h +16 -7
  6. package/android/src/main/cpp/AudioDecoder/AudioDecoder.cpp +64 -0
  7. package/android/src/main/cpp/AudioDecoder/AudioDecoder.h +21 -0
  8. package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +16 -7
  9. package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +5 -4
  10. package/android/src/main/java/com/swmansion/audioapi/module/AudioAPIInstaller.kt +14 -4
  11. package/android/src/main/java/com/swmansion/audioapi/nativemodules/AudioAPIModule.kt +2 -3
  12. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +9 -3
  13. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +13 -7
  14. package/common/cpp/HostObjects/AudioBufferHostObject.cpp +7 -0
  15. package/common/cpp/HostObjects/AudioContextHostObject.cpp +3 -2
  16. package/common/cpp/HostObjects/AudioContextHostObject.h +6 -3
  17. package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +38 -2
  18. package/common/cpp/HostObjects/BaseAudioContextHostObject.h +4 -1
  19. package/common/cpp/core/AudioArray.cpp +28 -14
  20. package/common/cpp/core/AudioArray.h +20 -14
  21. package/common/cpp/core/AudioBuffer.cpp +14 -11
  22. package/common/cpp/core/AudioBuffer.h +1 -0
  23. package/common/cpp/core/AudioBufferSourceNode.cpp +29 -19
  24. package/common/cpp/core/AudioBufferSourceNode.h +1 -1
  25. package/common/cpp/core/AudioBus.cpp +276 -115
  26. package/common/cpp/core/AudioBus.h +29 -9
  27. package/common/cpp/core/AudioContext.cpp +5 -9
  28. package/common/cpp/core/AudioDestinationNode.cpp +11 -8
  29. package/common/cpp/core/AudioDestinationNode.h +4 -4
  30. package/common/cpp/core/AudioNode.cpp +25 -17
  31. package/common/cpp/core/AudioNode.h +5 -5
  32. package/common/cpp/core/AudioNodeManager.cpp +10 -7
  33. package/common/cpp/core/AudioNodeManager.h +11 -4
  34. package/common/cpp/core/AudioScheduledSourceNode.cpp +2 -2
  35. package/common/cpp/core/BaseAudioContext.cpp +49 -12
  36. package/common/cpp/core/BaseAudioContext.h +16 -7
  37. package/common/cpp/core/BiquadFilterNode.cpp +5 -3
  38. package/common/cpp/core/GainNode.cpp +1 -1
  39. package/common/cpp/core/OscillatorNode.cpp +4 -4
  40. package/common/cpp/core/OscillatorNode.h +2 -2
  41. package/common/cpp/core/StereoPannerNode.cpp +10 -7
  42. package/common/cpp/core/StereoPannerNode.h +1 -1
  43. package/common/cpp/utils/FFTFrame.h +5 -1
  44. package/common/cpp/utils/JsiPromise.cpp +64 -0
  45. package/common/cpp/utils/JsiPromise.h +48 -0
  46. package/common/cpp/utils/Locker.h +8 -6
  47. package/common/cpp/utils/VectorMath.cpp +71 -55
  48. package/common/cpp/utils/android/FFTFrame.cpp +12 -11
  49. package/common/cpp/utils/ios/FFTFrame.cpp +6 -1
  50. package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +7 -0
  51. package/common/cpp/wrappers/BaseAudioContextWrapper.h +2 -0
  52. package/ios/AudioAPIModule.mm +4 -1
  53. package/ios/AudioDecoder/AudioDecoder.h +17 -0
  54. package/ios/AudioDecoder/AudioDecoder.m +80 -0
  55. package/ios/AudioDecoder/IOSAudioDecoder.h +28 -0
  56. package/ios/AudioDecoder/IOSAudioDecoder.mm +46 -0
  57. package/ios/AudioPlayer/AudioPlayer.h +1 -1
  58. package/ios/AudioPlayer/AudioPlayer.m +2 -2
  59. package/ios/AudioPlayer/IOSAudioPlayer.h +5 -5
  60. package/ios/AudioPlayer/IOSAudioPlayer.mm +4 -3
  61. package/lib/module/core/BaseAudioContext.js +4 -0
  62. package/lib/module/core/BaseAudioContext.js.map +1 -1
  63. package/lib/module/index.js +232 -17
  64. package/lib/module/index.js.map +1 -1
  65. package/lib/module/index.native.js +18 -0
  66. package/lib/module/index.native.js.map +1 -0
  67. package/lib/typescript/core/BaseAudioContext.d.ts +1 -0
  68. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  69. package/lib/typescript/index.d.ts +100 -13
  70. package/lib/typescript/index.d.ts.map +1 -1
  71. package/lib/typescript/index.native.d.ts +14 -0
  72. package/lib/typescript/index.native.d.ts.map +1 -0
  73. package/lib/typescript/interfaces.d.ts +1 -0
  74. package/lib/typescript/interfaces.d.ts.map +1 -1
  75. package/package.json +4 -2
  76. package/src/core/BaseAudioContext.ts +6 -0
  77. package/src/index.native.ts +25 -0
  78. package/src/index.ts +403 -19
  79. package/src/interfaces.ts +1 -0
  80. package/android/libs/fftw3/x86/libfftw3.a +0 -0
  81. package/android/libs/fftw3/x86_64/libfftw3.a +0 -0
  82. /package/android/libs/{fftw3/arm64-v8a → arm64-v8a}/libfftw3.a +0 -0
  83. /package/android/libs/{fftw3/armeabi-v7a → armeabi-v7a}/libfftw3.a +0 -0
  84. /package/android/libs/include/{fftw3/fftw3.h → fftw3.h} +0 -0
@@ -5,14 +5,18 @@ namespace audioapi {
5
5
  using namespace facebook::jni;
6
6
 
7
7
  AudioAPIInstaller::AudioAPIInstaller(
8
- jni::alias_ref<AudioAPIInstaller::jhybridobject> &jThis)
9
- : javaPart_(make_global(jThis)) {}
8
+ jni::alias_ref<AudioAPIInstaller::jhybridobject> &jThis,
9
+ jsi::Runtime *rnRuntime,
10
+ const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker)
11
+ : javaPart_(make_global(jThis)),
12
+ rnRuntime_(rnRuntime),
13
+ jsCallInvoker_(jsCallInvoker) {}
10
14
 
11
- void AudioAPIInstaller::install(jlong jsContext) {
15
+ void AudioAPIInstaller::install() {
12
16
  auto audioAPIInstallerWrapper =
13
17
  std::make_shared<AudioAPIInstallerWrapper>(this);
14
18
  AudioAPIInstallerHostObject::createAndInstallFromWrapper(
15
- audioAPIInstallerWrapper, jsContext);
19
+ audioAPIInstallerWrapper, rnRuntime_, jsCallInvoker_);
16
20
  }
17
21
 
18
22
  std::shared_ptr<AudioContext> AudioAPIInstaller::createAudioContext() {
@@ -1,7 +1,7 @@
1
1
  #pragma once
2
2
 
3
+ #include <ReactCommon/CallInvokerHolder.h>
3
4
  #include <fbjni/fbjni.h>
4
- #include <jsi/jsi.h>
5
5
  #include <react/jni/CxxModuleWrapper.h>
6
6
  #include <react/jni/JMessageQueueThread.h>
7
7
  #include <memory>
@@ -14,7 +14,7 @@
14
14
  namespace audioapi {
15
15
 
16
16
  using namespace facebook;
17
- using namespace facebook::jni;
17
+ using namespace react;
18
18
 
19
19
  class AudioAPIInstaller : public jni::HybridClass<AudioAPIInstaller> {
20
20
  public:
@@ -22,8 +22,13 @@ class AudioAPIInstaller : public jni::HybridClass<AudioAPIInstaller> {
22
22
  "Lcom/swmansion/audioapi/module/AudioAPIInstaller;";
23
23
 
24
24
  static jni::local_ref<AudioAPIInstaller::jhybriddata> initHybrid(
25
- jni::alias_ref<jhybridobject> jThis) {
26
- return makeCxxInstance(jThis);
25
+ jni::alias_ref<jhybridobject> jThis,
26
+ jlong jsContext,
27
+ jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
28
+ jsCallInvokerHolder) {
29
+ auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker();
30
+ auto rnRuntime = reinterpret_cast<jsi::Runtime *>(jsContext);
31
+ return makeCxxInstance(jThis, rnRuntime, jsCallInvoker);
27
32
  }
28
33
 
29
34
  static void registerNatives() {
@@ -34,15 +39,19 @@ class AudioAPIInstaller : public jni::HybridClass<AudioAPIInstaller> {
34
39
  }
35
40
 
36
41
  std::shared_ptr<AudioContext> createAudioContext();
37
- void install(jlong jsContext);
42
+ void install();
38
43
 
39
44
  private:
40
45
  friend HybridBase;
41
46
 
42
- global_ref<AudioAPIInstaller::javaobject> javaPart_;
47
+ jni::global_ref<AudioAPIInstaller::javaobject> javaPart_;
48
+ jsi::Runtime *rnRuntime_;
49
+ std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker_;
43
50
 
44
51
  explicit AudioAPIInstaller(
45
- jni::alias_ref<AudioAPIInstaller::jhybridobject> &jThis);
52
+ jni::alias_ref<AudioAPIInstaller::jhybridobject> &jThis,
53
+ jsi::Runtime *rnRuntime,
54
+ const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker);
46
55
  };
47
56
 
48
57
  } // namespace audioapi
@@ -0,0 +1,64 @@
1
+ #include "AudioDecoder.h"
2
+
3
+ #define MINIAUDIO_IMPLEMENTATION
4
+ #include <android/log.h>
5
+ #include <miniaudio.h>
6
+
7
+ #include "AudioArray.h"
8
+ #include "AudioBus.h"
9
+
10
+ namespace audioapi {
11
+
12
+ AudioDecoder::AudioDecoder(int sampleRate) : sampleRate_(sampleRate) {}
13
+
14
+ AudioBus *AudioDecoder::decodeWithFilePath(const std::string &path) const {
15
+ ma_decoder decoder;
16
+ ma_decoder_config config =
17
+ ma_decoder_config_init(ma_format_f32, 2, sampleRate_);
18
+ ma_result result = ma_decoder_init_file(path.c_str(), &config, &decoder);
19
+ if (result != MA_SUCCESS) {
20
+ __android_log_print(
21
+ ANDROID_LOG_ERROR,
22
+ "AudioDecoder",
23
+ "Failed to initialize decoder for file: %s",
24
+ path.c_str());
25
+ return new AudioBus(1, 1, 1);
26
+ }
27
+
28
+ ma_uint64 totalFrameCount;
29
+ ma_decoder_get_length_in_pcm_frames(&decoder, &totalFrameCount);
30
+
31
+ auto *audioBus =
32
+ new AudioBus(sampleRate_, static_cast<int>(totalFrameCount), 2);
33
+ auto *buffer = new float[totalFrameCount * 2];
34
+
35
+ ma_uint64 framesDecoded;
36
+ ma_decoder_read_pcm_frames(&decoder, buffer, totalFrameCount, &framesDecoded);
37
+ if (framesDecoded == 0) {
38
+ __android_log_print(
39
+ ANDROID_LOG_ERROR,
40
+ "AudioDecoder",
41
+ "Failed to decode audio file: %s",
42
+ path.c_str());
43
+ }
44
+
45
+ for (int i = 0; i < decoder.outputChannels; ++i) {
46
+ float *channelData = audioBus->getChannel(i)->getData();
47
+
48
+ for (ma_uint64 j = 0; j < framesDecoded; ++j) {
49
+ channelData[j] = buffer[j * decoder.outputChannels + i];
50
+ }
51
+ }
52
+
53
+ delete[] buffer;
54
+ ma_decoder_uninit(&decoder);
55
+
56
+ return audioBus;
57
+ }
58
+
59
+ AudioBus *AudioDecoder::decodeWithArrayBuffer() const {
60
+ // TODO: implement this
61
+ return new AudioBus(1, 1, 1);
62
+ }
63
+
64
+ } // namespace audioapi
@@ -0,0 +1,21 @@
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ namespace audioapi {
6
+
7
+ class AudioBus;
8
+
9
+ class AudioDecoder {
10
+ public:
11
+ explicit AudioDecoder(int sampleRate);
12
+
13
+ [[nodiscard]] AudioBus *decodeWithFilePath(const std::string &path) const;
14
+ // TODO: implement this
15
+ [[nodiscard]] AudioBus *decodeWithArrayBuffer() const;
16
+
17
+ private:
18
+ int sampleRate_;
19
+ };
20
+
21
+ } // namespace audioapi
@@ -1,13 +1,14 @@
1
1
 
2
- #include "AudioBus.h"
3
- #include "Constants.h"
4
- #include "AudioArray.h"
5
2
  #include "AudioPlayer.h"
3
+ #include "AudioArray.h"
4
+ #include "AudioBus.h"
6
5
  #include "AudioContext.h"
6
+ #include "Constants.h"
7
7
 
8
8
  namespace audioapi {
9
9
 
10
- AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
10
+ AudioPlayer::AudioPlayer(
11
+ const std::function<void(AudioBus *, int)> &renderAudio)
11
12
  : renderAudio_(renderAudio) {
12
13
  AudioStreamBuilder builder;
13
14
 
@@ -20,7 +21,9 @@ AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
20
21
  ->setDataCallback(this)
21
22
  ->openStream(mStream_);
22
23
 
23
- mBus_ = std::make_shared<AudioBus>(getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
24
+ mBus_ = std::make_shared<AudioBus>(
25
+ getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
26
+ isInitialized_ = true;
24
27
  }
25
28
 
26
29
  int AudioPlayer::getSampleRate() const {
@@ -38,6 +41,8 @@ void AudioPlayer::start() {
38
41
  }
39
42
 
40
43
  void AudioPlayer::stop() {
44
+ isInitialized_ = false;
45
+
41
46
  if (mStream_) {
42
47
  mStream_->requestStop();
43
48
  mStream_->close();
@@ -49,14 +54,18 @@ DataCallbackResult AudioPlayer::onAudioReady(
49
54
  AudioStream *oboeStream,
50
55
  void *audioData,
51
56
  int32_t numFrames) {
52
- auto buffer = static_cast<float *>(audioData);
57
+ if (!isInitialized_) {
58
+ return DataCallbackResult::Continue;
59
+ }
53
60
 
61
+ auto buffer = static_cast<float *>(audioData);
54
62
  renderAudio_(mBus_.get(), numFrames);
55
63
 
56
64
  // TODO: optimize this with SIMD?
57
65
  for (int32_t i = 0; i < numFrames; i += 1) {
58
66
  for (int channel = 0; channel < CHANNEL_COUNT; channel += 1) {
59
- buffer[i * CHANNEL_COUNT + channel] = mBus_->getChannel(channel)->getData()[i];
67
+ buffer[i * CHANNEL_COUNT + channel] =
68
+ mBus_->getChannel(channel)->getData()[i];
60
69
  }
61
70
  }
62
71
 
@@ -12,10 +12,10 @@ class AudioBus;
12
12
 
13
13
  class AudioPlayer : public AudioStreamDataCallback {
14
14
  public:
15
- explicit AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio);
15
+ explicit AudioPlayer(const std::function<void(AudioBus *, int)> &renderAudio);
16
16
 
17
- int getSampleRate() const;
18
- int getBufferSizeInFrames() const;
17
+ [[nodiscard]] int getSampleRate() const;
18
+ [[nodiscard]] int getBufferSizeInFrames() const;
19
19
  void start();
20
20
  void stop();
21
21
 
@@ -25,9 +25,10 @@ class AudioPlayer : public AudioStreamDataCallback {
25
25
  int32_t numFrames) override;
26
26
 
27
27
  private:
28
- std::function<void(AudioBus*, int)> renderAudio_;
28
+ std::function<void(AudioBus *, int)> renderAudio_;
29
29
  std::shared_ptr<AudioStream> mStream_;
30
30
  std::shared_ptr<AudioBus> mBus_;
31
+ bool isInitialized_ = false;
31
32
  };
32
33
 
33
34
  } // namespace audioapi
@@ -1,8 +1,14 @@
1
1
  package com.swmansion.audioapi.module
2
2
 
3
3
  import com.facebook.jni.HybridData
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.common.annotations.FrameworkAPI
6
+ import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
4
7
 
5
- class AudioAPIInstaller {
8
+ @OptIn(FrameworkAPI::class)
9
+ class AudioAPIInstaller(
10
+ reactContext: ReactApplicationContext,
11
+ ) {
6
12
  private val mHybridData: HybridData?
7
13
 
8
14
  companion object {
@@ -12,10 +18,14 @@ class AudioAPIInstaller {
12
18
  }
13
19
 
14
20
  init {
15
- mHybridData = initHybrid()
21
+ val jsCallInvokerHolder = reactContext.jsCallInvokerHolder as CallInvokerHolderImpl
22
+ mHybridData = initHybrid(reactContext.javaScriptContextHolder!!.get(), jsCallInvokerHolder)
16
23
  }
17
24
 
18
- external fun initHybrid(): HybridData?
25
+ external fun initHybrid(
26
+ jsContext: Long,
27
+ callInvoker: CallInvokerHolderImpl,
28
+ ): HybridData?
19
29
 
20
- external fun install(jsContext: Long)
30
+ external fun install()
21
31
  }
@@ -12,9 +12,8 @@ class AudioAPIModule(
12
12
 
13
13
  @ReactMethod(isBlockingSynchronousMethod = true)
14
14
  fun install(): Boolean {
15
- val audioAPIInstaller = AudioAPIInstaller()
16
- val jsContext = reactContext.javaScriptContextHolder!!.get()
17
- audioAPIInstaller.install(jsContext)
15
+ val audioAPIInstaller = AudioAPIInstaller(reactContext)
16
+ audioAPIInstaller.install()
18
17
 
19
18
  return true
20
19
  }
@@ -4,8 +4,13 @@ namespace audioapi {
4
4
  using namespace facebook;
5
5
 
6
6
  AudioAPIInstallerHostObject::AudioAPIInstallerHostObject(
7
- const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper)
8
- : wrapper_(wrapper) {}
7
+ const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper,
8
+ jsi::Runtime *runtime,
9
+ const std::shared_ptr<facebook::react::CallInvoker> &jsInvoker)
10
+ : wrapper_(wrapper) {
11
+ promiseVendor_ =
12
+ std::make_shared<JsiPromise::PromiseVendor>(runtime, jsInvoker);
13
+ }
9
14
 
10
15
  std::vector<jsi::PropNameID> AudioAPIInstallerHostObject::getPropertyNames(
11
16
  jsi::Runtime &runtime) {
@@ -32,7 +37,8 @@ jsi::Value AudioAPIInstallerHostObject::get(
32
37
  size_t count) -> jsi::Value {
33
38
  auto audioContext = wrapper_->createAudioContext();
34
39
  auto audioContextHostObject =
35
- AudioContextHostObject::createFromWrapper(audioContext);
40
+ AudioContextHostObject::createFromWrapper(
41
+ audioContext, promiseVendor_);
36
42
  return jsi::Object::createFromHostObject(
37
43
  runtime, audioContextHostObject);
38
44
  });
@@ -1,5 +1,6 @@
1
1
  #pragma once
2
2
 
3
+ #include <ReactCommon/CallInvoker.h>
3
4
  #include <jsi/jsi.h>
4
5
  #include <memory>
5
6
  #include <utility>
@@ -7,6 +8,7 @@
7
8
 
8
9
  #include "AudioAPIInstallerWrapper.h"
9
10
  #include "AudioContextHostObject.h"
11
+ #include "JsiPromise.h"
10
12
 
11
13
  namespace audioapi {
12
14
  using namespace facebook;
@@ -16,17 +18,20 @@ class AudioAPIInstallerWrapper;
16
18
  class AudioAPIInstallerHostObject : public jsi::HostObject {
17
19
  public:
18
20
  explicit AudioAPIInstallerHostObject(
19
- const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper);
21
+ const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper,
22
+ jsi::Runtime *runtime,
23
+ const std::shared_ptr<react::CallInvoker> &jsInvoker);
20
24
 
21
25
  #ifdef ANDROID
22
26
  static void createAndInstallFromWrapper(
23
27
  const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper,
24
- jlong jsContext) {
25
- auto runtime = reinterpret_cast<jsi::Runtime *>(jsContext);
26
- auto hostObject = std::make_shared<AudioAPIInstallerHostObject>(wrapper);
27
- auto object = jsi::Object::createFromHostObject(*runtime, hostObject);
28
- runtime->global().setProperty(
29
- *runtime, "__AudioAPIInstaller", std::move(object));
28
+ jsi::Runtime *rnRuntime,
29
+ const std::shared_ptr<react::CallInvoker> &jsInvoker) {
30
+ auto hostObject = std::make_shared<AudioAPIInstallerHostObject>(
31
+ wrapper, rnRuntime, jsInvoker);
32
+ auto object = jsi::Object::createFromHostObject(*rnRuntime, hostObject);
33
+ rnRuntime->global().setProperty(
34
+ *rnRuntime, "__AudioAPIInstaller", std::move(object));
30
35
  }
31
36
  #endif
32
37
 
@@ -41,5 +46,6 @@ class AudioAPIInstallerHostObject : public jsi::HostObject {
41
46
 
42
47
  private:
43
48
  std::shared_ptr<AudioAPIInstallerWrapper> wrapper_;
49
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor_;
44
50
  };
45
51
  } // namespace audioapi
@@ -128,6 +128,13 @@ jsi::Value AudioBufferHostObject::get(
128
128
  });
129
129
  }
130
130
 
131
+ // `decodeAudioData` is a method that returns a promise to
132
+ // AudioBufferHostObject It seems that async/await checks for the presence of
133
+ // `then` method on the object
134
+ if (propName == "then") {
135
+ return jsi::Value::undefined();
136
+ }
137
+
131
138
  throw std::runtime_error("Not yet implemented!");
132
139
  }
133
140
 
@@ -4,8 +4,9 @@ namespace audioapi {
4
4
  using namespace facebook;
5
5
 
6
6
  AudioContextHostObject::AudioContextHostObject(
7
- const std::shared_ptr<AudioContextWrapper> &wrapper)
8
- : BaseAudioContextHostObject(wrapper) {}
7
+ const std::shared_ptr<AudioContextWrapper> &wrapper,
8
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor)
9
+ : BaseAudioContextHostObject(wrapper, promiseVendor) {}
9
10
 
10
11
  std::vector<jsi::PropNameID> AudioContextHostObject::getPropertyNames(
11
12
  jsi::Runtime &runtime) {
@@ -6,6 +6,7 @@
6
6
 
7
7
  #include "AudioContextWrapper.h"
8
8
  #include "BaseAudioContextHostObject.h"
9
+ #include "JsiPromise.h"
9
10
 
10
11
  namespace audioapi {
11
12
  using namespace facebook;
@@ -13,7 +14,8 @@ using namespace facebook;
13
14
  class AudioContextHostObject : public BaseAudioContextHostObject {
14
15
  public:
15
16
  explicit AudioContextHostObject(
16
- const std::shared_ptr<AudioContextWrapper> &wrapper);
17
+ const std::shared_ptr<AudioContextWrapper> &wrapper,
18
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor);
17
19
 
18
20
  jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override;
19
21
 
@@ -25,8 +27,9 @@ class AudioContextHostObject : public BaseAudioContextHostObject {
25
27
  std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
26
28
 
27
29
  static std::shared_ptr<AudioContextHostObject> createFromWrapper(
28
- const std::shared_ptr<AudioContextWrapper> &wrapper) {
29
- return std::make_shared<AudioContextHostObject>(wrapper);
30
+ const std::shared_ptr<AudioContextWrapper> &wrapper,
31
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor) {
32
+ return std::make_shared<AudioContextHostObject>(wrapper, promiseVendor);
30
33
  }
31
34
 
32
35
  private:
@@ -1,11 +1,14 @@
1
+ #include <thread>
2
+
1
3
  #include "BaseAudioContextHostObject.h"
2
4
 
3
5
  namespace audioapi {
4
6
  using namespace facebook;
5
7
 
6
8
  BaseAudioContextHostObject::BaseAudioContextHostObject(
7
- const std::shared_ptr<BaseAudioContextWrapper> &wrapper)
8
- : wrapper_(wrapper) {
9
+ const std::shared_ptr<BaseAudioContextWrapper> &wrapper,
10
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor)
11
+ : wrapper_(wrapper), promiseVendor_(promiseVendor) {
9
12
  auto destinationNodeWrapper = wrapper_->getDestination();
10
13
  destination_ =
11
14
  AudioDestinationNodeHostObject::createFromWrapper(destinationNodeWrapper);
@@ -30,6 +33,8 @@ std::vector<jsi::PropNameID> BaseAudioContextHostObject::getPropertyNames(
30
33
  propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "createBuffer"));
31
34
  propertyNames.push_back(
32
35
  jsi::PropNameID::forUtf8(runtime, "createPeriodicWave"));
36
+ propertyNames.push_back(
37
+ jsi::PropNameID::forUtf8(runtime, "decodeAudioDataSource"));
33
38
  return propertyNames;
34
39
  }
35
40
 
@@ -200,6 +205,37 @@ jsi::Value BaseAudioContextHostObject::get(
200
205
  });
201
206
  }
202
207
 
208
+ if (propName == "decodeAudioDataSource") {
209
+ auto decode = [this](
210
+ jsi::Runtime &runtime,
211
+ const jsi::Value &,
212
+ const jsi::Value *arguments,
213
+ size_t count) -> jsi::Value {
214
+ auto sourcePath = arguments[0].getString(runtime).utf8(runtime);
215
+
216
+ auto promise = promiseVendor_->createPromise(
217
+ [this, &runtime, sourcePath](
218
+ std::shared_ptr<JsiPromise::Promise> promise) {
219
+ std::thread([this,
220
+ &runtime,
221
+ sourcePath,
222
+ promise = std::move(promise)]() {
223
+ auto results = wrapper_->decodeAudioDataSource(sourcePath);
224
+ auto audioBufferHostObject =
225
+ AudioBufferHostObject::createFromWrapper(results);
226
+
227
+ promise->resolve(jsi::Object::createFromHostObject(
228
+ runtime, audioBufferHostObject));
229
+ }).detach();
230
+ });
231
+
232
+ return promise;
233
+ };
234
+
235
+ return jsi::Function::createFromHostFunction(
236
+ runtime, propNameId, 1, decode);
237
+ }
238
+
203
239
  throw std::runtime_error("Not yet implemented!");
204
240
  }
205
241
 
@@ -11,6 +11,7 @@
11
11
  #include "BaseAudioContextWrapper.h"
12
12
  #include "BiquadFilterNodeHostObject.h"
13
13
  #include "GainNodeHostObject.h"
14
+ #include "JsiPromise.h"
14
15
  #include "OscillatorNodeHostObject.h"
15
16
  #include "PeriodicWaveHostObject.h"
16
17
  #include "StereoPannerNodeHostObject.h"
@@ -21,7 +22,8 @@ using namespace facebook;
21
22
  class BaseAudioContextHostObject : public jsi::HostObject {
22
23
  public:
23
24
  explicit BaseAudioContextHostObject(
24
- const std::shared_ptr<BaseAudioContextWrapper> &wrapper);
25
+ const std::shared_ptr<BaseAudioContextWrapper> &wrapper,
26
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor);
25
27
 
26
28
  jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override;
27
29
 
@@ -35,5 +37,6 @@ class BaseAudioContextHostObject : public jsi::HostObject {
35
37
  protected:
36
38
  std::shared_ptr<BaseAudioContextWrapper> wrapper_;
37
39
  std::shared_ptr<AudioDestinationNodeHostObject> destination_;
40
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor_;
38
41
  };
39
42
  } // namespace audioapi
@@ -5,14 +5,14 @@
5
5
 
6
6
  namespace audioapi {
7
7
 
8
- AudioArray::AudioArray(int size) : size_(size), data_(0) {
8
+ AudioArray::AudioArray(int size) : data_(nullptr), size_(size) {
9
9
  resize(size);
10
10
  }
11
11
 
12
12
  AudioArray::~AudioArray() {
13
13
  if (data_) {
14
14
  delete[] data_;
15
- data_ = 0;
15
+ data_ = nullptr;
16
16
  }
17
17
  }
18
18
 
@@ -20,15 +20,15 @@ int AudioArray::getSize() const {
20
20
  return size_;
21
21
  }
22
22
 
23
- float* AudioArray::getData() const {
23
+ float *AudioArray::getData() const {
24
24
  return data_;
25
25
  }
26
26
 
27
- float& AudioArray::operator[](int index) {
27
+ float &AudioArray::operator[](int index) {
28
28
  return data_[index];
29
29
  }
30
30
 
31
- const float& AudioArray::operator[](int index) const {
31
+ const float &AudioArray::operator[](int index) const {
32
32
  return data_[index];
33
33
  }
34
34
 
@@ -75,29 +75,43 @@ void AudioArray::zero(int start, int length) {
75
75
  memset(data_ + start, 0, length * sizeof(float));
76
76
  }
77
77
 
78
- void AudioArray::sum(const AudioArray* source) {
78
+ void AudioArray::sum(const AudioArray *source) {
79
79
  sum(source, 0, 0, size_);
80
80
  }
81
81
 
82
- void AudioArray::sum(const AudioArray* source, int start, int length) {
82
+ void AudioArray::sum(const AudioArray *source, int start, int length) {
83
83
  sum(source, start, start, length);
84
84
  }
85
85
 
86
- void AudioArray::sum(const AudioArray* source, int sourceStart, int destinationStart, int length) {
87
- VectorMath::add(data_ + destinationStart, source->getData() + sourceStart, data_ + destinationStart, length);
86
+ void AudioArray::sum(
87
+ const AudioArray *source,
88
+ int sourceStart,
89
+ int destinationStart,
90
+ int length) {
91
+ VectorMath::add(
92
+ data_ + destinationStart,
93
+ source->getData() + sourceStart,
94
+ data_ + destinationStart,
95
+ length);
88
96
  }
89
97
 
90
- void AudioArray::copy(const AudioArray* source) {
98
+ void AudioArray::copy(const AudioArray *source) {
91
99
  copy(source, 0, size_);
92
100
  }
93
101
 
94
- void AudioArray::copy(const AudioArray* source, int start, int length) {
102
+ void AudioArray::copy(const AudioArray *source, int start, int length) {
95
103
  copy(source, start, start, length);
96
104
  }
97
105
 
98
- void AudioArray::copy(const AudioArray* source, int sourceStart, int destinationStart, int length) {
99
- memcpy(data_ + destinationStart, source->getData() + sourceStart, length * sizeof(float));
106
+ void AudioArray::copy(
107
+ const AudioArray *source,
108
+ int sourceStart,
109
+ int destinationStart,
110
+ int length) {
111
+ memcpy(
112
+ data_ + destinationStart,
113
+ source->getData() + sourceStart,
114
+ length * sizeof(float));
100
115
  }
101
116
 
102
117
  } // namespace audioapi
103
-
@@ -1,7 +1,7 @@
1
1
  #pragma once
2
2
 
3
- #include <memory>
4
3
  #include <algorithm>
4
+ #include <memory>
5
5
 
6
6
  namespace audioapi {
7
7
 
@@ -11,28 +11,34 @@ class AudioArray {
11
11
  ~AudioArray();
12
12
 
13
13
  [[nodiscard]] int getSize() const;
14
- float* getData() const;
15
-
14
+ [[nodiscard]] float *getData() const;
16
15
 
17
- float& operator[](int index);
18
- const float& operator[](int index) const;
16
+ float &operator[](int index);
17
+ const float &operator[](int index) const;
19
18
 
20
19
  void normalize();
21
20
  void resize(int size);
22
21
  void scale(float value);
23
- float getMaxAbsValue() const;
22
+ [[nodiscard]] float getMaxAbsValue() const;
24
23
 
25
24
  void zero();
26
25
  void zero(int start, int length);
27
26
 
28
- void sum(const AudioArray* source);
29
- void sum(const AudioArray* source, int start, int length);
30
- void sum(const AudioArray* source, int sourceStart, int destinationStart, int length);
31
-
32
- void copy(const AudioArray* source);
33
- void copy(const AudioArray* source, int start, int length);
34
- void copy(const AudioArray* source, int sourceStart, int destinationStart, int length);
35
-
27
+ void sum(const AudioArray *source);
28
+ void sum(const AudioArray *source, int start, int length);
29
+ void sum(
30
+ const AudioArray *source,
31
+ int sourceStart,
32
+ int destinationStart,
33
+ int length);
34
+
35
+ void copy(const AudioArray *source);
36
+ void copy(const AudioArray *source, int start, int length);
37
+ void copy(
38
+ const AudioArray *source,
39
+ int sourceStart,
40
+ int destinationStart,
41
+ int length);
36
42
 
37
43
  private:
38
44
  float *data_;