react-native-audio-api 0.4.3 → 0.4.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.
@@ -15,7 +15,7 @@ buildscript {
15
15
 
16
16
  def reactNativeArchitectures() {
17
17
  def value = rootProject.getProperties().get("reactNativeArchitectures")
18
- return value ? value.split(",") : ["armeabi-v7a", "arm64-v8a", "x86_64"]
18
+ return value ? value.split(",") : ["armeabi-v7a", "arm64-v8a", "x86_64", "x86"]
19
19
  }
20
20
 
21
21
  def isNewArchitectureEnabled() {
Binary file
@@ -143,20 +143,16 @@ class BaseAudioContextHostObject : public JsiHostObject {
143
143
  JSI_HOST_FUNCTION(decodeAudioDataSource) {
144
144
  auto sourcePath = args[0].getString(runtime).utf8(runtime);
145
145
 
146
- auto promise = promiseVendor_->createPromise(
147
- [this, &runtime, sourcePath](std::shared_ptr<Promise> promise) {
148
- std::thread([this,
149
- &runtime,
150
- sourcePath,
151
- promise = std::move(promise)]() {
152
- auto results = context_->decodeAudioDataSource(sourcePath);
153
- auto audioBufferHostObject =
154
- std::make_shared<AudioBufferHostObject>(results);
155
-
156
- promise->resolve(jsi::Object::createFromHostObject(
157
- runtime, audioBufferHostObject));
158
- }).detach();
146
+ auto promise = promiseVendor_->createPromise([this, sourcePath](std::shared_ptr<Promise> promise) {
147
+ std::thread([this, sourcePath, promise = std::move(promise)]() {
148
+ auto results = context_->decodeAudioDataSource(sourcePath);
149
+ auto audioBufferHostObject = std::make_shared<AudioBufferHostObject>(results);
150
+
151
+ promise->resolve([audioBufferHostObject = std::move(audioBufferHostObject)](jsi::Runtime &runtime) {
152
+ return jsi::Object::createFromHostObject(runtime, audioBufferHostObject);
159
153
  });
154
+ }).detach();
155
+ });
160
156
 
161
157
  return promise;
162
158
  }
@@ -35,7 +35,7 @@ AudioContext::AudioContext(float sampleRate) : BaseAudioContext() {
35
35
  }
36
36
 
37
37
  AudioContext::~AudioContext() {
38
- if (isRunning()) {
38
+ if (isClosed()) {
39
39
  return;
40
40
  }
41
41
 
@@ -48,7 +48,7 @@ void AudioContext::close() {
48
48
  }
49
49
 
50
50
  std::function<void(AudioBus *, int)> AudioContext::renderAudio() {
51
- if (!isRunning()) {
51
+ if (!isRunning() || !destination_) {
52
52
  return [](AudioBus *, int) {};
53
53
  }
54
54
 
@@ -13,7 +13,6 @@ AudioNode::AudioNode(BaseAudioContext *context) : context_(context) {
13
13
  }
14
14
 
15
15
  AudioNode::~AudioNode() {
16
- isInitialized_ = false;
17
16
  cleanup();
18
17
  }
19
18
 
@@ -42,14 +41,9 @@ void AudioNode::connect(const std::shared_ptr<AudioNode> &node) {
42
41
  shared_from_this(), node, AudioNodeManager::ConnectionType::CONNECT);
43
42
  }
44
43
 
45
- void AudioNode::connectNode(const std::shared_ptr<AudioNode> &node) {
46
- outputNodes_.push_back(node);
47
- node->onInputConnected(this);
48
- }
49
-
50
44
  void AudioNode::disconnect() {
51
45
  for (auto &outputNode : outputNodes_) {
52
- disconnectNode(outputNode);
46
+ disconnect(outputNode);
53
47
  }
54
48
  }
55
49
 
@@ -58,16 +52,6 @@ void AudioNode::disconnect(const std::shared_ptr<AudioNode> &node) {
58
52
  shared_from_this(), node, AudioNodeManager::ConnectionType::DISCONNECT);
59
53
  }
60
54
 
61
- void AudioNode::disconnectNode(const std::shared_ptr<AudioNode> &node) {
62
- node->onInputDisconnected(this);
63
-
64
- auto position = std::find(outputNodes_.begin(), outputNodes_.end(), node);
65
-
66
- if (position != outputNodes_.end()) {
67
- outputNodes_.erase(position);
68
- }
69
- }
70
-
71
55
  bool AudioNode::isEnabled() const {
72
56
  return isEnabled_;
73
57
  }
@@ -186,10 +170,30 @@ AudioBus *AudioNode::processAudio(AudioBus *outputBus, int framesToProcess) {
186
170
  }
187
171
 
188
172
  void AudioNode::cleanup() {
173
+ isInitialized_ = false;
174
+
175
+ for (const auto &outputNode : outputNodes_) {
176
+ outputNode->onInputDisconnected(this);
177
+ }
178
+
179
+ for (const auto &inputNode : inputNodes_) {
180
+ inputNode->disconnectNode(shared_from_this());
181
+ }
182
+
189
183
  outputNodes_.clear();
190
184
  inputNodes_.clear();
191
185
  }
192
186
 
187
+ void AudioNode::connectNode(const std::shared_ptr<AudioNode> &node) {
188
+ outputNodes_.insert(node);
189
+ node->onInputConnected(this);
190
+ }
191
+
192
+ void AudioNode::disconnectNode(const std::shared_ptr<AudioNode> &node) {
193
+ outputNodes_.erase(node);
194
+ node->onInputDisconnected(this);
195
+ }
196
+
193
197
  void AudioNode::onInputEnabled() {
194
198
  numberOfEnabledInputNodes_ += 1;
195
199
 
@@ -211,7 +215,7 @@ void AudioNode::onInputConnected(AudioNode *node) {
211
215
  return;
212
216
  }
213
217
 
214
- inputNodes_.push_back(node);
218
+ inputNodes_.insert(node);
215
219
 
216
220
  if (node->isEnabled()) {
217
221
  onInputEnabled();
@@ -223,23 +227,11 @@ void AudioNode::onInputDisconnected(AudioNode *node) {
223
227
  return;
224
228
  }
225
229
 
226
- auto position = std::find(inputNodes_.begin(), inputNodes_.end(), node);
227
-
228
- if (position != inputNodes_.end()) {
229
- inputNodes_.erase(position);
230
- }
231
-
232
- if (!inputNodes_.empty()) {
233
- return;
234
- }
230
+ inputNodes_.erase(node);
235
231
 
236
232
  if (isEnabled()) {
237
233
  node->onInputDisabled();
238
234
  }
239
-
240
- for (const auto &outputNode : outputNodes_) {
241
- disconnectNode(outputNode);
242
- }
243
235
  }
244
236
 
245
237
  } // namespace audioapi
@@ -2,7 +2,7 @@
2
2
 
3
3
  #include <memory>
4
4
  #include <string>
5
- #include <vector>
5
+ #include <unordered_set>
6
6
  #include <cstddef>
7
7
 
8
8
  #include "ChannelCountMode.h"
@@ -18,6 +18,7 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {
18
18
  public:
19
19
  explicit AudioNode(BaseAudioContext *context);
20
20
  virtual ~AudioNode();
21
+
21
22
  int getNumberOfInputs() const;
22
23
  int getNumberOfOutputs() const;
23
24
  int getChannelCount() const;
@@ -45,8 +46,8 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {
45
46
  ChannelInterpretation channelInterpretation_ =
46
47
  ChannelInterpretation::SPEAKERS;
47
48
 
48
- std::vector<AudioNode *> inputNodes_ = {};
49
- std::vector<std::shared_ptr<AudioNode>> outputNodes_ = {};
49
+ std::unordered_set<AudioNode *> inputNodes_ = {};
50
+ std::unordered_set<std::shared_ptr<AudioNode>> outputNodes_ = {};
50
51
 
51
52
  int numberOfEnabledInputNodes_ = 0;
52
53
  bool isInitialized_ = false;
@@ -7,7 +7,6 @@ namespace audioapi {
7
7
 
8
8
  AudioNodeManager::~AudioNodeManager() {
9
9
  audioNodesToConnect_.clear();
10
- sourceNodes_.clear();
11
10
  }
12
11
 
13
12
  void AudioNodeManager::addPendingConnection(
@@ -19,31 +18,33 @@ void AudioNodeManager::addPendingConnection(
19
18
  audioNodesToConnect_.emplace_back(from, to, type);
20
19
  }
21
20
 
22
- void AudioNodeManager::addSourceNode(const std::shared_ptr<AudioNode> &node) {
23
- Locker lock(getGraphLock());
24
-
25
- sourceNodes_.push_back(node);
26
- }
27
-
28
21
  void AudioNodeManager::preProcessGraph() {
29
22
  if (!Locker::tryLock(getGraphLock())) {
30
23
  return;
31
24
  }
32
25
 
33
26
  settlePendingConnections();
34
- removeFinishedSourceNodes();
27
+ prepareNodesForDestruction();
35
28
  }
36
29
 
37
30
  std::mutex &AudioNodeManager::getGraphLock() {
38
31
  return graphLock_;
39
32
  }
40
33
 
34
+ void AudioNodeManager::addNode(const std::shared_ptr<AudioNode> &node) {
35
+ Locker lock(getGraphLock());
36
+
37
+ nodes_.insert(node);
38
+ }
39
+
41
40
  void AudioNodeManager::settlePendingConnections() {
42
41
  for (auto &connection : audioNodesToConnect_) {
43
42
  std::shared_ptr<AudioNode> from = std::get<0>(connection);
44
43
  std::shared_ptr<AudioNode> to = std::get<1>(connection);
45
44
  ConnectionType type = std::get<2>(connection);
46
45
 
46
+ // add assert to check if from and to are neither null nor uninitialized
47
+
47
48
  if (type == ConnectionType::CONNECT) {
48
49
  from->connectNode(to);
49
50
  } else {
@@ -54,16 +55,11 @@ void AudioNodeManager::settlePendingConnections() {
54
55
  audioNodesToConnect_.clear();
55
56
  }
56
57
 
57
- void AudioNodeManager::removeFinishedSourceNodes() {
58
- for (auto it = sourceNodes_.begin(); it != sourceNodes_.end();) {
59
- auto currentNode = it->get();
60
- // Release the source node if use count is equal to 1 (this vector)
61
- if (!currentNode->isEnabled() && it->use_count() == 1) {
62
- for (auto &outputNode : currentNode->outputNodes_) {
63
- currentNode->disconnectNode(outputNode);
64
- }
65
-
66
- it = sourceNodes_.erase(it);
58
+ void AudioNodeManager::prepareNodesForDestruction() {
59
+ for (auto it = nodes_.begin(); it != nodes_.end();) {
60
+ if (it->use_count() == 1) {
61
+ it->get()->cleanup();
62
+ it = nodes_.erase(it);
67
63
  } else {
68
64
  ++it;
69
65
  }
@@ -4,6 +4,7 @@
4
4
  #include <mutex>
5
5
  #include <tuple>
6
6
  #include <vector>
7
+ #include <unordered_set>
7
8
 
8
9
  namespace audioapi {
9
10
 
@@ -15,20 +16,24 @@ class AudioNodeManager {
15
16
  AudioNodeManager() = default;
16
17
  ~AudioNodeManager();
17
18
 
19
+ std::mutex &getGraphLock();
20
+
18
21
  void preProcessGraph();
22
+
19
23
  void addPendingConnection(
20
24
  const std::shared_ptr<AudioNode> &from,
21
25
  const std::shared_ptr<AudioNode> &to,
22
26
  ConnectionType type);
23
27
 
24
- void addSourceNode(const std::shared_ptr<AudioNode> &node);
25
-
26
- std::mutex &getGraphLock();
28
+ void addNode(const std::shared_ptr<AudioNode> &node);
27
29
 
28
30
  private:
29
31
  std::mutex graphLock_;
30
32
 
31
- std::vector<std::shared_ptr<AudioNode>> sourceNodes_;
33
+ // all nodes created in the context
34
+ std::unordered_set<std::shared_ptr<AudioNode>> nodes_;
35
+
36
+ // connections to be settled
32
37
  std::vector<std::tuple<
33
38
  std::shared_ptr<AudioNode>,
34
39
  std::shared_ptr<AudioNode>,
@@ -36,7 +41,7 @@ class AudioNodeManager {
36
41
  audioNodesToConnect_;
37
42
 
38
43
  void settlePendingConnections();
39
- void removeFinishedSourceNodes();
44
+ void prepareNodesForDestruction();
40
45
  };
41
46
 
42
47
  } // namespace audioapi
@@ -18,8 +18,6 @@ AudioScheduledSourceNode::AudioScheduledSourceNode(BaseAudioContext *context)
18
18
  void AudioScheduledSourceNode::start(double time) {
19
19
  playbackState_ = PlaybackState::SCHEDULED;
20
20
  startTime_ = time;
21
-
22
- context_->getNodeManager()->addSourceNode(shared_from_this());
23
21
  }
24
22
 
25
23
  void AudioScheduledSourceNode::stop(double time) {
@@ -42,23 +42,33 @@ std::shared_ptr<AudioDestinationNode> BaseAudioContext::getDestination() {
42
42
  }
43
43
 
44
44
  std::shared_ptr<OscillatorNode> BaseAudioContext::createOscillator() {
45
- return std::make_shared<OscillatorNode>(this);
45
+ auto oscillator = std::make_shared<OscillatorNode>(this);
46
+ nodeManager_->addNode(oscillator);
47
+ return oscillator;
46
48
  }
47
49
 
48
50
  std::shared_ptr<GainNode> BaseAudioContext::createGain() {
49
- return std::make_shared<GainNode>(this);
51
+ auto gain = std::make_shared<GainNode>(this);
52
+ nodeManager_->addNode(gain);
53
+ return gain;
50
54
  }
51
55
 
52
56
  std::shared_ptr<StereoPannerNode> BaseAudioContext::createStereoPanner() {
53
- return std::make_shared<StereoPannerNode>(this);
57
+ auto stereoPanner = std::make_shared<StereoPannerNode>(this);
58
+ nodeManager_->addNode(stereoPanner);
59
+ return stereoPanner;
54
60
  }
55
61
 
56
62
  std::shared_ptr<BiquadFilterNode> BaseAudioContext::createBiquadFilter() {
57
- return std::make_shared<BiquadFilterNode>(this);
63
+ auto biquadFilter = std::make_shared<BiquadFilterNode>(this);
64
+ nodeManager_->addNode(biquadFilter);
65
+ return biquadFilter;
58
66
  }
59
67
 
60
68
  std::shared_ptr<AudioBufferSourceNode> BaseAudioContext::createBufferSource() {
61
- return std::make_shared<AudioBufferSourceNode>(this);
69
+ auto bufferSource = std::make_shared<AudioBufferSourceNode>(this);
70
+ nodeManager_->addNode(bufferSource);
71
+ return bufferSource;
62
72
  }
63
73
 
64
74
  std::shared_ptr<AudioBuffer> BaseAudioContext::createBuffer(
@@ -78,7 +88,9 @@ std::shared_ptr<PeriodicWave> BaseAudioContext::createPeriodicWave(
78
88
  }
79
89
 
80
90
  std::shared_ptr<AnalyserNode> BaseAudioContext::createAnalyser() {
81
- return std::make_shared<AnalyserNode>(this);
91
+ auto analyser = std::make_shared<AnalyserNode>(this);
92
+ nodeManager_->addNode(analyser);
93
+ return analyser;
82
94
  }
83
95
 
84
96
  std::shared_ptr<AudioBuffer> BaseAudioContext::decodeAudioDataSource(
@@ -36,9 +36,12 @@ jsi::Value PromiseVendor::createPromise(
36
36
  auto reject = std::make_shared<jsi::Function>(std::move(rejectLocal));
37
37
 
38
38
  auto resolveWrapper =
39
- [resolve, &runtime, callInvoker](jsi::Value value) -> void {
40
- auto valueShared = std::make_shared<jsi::Value>(std::move(value));
41
- callInvoker->invokeAsync([resolve, &runtime, valueShared]() -> void {
39
+ [resolve, &runtime, callInvoker](
40
+ const std::function<jsi::Value(jsi::Runtime &)> resolver)
41
+ -> void {
42
+ callInvoker->invokeAsync([resolve, &runtime, resolver]() -> void {
43
+ auto valueShared = std::make_shared<jsi::Value>(resolver(runtime));
44
+
42
45
  resolve->call(runtime, *valueShared);
43
46
  });
44
47
  };
@@ -13,33 +13,26 @@ using namespace facebook;
13
13
 
14
14
  class Promise {
15
15
  public:
16
- Promise(
17
- std::function<void(jsi::Value)> resolve,
18
- std::function<void(const std::string &)> reject)
19
- : resolve_(std::move(resolve)), reject_(std::move(reject)) {}
16
+ Promise(std::function<void(const std::function<jsi::Value(jsi::Runtime&)>)> resolve, std::function<void(const std::string &)> reject) : resolve_(std::move(resolve)), reject_(std::move(reject)) {}
20
17
 
21
- void resolve(jsi::Value &&value) {
22
- resolve_(std::forward<jsi::Value>(value));
18
+ void resolve(const std::function<jsi::Value(jsi::Runtime&)> &resolver) {
19
+ resolve_(std::forward<const std::function<jsi::Value(jsi::Runtime&)>>(resolver));
23
20
  }
21
+
24
22
  void reject(const std::string &errorMessage) {
25
23
  reject_(errorMessage);
26
24
  }
27
25
 
28
26
  private:
29
- std::function<void(jsi::Value)> resolve_;
27
+ std::function<void(const std::function<jsi::Value(jsi::Runtime&)>)> resolve_;
30
28
  std::function<void(const std::string &)> reject_;
31
29
  };
32
30
 
33
31
  class PromiseVendor {
34
32
  public:
35
- PromiseVendor(
36
- jsi::Runtime *runtime,
37
- const std::shared_ptr<react::CallInvoker> &callInvoker)
38
- : runtime_(runtime), callInvoker_(callInvoker) {}
33
+ PromiseVendor(jsi::Runtime *runtime, const std::shared_ptr<react::CallInvoker> &callInvoker): runtime_(runtime), callInvoker_(callInvoker) {}
39
34
 
40
- public:
41
- jsi::Value createPromise(
42
- const std::function<void(std::shared_ptr<Promise>)> &function);
35
+ jsi::Value createPromise(const std::function<void(std::shared_ptr<Promise>)> &function);
43
36
 
44
37
  private:
45
38
  jsi::Runtime *runtime_;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-audio-api",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "description": "react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",