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.
- package/android/CMakeLists.txt +2 -2
- package/android/build.gradle +1 -3
- package/android/libs/include/miniaudio.h +92621 -0
- package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.cpp +8 -4
- package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.h +16 -7
- package/android/src/main/cpp/AudioDecoder/AudioDecoder.cpp +64 -0
- package/android/src/main/cpp/AudioDecoder/AudioDecoder.h +21 -0
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +16 -7
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +5 -4
- package/android/src/main/java/com/swmansion/audioapi/module/AudioAPIInstaller.kt +14 -4
- package/android/src/main/java/com/swmansion/audioapi/nativemodules/AudioAPIModule.kt +2 -3
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +9 -3
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +13 -7
- package/common/cpp/HostObjects/AudioBufferHostObject.cpp +7 -0
- package/common/cpp/HostObjects/AudioContextHostObject.cpp +3 -2
- package/common/cpp/HostObjects/AudioContextHostObject.h +6 -3
- package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +38 -2
- package/common/cpp/HostObjects/BaseAudioContextHostObject.h +4 -1
- package/common/cpp/core/AudioArray.cpp +28 -14
- package/common/cpp/core/AudioArray.h +20 -14
- package/common/cpp/core/AudioBuffer.cpp +14 -11
- package/common/cpp/core/AudioBuffer.h +1 -0
- package/common/cpp/core/AudioBufferSourceNode.cpp +29 -19
- package/common/cpp/core/AudioBufferSourceNode.h +1 -1
- package/common/cpp/core/AudioBus.cpp +276 -115
- package/common/cpp/core/AudioBus.h +29 -9
- package/common/cpp/core/AudioContext.cpp +5 -9
- package/common/cpp/core/AudioDestinationNode.cpp +11 -8
- package/common/cpp/core/AudioDestinationNode.h +4 -4
- package/common/cpp/core/AudioNode.cpp +25 -17
- package/common/cpp/core/AudioNode.h +5 -5
- package/common/cpp/core/AudioNodeManager.cpp +10 -7
- package/common/cpp/core/AudioNodeManager.h +11 -4
- package/common/cpp/core/AudioScheduledSourceNode.cpp +2 -2
- package/common/cpp/core/BaseAudioContext.cpp +49 -12
- package/common/cpp/core/BaseAudioContext.h +16 -7
- package/common/cpp/core/BiquadFilterNode.cpp +5 -3
- package/common/cpp/core/GainNode.cpp +1 -1
- package/common/cpp/core/OscillatorNode.cpp +4 -4
- package/common/cpp/core/OscillatorNode.h +2 -2
- package/common/cpp/core/StereoPannerNode.cpp +10 -7
- package/common/cpp/core/StereoPannerNode.h +1 -1
- package/common/cpp/utils/FFTFrame.h +5 -1
- package/common/cpp/utils/JsiPromise.cpp +64 -0
- package/common/cpp/utils/JsiPromise.h +48 -0
- package/common/cpp/utils/Locker.h +8 -6
- package/common/cpp/utils/VectorMath.cpp +71 -55
- package/common/cpp/utils/android/FFTFrame.cpp +12 -11
- package/common/cpp/utils/ios/FFTFrame.cpp +6 -1
- package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +7 -0
- package/common/cpp/wrappers/BaseAudioContextWrapper.h +2 -0
- package/ios/AudioAPIModule.mm +4 -1
- package/ios/AudioDecoder/AudioDecoder.h +17 -0
- package/ios/AudioDecoder/AudioDecoder.m +80 -0
- package/ios/AudioDecoder/IOSAudioDecoder.h +28 -0
- package/ios/AudioDecoder/IOSAudioDecoder.mm +46 -0
- package/ios/AudioPlayer/AudioPlayer.h +1 -1
- package/ios/AudioPlayer/AudioPlayer.m +2 -2
- package/ios/AudioPlayer/IOSAudioPlayer.h +5 -5
- package/ios/AudioPlayer/IOSAudioPlayer.mm +4 -3
- package/lib/module/core/BaseAudioContext.js +4 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/index.js +232 -17
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.native.js +18 -0
- package/lib/module/index.native.js.map +1 -0
- package/lib/typescript/core/BaseAudioContext.d.ts +1 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +100 -13
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/index.native.d.ts +14 -0
- package/lib/typescript/index.native.d.ts.map +1 -0
- package/lib/typescript/interfaces.d.ts +1 -0
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/core/BaseAudioContext.ts +6 -0
- package/src/index.native.ts +25 -0
- package/src/index.ts +403 -19
- package/src/interfaces.ts +1 -0
- package/android/libs/fftw3/x86/libfftw3.a +0 -0
- package/android/libs/fftw3/x86_64/libfftw3.a +0 -0
- /package/android/libs/{fftw3/arm64-v8a → arm64-v8a}/libfftw3.a +0 -0
- /package/android/libs/{fftw3/armeabi-v7a → armeabi-v7a}/libfftw3.a +0 -0
- /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
|
-
|
|
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(
|
|
15
|
+
void AudioAPIInstaller::install() {
|
|
12
16
|
auto audioAPIInstallerWrapper =
|
|
13
17
|
std::make_shared<AudioAPIInstallerWrapper>(this);
|
|
14
18
|
AudioAPIInstallerHostObject::createAndInstallFromWrapper(
|
|
15
|
-
audioAPIInstallerWrapper,
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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>(
|
|
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
|
-
|
|
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] =
|
|
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
|
|
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
|
-
|
|
21
|
+
val jsCallInvokerHolder = reactContext.jsCallInvokerHolder as CallInvokerHolderImpl
|
|
22
|
+
mHybridData = initHybrid(reactContext.javaScriptContextHolder!!.get(), jsCallInvokerHolder)
|
|
16
23
|
}
|
|
17
24
|
|
|
18
|
-
external fun initHybrid(
|
|
25
|
+
external fun initHybrid(
|
|
26
|
+
jsContext: Long,
|
|
27
|
+
callInvoker: CallInvokerHolderImpl,
|
|
28
|
+
): HybridData?
|
|
19
29
|
|
|
20
|
-
external fun install(
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
auto hostObject = std::make_shared<AudioAPIInstallerHostObject>(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) :
|
|
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_ =
|
|
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*
|
|
23
|
+
float *AudioArray::getData() const {
|
|
24
24
|
return data_;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
float&
|
|
27
|
+
float &AudioArray::operator[](int index) {
|
|
28
28
|
return data_[index];
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const float&
|
|
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*
|
|
78
|
+
void AudioArray::sum(const AudioArray *source) {
|
|
79
79
|
sum(source, 0, 0, size_);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
void AudioArray::sum(const AudioArray*
|
|
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(
|
|
87
|
-
|
|
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*
|
|
98
|
+
void AudioArray::copy(const AudioArray *source) {
|
|
91
99
|
copy(source, 0, size_);
|
|
92
100
|
}
|
|
93
101
|
|
|
94
|
-
void AudioArray::copy(const AudioArray*
|
|
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(
|
|
99
|
-
|
|
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*
|
|
15
|
-
|
|
14
|
+
[[nodiscard]] float *getData() const;
|
|
16
15
|
|
|
17
|
-
float&
|
|
18
|
-
const float&
|
|
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*
|
|
29
|
-
void sum(const AudioArray*
|
|
30
|
-
void sum(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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_;
|