react-native-audio-api 0.3.0-rc2 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RNAudioAPI.podspec +40 -29
- package/android/CMakeLists.txt +17 -21
- package/android/build.gradle +26 -9
- package/android/src/main/cpp/OnLoad.cpp +1 -1
- package/android/src/main/cpp/core/AudioAPIInstaller.cpp +37 -0
- package/android/src/main/cpp/{AudioAPIInstaller → core}/AudioAPIInstaller.h +5 -16
- package/android/src/main/cpp/{AudioDecoder → core}/AudioDecoder.cpp +0 -8
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +2 -0
- package/android/src/main/java/com/swmansion/audioapi/nativemodules/AudioAPIModule.kt +6 -4
- package/common/cpp/HostObjects/AudioAPIInstallerHostObject.h +48 -0
- package/common/cpp/HostObjects/AudioBufferHostObject.h +79 -13
- package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.h +93 -14
- package/common/cpp/HostObjects/AudioContextHostObject.h +10 -21
- package/common/cpp/HostObjects/AudioDestinationNodeHostObject.h +3 -16
- package/common/cpp/HostObjects/AudioNodeHostObject.h +48 -11
- package/common/cpp/HostObjects/AudioParamHostObject.h +93 -14
- package/common/cpp/HostObjects/AudioScheduledSourceNodeHostObject.h +23 -16
- package/common/cpp/HostObjects/BaseAudioContextHostObject.h +131 -14
- package/common/cpp/HostObjects/BiquadFilterNodeHostObject.h +76 -18
- package/common/cpp/HostObjects/GainNodeHostObject.h +10 -15
- package/common/cpp/HostObjects/OscillatorNodeHostObject.h +40 -17
- package/common/cpp/HostObjects/PeriodicWaveHostObject.h +4 -17
- package/common/cpp/HostObjects/StereoPannerNodeHostObject.h +10 -17
- package/common/cpp/core/AudioBufferSourceNode.cpp +181 -73
- package/common/cpp/core/AudioBufferSourceNode.h +41 -1
- package/{android/src/main/cpp/AudioDecoder → common/cpp/core}/AudioDecoder.h +1 -3
- package/common/cpp/core/AudioDestinationNode.h +1 -1
- package/common/cpp/core/AudioParam.cpp +218 -58
- package/common/cpp/core/AudioParam.h +19 -15
- package/common/cpp/core/AudioScheduledSourceNode.cpp +94 -21
- package/common/cpp/core/AudioScheduledSourceNode.h +16 -5
- package/common/cpp/core/BaseAudioContext.cpp +3 -13
- package/common/cpp/core/BaseAudioContext.h +2 -4
- package/common/cpp/core/BiquadFilterNode.cpp +5 -7
- package/common/cpp/{HostObjects → core}/Constants.h +2 -2
- package/common/cpp/core/GainNode.cpp +1 -1
- package/common/cpp/core/OscillatorNode.cpp +11 -5
- package/common/cpp/core/ParamChangeEvent.cpp +58 -0
- package/common/cpp/core/{ParamChange.h → ParamChangeEvent.h} +11 -5
- package/common/cpp/core/StereoPannerNode.cpp +1 -1
- package/common/cpp/jsi/JsiHostObject.cpp +90 -0
- package/common/cpp/jsi/JsiHostObject.h +100 -0
- package/common/cpp/{utils → jsi}/JsiPromise.cpp +10 -9
- package/common/cpp/jsi/JsiPromise.h +48 -0
- package/common/cpp/jsi/RuntimeAwareCache.h +57 -0
- package/common/cpp/jsi/RuntimeLifecycleMonitor.cpp +61 -0
- package/common/cpp/jsi/RuntimeLifecycleMonitor.h +32 -0
- package/common/cpp/types/BiquadFilterType.h +0 -4
- package/common/cpp/types/ChannelCountMode.h +0 -3
- package/common/cpp/types/ChannelInterpretation.h +0 -3
- package/common/cpp/types/ContextState.h +0 -3
- package/common/cpp/types/OscillatorType.h +0 -4
- package/common/cpp/types/ParamChangeEventType.h +13 -0
- package/common/cpp/utils/AudioUtils.cpp +26 -0
- package/common/cpp/utils/AudioUtils.h +12 -0
- package/common/cpp/utils/{ios/FFTFrame.cpp → FFTFrame.cpp} +30 -3
- package/common/cpp/utils/VectorMath.h +7 -33
- package/ios/AudioAPIModule.h +4 -12
- package/ios/AudioAPIModule.mm +26 -25
- package/ios/core/AudioDecoder.mm +45 -0
- package/ios/{AudioPlayer → core}/AudioPlayer.m +2 -1
- package/lib/module/core/AudioBuffer.js +3 -1
- package/lib/module/core/AudioBuffer.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +19 -2
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioContext.js +3 -1
- package/lib/module/core/AudioContext.js.map +1 -1
- package/lib/module/core/AudioDestinationNode.js +4 -6
- package/lib/module/core/AudioDestinationNode.js.map +1 -1
- package/lib/module/core/AudioNode.js +3 -1
- package/lib/module/core/AudioNode.js.map +1 -1
- package/lib/module/core/AudioParam.js +27 -1
- package/lib/module/core/AudioParam.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +4 -5
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +11 -9
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/core/BiquadFilterNode.js +5 -3
- package/lib/module/core/BiquadFilterNode.js.map +1 -1
- package/lib/module/core/GainNode.js +4 -2
- package/lib/module/core/GainNode.js.map +1 -1
- package/lib/module/core/OscillatorNode.js +5 -3
- package/lib/module/core/OscillatorNode.js.map +1 -1
- package/lib/module/core/PeriodicWave.js +2 -0
- package/lib/module/core/PeriodicWave.js.map +1 -1
- package/lib/module/core/StereoPannerNode.js +4 -2
- package/lib/module/core/StereoPannerNode.js.map +1 -1
- package/lib/module/core/types.js +1 -1
- package/lib/module/errors/IndexSizeError.js +2 -0
- package/lib/module/errors/IndexSizeError.js.map +1 -1
- package/lib/module/errors/InvalidAccessError.js +2 -0
- package/lib/module/errors/InvalidAccessError.js.map +1 -1
- package/lib/module/errors/InvalidStateError.js +2 -0
- package/lib/module/errors/InvalidStateError.js.map +1 -1
- package/lib/module/errors/RangeError.js +2 -0
- package/lib/module/errors/RangeError.js.map +1 -1
- package/lib/module/errors/index.js +6 -4
- package/lib/module/errors/index.js.map +1 -1
- package/lib/module/index.js +35 -10
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.native.js +16 -14
- package/lib/module/index.native.js.map +1 -1
- package/lib/module/interfaces.js +2 -0
- package/lib/module/specs/global.d.js +4 -0
- package/lib/module/{modules → specs}/global.d.js.map +1 -1
- package/lib/module/{utils → specs}/install.js +5 -9
- package/lib/module/specs/install.js.map +1 -0
- package/lib/typescript/core/AudioBuffer.d.ts +2 -0
- package/lib/typescript/core/AudioBuffer.d.ts.map +1 -1
- package/lib/typescript/core/AudioBufferSourceNode.d.ts +7 -0
- package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioDestinationNode.d.ts +0 -3
- package/lib/typescript/core/AudioDestinationNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioParam.d.ts +4 -0
- package/lib/typescript/core/AudioParam.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +0 -3
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/PeriodicWave.d.ts +2 -0
- package/lib/typescript/core/PeriodicWave.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +13 -3
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +8 -0
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/{utils → specs}/install.d.ts.map +1 -1
- package/metro-config/index.d.ts +5 -0
- package/metro-config/index.js +41 -0
- package/metro-config/tsconfig.json +3 -0
- package/package.json +50 -16
- package/scripts/audioapi_utils.rb +56 -0
- package/src/core/AudioBufferSourceNode.ts +23 -0
- package/src/core/AudioDestinationNode.ts +1 -7
- package/src/core/AudioParam.ts +48 -0
- package/src/core/AudioScheduledSourceNode.ts +0 -5
- package/src/index.native.ts +1 -1
- package/src/index.ts +54 -13
- package/src/interfaces.ts +17 -0
- package/src/{modules → specs}/global.d.ts +2 -0
- package/src/{utils → specs}/install.ts +4 -11
- package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.cpp +0 -26
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +0 -58
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +0 -51
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerWrapper.h +0 -38
- package/common/cpp/AudioAPIInstaller/android/AudioAPIInstallerWrapper.cpp +0 -16
- package/common/cpp/AudioAPIInstaller/ios/AudioAPIInstallerWrapper.cpp +0 -12
- package/common/cpp/HostObjects/AudioBufferHostObject.cpp +0 -150
- package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +0 -79
- package/common/cpp/HostObjects/AudioContextHostObject.cpp +0 -55
- package/common/cpp/HostObjects/AudioDestinationNodeHostObject.cpp +0 -33
- package/common/cpp/HostObjects/AudioNodeHostObject.cpp +0 -102
- package/common/cpp/HostObjects/AudioParamHostObject.cpp +0 -115
- package/common/cpp/HostObjects/AudioScheduledSourceNodeHostObject.cpp +0 -73
- package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +0 -250
- package/common/cpp/HostObjects/BiquadFilterNodeHostObject.cpp +0 -125
- package/common/cpp/HostObjects/GainNodeHostObject.cpp +0 -41
- package/common/cpp/HostObjects/OscillatorNodeHostObject.cpp +0 -88
- package/common/cpp/HostObjects/PeriodicWaveHostObject.cpp +0 -33
- package/common/cpp/HostObjects/StereoPannerNodeHostObject.cpp +0 -41
- package/common/cpp/core/ParamChange.cpp +0 -46
- package/common/cpp/utils/JsiPromise.h +0 -48
- package/common/cpp/utils/android/FFTFrame.cpp +0 -23
- package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.cpp +0 -45
- package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.h +0 -26
- package/common/cpp/wrappers/AudioBufferWrapper.cpp +0 -46
- package/common/cpp/wrappers/AudioBufferWrapper.h +0 -30
- package/common/cpp/wrappers/AudioContextWrapper.cpp +0 -17
- package/common/cpp/wrappers/AudioContextWrapper.h +0 -19
- package/common/cpp/wrappers/AudioDestinationNodeWrapper.h +0 -16
- package/common/cpp/wrappers/AudioNodeWrapper.cpp +0 -37
- package/common/cpp/wrappers/AudioNodeWrapper.h +0 -25
- package/common/cpp/wrappers/AudioParamWrapper.cpp +0 -42
- package/common/cpp/wrappers/AudioParamWrapper.h +0 -25
- package/common/cpp/wrappers/AudioScheduledSourceNodeWrapper.cpp +0 -23
- package/common/cpp/wrappers/AudioScheduledSourceNodeWrapper.h +0 -23
- package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +0 -83
- package/common/cpp/wrappers/BaseAudioContextWrapper.h +0 -51
- package/common/cpp/wrappers/BiquadFilterNodeWrapper.cpp +0 -60
- package/common/cpp/wrappers/BiquadFilterNodeWrapper.h +0 -37
- package/common/cpp/wrappers/GainNodeWrapper.cpp +0 -14
- package/common/cpp/wrappers/GainNodeWrapper.h +0 -20
- package/common/cpp/wrappers/OscillatorNodeWrapper.cpp +0 -44
- package/common/cpp/wrappers/OscillatorNodeWrapper.h +0 -31
- package/common/cpp/wrappers/PeriodicWaveWrapper.h +0 -17
- package/common/cpp/wrappers/StereoPannerNodeWrapper.cpp +0 -16
- package/common/cpp/wrappers/StereoPannerNodeWrapper.h +0 -21
- package/ios/AudioDecoder/AudioDecoder.h +0 -17
- package/ios/AudioDecoder/AudioDecoder.m +0 -80
- package/ios/AudioDecoder/IOSAudioDecoder.h +0 -28
- package/ios/AudioDecoder/IOSAudioDecoder.mm +0 -46
- package/lib/module/modules/global.d.js +0 -2
- package/lib/module/utils/install.js.map +0 -1
- /package/android/src/main/cpp/{AudioPlayer → core}/AudioPlayer.cpp +0 -0
- /package/android/src/main/cpp/{AudioPlayer → core}/AudioPlayer.h +0 -0
- /package/{android/libs/include → common/cpp/libs}/miniaudio.h +0 -0
- /package/ios/{AudioPlayer → core}/AudioPlayer.h +0 -0
- /package/ios/{AudioPlayer → core}/IOSAudioPlayer.h +0 -0
- /package/ios/{AudioPlayer → core}/IOSAudioPlayer.mm +0 -0
- /package/lib/typescript/{utils → specs}/install.d.ts +0 -0
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
namespace audioapi {
|
|
9
9
|
constexpr int SAMPLE_RATE = 44100;
|
|
10
10
|
constexpr int CHANNEL_COUNT = 2;
|
|
11
|
-
constexpr float MOST_POSITIVE_SINGLE_FLOAT =
|
|
12
|
-
|
|
11
|
+
constexpr float MOST_POSITIVE_SINGLE_FLOAT = static_cast<float>(std::numeric_limits<float>::max());
|
|
12
|
+
constexpr float MOST_NEGATIVE_SINGLE_FLOAT = static_cast<float>(std::numeric_limits<float>::lowest());
|
|
13
13
|
constexpr float NYQUIST_FREQUENCY = SAMPLE_RATE / 2.0;
|
|
14
14
|
static float MAX_DETUNE = 1200 * std::log2(MOST_POSITIVE_SINGLE_FLOAT);
|
|
15
15
|
constexpr float MAX_GAIN = MOST_POSITIVE_SINGLE_FLOAT;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
namespace audioapi {
|
|
7
7
|
|
|
8
8
|
GainNode::GainNode(BaseAudioContext *context) : AudioNode(context) {
|
|
9
|
-
gainParam_ = std::make_shared<AudioParam>(
|
|
9
|
+
gainParam_ = std::make_shared<AudioParam>(1.0, -MAX_GAIN, MAX_GAIN);
|
|
10
10
|
isInitialized_ = true;
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -8,9 +8,8 @@ namespace audioapi {
|
|
|
8
8
|
OscillatorNode::OscillatorNode(BaseAudioContext *context)
|
|
9
9
|
: AudioScheduledSourceNode(context) {
|
|
10
10
|
frequencyParam_ = std::make_shared<AudioParam>(
|
|
11
|
-
|
|
12
|
-
detuneParam_ =
|
|
13
|
-
std::make_shared<AudioParam>(context, 0.0, -MAX_DETUNE, MAX_DETUNE);
|
|
11
|
+
444.0, -NYQUIST_FREQUENCY, NYQUIST_FREQUENCY);
|
|
12
|
+
detuneParam_ = std::make_shared<AudioParam>(0.0, -MAX_DETUNE, MAX_DETUNE);
|
|
14
13
|
type_ = OscillatorType::SINE;
|
|
15
14
|
periodicWave_ = context_->getBasicWaveForm(type_);
|
|
16
15
|
isInitialized_ = true;
|
|
@@ -40,15 +39,20 @@ void OscillatorNode::setPeriodicWave(
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
void OscillatorNode::processNode(AudioBus *processingBus, int framesToProcess) {
|
|
42
|
+
size_t startOffset = 0;
|
|
43
|
+
size_t offsetLength = 0;
|
|
44
|
+
|
|
45
|
+
updatePlaybackInfo(processingBus, framesToProcess, startOffset, offsetLength);
|
|
46
|
+
|
|
43
47
|
if (!isPlaying()) {
|
|
44
48
|
processingBus->zero();
|
|
45
49
|
return;
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
double time = context_->getCurrentTime();
|
|
49
52
|
double deltaTime = 1.0 / context_->getSampleRate();
|
|
53
|
+
double time = context_->getCurrentTime() + startOffset * deltaTime;
|
|
50
54
|
|
|
51
|
-
for (
|
|
55
|
+
for (size_t i = startOffset; i < offsetLength; i += 1) {
|
|
52
56
|
auto detuneRatio =
|
|
53
57
|
std::pow(2.0f, detuneParam_->getValueAtTime(time) / 1200.0f);
|
|
54
58
|
auto detunedFrequency =
|
|
@@ -70,6 +74,8 @@ void OscillatorNode::processNode(AudioBus *processingBus, int framesToProcess) {
|
|
|
70
74
|
|
|
71
75
|
time += deltaTime;
|
|
72
76
|
}
|
|
77
|
+
|
|
78
|
+
handleStopScheduled();
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
} // namespace audioapi
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#include "ParamChangeEvent.h"
|
|
2
|
+
|
|
3
|
+
#include <utility>
|
|
4
|
+
|
|
5
|
+
namespace audioapi {
|
|
6
|
+
|
|
7
|
+
ParamChangeEvent::ParamChangeEvent(
|
|
8
|
+
double startTime,
|
|
9
|
+
double endTime,
|
|
10
|
+
float startValue,
|
|
11
|
+
float endValue,
|
|
12
|
+
std::function<float(double, double, float, float, double)> calculateValue,
|
|
13
|
+
ParamChangeEventType type)
|
|
14
|
+
: startTime_(startTime),
|
|
15
|
+
endTime_(endTime),
|
|
16
|
+
startValue_(startValue),
|
|
17
|
+
endValue_(endValue),
|
|
18
|
+
calculateValue_(std::move(calculateValue)),
|
|
19
|
+
type_(type) {}
|
|
20
|
+
|
|
21
|
+
double ParamChangeEvent::getEndTime() const {
|
|
22
|
+
return endTime_;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
double ParamChangeEvent::getStartTime() const {
|
|
26
|
+
return startTime_;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
float ParamChangeEvent::getEndValue() const {
|
|
30
|
+
return endValue_;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
float ParamChangeEvent::getStartValue() const {
|
|
34
|
+
return startValue_;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
std::function<float(double, double, float, float, double)>
|
|
38
|
+
ParamChangeEvent::getCalculateValue() const {
|
|
39
|
+
return calculateValue_;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
ParamChangeEventType ParamChangeEvent::getType() const {
|
|
43
|
+
return type_;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void ParamChangeEvent::setEndTime(double endTime) {
|
|
47
|
+
endTime_ = endTime;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
void ParamChangeEvent::setStartValue(float startValue) {
|
|
51
|
+
startValue_ = startValue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void ParamChangeEvent::setEndValue(float endValue) {
|
|
55
|
+
endValue_ = endValue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
} // namespace audioapi
|
|
@@ -2,18 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
#include <functional>
|
|
4
4
|
#include <memory>
|
|
5
|
+
#include "ParamChangeEventType.h"
|
|
5
6
|
|
|
6
7
|
namespace audioapi {
|
|
7
8
|
|
|
8
|
-
class
|
|
9
|
+
class ParamChangeEvent {
|
|
9
10
|
public:
|
|
10
|
-
explicit
|
|
11
|
+
explicit ParamChangeEvent(
|
|
11
12
|
double startTime,
|
|
12
13
|
double endTime,
|
|
13
14
|
float startValue,
|
|
14
15
|
float endValue,
|
|
15
|
-
std::function<float(double, double, float, float, double)>
|
|
16
|
-
|
|
16
|
+
std::function<float(double, double, float, float, double)> calculateValue,
|
|
17
|
+
ParamChangeEventType type);
|
|
17
18
|
|
|
18
19
|
[[nodiscard]] double getEndTime() const;
|
|
19
20
|
[[nodiscard]] double getStartTime() const;
|
|
@@ -21,7 +22,11 @@ class ParamChange {
|
|
|
21
22
|
[[nodiscard]] float getStartValue() const;
|
|
22
23
|
[[nodiscard]] std::function<float(double, double, float, float, double)>
|
|
23
24
|
getCalculateValue() const;
|
|
24
|
-
|
|
25
|
+
[[nodiscard]] ParamChangeEventType getType() const;
|
|
26
|
+
|
|
27
|
+
void setEndTime(double endTime);
|
|
28
|
+
void setStartValue(float startValue);
|
|
29
|
+
void setEndValue(float endValue);
|
|
25
30
|
|
|
26
31
|
private:
|
|
27
32
|
double startTime_;
|
|
@@ -29,6 +34,7 @@ class ParamChange {
|
|
|
29
34
|
float startValue_;
|
|
30
35
|
float endValue_;
|
|
31
36
|
std::function<float(double, double, float, float, double)> calculateValue_;
|
|
37
|
+
ParamChangeEventType type_;
|
|
32
38
|
};
|
|
33
39
|
|
|
34
40
|
} // namespace audioapi
|
|
@@ -11,7 +11,7 @@ namespace audioapi {
|
|
|
11
11
|
StereoPannerNode::StereoPannerNode(BaseAudioContext *context)
|
|
12
12
|
: AudioNode(context) {
|
|
13
13
|
channelCountMode_ = ChannelCountMode::CLAMPED_MAX;
|
|
14
|
-
panParam_ = std::make_shared<AudioParam>(
|
|
14
|
+
panParam_ = std::make_shared<AudioParam>(0.0, -MAX_PAN, MAX_PAN);
|
|
15
15
|
isInitialized_ = true;
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#include "JsiHostObject.h"
|
|
2
|
+
|
|
3
|
+
namespace audioapi {
|
|
4
|
+
JsiHostObject::JsiHostObject() {
|
|
5
|
+
getters_ = std::make_unique<std::unordered_map<
|
|
6
|
+
std::string,
|
|
7
|
+
jsi::Value (JsiHostObject::*)(jsi::Runtime &)>>();
|
|
8
|
+
functions_ = std::make_unique<std::unordered_map<
|
|
9
|
+
std::string,
|
|
10
|
+
jsi::Value (JsiHostObject::*)(
|
|
11
|
+
jsi::Runtime &, const jsi::Value &, const jsi::Value *, size_t)>>();
|
|
12
|
+
setters_ = std::make_unique<std::unordered_map<
|
|
13
|
+
std::string,
|
|
14
|
+
void (JsiHostObject::*)(jsi::Runtime &, const jsi::Value &)>>();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
std::vector<jsi::PropNameID> JsiHostObject::getPropertyNames(jsi::Runtime &rt) {
|
|
18
|
+
std::vector<jsi::PropNameID> propertyNames;
|
|
19
|
+
propertyNames.reserve(
|
|
20
|
+
getters_->size() + functions_->size() + setters_->size());
|
|
21
|
+
|
|
22
|
+
for (const auto &it : *getters_) {
|
|
23
|
+
propertyNames.push_back(jsi::PropNameID::forUtf8(rt, it.first));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (const auto &it : *functions_) {
|
|
27
|
+
propertyNames.push_back(jsi::PropNameID::forAscii(rt, it.first));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
for (const auto &it : *setters_) {
|
|
31
|
+
propertyNames.push_back(jsi::PropNameID::forAscii(rt, it.first));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return propertyNames;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
jsi::Value JsiHostObject::get(
|
|
38
|
+
jsi::Runtime &runtime,
|
|
39
|
+
const jsi::PropNameID &name) {
|
|
40
|
+
auto nameAsString = name.utf8(runtime);
|
|
41
|
+
auto &hostFunctionCache = hostFunctionCache_.get(runtime);
|
|
42
|
+
|
|
43
|
+
auto cachedFunction = hostFunctionCache.find(nameAsString);
|
|
44
|
+
if (cachedFunction != hostFunctionCache.end()) {
|
|
45
|
+
return cachedFunction->second.asFunction(runtime);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
auto getter = getters_->find(nameAsString);
|
|
49
|
+
if (getter != getters_->end()) {
|
|
50
|
+
auto dispatcher = std::bind(getter->second, this, std::placeholders::_1);
|
|
51
|
+
|
|
52
|
+
return dispatcher(runtime);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
auto function = functions_->find(nameAsString);
|
|
56
|
+
if (function != functions_->end()) {
|
|
57
|
+
auto dispatcher = std::bind(
|
|
58
|
+
function->second,
|
|
59
|
+
reinterpret_cast<JsiHostObject *>(this),
|
|
60
|
+
std::placeholders::_1,
|
|
61
|
+
std::placeholders::_2,
|
|
62
|
+
std::placeholders::_3,
|
|
63
|
+
std::placeholders::_4);
|
|
64
|
+
|
|
65
|
+
return hostFunctionCache
|
|
66
|
+
.emplace(
|
|
67
|
+
nameAsString,
|
|
68
|
+
jsi::Function::createFromHostFunction(runtime, name, 0, dispatcher))
|
|
69
|
+
.first->second.asFunction(runtime);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return jsi::Value::undefined();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void JsiHostObject::set(
|
|
76
|
+
jsi::Runtime &runtime,
|
|
77
|
+
const jsi::PropNameID &name,
|
|
78
|
+
const jsi::Value &value) {
|
|
79
|
+
auto nameAsString = name.utf8(runtime);
|
|
80
|
+
|
|
81
|
+
auto setter = setters_->find(nameAsString);
|
|
82
|
+
|
|
83
|
+
if (setter != setters_->end()) {
|
|
84
|
+
auto dispatcher = std::bind(
|
|
85
|
+
setter->second, this, std::placeholders::_1, std::placeholders::_2);
|
|
86
|
+
|
|
87
|
+
return dispatcher(runtime, value);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
#include <map>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <unordered_map>
|
|
8
|
+
#include <utility>
|
|
9
|
+
#include <vector>
|
|
10
|
+
|
|
11
|
+
#include "RuntimeAwareCache.h"
|
|
12
|
+
|
|
13
|
+
#define JSI_HOST_FUNCTION(NAME) \
|
|
14
|
+
jsi::Value NAME( \
|
|
15
|
+
jsi::Runtime &runtime, \
|
|
16
|
+
const jsi::Value &thisVal, \
|
|
17
|
+
const jsi::Value *args, \
|
|
18
|
+
size_t count)
|
|
19
|
+
|
|
20
|
+
#define JSI_EXPORT_FUNCTION(CLASS, FUNCTION) \
|
|
21
|
+
std::make_pair( \
|
|
22
|
+
std::string(#FUNCTION), \
|
|
23
|
+
static_cast<jsi::Value (JsiHostObject::*)( \
|
|
24
|
+
jsi::Runtime &, const jsi::Value &, const jsi::Value *, size_t)>( \
|
|
25
|
+
&CLASS::FUNCTION))
|
|
26
|
+
|
|
27
|
+
#define JSI_PROPERTY_GETTER(name) jsi::Value name(jsi::Runtime &runtime)
|
|
28
|
+
|
|
29
|
+
#define JSI_EXPORT_PROPERTY_GETTER(CLASS, FUNCTION) \
|
|
30
|
+
std::make_pair( \
|
|
31
|
+
std::string(#FUNCTION), \
|
|
32
|
+
static_cast<jsi::Value (JsiHostObject::*)(jsi::Runtime &)>( \
|
|
33
|
+
&CLASS::FUNCTION))
|
|
34
|
+
|
|
35
|
+
#define JSI_PROPERTY_SETTER(name) \
|
|
36
|
+
void name(jsi::Runtime &runtime, const jsi::Value &value)
|
|
37
|
+
|
|
38
|
+
#define JSI_EXPORT_PROPERTY_SETTER(CLASS, FUNCTION) \
|
|
39
|
+
std::make_pair( \
|
|
40
|
+
std::string(#FUNCTION), \
|
|
41
|
+
static_cast<void (JsiHostObject::*)( \
|
|
42
|
+
jsi::Runtime &, const jsi::Value &)>(&CLASS::FUNCTION))
|
|
43
|
+
|
|
44
|
+
namespace audioapi {
|
|
45
|
+
|
|
46
|
+
using namespace facebook;
|
|
47
|
+
|
|
48
|
+
class JsiHostObject : public jsi::HostObject {
|
|
49
|
+
public:
|
|
50
|
+
JsiHostObject();
|
|
51
|
+
|
|
52
|
+
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
|
53
|
+
|
|
54
|
+
jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override;
|
|
55
|
+
|
|
56
|
+
void set(
|
|
57
|
+
jsi::Runtime &runtime,
|
|
58
|
+
const jsi::PropNameID &name,
|
|
59
|
+
const jsi::Value &value) override;
|
|
60
|
+
|
|
61
|
+
template <typename... Args>
|
|
62
|
+
void addGetters(Args... args) {
|
|
63
|
+
(getters_->insert(args), ...);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
template <typename... Args>
|
|
67
|
+
void addSetters(Args... args) {
|
|
68
|
+
(setters_->insert(args), ...);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
template <typename... Args>
|
|
72
|
+
void addFunctions(Args... args) {
|
|
73
|
+
(functions_->insert(args), ...);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
protected:
|
|
77
|
+
std::unique_ptr<std::unordered_map<
|
|
78
|
+
std::string,
|
|
79
|
+
jsi::Value (JsiHostObject::*)(jsi::Runtime &)>>
|
|
80
|
+
getters_;
|
|
81
|
+
|
|
82
|
+
std::unique_ptr<std::unordered_map<
|
|
83
|
+
std::string,
|
|
84
|
+
jsi::Value (JsiHostObject::*)(
|
|
85
|
+
jsi::Runtime &,
|
|
86
|
+
const jsi::Value &,
|
|
87
|
+
const jsi::Value *,
|
|
88
|
+
size_t)>>
|
|
89
|
+
functions_;
|
|
90
|
+
|
|
91
|
+
std::unique_ptr<std::unordered_map<
|
|
92
|
+
std::string,
|
|
93
|
+
void (JsiHostObject::*)(jsi::Runtime &, const jsi::Value &)>>
|
|
94
|
+
setters_;
|
|
95
|
+
|
|
96
|
+
private:
|
|
97
|
+
RuntimeAwareCache<std::map<std::string, jsi::Function>> hostFunctionCache_;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
} // namespace audioapi
|
|
@@ -4,17 +4,18 @@
|
|
|
4
4
|
#include <jsi/jsi.h>
|
|
5
5
|
#include <functional>
|
|
6
6
|
|
|
7
|
-
namespace
|
|
7
|
+
namespace audioapi {
|
|
8
8
|
|
|
9
9
|
using namespace facebook;
|
|
10
10
|
|
|
11
11
|
jsi::Value PromiseVendor::createPromise(
|
|
12
|
-
std::function<void(std::shared_ptr<Promise>)>
|
|
13
|
-
if (
|
|
14
|
-
throw
|
|
12
|
+
const std::function<void(std::shared_ptr<Promise>)> &function) {
|
|
13
|
+
if (runtime_ == nullptr) {
|
|
14
|
+
throw std::runtime_error("Runtime was null!");
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
auto
|
|
16
|
+
|
|
17
|
+
auto &runtime = *runtime_;
|
|
18
|
+
auto callInvoker = callInvoker_;
|
|
18
19
|
|
|
19
20
|
// get Promise constructor
|
|
20
21
|
auto promiseCtor = runtime.global().getPropertyAsFunction(runtime, "Promise");
|
|
@@ -24,7 +25,7 @@ jsi::Value PromiseVendor::createPromise(
|
|
|
24
25
|
runtime,
|
|
25
26
|
jsi::PropNameID::forUtf8(runtime, "runPromise"),
|
|
26
27
|
2,
|
|
27
|
-
[callInvoker,
|
|
28
|
+
[callInvoker, function](
|
|
28
29
|
jsi::Runtime &runtime,
|
|
29
30
|
const jsi::Value &thisValue,
|
|
30
31
|
const jsi::Value *arguments,
|
|
@@ -52,7 +53,7 @@ jsi::Value PromiseVendor::createPromise(
|
|
|
52
53
|
};
|
|
53
54
|
|
|
54
55
|
auto promise = std::make_shared<Promise>(resolveWrapper, rejectWrapper);
|
|
55
|
-
|
|
56
|
+
function(promise);
|
|
56
57
|
|
|
57
58
|
return jsi::Value::undefined();
|
|
58
59
|
});
|
|
@@ -61,4 +62,4 @@ jsi::Value PromiseVendor::createPromise(
|
|
|
61
62
|
return promiseCtor.callAsConstructor(runtime, runPromise);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
} // namespace
|
|
65
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <ReactCommon/CallInvoker.h>
|
|
4
|
+
#include <jsi/jsi.h>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <utility>
|
|
8
|
+
|
|
9
|
+
namespace audioapi {
|
|
10
|
+
|
|
11
|
+
using namespace facebook;
|
|
12
|
+
|
|
13
|
+
class Promise {
|
|
14
|
+
public:
|
|
15
|
+
Promise(
|
|
16
|
+
std::function<void(jsi::Value)> resolve,
|
|
17
|
+
std::function<void(const std::string &)> reject)
|
|
18
|
+
: resolve_(std::move(resolve)), reject_(std::move(reject)) {}
|
|
19
|
+
|
|
20
|
+
void resolve(jsi::Value &&value) {
|
|
21
|
+
resolve_(std::forward<jsi::Value>(value));
|
|
22
|
+
}
|
|
23
|
+
void reject(const std::string &errorMessage) {
|
|
24
|
+
reject_(errorMessage);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private:
|
|
28
|
+
std::function<void(jsi::Value)> resolve_;
|
|
29
|
+
std::function<void(const std::string &)> reject_;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
class PromiseVendor {
|
|
33
|
+
public:
|
|
34
|
+
PromiseVendor(
|
|
35
|
+
jsi::Runtime *runtime,
|
|
36
|
+
const std::shared_ptr<react::CallInvoker> &callInvoker)
|
|
37
|
+
: runtime_(runtime), callInvoker_(callInvoker) {}
|
|
38
|
+
|
|
39
|
+
public:
|
|
40
|
+
jsi::Value createPromise(
|
|
41
|
+
const std::function<void(std::shared_ptr<Promise>)> &function);
|
|
42
|
+
|
|
43
|
+
private:
|
|
44
|
+
jsi::Runtime *runtime_;
|
|
45
|
+
std::shared_ptr<react::CallInvoker> callInvoker_;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <unordered_map>
|
|
7
|
+
#include <utility>
|
|
8
|
+
|
|
9
|
+
#include "RuntimeLifecycleMonitor.h"
|
|
10
|
+
|
|
11
|
+
namespace audioapi {
|
|
12
|
+
|
|
13
|
+
using namespace facebook;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Provides a way to keep data specific to a jsi::Runtime instance that gets
|
|
17
|
+
* cleaned up when that runtime is destroyed. This is necessary because JSI does
|
|
18
|
+
* not allow for its associated objects to be retained past the runtime
|
|
19
|
+
* lifetime. If an object (e.g. jsi::Values or jsi::Function instances) is kept
|
|
20
|
+
* after the runtime is torn down, its destructor (once it is destroyed
|
|
21
|
+
* eventually) will result in a crash (JSI objects keep a pointer to memory
|
|
22
|
+
* managed by the runtime, accessing that portion of the memory after runtime is
|
|
23
|
+
* deleted is the root cause of that crash).
|
|
24
|
+
*/
|
|
25
|
+
template <typename T>
|
|
26
|
+
class RuntimeAwareCache : public RuntimeLifecycleListener {
|
|
27
|
+
public:
|
|
28
|
+
void onRuntimeDestroyed(jsi::Runtime *rt) override {
|
|
29
|
+
// A runtime has been destroyed, so destroy the related cache.
|
|
30
|
+
runtimeCaches_.erase(rt);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
~RuntimeAwareCache() override {
|
|
34
|
+
for (auto &cache : runtimeCaches_) {
|
|
35
|
+
// remove all `onRuntimeDestroyed` listeners.
|
|
36
|
+
RuntimeLifecycleMonitor::removeListener(*cache.first, this);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
T &get(jsi::Runtime &rt) {
|
|
41
|
+
if (runtimeCaches_.count(&rt) == 0) {
|
|
42
|
+
// This is the first time this Runtime has been accessed.
|
|
43
|
+
// We set up a `onRuntimeDestroyed` listener for it and
|
|
44
|
+
// initialize the cache map.
|
|
45
|
+
RuntimeLifecycleMonitor::addListener(rt, this);
|
|
46
|
+
|
|
47
|
+
T cache;
|
|
48
|
+
runtimeCaches_.emplace(&rt, std::move(cache));
|
|
49
|
+
}
|
|
50
|
+
return runtimeCaches_.at(&rt);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private:
|
|
54
|
+
std::unordered_map<jsi::Runtime *, T> runtimeCaches_;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#include "RuntimeLifecycleMonitor.h"
|
|
2
|
+
|
|
3
|
+
#include <unordered_map>
|
|
4
|
+
#include <unordered_set>
|
|
5
|
+
#include <utility>
|
|
6
|
+
|
|
7
|
+
namespace audioapi {
|
|
8
|
+
|
|
9
|
+
static std::unordered_map<
|
|
10
|
+
jsi::Runtime *,
|
|
11
|
+
std::unordered_set<RuntimeLifecycleListener *>>
|
|
12
|
+
listeners;
|
|
13
|
+
|
|
14
|
+
struct RuntimeLifecycleMonitorObject : public jsi::HostObject {
|
|
15
|
+
jsi::Runtime *rt_;
|
|
16
|
+
explicit RuntimeLifecycleMonitorObject(jsi::Runtime *rt) : rt_(rt) {}
|
|
17
|
+
~RuntimeLifecycleMonitorObject() override {
|
|
18
|
+
auto listenersSet = listeners.find(rt_);
|
|
19
|
+
if (listenersSet != listeners.end()) {
|
|
20
|
+
for (auto listener : listenersSet->second) {
|
|
21
|
+
listener->onRuntimeDestroyed(rt_);
|
|
22
|
+
}
|
|
23
|
+
listeners.erase(listenersSet);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
void RuntimeLifecycleMonitor::addListener(
|
|
29
|
+
jsi::Runtime &rt,
|
|
30
|
+
RuntimeLifecycleListener *listener) {
|
|
31
|
+
auto listenersSet = listeners.find(&rt);
|
|
32
|
+
if (listenersSet == listeners.end()) {
|
|
33
|
+
// We install a global host object in the provided runtime, this way we can
|
|
34
|
+
// use that host object destructor to get notified when the runtime is being
|
|
35
|
+
// terminated. We use a unique name for the object as it gets saved with the
|
|
36
|
+
// runtime's global object.
|
|
37
|
+
rt.global().setProperty(
|
|
38
|
+
rt,
|
|
39
|
+
"__rnaudioapi_runtime_lifecycle_monitor",
|
|
40
|
+
jsi::Object::createFromHostObject(
|
|
41
|
+
rt, std::make_shared<RuntimeLifecycleMonitorObject>(&rt)));
|
|
42
|
+
std::unordered_set<RuntimeLifecycleListener *> newSet;
|
|
43
|
+
newSet.insert(listener);
|
|
44
|
+
listeners.emplace(&rt, std::move(newSet));
|
|
45
|
+
} else {
|
|
46
|
+
listenersSet->second.insert(listener);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
void RuntimeLifecycleMonitor::removeListener(
|
|
51
|
+
jsi::Runtime &rt,
|
|
52
|
+
RuntimeLifecycleListener *listener) {
|
|
53
|
+
auto listenersSet = listeners.find(&rt);
|
|
54
|
+
if (listenersSet == listeners.end()) {
|
|
55
|
+
// nothing to do here
|
|
56
|
+
} else {
|
|
57
|
+
listenersSet->second.erase(listener);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
#include <memory>
|
|
5
|
+
|
|
6
|
+
namespace audioapi {
|
|
7
|
+
|
|
8
|
+
using namespace facebook;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Listener interface that allows for getting notified when a jsi::Runtime
|
|
12
|
+
* instance is destroyed.
|
|
13
|
+
*/
|
|
14
|
+
struct RuntimeLifecycleListener {
|
|
15
|
+
virtual ~RuntimeLifecycleListener() = default;
|
|
16
|
+
virtual void onRuntimeDestroyed(jsi::Runtime *) = 0;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This class provides an API via static methods for registering and
|
|
21
|
+
* unregistering runtime lifecycle listeners. The listeners can be used to
|
|
22
|
+
* cleanup any data that references a given jsi::Runtime instance before it gets
|
|
23
|
+
* destroyed.
|
|
24
|
+
*/
|
|
25
|
+
struct RuntimeLifecycleMonitor {
|
|
26
|
+
static void addListener(jsi::Runtime &rt, RuntimeLifecycleListener *listener);
|
|
27
|
+
static void removeListener(
|
|
28
|
+
jsi::Runtime &rt,
|
|
29
|
+
RuntimeLifecycleListener *listener);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
} // namespace audioapi
|