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.
Files changed (87) hide show
  1. package/README.md +4 -1
  2. package/android/src/main/cpp/audioapi/android/core/AudioDecoder.cpp +12 -14
  3. package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +38 -8
  4. package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +9 -3
  5. package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +4 -0
  6. package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +2 -2
  7. package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +2 -2
  8. package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +46 -0
  9. package/android/src/main/res/drawable/skip_backward_15.xml +16 -0
  10. package/android/src/main/res/drawable/skip_forward_15.xml +16 -0
  11. package/android/src/oldarch/NativeAudioAPIModuleSpec.java +4 -0
  12. package/common/cpp/audioapi/HostObjects/AudioBufferBaseSourceNodeHostObject.h +9 -0
  13. package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +3 -5
  14. package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +11 -2
  15. package/common/cpp/audioapi/core/AudioContext.cpp +6 -4
  16. package/common/cpp/audioapi/core/AudioContext.h +1 -1
  17. package/common/cpp/audioapi/core/AudioParam.cpp +13 -0
  18. package/common/cpp/audioapi/core/AudioParam.h +3 -0
  19. package/common/cpp/audioapi/core/BaseAudioContext.cpp +1 -1
  20. package/common/cpp/audioapi/core/BaseAudioContext.h +3 -2
  21. package/common/cpp/audioapi/core/OfflineAudioContext.cpp +2 -1
  22. package/common/cpp/audioapi/core/OfflineAudioContext.h +1 -1
  23. package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +1 -1
  24. package/common/cpp/audioapi/core/inputs/AudioRecorder.h +1 -0
  25. package/common/cpp/audioapi/core/sources/AudioBuffer.h +1 -0
  26. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +11 -0
  27. package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +4 -1
  28. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +11 -0
  29. package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +2 -1
  30. package/common/cpp/audioapi/core/utils/AudioNodeDestructor.h +1 -0
  31. package/common/cpp/audioapi/core/utils/AudioNodeManager.h +1 -2
  32. package/common/cpp/audioapi/dsp/AudioUtils.cpp +1 -1
  33. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +47 -17
  34. package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +6 -5
  35. package/common/cpp/audioapi/events/IAudioEventHandlerRegistry.h +25 -0
  36. package/common/cpp/audioapi/jsi/JsiPromise.cpp +1 -0
  37. package/common/cpp/audioapi/utils/AudioArray.h +1 -0
  38. package/common/cpp/audioapi/utils/CircularAudioArray.h +1 -0
  39. package/common/cpp/test/CMakeLists.txt +63 -0
  40. package/common/cpp/test/GainTest.cpp +78 -0
  41. package/common/cpp/test/MockAudioEventHandlerRegistry.h +22 -0
  42. package/common/cpp/test/OscillatorTest.cpp +22 -0
  43. package/common/cpp/test/RunTests.sh +26 -0
  44. package/ios/audioapi/ios/AudioAPIModule.mm +6 -0
  45. package/ios/audioapi/ios/core/IOSAudioPlayer.h +2 -1
  46. package/ios/audioapi/ios/core/IOSAudioPlayer.mm +5 -2
  47. package/ios/audioapi/ios/system/AudioSessionManager.h +4 -0
  48. package/ios/audioapi/ios/system/AudioSessionManager.mm +26 -0
  49. package/ios/audioapi/ios/system/LockScreenManager.mm +2 -0
  50. package/lib/commonjs/core/AudioBufferSourceNode.js +2 -2
  51. package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
  52. package/lib/commonjs/core/AudioScheduledSourceNode.js +4 -4
  53. package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
  54. package/lib/commonjs/plugin/withAudioAPI.js +1 -1
  55. package/lib/commonjs/plugin/withAudioAPI.js.map +1 -1
  56. package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
  57. package/lib/commonjs/system/AudioManager.js +3 -0
  58. package/lib/commonjs/system/AudioManager.js.map +1 -1
  59. package/lib/module/core/AudioBufferSourceNode.js +2 -2
  60. package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
  61. package/lib/module/core/AudioScheduledSourceNode.js +4 -4
  62. package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
  63. package/lib/module/plugin/withAudioAPI.js +1 -1
  64. package/lib/module/plugin/withAudioAPI.js.map +1 -1
  65. package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
  66. package/lib/module/system/AudioManager.js +3 -0
  67. package/lib/module/system/AudioManager.js.map +1 -1
  68. package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
  69. package/lib/typescript/core/AudioScheduledSourceNode.d.ts +2 -2
  70. package/lib/typescript/interfaces.d.ts +2 -2
  71. package/lib/typescript/interfaces.d.ts.map +1 -1
  72. package/lib/typescript/specs/NativeAudioAPIModule.d.ts +2 -1
  73. package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
  74. package/lib/typescript/system/AudioManager.d.ts +2 -1
  75. package/lib/typescript/system/AudioManager.d.ts.map +1 -1
  76. package/lib/typescript/system/types.d.ts +11 -0
  77. package/lib/typescript/system/types.d.ts.map +1 -1
  78. package/package.json +1 -1
  79. package/src/core/AudioBufferSourceNode.ts +2 -8
  80. package/src/core/AudioScheduledSourceNode.ts +4 -4
  81. package/src/interfaces.ts +2 -5
  82. package/src/plugin/withAudioAPI.ts +1 -1
  83. package/src/specs/NativeAudioAPIModule.ts +4 -1
  84. package/src/system/AudioManager.ts +10 -1
  85. package/src/system/types.ts +14 -0
  86. package/android/src/main/res/drawable/skip_backward_10.xml +0 -9
  87. 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,
