react-native-audio-api 0.3.1 → 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 +4 -13
- 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/AudioParamHostObject.h +39 -2
- package/common/cpp/core/AudioBufferSourceNode.cpp +4 -3
- package/{android/src/main/cpp/AudioDecoder → common/cpp/core}/AudioDecoder.h +1 -3
- package/common/cpp/core/AudioParam.cpp +218 -58
- package/common/cpp/core/AudioParam.h +19 -15
- package/common/cpp/core/AudioScheduledSourceNode.cpp +9 -1
- package/common/cpp/core/AudioScheduledSourceNode.h +4 -1
- 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 -4
- package/common/cpp/core/GainNode.cpp +1 -1
- package/common/cpp/core/OscillatorNode.cpp +4 -3
- 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 +35 -30
- package/common/cpp/jsi/JsiHostObject.h +12 -6
- 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.h +1 -5
- 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 +25 -20
- package/ios/core/AudioDecoder.mm +45 -0
- package/lib/module/core/AudioBuffer.js +3 -1
- package/lib/module/core/AudioBuffer.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +5 -3
- 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 +18 -11
- 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/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 +9 -3
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +4 -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/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 +31 -14
- package/src/interfaces.ts +12 -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 -20
- package/common/cpp/core/ParamChange.cpp +0 -46
- package/common/cpp/utils/android/FFTFrame.cpp +0 -23
- package/ios/AudioDecoder/AudioDecoder.h +0 -17
- package/ios/AudioDecoder/AudioDecoder.m +0 -79
- 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/common/cpp/{AudioAPIInstaller → HostObjects}/AudioAPIInstallerHostObject.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}/AudioPlayer.m +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
|
@@ -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
|
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
namespace audioapi {
|
|
4
4
|
JsiHostObject::JsiHostObject() {
|
|
5
|
-
|
|
5
|
+
getters_ = std::make_unique<std::unordered_map<
|
|
6
6
|
std::string,
|
|
7
7
|
jsi::Value (JsiHostObject::*)(jsi::Runtime &)>>();
|
|
8
|
-
|
|
8
|
+
functions_ = std::make_unique<std::unordered_map<
|
|
9
9
|
std::string,
|
|
10
10
|
jsi::Value (JsiHostObject::*)(
|
|
11
11
|
jsi::Runtime &, const jsi::Value &, const jsi::Value *, size_t)>>();
|
|
12
|
-
|
|
12
|
+
setters_ = std::make_unique<std::unordered_map<
|
|
13
13
|
std::string,
|
|
14
14
|
void (JsiHostObject::*)(jsi::Runtime &, const jsi::Value &)>>();
|
|
15
15
|
}
|
|
@@ -17,18 +17,17 @@ JsiHostObject::JsiHostObject() {
|
|
|
17
17
|
std::vector<jsi::PropNameID> JsiHostObject::getPropertyNames(jsi::Runtime &rt) {
|
|
18
18
|
std::vector<jsi::PropNameID> propertyNames;
|
|
19
19
|
propertyNames.reserve(
|
|
20
|
-
|
|
21
|
-
propertySetters_->size());
|
|
20
|
+
getters_->size() + functions_->size() + setters_->size());
|
|
22
21
|
|
|
23
|
-
for (const auto &it : *
|
|
22
|
+
for (const auto &it : *getters_) {
|
|
24
23
|
propertyNames.push_back(jsi::PropNameID::forUtf8(rt, it.first));
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
for (const auto &it : *
|
|
26
|
+
for (const auto &it : *functions_) {
|
|
28
27
|
propertyNames.push_back(jsi::PropNameID::forAscii(rt, it.first));
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
for (const auto &it : *
|
|
30
|
+
for (const auto &it : *setters_) {
|
|
32
31
|
propertyNames.push_back(jsi::PropNameID::forAscii(rt, it.first));
|
|
33
32
|
}
|
|
34
33
|
|
|
@@ -39,27 +38,35 @@ jsi::Value JsiHostObject::get(
|
|
|
39
38
|
jsi::Runtime &runtime,
|
|
40
39
|
const jsi::PropNameID &name) {
|
|
41
40
|
auto nameAsString = name.utf8(runtime);
|
|
41
|
+
auto &hostFunctionCache = hostFunctionCache_.get(runtime);
|
|
42
42
|
|
|
43
|
-
auto
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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);
|
|
48
51
|
|
|
49
52
|
return dispatcher(runtime);
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
auto
|
|
53
|
-
if (
|
|
54
|
-
auto dispatcher =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return
|
|
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);
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
return jsi::Value::undefined();
|
|
@@ -71,13 +78,11 @@ void JsiHostObject::set(
|
|
|
71
78
|
const jsi::Value &value) {
|
|
72
79
|
auto nameAsString = name.utf8(runtime);
|
|
73
80
|
|
|
74
|
-
auto
|
|
81
|
+
auto setter = setters_->find(nameAsString);
|
|
75
82
|
|
|
76
|
-
if (
|
|
77
|
-
auto dispatcher =
|
|
78
|
-
|
|
79
|
-
return (this->*(propertySetter->second))(runtime, value);
|
|
80
|
-
};
|
|
83
|
+
if (setter != setters_->end()) {
|
|
84
|
+
auto dispatcher = std::bind(
|
|
85
|
+
setter->second, this, std::placeholders::_1, std::placeholders::_2);
|
|
81
86
|
|
|
82
87
|
return dispatcher(runtime, value);
|
|
83
88
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include <jsi/jsi.h>
|
|
4
|
+
#include <map>
|
|
4
5
|
#include <memory>
|
|
5
6
|
#include <string>
|
|
6
7
|
#include <unordered_map>
|
|
7
8
|
#include <utility>
|
|
8
9
|
#include <vector>
|
|
9
10
|
|
|
11
|
+
#include "RuntimeAwareCache.h"
|
|
12
|
+
|
|
10
13
|
#define JSI_HOST_FUNCTION(NAME) \
|
|
11
14
|
jsi::Value NAME( \
|
|
12
15
|
jsi::Runtime &runtime, \
|
|
@@ -57,24 +60,24 @@ class JsiHostObject : public jsi::HostObject {
|
|
|
57
60
|
|
|
58
61
|
template <typename... Args>
|
|
59
62
|
void addGetters(Args... args) {
|
|
60
|
-
(
|
|
63
|
+
(getters_->insert(args), ...);
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
template <typename... Args>
|
|
64
67
|
void addSetters(Args... args) {
|
|
65
|
-
(
|
|
68
|
+
(setters_->insert(args), ...);
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
template <typename... Args>
|
|
69
72
|
void addFunctions(Args... args) {
|
|
70
|
-
(
|
|
73
|
+
(functions_->insert(args), ...);
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
protected:
|
|
74
77
|
std::unique_ptr<std::unordered_map<
|
|
75
78
|
std::string,
|
|
76
79
|
jsi::Value (JsiHostObject::*)(jsi::Runtime &)>>
|
|
77
|
-
|
|
80
|
+
getters_;
|
|
78
81
|
|
|
79
82
|
std::unique_ptr<std::unordered_map<
|
|
80
83
|
std::string,
|
|
@@ -83,12 +86,15 @@ class JsiHostObject : public jsi::HostObject {
|
|
|
83
86
|
const jsi::Value &,
|
|
84
87
|
const jsi::Value *,
|
|
85
88
|
size_t)>>
|
|
86
|
-
|
|
89
|
+
functions_;
|
|
87
90
|
|
|
88
91
|
std::unique_ptr<std::unordered_map<
|
|
89
92
|
std::string,
|
|
90
93
|
void (JsiHostObject::*)(jsi::Runtime &, const jsi::Value &)>>
|
|
91
|
-
|
|
94
|
+
setters_;
|
|
95
|
+
|
|
96
|
+
private:
|
|
97
|
+
RuntimeAwareCache<std::map<std::string, jsi::Function>> hostFunctionCache_;
|
|
92
98
|
};
|
|
93
99
|
|
|
94
100
|
} // 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
|
|
@@ -7,10 +7,6 @@ size_t timeToSampleFrame(double time, int sampleRate);
|
|
|
7
7
|
|
|
8
8
|
double sampleFrameToTime(int sampleFrame, int sampleRate);
|
|
9
9
|
|
|
10
|
-
float linearInterpolate(
|
|
11
|
-
const float *source,
|
|
12
|
-
size_t firstIndex,
|
|
13
|
-
size_t secondIndex,
|
|
14
|
-
float factor);
|
|
10
|
+
float linearInterpolate(const float *source, size_t firstIndex, size_t secondIndex, float factor);
|
|
15
11
|
|
|
16
12
|
} // namespace audioapi::AudioUtils
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
#if defined(HAVE_ACCELERATE)
|
|
2
1
|
#include "FFTFrame.h"
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
#if defined(HAVE_ACCELERATE)
|
|
4
|
+
#include <Accelerate/Accelerate.h>
|
|
5
|
+
#endif
|
|
6
|
+
|
|
7
|
+
#if defined(ANDROID)
|
|
8
|
+
#include <fftw3.h>
|
|
9
|
+
#endif
|
|
4
10
|
|
|
5
11
|
namespace audioapi {
|
|
12
|
+
#if defined(HAVE_ACCELERATE)
|
|
6
13
|
|
|
7
14
|
void FFTFrame::inverse(float *timeDomainData) {
|
|
8
15
|
FFTSetup fftSetup_ = vDSP_create_fftsetup(log2Size_, FFT_RADIX2);
|
|
@@ -25,5 +32,25 @@ void FFTFrame::inverse(float *timeDomainData) {
|
|
|
25
32
|
|
|
26
33
|
vDSP_destroy_fftsetup(fftSetup_);
|
|
27
34
|
}
|
|
28
|
-
|
|
35
|
+
|
|
36
|
+
#elif defined(ANDROID)
|
|
37
|
+
|
|
38
|
+
void FFTFrame::inverse(float *timeDomainData) {
|
|
39
|
+
fftwf_complex *freqDomainData = fftwf_alloc_complex(size_ / 2);
|
|
40
|
+
for (int i = 0; i < size_ / 2; i++) {
|
|
41
|
+
freqDomainData[i][0] = realData_[i];
|
|
42
|
+
freqDomainData[i][1] = imaginaryData_[i];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
auto plan = fftwf_plan_dft_c2r_1d(
|
|
46
|
+
size_, freqDomainData, timeDomainData, FFTW_ESTIMATE);
|
|
47
|
+
fftwf_execute(plan);
|
|
48
|
+
fftwf_destroy_plan(plan);
|
|
49
|
+
fftwf_free(freqDomainData);
|
|
50
|
+
|
|
51
|
+
VectorMath::multiplyByScalar(
|
|
52
|
+
timeDomainData, 1.0f / static_cast<float>(size_), timeDomainData, size_);
|
|
53
|
+
}
|
|
54
|
+
|
|
29
55
|
#endif
|
|
56
|
+
} // namespace audioapi
|
|
@@ -32,40 +32,14 @@
|
|
|
32
32
|
|
|
33
33
|
namespace audioapi::VectorMath {
|
|
34
34
|
|
|
35
|
-
void multiplyByScalarThenAddToOutput(
|
|
36
|
-
const float *inputVector,
|
|
37
|
-
float scalar,
|
|
38
|
-
float *outputVector,
|
|
39
|
-
size_t numberOfElementsToProcess);
|
|
35
|
+
void multiplyByScalarThenAddToOutput(const float *inputVector, float scalar, float *outputVector, size_t numberOfElementsToProcess);
|
|
40
36
|
|
|
41
|
-
void multiplyByScalar(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
void addScalar(
|
|
47
|
-
const float *inputVector,
|
|
48
|
-
float scalar,
|
|
49
|
-
float *outputVector,
|
|
50
|
-
size_t numberOfElementsToProcess);
|
|
51
|
-
void add(
|
|
52
|
-
const float *inputVector1,
|
|
53
|
-
const float *inputVector2,
|
|
54
|
-
float *outputVector,
|
|
55
|
-
size_t numberOfElementsToProcess);
|
|
56
|
-
void subtract(
|
|
57
|
-
const float *inputVector1,
|
|
58
|
-
const float *inputVector2,
|
|
59
|
-
float *outputVector,
|
|
60
|
-
size_t numberOfElementsToProcess);
|
|
61
|
-
void multiply(
|
|
62
|
-
const float *inputVector1,
|
|
63
|
-
const float *inputVector2,
|
|
64
|
-
float *outputVector,
|
|
65
|
-
size_t numberOfElementsToProcess);
|
|
37
|
+
void multiplyByScalar(const float *inputVector, float scalar, float *outputVector, size_t numberOfElementsToProcess);
|
|
38
|
+
void addScalar(const float *inputVector, float scalar, float *outputVector, size_t numberOfElementsToProcess);
|
|
39
|
+
void add(const float *inputVector1, const float *inputVector2, float *outputVector, size_t numberOfElementsToProcess);
|
|
40
|
+
void subtract(const float *inputVector1, const float *inputVector2, float *outputVector, size_t numberOfElementsToProcess);
|
|
41
|
+
void multiply(const float *inputVector1, const float *inputVector2, float *outputVector, size_t numberOfElementsToProcess);
|
|
66
42
|
|
|
67
43
|
// Finds the maximum magnitude of a float vector.
|
|
68
|
-
float maximumMagnitude(
|
|
69
|
-
const float *inputVector,
|
|
70
|
-
size_t numberOfElementsToProcess);
|
|
44
|
+
float maximumMagnitude(const float *inputVector, size_t numberOfElementsToProcess);
|
|
71
45
|
} // namespace audioapi::VectorMath
|
package/ios/AudioAPIModule.h
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2
|
-
#import <React/
|
|
3
|
-
#
|
|
4
|
-
#import <React/RCTRuntimeExecutorModule.h>
|
|
5
|
-
#import <ReactCommon/RCTRuntimeExecutor.h>
|
|
6
|
-
#endif // REACT_NATIVE_MINOR_VERSION >= 74
|
|
2
|
+
#import <React/RCTCallInvokerModule.h>
|
|
3
|
+
#import <rnaudioapi/rnaudioapi.h>
|
|
7
4
|
#else // RCT_NEW_ARCH_ENABLED
|
|
8
5
|
#import <React/RCTBridgeModule.h>
|
|
9
6
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
@@ -12,13 +9,8 @@
|
|
|
12
9
|
|
|
13
10
|
@interface AudioAPIModule : RCTEventEmitter
|
|
14
11
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
15
|
-
<
|
|
16
|
-
#if REACT_NATIVE_MINOR_VERSION >= 74
|
|
17
|
-
,
|
|
18
|
-
RCTRuntimeExecutorModule
|
|
19
|
-
#endif // REACT_NATIVE_MINOR_VERSION >= 74
|
|
12
|
+
<RCTCallInvokerModule>
|
|
20
13
|
#else
|
|
21
|
-
<RCTBridgeModule
|
|
14
|
+
<RCTBridgeModule>
|
|
22
15
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
23
|
-
>
|
|
24
16
|
@end
|
package/ios/AudioAPIModule.mm
CHANGED
|
@@ -1,39 +1,44 @@
|
|
|
1
1
|
#import "AudioAPIModule.h"
|
|
2
2
|
|
|
3
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
3
4
|
#import <React/RCTBridge+Private.h>
|
|
4
|
-
#import <React/
|
|
5
|
-
#import <React/RCTUtils.h>
|
|
5
|
+
#import <React/RCTCallInvoker.h>
|
|
6
6
|
#import <ReactCommon/RCTTurboModule.h>
|
|
7
|
-
#
|
|
7
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
8
8
|
|
|
9
9
|
#import "AudioAPIInstallerHostObject.h"
|
|
10
10
|
|
|
11
11
|
@implementation AudioAPIModule
|
|
12
12
|
|
|
13
|
+
#if defined(RCT_NEW_ARCH_ENABLED)
|
|
14
|
+
// nothing
|
|
15
|
+
#else // defined(RCT_NEW_ARCH_ENABLED)
|
|
16
|
+
@interface RCTBridge (RCTTurboModule)
|
|
17
|
+
- (std::shared_ptr<facebook::react::CallInvoker>)jsCallInvoker;
|
|
18
|
+
- (void)_tryAndHandleError:(dispatch_block_t)block;
|
|
19
|
+
@end
|
|
20
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
21
|
+
|
|
22
|
+
#if defined(RCT_NEW_ARCH_ENABLED)
|
|
23
|
+
@synthesize callInvoker = _callInvoker;
|
|
24
|
+
#endif // defined(RCT_NEW_ARCH_ENABLED)
|
|
25
|
+
|
|
13
26
|
RCT_EXPORT_MODULE(AudioAPIModule)
|
|
14
27
|
|
|
15
28
|
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
|
|
16
29
|
{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (cxxBridge == nil) {
|
|
21
|
-
NSLog(@"Error during getting bridge!");
|
|
22
|
-
return @false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
using namespace facebook;
|
|
26
|
-
|
|
27
|
-
auto jsRuntime = (jsi::Runtime *)cxxBridge.runtime;
|
|
30
|
+
auto *cxxBridge = reinterpret_cast<RCTCxxBridge *>(self.bridge);
|
|
31
|
+
auto jsiRuntime = reinterpret_cast<facebook::jsi::Runtime *>(cxxBridge.runtime);
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
#if defined(RCT_NEW_ARCH_ENABLED)
|
|
34
|
+
auto jsCallInvoker = _callInvoker.callInvoker;
|
|
35
|
+
#else // defined(RCT_NEW_ARCH_ENABLED)
|
|
36
|
+
auto jsCallInvoker = self.bridge.jsCallInvoker;
|
|
37
|
+
#endif // defined(RCT_NEW_ARCH_ENABLED)
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
assert(jsiRuntime != nullptr);
|
|
35
40
|
|
|
36
|
-
auto hostObject = std::make_shared<audioapi::AudioAPIInstallerHostObject>(
|
|
41
|
+
auto hostObject = std::make_shared<audioapi::AudioAPIInstallerHostObject>(jsiRuntime, jsCallInvoker);
|
|
37
42
|
hostObject->install();
|
|
38
43
|
|
|
39
44
|
NSLog(@"Successfully installed JSI bindings for react-native-audio-api!");
|