react-native-audio-api 0.6.5-rc.1 → 0.6.5
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/README.md +4 -1
- package/android/src/main/cpp/audioapi/android/core/AudioDecoder.cpp +12 -14
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +38 -8
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +9 -3
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +4 -0
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +2 -2
- package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +2 -2
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +46 -0
- package/android/src/main/res/drawable/skip_backward_15.xml +16 -0
- package/android/src/main/res/drawable/skip_forward_15.xml +16 -0
- package/android/src/oldarch/NativeAudioAPIModuleSpec.java +4 -0
- package/common/cpp/audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h +9 -0
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +3 -5
- package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +11 -2
- package/common/cpp/audioapi/core/AudioContext.cpp +6 -4
- package/common/cpp/audioapi/core/AudioContext.h +1 -1
- package/common/cpp/audioapi/core/AudioParam.cpp +13 -0
- package/common/cpp/audioapi/core/AudioParam.h +3 -0
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +1 -1
- package/common/cpp/audioapi/core/BaseAudioContext.h +3 -2
- package/common/cpp/audioapi/core/OfflineAudioContext.cpp +2 -1
- package/common/cpp/audioapi/core/OfflineAudioContext.h +1 -1
- package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +1 -1
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +1 -0
- package/common/cpp/audioapi/core/sources/AudioBuffer.h +1 -0
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +11 -0
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +4 -1
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +11 -0
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +2 -1
- package/common/cpp/audioapi/core/utils/AudioNodeDestructor.h +1 -0
- package/common/cpp/audioapi/core/utils/AudioNodeManager.h +1 -2
- package/common/cpp/audioapi/dsp/AudioUtils.cpp +1 -1
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +47 -17
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +6 -5
- package/common/cpp/audioapi/events/IAudioEventHandlerRegistry.h +25 -0
- package/common/cpp/audioapi/jsi/JsiPromise.cpp +1 -0
- package/common/cpp/audioapi/utils/AudioArray.h +1 -0
- package/common/cpp/audioapi/utils/CircularAudioArray.h +1 -0
- package/common/cpp/test/CMakeLists.txt +63 -0
- package/common/cpp/test/GainTest.cpp +78 -0
- package/common/cpp/test/MockAudioEventHandlerRegistry.h +22 -0
- package/common/cpp/test/OscillatorTest.cpp +22 -0
- package/common/cpp/test/RunTests.sh +26 -0
- package/ios/audioapi/ios/AudioAPIModule.mm +6 -0
- package/ios/audioapi/ios/core/IOSAudioPlayer.h +2 -1
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +5 -2
- package/ios/audioapi/ios/system/AudioSessionManager.h +4 -0
- package/ios/audioapi/ios/system/AudioSessionManager.mm +26 -0
- package/ios/audioapi/ios/system/LockScreenManager.mm +2 -0
- package/lib/commonjs/core/AudioBufferSourceNode.js +2 -2
- package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/commonjs/core/AudioScheduledSourceNode.js +4 -4
- package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/commonjs/plugin/withAudioAPI.js +1 -1
- package/lib/commonjs/plugin/withAudioAPI.js.map +1 -1
- package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/commonjs/system/AudioManager.js +3 -0
- package/lib/commonjs/system/AudioManager.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +2 -2
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +4 -4
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/plugin/withAudioAPI.js +1 -1
- package/lib/module/plugin/withAudioAPI.js.map +1 -1
- package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/module/system/AudioManager.js +3 -0
- package/lib/module/system/AudioManager.js.map +1 -1
- package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +2 -2
- package/lib/typescript/interfaces.d.ts +2 -2
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts +2 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
- package/lib/typescript/system/AudioManager.d.ts +2 -1
- package/lib/typescript/system/AudioManager.d.ts.map +1 -1
- package/lib/typescript/system/types.d.ts +11 -0
- package/lib/typescript/system/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/AudioBufferSourceNode.ts +2 -8
- package/src/core/AudioScheduledSourceNode.ts +4 -4
- package/src/interfaces.ts +2 -5
- package/src/plugin/withAudioAPI.ts +1 -1
- package/src/specs/NativeAudioAPIModule.ts +4 -1
- package/src/system/AudioManager.ts +10 -1
- package/src/system/types.ts +14 -0
- package/android/src/main/res/drawable/skip_backward_10.xml +0 -9
- package/android/src/main/res/drawable/skip_forward_10.xml +0 -9
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
#include <audioapi/libs/signalsmith-stretch/signalsmith-stretch.h>
|
|
5
5
|
|
|
6
6
|
#include <memory>
|
|
7
|
+
#include <mutex>
|
|
8
|
+
#include <atomic>
|
|
7
9
|
|
|
8
10
|
namespace audioapi {
|
|
9
11
|
|
|
@@ -18,6 +20,7 @@ class AudioBufferBaseSourceNode : public AudioScheduledSourceNode {
|
|
|
18
20
|
[[nodiscard]] std::shared_ptr<AudioParam> getDetuneParam() const;
|
|
19
21
|
[[nodiscard]] std::shared_ptr<AudioParam> getPlaybackRateParam() const;
|
|
20
22
|
|
|
23
|
+
void clearOnPositionChangedCallback();
|
|
21
24
|
void setOnPositionChangedCallbackId(uint64_t callbackId);
|
|
22
25
|
void setOnPositionChangedInterval(int interval);
|
|
23
26
|
[[nodiscard]] int getOnPositionChangedInterval();
|
|
@@ -36,7 +39,7 @@ class AudioBufferBaseSourceNode : public AudioScheduledSourceNode {
|
|
|
36
39
|
// internal helper
|
|
37
40
|
double vReadIndex_;
|
|
38
41
|
|
|
39
|
-
uint64_t onPositionChangedCallbackId_ = 0; // 0 means no callback
|
|
42
|
+
std::atomic<uint64_t> onPositionChangedCallbackId_ = 0; // 0 means no callback
|
|
40
43
|
int onPositionChangedInterval_;
|
|
41
44
|
int onPositionChangedTime_ = 0;
|
|
42
45
|
|
|
@@ -54,6 +54,17 @@ bool AudioScheduledSourceNode::isStopScheduled() {
|
|
|
54
54
|
return playbackState_ == PlaybackState::STOP_SCHEDULED;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
void AudioScheduledSourceNode::clearOnEndedCallback() {
|
|
58
|
+
if (onEndedCallbackId_ == 0 || context_ == nullptr ||
|
|
59
|
+
context_->audioEventHandlerRegistry_ == nullptr) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
context_->audioEventHandlerRegistry_->unregisterHandler(
|
|
64
|
+
"ended", onEndedCallbackId_);
|
|
65
|
+
onEndedCallbackId_ = 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
57
68
|
void AudioScheduledSourceNode::setOnEndedCallbackId(const uint64_t callbackId) {
|
|
58
69
|
onEndedCallbackId_ = callbackId;
|
|
59
70
|
}
|
|
@@ -38,6 +38,7 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
38
38
|
bool isFinished();
|
|
39
39
|
bool isStopScheduled();
|
|
40
40
|
|
|
41
|
+
void clearOnEndedCallback();
|
|
41
42
|
void setOnEndedCallbackId(uint64_t callbackId);
|
|
42
43
|
|
|
43
44
|
void disable() override;
|
|
@@ -48,7 +49,7 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
48
49
|
|
|
49
50
|
PlaybackState playbackState_;
|
|
50
51
|
|
|
51
|
-
uint64_t onEndedCallbackId_ = 0;
|
|
52
|
+
std::atomic<uint64_t> onEndedCallbackId_ = 0;
|
|
52
53
|
|
|
53
54
|
void updatePlaybackInfo(
|
|
54
55
|
const std::shared_ptr<AudioBus>& processingBus,
|
|
@@ -20,8 +20,6 @@ class AudioNodeManager {
|
|
|
20
20
|
AudioNodeManager() = default;
|
|
21
21
|
~AudioNodeManager();
|
|
22
22
|
|
|
23
|
-
std::mutex &getGraphLock();
|
|
24
|
-
|
|
25
23
|
void preProcessGraph();
|
|
26
24
|
|
|
27
25
|
void addPendingNodeConnection(
|
|
@@ -62,6 +60,7 @@ class AudioNodeManager {
|
|
|
62
60
|
ConnectionType>>
|
|
63
61
|
audioParamToConnect_;
|
|
64
62
|
|
|
63
|
+
std::mutex &getGraphLock();
|
|
65
64
|
void settlePendingConnections();
|
|
66
65
|
void cleanupNode(const std::shared_ptr<AudioNode> &node);
|
|
67
66
|
void prepareNodesForDestruction();
|
|
@@ -4,7 +4,8 @@ namespace audioapi {
|
|
|
4
4
|
|
|
5
5
|
AudioEventHandlerRegistry::AudioEventHandlerRegistry(
|
|
6
6
|
jsi::Runtime *runtime,
|
|
7
|
-
const std::shared_ptr<react::CallInvoker> &callInvoker)
|
|
7
|
+
const std::shared_ptr<react::CallInvoker> &callInvoker)
|
|
8
|
+
: IAudioEventHandlerRegistry() {
|
|
8
9
|
runtime_ = runtime;
|
|
9
10
|
callInvoker_ = callInvoker;
|
|
10
11
|
|
|
@@ -91,8 +92,18 @@ void AudioEventHandlerRegistry::invokeHandlerWithEventBody(
|
|
|
91
92
|
continue;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
try {
|
|
96
|
+
auto eventObject = createEventObject(body);
|
|
97
|
+
handler->call(*runtime_, eventObject);
|
|
98
|
+
} catch (const std::exception &e) {
|
|
99
|
+
// re-throw the exception to be handled by the caller
|
|
100
|
+
// std::exception is safe to parse by the rn bridge
|
|
101
|
+
throw;
|
|
102
|
+
} catch (...) {
|
|
103
|
+
printf(
|
|
104
|
+
"Unknown exception occurred while invoking handler for event: %s\n",
|
|
105
|
+
eventName.c_str());
|
|
106
|
+
}
|
|
96
107
|
}
|
|
97
108
|
});
|
|
98
109
|
}
|
|
@@ -122,8 +133,26 @@ void AudioEventHandlerRegistry::invokeHandlerWithEventBody(
|
|
|
122
133
|
return;
|
|
123
134
|
}
|
|
124
135
|
|
|
125
|
-
|
|
126
|
-
|
|
136
|
+
// Depending on how the AudioBufferSourceNode is handled on the JS side,
|
|
137
|
+
// it sometimes might enter race condition where the ABSN is deleted on JS
|
|
138
|
+
// side, but it is still processed on the audio thread, leading to a crash
|
|
139
|
+
// when f.e. `positionChanged` event is triggered.
|
|
140
|
+
|
|
141
|
+
// In case of debugging this, please increment the hours spent counter
|
|
142
|
+
|
|
143
|
+
// Hours spent on this: 5
|
|
144
|
+
try {
|
|
145
|
+
auto eventObject = createEventObject(body);
|
|
146
|
+
handlerIt->second->call(*runtime_, eventObject);
|
|
147
|
+
} catch (const std::exception &e) {
|
|
148
|
+
// re-throw the exception to be handled by the caller
|
|
149
|
+
// std::exception is safe to parse by the rn bridge
|
|
150
|
+
throw;
|
|
151
|
+
} catch (...) {
|
|
152
|
+
printf(
|
|
153
|
+
"Unknown exception occurred while invoking handler for event: %s\n",
|
|
154
|
+
eventName.c_str());
|
|
155
|
+
}
|
|
127
156
|
});
|
|
128
157
|
}
|
|
129
158
|
|
|
@@ -135,19 +164,20 @@ jsi::Object AudioEventHandlerRegistry::createEventObject(
|
|
|
135
164
|
const auto name = pair.first.data();
|
|
136
165
|
const auto &value = pair.second;
|
|
137
166
|
|
|
138
|
-
if (holds_alternative<int>(value)) {
|
|
139
|
-
eventObject.setProperty(*runtime_, name, get<int>(value));
|
|
140
|
-
} else if (holds_alternative<double>(value)) {
|
|
141
|
-
eventObject.setProperty(*runtime_, name, get<double>(value));
|
|
142
|
-
} else if (holds_alternative<float>(value)) {
|
|
143
|
-
eventObject.setProperty(*runtime_, name, get<float>(value));
|
|
144
|
-
} else if (holds_alternative<bool>(value)) {
|
|
145
|
-
eventObject.setProperty(*runtime_, name, get<bool>(value));
|
|
146
|
-
} else if (holds_alternative<std::string>(value)) {
|
|
147
|
-
eventObject.setProperty(*runtime_, name, get<std::string>(value));
|
|
148
|
-
} else if (holds_alternative<std::shared_ptr<jsi::HostObject>>(
|
|
167
|
+
if (std::holds_alternative<int>(value)) {
|
|
168
|
+
eventObject.setProperty(*runtime_, name, std::get<int>(value));
|
|
169
|
+
} else if (std::holds_alternative<double>(value)) {
|
|
170
|
+
eventObject.setProperty(*runtime_, name, std::get<double>(value));
|
|
171
|
+
} else if (std::holds_alternative<float>(value)) {
|
|
172
|
+
eventObject.setProperty(*runtime_, name, std::get<float>(value));
|
|
173
|
+
} else if (std::holds_alternative<bool>(value)) {
|
|
174
|
+
eventObject.setProperty(*runtime_, name, std::get<bool>(value));
|
|
175
|
+
} else if (std::holds_alternative<std::string>(value)) {
|
|
176
|
+
eventObject.setProperty(*runtime_, name, std::get<std::string>(value));
|
|
177
|
+
} else if (std::holds_alternative<std::shared_ptr<jsi::HostObject>>(
|
|
178
|
+
value)) {
|
|
149
179
|
auto hostObject = jsi::Object::createFromHostObject(
|
|
150
|
-
*runtime_, get<std::shared_ptr<jsi::HostObject>>(value));
|
|
180
|
+
*runtime_, std::get<std::shared_ptr<jsi::HostObject>>(value));
|
|
151
181
|
eventObject.setProperty(*runtime_, name, hostObject);
|
|
152
182
|
}
|
|
153
183
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
#include <jsi/jsi.h>
|
|
4
4
|
#include <ReactCommon/CallInvoker.h>
|
|
5
|
+
#include <audioapi/events/IAudioEventHandlerRegistry.h>
|
|
5
6
|
#include <memory>
|
|
6
7
|
#include <unordered_map>
|
|
7
8
|
#include <array>
|
|
@@ -14,18 +15,18 @@ using namespace facebook;
|
|
|
14
15
|
|
|
15
16
|
using EventValue = std::variant<int, float, double, std::string, bool, std::shared_ptr<jsi::HostObject>>;
|
|
16
17
|
|
|
17
|
-
class AudioEventHandlerRegistry {
|
|
18
|
+
class AudioEventHandlerRegistry : public IAudioEventHandlerRegistry {
|
|
18
19
|
public:
|
|
19
20
|
explicit AudioEventHandlerRegistry(
|
|
20
21
|
jsi::Runtime *runtime,
|
|
21
22
|
const std::shared_ptr<react::CallInvoker> &callInvoker);
|
|
22
23
|
~AudioEventHandlerRegistry();
|
|
23
24
|
|
|
24
|
-
uint64_t registerHandler(const std::string &eventName, const std::shared_ptr<jsi::Function> &handler);
|
|
25
|
-
void unregisterHandler(const std::string &eventName, uint64_t listenerId);
|
|
25
|
+
uint64_t registerHandler(const std::string &eventName, const std::shared_ptr<jsi::Function> &handler) override;
|
|
26
|
+
void unregisterHandler(const std::string &eventName, uint64_t listenerId) override;
|
|
26
27
|
|
|
27
|
-
void invokeHandlerWithEventBody(const std::string &eventName, const std::unordered_map<std::string, EventValue> &body);
|
|
28
|
-
void invokeHandlerWithEventBody(const std::string &eventName, uint64_t listenerId, const std::unordered_map<std::string, EventValue> &body);
|
|
28
|
+
void invokeHandlerWithEventBody(const std::string &eventName, const std::unordered_map<std::string, EventValue> &body) override;
|
|
29
|
+
void invokeHandlerWithEventBody(const std::string &eventName, uint64_t listenerId, const std::unordered_map<std::string, EventValue> &body) override;
|
|
29
30
|
|
|
30
31
|
private:
|
|
31
32
|
std::atomic<uint64_t> listenerIdCounter_{1}; // Atomic counter for listener IDs
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
#include <ReactCommon/CallInvoker.h>
|
|
5
|
+
#include <unordered_map>
|
|
6
|
+
#include <variant>
|
|
7
|
+
#include <string>
|
|
8
|
+
#include <memory>
|
|
9
|
+
|
|
10
|
+
namespace audioapi {
|
|
11
|
+
|
|
12
|
+
using EventValue = std::variant<int, float, double, std::string, bool, std::shared_ptr<facebook::jsi::HostObject>>;
|
|
13
|
+
|
|
14
|
+
class IAudioEventHandlerRegistry {
|
|
15
|
+
public:
|
|
16
|
+
virtual ~IAudioEventHandlerRegistry() = default;
|
|
17
|
+
|
|
18
|
+
virtual uint64_t registerHandler(const std::string &eventName, const std::shared_ptr<facebook::jsi::Function> &handler) = 0;
|
|
19
|
+
virtual void unregisterHandler(const std::string &eventName, uint64_t listenerId) = 0;
|
|
20
|
+
|
|
21
|
+
virtual void invokeHandlerWithEventBody(const std::string &eventName, const std::unordered_map<std::string, EventValue> &body) = 0;
|
|
22
|
+
virtual void invokeHandlerWithEventBody(const std::string &eventName, uint64_t listenerId, const std::unordered_map<std::string, EventValue> &body) = 0;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.14)
|
|
2
|
+
project(rnaudioapi_test)
|
|
3
|
+
|
|
4
|
+
set(CMAKE_CXX_STANDARD 17)
|
|
5
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
6
|
+
set(ROOT ${CMAKE_SOURCE_DIR}/../../../../..)
|
|
7
|
+
set(REACT_NATIVE_DIR "${ROOT}/node_modules/react-native")
|
|
8
|
+
set(JSI_DIR "${REACT_NATIVE_DIR}/ReactCommon/jsi")
|
|
9
|
+
|
|
10
|
+
include(FetchContent)
|
|
11
|
+
FetchContent_Declare(
|
|
12
|
+
googletest
|
|
13
|
+
URL https://github.com/google/googletest/archive/3983f67e32fb3e9294487b9d4f9586efa6e5d088.zip
|
|
14
|
+
)
|
|
15
|
+
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
|
16
|
+
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|
17
|
+
FetchContent_MakeAvailable(googletest)
|
|
18
|
+
|
|
19
|
+
enable_testing()
|
|
20
|
+
|
|
21
|
+
file(GLOB_RECURSE RNAUDIOAPI_SRC
|
|
22
|
+
CONFIGURE_DEPENDS
|
|
23
|
+
"${ROOT}/node_modules/react-native-audio-api/common/cpp/audioapi/*.cpp"
|
|
24
|
+
"${ROOT}/node_modules/react-native-audio-api/android/src/main/cpp/audioapi/android/core/AudioDecoder.cpp"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
list(REMOVE_ITEM RNAUDIOAPI_SRC "${ROOT}/node_modules/react-native-audio-api/common/cpp/audioapi/core/AudioContext.cpp")
|
|
28
|
+
|
|
29
|
+
file(GLOB_RECURSE RNAUDIOAPI_LIBS
|
|
30
|
+
CONFIGURE_DEPENDS
|
|
31
|
+
"${ROOT}/node_modules/react-native-audio-api/common/cpp/audioapi/libs/*.c"
|
|
32
|
+
"${ROOT}/node_modules/react-native-audio-api/common/cpp/audioapi/libs/*.h"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
add_library(rnaudioapi STATIC ${RNAUDIOAPI_SRC})
|
|
36
|
+
add_library(rnaudioapi_libs STATIC ${RNAUDIOAPI_LIBS})
|
|
37
|
+
|
|
38
|
+
target_include_directories(rnaudioapi PUBLIC
|
|
39
|
+
${ROOT}/packages/react-native-audio-api/common/cpp
|
|
40
|
+
${JSI_DIR}
|
|
41
|
+
"${REACT_NATIVE_DIR}/ReactCommon"
|
|
42
|
+
"${REACT_NATIVE_DIR}/ReactCommon/callinvoker"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
target_include_directories(rnaudioapi_libs PUBLIC
|
|
46
|
+
${ROOT}/packages/react-native-audio-api/common/cpp
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
add_executable(
|
|
50
|
+
tests
|
|
51
|
+
OscillatorTest.cpp
|
|
52
|
+
GainTest.cpp
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
target_link_libraries(tests
|
|
56
|
+
rnaudioapi
|
|
57
|
+
rnaudioapi_libs
|
|
58
|
+
GTest::gtest_main
|
|
59
|
+
GTest::gmock
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
include(GoogleTest)
|
|
63
|
+
gtest_discover_tests(tests)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#include <audioapi/core/OfflineAudioContext.h>
|
|
2
|
+
#include <audioapi/core/effects/GainNode.h>
|
|
3
|
+
#include <audioapi/utils/AudioArray.h>
|
|
4
|
+
#include <audioapi/utils/AudioBus.h>
|
|
5
|
+
#include <gtest/gtest.h>
|
|
6
|
+
#include "MockAudioEventHandlerRegistry.h"
|
|
7
|
+
|
|
8
|
+
class GainTest : public ::testing::Test {
|
|
9
|
+
protected:
|
|
10
|
+
std::shared_ptr<audioapi::IAudioEventHandlerRegistry> eventRegistry;
|
|
11
|
+
std::unique_ptr<audioapi::OfflineAudioContext> context;
|
|
12
|
+
static constexpr int sampleRate = 44100;
|
|
13
|
+
|
|
14
|
+
void SetUp() override {
|
|
15
|
+
eventRegistry = std::make_shared<MockAudioEventHandlerRegistry>();
|
|
16
|
+
context = std::make_unique<audioapi::OfflineAudioContext>(
|
|
17
|
+
2, 5 * sampleRate, sampleRate, eventRegistry);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
class TestableGainNode : public audioapi::GainNode {
|
|
22
|
+
public:
|
|
23
|
+
explicit TestableGainNode(audioapi::BaseAudioContext *context)
|
|
24
|
+
: audioapi::GainNode(context) {}
|
|
25
|
+
|
|
26
|
+
void setGainParam(float value) {
|
|
27
|
+
getGainParam()->setValue(value);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void processNode(
|
|
31
|
+
const std::shared_ptr<audioapi::AudioBus> &processingBus,
|
|
32
|
+
int framesToProcess) override {
|
|
33
|
+
audioapi::GainNode::processNode(processingBus, framesToProcess);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
TEST_F(GainTest, GainCanBeCreated) {
|
|
38
|
+
auto gain = context->createGain();
|
|
39
|
+
ASSERT_NE(gain, nullptr);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
TEST_F(GainTest, GainModulatesVolumeCorrectly) {
|
|
43
|
+
static constexpr float GAIN_VALUE = 0.5f;
|
|
44
|
+
static constexpr int FRAMES_TO_PROCESS = 4;
|
|
45
|
+
auto gainNode = std::make_shared<TestableGainNode>(context.get());
|
|
46
|
+
gainNode->setGainParam(GAIN_VALUE);
|
|
47
|
+
|
|
48
|
+
auto bus =
|
|
49
|
+
std::make_shared<audioapi::AudioBus>(FRAMES_TO_PROCESS, 1, sampleRate);
|
|
50
|
+
for (size_t i = 0; i < bus->getSize(); ++i) {
|
|
51
|
+
bus->getChannel(0)->getData()[i] = i + 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
gainNode->processNode(bus, FRAMES_TO_PROCESS);
|
|
55
|
+
for (size_t i = 0; i < bus->getSize(); ++i) {
|
|
56
|
+
EXPECT_FLOAT_EQ((*bus->getChannel(0))[i], (i + 1) * GAIN_VALUE);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
TEST_F(GainTest, GainModulatesVolumeCorrectlyMultiChannel) {
|
|
61
|
+
static constexpr float GAIN_VALUE = 0.5f;
|
|
62
|
+
static constexpr int FRAMES_TO_PROCESS = 4;
|
|
63
|
+
auto gainNode = std::make_shared<TestableGainNode>(context.get());
|
|
64
|
+
gainNode->setGainParam(GAIN_VALUE);
|
|
65
|
+
|
|
66
|
+
auto bus =
|
|
67
|
+
std::make_shared<audioapi::AudioBus>(FRAMES_TO_PROCESS, 2, sampleRate);
|
|
68
|
+
for (size_t i = 0; i < bus->getSize(); ++i) {
|
|
69
|
+
bus->getChannel(0)->getData()[i] = i + 1;
|
|
70
|
+
bus->getChannel(1)->getData()[i] = -i - 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
gainNode->processNode(bus, FRAMES_TO_PROCESS);
|
|
74
|
+
for (size_t i = 0; i < bus->getSize(); ++i) {
|
|
75
|
+
EXPECT_FLOAT_EQ((*bus->getChannel(0))[i], (i + 1) * GAIN_VALUE);
|
|
76
|
+
EXPECT_FLOAT_EQ((*bus->getChannel(1))[i], (-i - 1) * GAIN_VALUE);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <gmock/gmock.h>
|
|
4
|
+
#include <audioapi/events/IAudioEventHandlerRegistry.h>
|
|
5
|
+
#include <unordered_map>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <memory>
|
|
8
|
+
|
|
9
|
+
using EventMap = std::unordered_map<std::string, audioapi::EventValue>;
|
|
10
|
+
|
|
11
|
+
class MockAudioEventHandlerRegistry : public audioapi::IAudioEventHandlerRegistry {
|
|
12
|
+
public:
|
|
13
|
+
MOCK_METHOD(uint64_t, registerHandler,
|
|
14
|
+
(const std::string &eventName, const std::shared_ptr<facebook::jsi::Function> &handler), (override));
|
|
15
|
+
MOCK_METHOD(void, unregisterHandler,
|
|
16
|
+
(const std::string &eventName, uint64_t listenerId), (override));
|
|
17
|
+
|
|
18
|
+
MOCK_METHOD(void, invokeHandlerWithEventBody,
|
|
19
|
+
(const std::string &eventName, const EventMap &body), (override));
|
|
20
|
+
MOCK_METHOD(void, invokeHandlerWithEventBody,
|
|
21
|
+
(const std::string &eventName, uint64_t listenerId, const EventMap &body), (override));
|
|
22
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#include <audioapi/core/OfflineAudioContext.h>
|
|
2
|
+
#include <audioapi/core/sources/OscillatorNode.h>
|
|
3
|
+
#include <gtest/gtest.h>
|
|
4
|
+
#include "MockAudioEventHandlerRegistry.h"
|
|
5
|
+
|
|
6
|
+
class OscillatorTest : public ::testing::Test {
|
|
7
|
+
protected:
|
|
8
|
+
std::shared_ptr<audioapi::IAudioEventHandlerRegistry> eventRegistry;
|
|
9
|
+
std::unique_ptr<audioapi::OfflineAudioContext> context;
|
|
10
|
+
static constexpr int sampleRate = 44100;
|
|
11
|
+
|
|
12
|
+
void SetUp() override {
|
|
13
|
+
eventRegistry = std::make_shared<MockAudioEventHandlerRegistry>();
|
|
14
|
+
context = std::make_unique<audioapi::OfflineAudioContext>(
|
|
15
|
+
2, 5 * sampleRate, sampleRate, eventRegistry);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
TEST_F(OscillatorTest, OscillatorCanBeCreated) {
|
|
20
|
+
auto osc = context->createOscillator();
|
|
21
|
+
ASSERT_NE(osc, nullptr);
|
|
22
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
cleanup() {
|
|
6
|
+
echo "Cleaning up..."
|
|
7
|
+
rm -rf build/
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
trap cleanup EXIT
|
|
11
|
+
# Step 1: Move to the script's directory
|
|
12
|
+
cd packages/react-native-audio-api/common/cpp/test
|
|
13
|
+
# Step 2: Configure CMake project
|
|
14
|
+
# mkdir build
|
|
15
|
+
cmake -S . -B build
|
|
16
|
+
|
|
17
|
+
# Step 3: Build the project
|
|
18
|
+
cmake --build build
|
|
19
|
+
|
|
20
|
+
# Step 4: Run the test binary
|
|
21
|
+
cd build
|
|
22
|
+
./tests
|
|
23
|
+
cd ..
|
|
24
|
+
|
|
25
|
+
# Step 5: Clean up build directory
|
|
26
|
+
rm -rf build/
|
|
@@ -139,6 +139,12 @@ RCT_EXPORT_METHOD(checkRecordingPermissions : (nonnull RCTPromiseResolveBlock)
|
|
|
139
139
|
[self.audioSessionManager checkRecordingPermissions:resolve reject:reject];
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
RCT_EXPORT_METHOD(getDevicesInfo : (nonnull RCTPromiseResolveBlock)resolve reject : (nonnull RCTPromiseRejectBlock)
|
|
143
|
+
reject)
|
|
144
|
+
{
|
|
145
|
+
[self.audioSessionManager getDevicesInfo:resolve reject:reject];
|
|
146
|
+
}
|
|
147
|
+
|
|
142
148
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
143
149
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
144
150
|
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
namespace audioapi {
|
|
10
10
|
|
|
11
|
-
IOSAudioPlayer::IOSAudioPlayer(
|
|
12
|
-
|
|
11
|
+
IOSAudioPlayer::IOSAudioPlayer(
|
|
12
|
+
const std::function<void(std::shared_ptr<AudioBus>, int)> &renderAudio,
|
|
13
|
+
float sampleRate,
|
|
14
|
+
int channelCount)
|
|
15
|
+
: renderAudio_(renderAudio), channelCount_(channelCount), audioBus_(0), isRunning_(false)
|
|
13
16
|
{
|
|
14
17
|
RenderAudioBlock renderAudioBlock = ^(AudioBufferList *outputData, int numFrames) {
|
|
15
18
|
int processedFrames = 0;
|
|
@@ -26,7 +26,11 @@
|
|
|
26
26
|
options:(NSArray *)options
|
|
27
27
|
allowHaptics:(BOOL)allowHaptics;
|
|
28
28
|
- (bool)setActive:(bool)active;
|
|
29
|
+
|
|
29
30
|
- (void)requestRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
|
|
30
31
|
- (void)checkRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
|
|
31
32
|
|
|
33
|
+
- (void)getDevicesInfo:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
|
|
34
|
+
- (NSArray<NSDictionary *> *)parseDeviceList:(NSArray<AVAudioSessionPortDescription *> *)devices;
|
|
35
|
+
|
|
32
36
|
@end
|
|
@@ -292,4 +292,30 @@
|
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
+
- (void)getDevicesInfo:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject
|
|
296
|
+
{
|
|
297
|
+
NSMutableDictionary *devicesInfo = [[NSMutableDictionary alloc] init];
|
|
298
|
+
|
|
299
|
+
[devicesInfo setValue:[self parseDeviceList:[self.audioSession availableInputs]] forKey:@"availableInputs"];
|
|
300
|
+
[devicesInfo setValue:[self parseDeviceList:[[self.audioSession currentRoute] inputs]] forKey:@"currentInputs"];
|
|
301
|
+
[devicesInfo setValue:[self parseDeviceList:[[self.audioSession currentRoute] outputs]] forKey:@"availableOutputs"];
|
|
302
|
+
[devicesInfo setValue:[self parseDeviceList:[[self.audioSession currentRoute] outputs]] forKey:@"currentOutputs"];
|
|
303
|
+
|
|
304
|
+
resolve(devicesInfo);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
- (NSArray<NSDictionary *> *)parseDeviceList:(NSArray<AVAudioSessionPortDescription *> *)devices
|
|
308
|
+
{
|
|
309
|
+
NSMutableArray<NSDictionary *> *deviceList = [[NSMutableArray alloc] init];
|
|
310
|
+
|
|
311
|
+
for (AVAudioSessionPortDescription *device in devices) {
|
|
312
|
+
[deviceList addObject:@{
|
|
313
|
+
@"name" : device.portName,
|
|
314
|
+
@"category" : device.portType,
|
|
315
|
+
}];
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return deviceList;
|
|
319
|
+
}
|
|
320
|
+
|
|
295
321
|
@end
|
|
@@ -189,8 +189,10 @@
|
|
|
189
189
|
} else if ([name isEqual:@"remotePreviousTrack"]) {
|
|
190
190
|
[self enableCommand:remoteCenter.previousTrackCommand withSelector:@selector(onPreviousTrack:) enabled:enabled];
|
|
191
191
|
} else if ([name isEqual:@"remoteSkipForward"]) {
|
|
192
|
+
remoteCenter.skipForwardCommand.preferredIntervals = @[ @15 ];
|
|
192
193
|
[self enableCommand:remoteCenter.skipForwardCommand withSelector:@selector(onSkipForward:) enabled:enabled];
|
|
193
194
|
} else if ([name isEqual:@"remoteSkipBackward"]) {
|
|
195
|
+
remoteCenter.skipBackwardCommand.preferredIntervals = @[ @15 ];
|
|
194
196
|
[self enableCommand:remoteCenter.skipBackwardCommand withSelector:@selector(onSkipBackward:) enabled:enabled];
|
|
195
197
|
} else if ([name isEqual:@"remoteSeekForward"]) {
|
|
196
198
|
[self enableCommand:remoteCenter.seekForwardCommand withSelector:@selector(onSeekForward:) enabled:enabled];
|
|
@@ -18,10 +18,10 @@ class AudioBufferSourceNode extends _AudioBufferBaseSourceNode.default {
|
|
|
18
18
|
}
|
|
19
19
|
set buffer(buffer) {
|
|
20
20
|
if (!buffer) {
|
|
21
|
-
this.node.setBuffer(
|
|
21
|
+
this.node.setBuffer(null);
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
-
this.node.setBuffer(
|
|
24
|
+
this.node.setBuffer(buffer.buffer);
|
|
25
25
|
}
|
|
26
26
|
get loopSkip() {
|
|
27
27
|
return this.node.loopSkip;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_AudioBufferBaseSourceNode","_interopRequireDefault","require","_AudioBuffer","_errors","e","__esModule","default","AudioBufferSourceNode","AudioBufferBaseSourceNode","buffer","node","AudioBuffer","setBuffer","loopSkip","value","loop","loopStart","loopEnd","start","when","offset","duration","RangeError","hasBeenStarted","InvalidStateError","exports"],"sourceRoot":"../../../src","sources":["core/AudioBufferSourceNode.ts"],"mappings":";;;;;;AACA,IAAAA,0BAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AAA0D,SAAAD,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE3C,MAAMG,qBAAqB,SAASC,kCAAyB,CAAC;EAC3E,IAAWC,MAAMA,CAAA,EAAuB;IACtC,MAAMA,MAAM,GAAI,IAAI,CAACC,IAAI,CAA4BD,MAAM;IAC3D,IAAI,CAACA,MAAM,EAAE;MACX,OAAO,IAAI;IACb;IACA,OAAO,IAAIE,oBAAW,CAACF,MAAM,CAAC;EAChC;EAEA,IAAWA,MAAMA,CAACA,MAA0B,EAAE;IAC5C,IAAI,CAACA,MAAM,EAAE;MACV,IAAI,CAACC,IAAI,CAA4BE,SAAS,
|
|
1
|
+
{"version":3,"names":["_AudioBufferBaseSourceNode","_interopRequireDefault","require","_AudioBuffer","_errors","e","__esModule","default","AudioBufferSourceNode","AudioBufferBaseSourceNode","buffer","node","AudioBuffer","setBuffer","loopSkip","value","loop","loopStart","loopEnd","start","when","offset","duration","RangeError","hasBeenStarted","InvalidStateError","exports"],"sourceRoot":"../../../src","sources":["core/AudioBufferSourceNode.ts"],"mappings":";;;;;;AACA,IAAAA,0BAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AAA0D,SAAAD,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE3C,MAAMG,qBAAqB,SAASC,kCAAyB,CAAC;EAC3E,IAAWC,MAAMA,CAAA,EAAuB;IACtC,MAAMA,MAAM,GAAI,IAAI,CAACC,IAAI,CAA4BD,MAAM;IAC3D,IAAI,CAACA,MAAM,EAAE;MACX,OAAO,IAAI;IACb;IACA,OAAO,IAAIE,oBAAW,CAACF,MAAM,CAAC;EAChC;EAEA,IAAWA,MAAMA,CAACA,MAA0B,EAAE;IAC5C,IAAI,CAACA,MAAM,EAAE;MACV,IAAI,CAACC,IAAI,CAA4BE,SAAS,CAAC,IAAI,CAAC;MACrD;IACF;IAEC,IAAI,CAACF,IAAI,CAA4BE,SAAS,CAACH,MAAM,CAACA,MAAM,CAAC;EAChE;EAEA,IAAWI,QAAQA,CAAA,EAAY;IAC7B,OAAQ,IAAI,CAACH,IAAI,CAA4BG,QAAQ;EACvD;EAEA,IAAWA,QAAQA,CAACC,KAAc,EAAE;IACjC,IAAI,CAACJ,IAAI,CAA4BG,QAAQ,GAAGC,KAAK;EACxD;EAEA,IAAWC,IAAIA,CAAA,EAAY;IACzB,OAAQ,IAAI,CAACL,IAAI,CAA4BK,IAAI;EACnD;EAEA,IAAWA,IAAIA,CAACD,KAAc,EAAE;IAC7B,IAAI,CAACJ,IAAI,CAA4BK,IAAI,GAAGD,KAAK;EACpD;EAEA,IAAWE,SAASA,CAAA,EAAW;IAC7B,OAAQ,IAAI,CAACN,IAAI,CAA4BM,SAAS;EACxD;EAEA,IAAWA,SAASA,CAACF,KAAa,EAAE;IACjC,IAAI,CAACJ,IAAI,CAA4BM,SAAS,GAAGF,KAAK;EACzD;EAEA,IAAWG,OAAOA,CAAA,EAAW;IAC3B,OAAQ,IAAI,CAACP,IAAI,CAA4BO,OAAO;EACtD;EAEA,IAAWA,OAAOA,CAACH,KAAa,EAAE;IAC/B,IAAI,CAACJ,IAAI,CAA4BO,OAAO,GAAGH,KAAK;EACvD;EAEOI,KAAKA,CAACC,IAAY,GAAG,CAAC,EAAEC,MAAc,GAAG,CAAC,EAAEC,QAAiB,EAAQ;IAC1E,IAAIF,IAAI,GAAG,CAAC,EAAE;MACZ,MAAM,IAAIG,kBAAU,CAClB,8CAA8CH,IAAI,EACpD,CAAC;IACH;IAEA,IAAIC,MAAM,GAAG,CAAC,EAAE;MACd,MAAM,IAAIE,kBAAU,CAClB,gDAAgDF,MAAM,EACxD,CAAC;IACH;IAEA,IAAIC,QAAQ,IAAIA,QAAQ,GAAG,CAAC,EAAE;MAC5B,MAAM,IAAIC,kBAAU,CAClB,kDAAkDD,QAAQ,EAC5D,CAAC;IACH;IAEA,IAAI,IAAI,CAACE,cAAc,EAAE;MACvB,MAAM,IAAIC,yBAAiB,CAAC,kCAAkC,CAAC;IACjE;IAEA,IAAI,CAACD,cAAc,GAAG,IAAI;IACzB,IAAI,CAACb,IAAI,CAA4BQ,KAAK,CAACC,IAAI,EAAEC,MAAM,EAAEC,QAAQ,CAAC;EACrE;AACF;AAACI,OAAA,CAAAnB,OAAA,GAAAC,qBAAA","ignoreList":[]}
|
|
@@ -30,12 +30,12 @@ class AudioScheduledSourceNode extends _AudioNode.default {
|
|
|
30
30
|
}
|
|
31
31
|
this.node.stop(when);
|
|
32
32
|
}
|
|
33
|
-
get
|
|
33
|
+
get onEnded() {
|
|
34
34
|
return this.onEndedCallback;
|
|
35
35
|
}
|
|
36
|
-
set
|
|
36
|
+
set onEnded(callback) {
|
|
37
37
|
if (!callback) {
|
|
38
|
-
this.node.
|
|
38
|
+
this.node.onEnded = '0';
|
|
39
39
|
this.onendedSubscription?.remove();
|
|
40
40
|
this.onendedSubscription = undefined;
|
|
41
41
|
this.onEndedCallback = undefined;
|
|
@@ -43,7 +43,7 @@ class AudioScheduledSourceNode extends _AudioNode.default {
|
|
|
43
43
|
}
|
|
44
44
|
this.onEndedCallback = callback;
|
|
45
45
|
this.onendedSubscription = this.audioEventEmitter.addAudioEventListener('ended', callback);
|
|
46
|
-
this.node.
|
|
46
|
+
this.node.onEnded = this.onendedSubscription.subscriptionId;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
exports.default = AudioScheduledSourceNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_AudioNode","_interopRequireDefault","require","_errors","_events","e","__esModule","default","AudioScheduledSourceNode","AudioNode","hasBeenStarted","audioEventEmitter","AudioEventEmitter","global","start","when","RangeError","InvalidStateError","node","stop","
|
|
1
|
+
{"version":3,"names":["_AudioNode","_interopRequireDefault","require","_errors","_events","e","__esModule","default","AudioScheduledSourceNode","AudioNode","hasBeenStarted","audioEventEmitter","AudioEventEmitter","global","start","when","RangeError","InvalidStateError","node","stop","onEnded","onEndedCallback","callback","onendedSubscription","remove","undefined","addAudioEventListener","subscriptionId","exports"],"sourceRoot":"../../../src","sources":["core/AudioScheduledSourceNode.ts"],"mappings":";;;;;;AACA,IAAAA,UAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAEA,IAAAE,OAAA,GAAAF,OAAA;AAAsE,SAAAD,uBAAAI,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAEvD,MAAMG,wBAAwB,SAASC,kBAAS,CAAC;EACpDC,cAAc,GAAY,KAAK;EACtBC,iBAAiB,GAAG,IAAIC,yBAAiB,CAC1DC,MAAM,CAACD,iBACT,CAAC;EAKME,KAAKA,CAACC,IAAY,GAAG,CAAC,EAAQ;IACnC,IAAIA,IAAI,GAAG,CAAC,EAAE;MACZ,MAAM,IAAIC,kBAAU,CAClB,8CAA8CD,IAAI,EACpD,CAAC;IACH;IAEA,IAAI,IAAI,CAACL,cAAc,EAAE;MACvB,MAAM,IAAIO,yBAAiB,CAAC,kCAAkC,CAAC;IACjE;IAEA,IAAI,CAACP,cAAc,GAAG,IAAI;IACzB,IAAI,CAACQ,IAAI,CAA+BJ,KAAK,CAACC,IAAI,CAAC;EACtD;EAEOI,IAAIA,CAACJ,IAAY,GAAG,CAAC,EAAQ;IAClC,IAAIA,IAAI,GAAG,CAAC,EAAE;MACZ,MAAM,IAAIC,kBAAU,CAClB,8CAA8CD,IAAI,EACpD,CAAC;IACH;IAEA,IAAI,CAAC,IAAI,CAACL,cAAc,EAAE;MACxB,MAAM,IAAIO,yBAAiB,CACzB,8CACF,CAAC;IACH;IAEC,IAAI,CAACC,IAAI,CAA+BC,IAAI,CAACJ,IAAI,CAAC;EACrD;EAEA,IAAWK,OAAOA,CAAA,EAAkD;IAClE,OAAO,IAAI,CAACC,eAAe;EAC7B;EAEA,IAAWD,OAAOA,CAACE,QAAkD,EAAE;IACrE,IAAI,CAACA,QAAQ,EAAE;MACZ,IAAI,CAACJ,IAAI,CAA+BE,OAAO,GAAG,GAAG;MACtD,IAAI,CAACG,mBAAmB,EAAEC,MAAM,CAAC,CAAC;MAClC,IAAI,CAACD,mBAAmB,GAAGE,SAAS;MACpC,IAAI,CAACJ,eAAe,GAAGI,SAAS;MAChC;IACF;IAEA,IAAI,CAACJ,eAAe,GAAGC,QAAQ;IAC/B,IAAI,CAACC,mBAAmB,GAAG,IAAI,CAACZ,iBAAiB,CAACe,qBAAqB,CACrE,OAAO,EACPJ,QACF,CAAC;IAEA,IAAI,CAACJ,IAAI,CAA+BE,OAAO,GAC9C,IAAI,CAACG,mBAAmB,CAACI,cAAc;EAC3C;AACF;AAACC,OAAA,CAAArB,OAAA,GAAAC,wBAAA","ignoreList":[]}
|