@@ -4,6 +4,7 @@
4
4
  #include <mutex>
5
5
  #include <thread>
6
6
  #include <atomic>
7
+ #include <functional>
7
8
  #include <vector>
8
9
  #include <memory>
9
10
 
@@ -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();
@@ -28,6 +28,6 @@ float linearToDecibels(float value) {
28
28
  }
29
29
 
30
30
  float decibelsToLinear(float value) {
31
- return powf(10, value / 20);
31
+ return pow(10, value / 20);
32
32
  }
33
33
  } // namespace audioapi::dsp
@@ -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
- auto eventObject = createEventObject(body);
95
- handler->call(*runtime_, eventObject);
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
- auto eventObject = createEventObject(body);
126
- handlerIt->second->call(*runtime_, eventObject);
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>>(value)) {
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
@@ -1,4 +1,5 @@
1
1
  #include <audioapi/jsi/JsiPromise.h>
2
+ #include <stdexcept>
2
3
 
3
4
  namespace audioapi {
4
5
 
@@ -3,6 +3,7 @@
3
3
  #include <algorithm>
4
4
  #include <memory>
5
5
  #include <cstddef>
6
+ #include <cstring>
6
7
 
7
8
  namespace audioapi {
8
9
 
@@ -1,6 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  #include <audioapi/utils/AudioArray.h>
4
+ #include <stdexcept>
4
5
 
5
6
  namespace audioapi {
6
7
 
@@ -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
@@ -17,7 +17,8 @@ class IOSAudioPlayer {
17
17
  public:
18
18
  IOSAudioPlayer(
19
19
  const std::function<void(std::shared_ptr<AudioBus>, int)> &renderAudio,
20
- float sampleRate);
20
+ float sampleRate,
21
+ int channelCount);
21
22
  ~IOSAudioPlayer();
22
23
 
23
24
  void start();
@@ -8,8 +8,11 @@
8
8
 
9
9
  namespace audioapi {
10
10
 
11
- IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus>, int)> &renderAudio, float sampleRate)
12
- : channelCount_(2), renderAudio_(renderAudio), audioBus_(0), isRunning_(false)
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(this.node, null);
21
+ this.node.setBuffer(null);
22
22
  return;
23
23
  }
24
- this.node.setBuffer(this.node, buffer.buffer);
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,CAC7C,IAAI,CAACF,IAAI,EACT,IACF,CAAC;MACD;IACF;IAEC,IAAI,CAACA,IAAI,CAA4BE,SAAS,CAC7C,IAAI,CAACF,IAAI,EACTD,MAAM,CAACA,MACT,CAAC;EACH;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":[]}
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 onended() {
33
+ get onEnded() {
34
34
  return this.onEndedCallback;
35
35
  }
36
- set onended(callback) {
36
+ set onEnded(callback) {
37
37
  if (!callback) {
38
- this.node.onended = '0';
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.onended = this.onendedSubscription.subscriptionId;
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","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":[]}
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":[]}