react-native-audio-api 0.2.0 → 0.3.0-rc1

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 (78) hide show
  1. package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +16 -7
  2. package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +3 -2
  3. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +5 -3
  4. package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +5 -1
  5. package/common/cpp/HostObjects/AudioBufferHostObject.cpp +6 -0
  6. package/common/cpp/HostObjects/AudioContextHostObject.cpp +2 -2
  7. package/common/cpp/HostObjects/AudioContextHostObject.h +4 -3
  8. package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +28 -2
  9. package/common/cpp/HostObjects/BaseAudioContextHostObject.h +3 -1
  10. package/common/cpp/core/AudioArray.cpp +28 -14
  11. package/common/cpp/core/AudioArray.h +20 -14
  12. package/common/cpp/core/AudioBuffer.cpp +14 -11
  13. package/common/cpp/core/AudioBuffer.h +1 -0
  14. package/common/cpp/core/AudioBufferSourceNode.cpp +29 -19
  15. package/common/cpp/core/AudioBufferSourceNode.h +1 -1
  16. package/common/cpp/core/AudioBus.cpp +276 -115
  17. package/common/cpp/core/AudioBus.h +29 -9
  18. package/common/cpp/core/AudioContext.cpp +5 -9
  19. package/common/cpp/core/AudioDestinationNode.cpp +10 -8
  20. package/common/cpp/core/AudioDestinationNode.h +4 -4
  21. package/common/cpp/core/AudioNode.cpp +25 -17
  22. package/common/cpp/core/AudioNode.h +5 -5
  23. package/common/cpp/core/AudioNodeManager.cpp +10 -7
  24. package/common/cpp/core/AudioNodeManager.h +11 -4
  25. package/common/cpp/core/AudioScheduledSourceNode.cpp +2 -2
  26. package/common/cpp/core/BaseAudioContext.cpp +46 -12
  27. package/common/cpp/core/BaseAudioContext.h +12 -5
  28. package/common/cpp/core/BiquadFilterNode.cpp +5 -3
  29. package/common/cpp/core/GainNode.cpp +1 -1
  30. package/common/cpp/core/OscillatorNode.cpp +4 -4
  31. package/common/cpp/core/OscillatorNode.h +2 -2
  32. package/common/cpp/core/StereoPannerNode.cpp +10 -7
  33. package/common/cpp/core/StereoPannerNode.h +1 -1
  34. package/common/cpp/utils/FFTFrame.h +5 -1
  35. package/common/cpp/utils/JsiPromise.cpp +59 -0
  36. package/common/cpp/utils/JsiPromise.h +42 -0
  37. package/common/cpp/utils/Locker.h +8 -6
  38. package/common/cpp/utils/VectorMath.cpp +71 -55
  39. package/common/cpp/utils/android/FFTFrame.cpp +12 -11
  40. package/common/cpp/utils/ios/FFTFrame.cpp +6 -1
  41. package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +7 -0
  42. package/common/cpp/wrappers/BaseAudioContextWrapper.h +1 -0
  43. package/ios/AudioAPIModule.mm +3 -1
  44. package/ios/AudioDecoder/AudioDecoder.h +17 -0
  45. package/ios/AudioDecoder/AudioDecoder.m +167 -0
  46. package/ios/AudioDecoder/IOSAudioDecoder.h +26 -0
  47. package/ios/AudioDecoder/IOSAudioDecoder.mm +40 -0
  48. package/ios/AudioPlayer/AudioPlayer.h +1 -1
  49. package/ios/AudioPlayer/AudioPlayer.m +0 -1
  50. package/ios/AudioPlayer/IOSAudioPlayer.h +5 -5
  51. package/ios/AudioPlayer/IOSAudioPlayer.mm +4 -3
  52. package/lib/module/core/BaseAudioContext.js +5 -0
  53. package/lib/module/core/BaseAudioContext.js.map +1 -1
  54. package/lib/module/index.js +235 -17
  55. package/lib/module/index.js.map +1 -1
  56. package/lib/module/index.native.js +18 -0
  57. package/lib/module/index.native.js.map +1 -0
  58. package/lib/module/utils/resolveAudioSource.js +10 -0
  59. package/lib/module/utils/resolveAudioSource.js.map +1 -0
  60. package/lib/typescript/core/BaseAudioContext.d.ts +2 -1
  61. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  62. package/lib/typescript/core/types.d.ts +6 -0
  63. package/lib/typescript/core/types.d.ts.map +1 -1
  64. package/lib/typescript/index.d.ts +100 -13
  65. package/lib/typescript/index.d.ts.map +1 -1
  66. package/lib/typescript/index.native.d.ts +14 -0
  67. package/lib/typescript/index.native.d.ts.map +1 -0
  68. package/lib/typescript/interfaces.d.ts +1 -0
  69. package/lib/typescript/interfaces.d.ts.map +1 -1
  70. package/lib/typescript/utils/resolveAudioSource.d.ts +3 -0
  71. package/lib/typescript/utils/resolveAudioSource.d.ts.map +1 -0
  72. package/package.json +4 -2
  73. package/src/core/BaseAudioContext.ts +12 -1
  74. package/src/core/types.ts +7 -0
  75. package/src/index.native.ts +25 -0
  76. package/src/index.ts +413 -19
  77. package/src/interfaces.ts +1 -0
  78. package/src/utils/resolveAudioSource.ts +14 -0
@@ -1,13 +1,14 @@
1
1
 
2
- #include "AudioBus.h"
3
- #include "Constants.h"
4
- #include "AudioArray.h"
5
2
  #include "AudioPlayer.h"
3
+ #include "AudioArray.h"
4
+ #include "AudioBus.h"
6
5
  #include "AudioContext.h"
6
+ #include "Constants.h"
7
7
 
8
8
  namespace audioapi {
9
9
 
10
- AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
10
+ AudioPlayer::AudioPlayer(
11
+ const std::function<void(AudioBus *, int)> &renderAudio)
11
12
  : renderAudio_(renderAudio) {
12
13
  AudioStreamBuilder builder;
13
14
 
@@ -20,7 +21,9 @@ AudioPlayer::AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio)
20
21
  ->setDataCallback(this)
21
22
  ->openStream(mStream_);
22
23
 
23
- mBus_ = std::make_shared<AudioBus>(getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
24
+ mBus_ = std::make_shared<AudioBus>(
25
+ getSampleRate(), getBufferSizeInFrames(), CHANNEL_COUNT);
26
+ isInitialized_ = true;
24
27
  }
25
28
 
26
29
  int AudioPlayer::getSampleRate() const {
@@ -38,6 +41,8 @@ void AudioPlayer::start() {
38
41
  }
39
42
 
40
43
  void AudioPlayer::stop() {
44
+ isInitialized_ = false;
45
+
41
46
  if (mStream_) {
42
47
  mStream_->requestStop();
43
48
  mStream_->close();
@@ -49,14 +54,18 @@ DataCallbackResult AudioPlayer::onAudioReady(
49
54
  AudioStream *oboeStream,
50
55
  void *audioData,
51
56
  int32_t numFrames) {
52
- auto buffer = static_cast<float *>(audioData);
57
+ if (!isInitialized_) {
58
+ return DataCallbackResult::Continue;
59
+ }
53
60
 
61
+ auto buffer = static_cast<float *>(audioData);
54
62
  renderAudio_(mBus_.get(), numFrames);
55
63
 
56
64
  // TODO: optimize this with SIMD?
57
65
  for (int32_t i = 0; i < numFrames; i += 1) {
58
66
  for (int channel = 0; channel < CHANNEL_COUNT; channel += 1) {
59
- buffer[i * CHANNEL_COUNT + channel] = mBus_->getChannel(channel)->getData()[i];
67
+ buffer[i * CHANNEL_COUNT + channel] =
68
+ mBus_->getChannel(channel)->getData()[i];
60
69
  }
61
70
  }
62
71
 
@@ -12,7 +12,7 @@ class AudioBus;
12
12
 
13
13
  class AudioPlayer : public AudioStreamDataCallback {
14
14
  public:
15
- explicit AudioPlayer(const std::function<void(AudioBus*, int)> &renderAudio);
15
+ explicit AudioPlayer(const std::function<void(AudioBus *, int)> &renderAudio);
16
16
 
17
17
  int getSampleRate() const;
18
18
  int getBufferSizeInFrames() const;
@@ -25,9 +25,10 @@ class AudioPlayer : public AudioStreamDataCallback {
25
25
  int32_t numFrames) override;
26
26
 
27
27
  private:
28
- std::function<void(AudioBus*, int)> renderAudio_;
28
+ std::function<void(AudioBus *, int)> renderAudio_;
29
29
  std::shared_ptr<AudioStream> mStream_;
30
30
  std::shared_ptr<AudioBus> mBus_;
31
+ bool isInitialized_ = false;
31
32
  };
32
33
 
33
34
  } // namespace audioapi
@@ -4,8 +4,10 @@ namespace audioapi {
4
4
  using namespace facebook;
5
5
 
6
6
  AudioAPIInstallerHostObject::AudioAPIInstallerHostObject(
7
- const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper)
8
- : wrapper_(wrapper) {}
7
+ const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper, jsi::Runtime* runtime, const std::shared_ptr<facebook::react::CallInvoker> &jsInvoker)
8
+ : wrapper_(wrapper) {
9
+ promiseVendor_ = std::make_shared<JsiPromise::PromiseVendor>(runtime, jsInvoker);
10
+ }
9
11
 
10
12
  std::vector<jsi::PropNameID> AudioAPIInstallerHostObject::getPropertyNames(
11
13
  jsi::Runtime &runtime) {
@@ -32,7 +34,7 @@ jsi::Value AudioAPIInstallerHostObject::get(
32
34
  size_t count) -> jsi::Value {
33
35
  auto audioContext = wrapper_->createAudioContext();
34
36
  auto audioContextHostObject =
35
- AudioContextHostObject::createFromWrapper(audioContext);
37
+ AudioContextHostObject::createFromWrapper(audioContext, promiseVendor_);
36
38
  return jsi::Object::createFromHostObject(
37
39
  runtime, audioContextHostObject);
38
40
  });
@@ -1,12 +1,15 @@
1
1
  #pragma once
2
2
 
3
+ #include <ReactCommon/CallInvoker.h>
3
4
  #include <jsi/jsi.h>
4
5
  #include <memory>
5
6
  #include <utility>
6
7
  #include <vector>
7
8
 
9
+
8
10
  #include "AudioAPIInstallerWrapper.h"
9
11
  #include "AudioContextHostObject.h"
12
+ #include "JsiPromise.h"
10
13
 
11
14
  namespace audioapi {
12
15
  using namespace facebook;
@@ -16,7 +19,7 @@ class AudioAPIInstallerWrapper;
16
19
  class AudioAPIInstallerHostObject : public jsi::HostObject {
17
20
  public:
18
21
  explicit AudioAPIInstallerHostObject(
19
- const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper);
22
+ const std::shared_ptr<AudioAPIInstallerWrapper> &wrapper, jsi::Runtime* runtime, const std::shared_ptr<react::CallInvoker> &jsInvoker);
20
23
 
21
24
  #ifdef ANDROID
22
25
  static void createAndInstallFromWrapper(
@@ -41,5 +44,6 @@ class AudioAPIInstallerHostObject : public jsi::HostObject {
41
44
 
42
45
  private:
43
46
  std::shared_ptr<AudioAPIInstallerWrapper> wrapper_;
47
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor_;
44
48
  };
45
49
  } // namespace audioapi
@@ -128,6 +128,12 @@ jsi::Value AudioBufferHostObject::get(
128
128
  });
129
129
  }
130
130
 
131
+ // `decodeAudioData` is a method that returns a promise to AudioBufferHostObject
132
+ // It seems that async/await checks for the presence of `then` method on the object
133
+ if (propName == "then") {
134
+ return jsi::Value::undefined();
135
+ }
136
+
131
137
  throw std::runtime_error("Not yet implemented!");
132
138
  }
133
139
 
@@ -4,8 +4,8 @@ namespace audioapi {
4
4
  using namespace facebook;
5
5
 
6
6
  AudioContextHostObject::AudioContextHostObject(
7
- const std::shared_ptr<AudioContextWrapper> &wrapper)
8
- : BaseAudioContextHostObject(wrapper) {}
7
+ const std::shared_ptr<AudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor)
8
+ : BaseAudioContextHostObject(wrapper, promiseVendor) {}
9
9
 
10
10
  std::vector<jsi::PropNameID> AudioContextHostObject::getPropertyNames(
11
11
  jsi::Runtime &runtime) {
@@ -4,6 +4,7 @@
4
4
  #include <memory>
5
5
  #include <vector>
6
6
 
7
+ #include"JsiPromise.h"
7
8
  #include "AudioContextWrapper.h"
8
9
  #include "BaseAudioContextHostObject.h"
9
10
 
@@ -13,7 +14,7 @@ using namespace facebook;
13
14
  class AudioContextHostObject : public BaseAudioContextHostObject {
14
15
  public:
15
16
  explicit AudioContextHostObject(
16
- const std::shared_ptr<AudioContextWrapper> &wrapper);
17
+ const std::shared_ptr<AudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor);
17
18
 
18
19
  jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override;
19
20
 
@@ -25,8 +26,8 @@ class AudioContextHostObject : public BaseAudioContextHostObject {
25
26
  std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
26
27
 
27
28
  static std::shared_ptr<AudioContextHostObject> createFromWrapper(
28
- const std::shared_ptr<AudioContextWrapper> &wrapper) {
29
- return std::make_shared<AudioContextHostObject>(wrapper);
29
+ const std::shared_ptr<AudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor) {
30
+ return std::make_shared<AudioContextHostObject>(wrapper, promiseVendor);
30
31
  }
31
32
 
32
33
  private:
@@ -1,11 +1,13 @@
1
+ #include <thread>
2
+
1
3
  #include "BaseAudioContextHostObject.h"
2
4
 
3
5
  namespace audioapi {
4
6
  using namespace facebook;
5
7
 
6
8
  BaseAudioContextHostObject::BaseAudioContextHostObject(
7
- const std::shared_ptr<BaseAudioContextWrapper> &wrapper)
8
- : wrapper_(wrapper) {
9
+ const std::shared_ptr<BaseAudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor)
10
+ : wrapper_(wrapper), promiseVendor_(promiseVendor) {
9
11
  auto destinationNodeWrapper = wrapper_->getDestination();
10
12
  destination_ =
11
13
  AudioDestinationNodeHostObject::createFromWrapper(destinationNodeWrapper);
@@ -30,6 +32,8 @@ std::vector<jsi::PropNameID> BaseAudioContextHostObject::getPropertyNames(
30
32
  propertyNames.push_back(jsi::PropNameID::forUtf8(runtime, "createBuffer"));
31
33
  propertyNames.push_back(
32
34
  jsi::PropNameID::forUtf8(runtime, "createPeriodicWave"));
35
+ propertyNames.push_back(
36
+ jsi::PropNameID::forUtf8(runtime, "decodeAudioDataSource"));
33
37
  return propertyNames;
34
38
  }
35
39
 
@@ -200,6 +204,28 @@ jsi::Value BaseAudioContextHostObject::get(
200
204
  });
201
205
  }
202
206
 
207
+ if (propName == "decodeAudioDataSource") {
208
+ auto decode = [this](jsi::Runtime& runtime,
209
+ const jsi::Value&,
210
+ const jsi::Value* arguments,
211
+ size_t count) -> jsi::Value {
212
+ auto sourcePath = arguments[0].getString(runtime).utf8(runtime);
213
+
214
+ auto promise = promiseVendor_->createPromise([this, &runtime, sourcePath](std::shared_ptr<JsiPromise::Promise> promise) {
215
+ std::thread([this, &runtime, sourcePath, promise = std::move(promise)]() {
216
+ auto results = wrapper_->decodeAudioDataSource(sourcePath);
217
+ auto audioBufferHostObject = AudioBufferHostObject::createFromWrapper(results);
218
+
219
+ promise->resolve(jsi::Object::createFromHostObject(runtime, audioBufferHostObject));
220
+ }).detach();
221
+ });
222
+
223
+ return promise;
224
+ };
225
+
226
+ return jsi::Function::createFromHostFunction(runtime, propNameId, 1, decode);
227
+ }
228
+
203
229
  throw std::runtime_error("Not yet implemented!");
204
230
  }
205
231
 
@@ -5,6 +5,7 @@
5
5
  #include <utility>
6
6
  #include <vector>
7
7
 
8
+ #include "JsiPromise.h"
8
9
  #include "AudioBufferHostObject.h"
9
10
  #include "AudioBufferSourceNodeHostObject.h"
10
11
  #include "AudioDestinationNodeHostObject.h"
@@ -21,7 +22,7 @@ using namespace facebook;
21
22
  class BaseAudioContextHostObject : public jsi::HostObject {
22
23
  public:
23
24
  explicit BaseAudioContextHostObject(
24
- const std::shared_ptr<BaseAudioContextWrapper> &wrapper);
25
+ const std::shared_ptr<BaseAudioContextWrapper> &wrapper, std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor);
25
26
 
26
27
  jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override;
27
28
 
@@ -35,5 +36,6 @@ class BaseAudioContextHostObject : public jsi::HostObject {
35
36
  protected:
36
37
  std::shared_ptr<BaseAudioContextWrapper> wrapper_;
37
38
  std::shared_ptr<AudioDestinationNodeHostObject> destination_;
39
+ std::shared_ptr<JsiPromise::PromiseVendor> promiseVendor_;
38
40
  };
39
41
  } // namespace audioapi
@@ -5,14 +5,14 @@
5
5
 
6
6
  namespace audioapi {
7
7
 
8
- AudioArray::AudioArray(int size) : size_(size), data_(0) {
8
+ AudioArray::AudioArray(int size) : data_(nullptr), size_(size) {
9
9
  resize(size);
10
10
  }
11
11
 
12
12
  AudioArray::~AudioArray() {
13
13
  if (data_) {
14
14
  delete[] data_;
15
- data_ = 0;
15
+ data_ = nullptr;
16
16
  }
17
17
  }
18
18
 
@@ -20,15 +20,15 @@ int AudioArray::getSize() const {
20
20
  return size_;
21
21
  }
22
22
 
23
- float* AudioArray::getData() const {
23
+ float *AudioArray::getData() const {
24
24
  return data_;
25
25
  }
26
26
 
27
- float& AudioArray::operator[](int index) {
27
+ float &AudioArray::operator[](int index) {
28
28
  return data_[index];
29
29
  }
30
30
 
31
- const float& AudioArray::operator[](int index) const {
31
+ const float &AudioArray::operator[](int index) const {
32
32
  return data_[index];
33
33
  }
34
34
 
@@ -75,29 +75,43 @@ void AudioArray::zero(int start, int length) {
75
75
  memset(data_ + start, 0, length * sizeof(float));
76
76
  }
77
77
 
78
- void AudioArray::sum(const AudioArray* source) {
78
+ void AudioArray::sum(const AudioArray *source) {
79
79
  sum(source, 0, 0, size_);
80
80
  }
81
81
 
82
- void AudioArray::sum(const AudioArray* source, int start, int length) {
82
+ void AudioArray::sum(const AudioArray *source, int start, int length) {
83
83
  sum(source, start, start, length);
84
84
  }
85
85
 
86
- void AudioArray::sum(const AudioArray* source, int sourceStart, int destinationStart, int length) {
87
- VectorMath::add(data_ + destinationStart, source->getData() + sourceStart, data_ + destinationStart, length);
86
+ void AudioArray::sum(
87
+ const AudioArray *source,
88
+ int sourceStart,
89
+ int destinationStart,
90
+ int length) {
91
+ VectorMath::add(
92
+ data_ + destinationStart,
93
+ source->getData() + sourceStart,
94
+ data_ + destinationStart,
95
+ length);
88
96
  }
89
97
 
90
- void AudioArray::copy(const AudioArray* source) {
98
+ void AudioArray::copy(const AudioArray *source) {
91
99
  copy(source, 0, size_);
92
100
  }
93
101
 
94
- void AudioArray::copy(const AudioArray* source, int start, int length) {
102
+ void AudioArray::copy(const AudioArray *source, int start, int length) {
95
103
  copy(source, start, start, length);
96
104
  }
97
105
 
98
- void AudioArray::copy(const AudioArray* source, int sourceStart, int destinationStart, int length) {
99
- memcpy(data_ + destinationStart, source->getData() + sourceStart, length * sizeof(float));
106
+ void AudioArray::copy(
107
+ const AudioArray *source,
108
+ int sourceStart,
109
+ int destinationStart,
110
+ int length) {
111
+ memcpy(
112
+ data_ + destinationStart,
113
+ source->getData() + sourceStart,
114
+ length * sizeof(float));
100
115
  }
101
116
 
102
117
  } // namespace audioapi
103
-
@@ -1,7 +1,7 @@
1
1
  #pragma once
2
2
 
3
- #include <memory>
4
3
  #include <algorithm>
4
+ #include <memory>
5
5
 
6
6
  namespace audioapi {
7
7
 
@@ -11,28 +11,34 @@ class AudioArray {
11
11
  ~AudioArray();
12
12
 
13
13
  [[nodiscard]] int getSize() const;
14
- float* getData() const;
15
-
14
+ [[nodiscard]] float *getData() const;
16
15
 
17
- float& operator[](int index);
18
- const float& operator[](int index) const;
16
+ float &operator[](int index);
17
+ const float &operator[](int index) const;
19
18
 
20
19
  void normalize();
21
20
  void resize(int size);
22
21
  void scale(float value);
23
- float getMaxAbsValue() const;
22
+ [[nodiscard]] float getMaxAbsValue() const;
24
23
 
25
24
  void zero();
26
25
  void zero(int start, int length);
27
26
 
28
- void sum(const AudioArray* source);
29
- void sum(const AudioArray* source, int start, int length);
30
- void sum(const AudioArray* source, int sourceStart, int destinationStart, int length);
31
-
32
- void copy(const AudioArray* source);
33
- void copy(const AudioArray* source, int start, int length);
34
- void copy(const AudioArray* source, int sourceStart, int destinationStart, int length);
35
-
27
+ void sum(const AudioArray *source);
28
+ void sum(const AudioArray *source, int start, int length);
29
+ void sum(
30
+ const AudioArray *source,
31
+ int sourceStart,
32
+ int destinationStart,
33
+ int length);
34
+
35
+ void copy(const AudioArray *source);
36
+ void copy(const AudioArray *source, int start, int length);
37
+ void copy(
38
+ const AudioArray *source,
39
+ int sourceStart,
40
+ int destinationStart,
41
+ int length);
36
42
 
37
43
  private:
38
44
  float *data_;
@@ -1,6 +1,6 @@
1
- #include "AudioBus.h"
2
- #include "AudioArray.h"
3
1
  #include "AudioBuffer.h"
2
+ #include "AudioArray.h"
3
+ #include "AudioBus.h"
4
4
 
5
5
  namespace audioapi {
6
6
 
@@ -8,6 +8,10 @@ AudioBuffer::AudioBuffer(int numberOfChannels, int length, int sampleRate) {
8
8
  bus_ = std::make_shared<AudioBus>(sampleRate, length, numberOfChannels);
9
9
  }
10
10
 
11
+ AudioBuffer::AudioBuffer(AudioBus *bus) {
12
+ bus_ = std::shared_ptr<AudioBus>(bus);
13
+ }
14
+
11
15
  int AudioBuffer::getLength() const {
12
16
  return bus_->getSize();
13
17
  }
@@ -24,7 +28,7 @@ double AudioBuffer::getDuration() const {
24
28
  return static_cast<double>(getLength()) / getSampleRate();
25
29
  }
26
30
 
27
- float* AudioBuffer::getChannelData(int channel) const {
31
+ float *AudioBuffer::getChannelData(int channel) const {
28
32
  return bus_->getChannel(channel)->getData();
29
33
  }
30
34
 
@@ -34,10 +38,10 @@ void AudioBuffer::copyFromChannel(
34
38
  int channelNumber,
35
39
  int startInChannel) const {
36
40
  memcpy(
37
- destination,
38
- bus_->getChannel(channelNumber)->getData() + startInChannel,
39
- std::min(destinationLength, getLength() - startInChannel) * sizeof(float)
40
- );
41
+ destination,
42
+ bus_->getChannel(channelNumber)->getData() + startInChannel,
43
+ std::min(destinationLength, getLength() - startInChannel) *
44
+ sizeof(float));
41
45
  }
42
46
 
43
47
  void AudioBuffer::copyToChannel(
@@ -46,10 +50,9 @@ void AudioBuffer::copyToChannel(
46
50
  int channelNumber,
47
51
  int startInChannel) {
48
52
  memcpy(
49
- bus_->getChannel(channelNumber)->getData() + startInChannel,
50
- source,
51
- std::min(sourceLength, getLength() - startInChannel) * sizeof(float)
52
- );
53
+ bus_->getChannel(channelNumber)->getData() + startInChannel,
54
+ source,
55
+ std::min(sourceLength, getLength() - startInChannel) * sizeof(float));
53
56
  }
54
57
 
55
58
  } // namespace audioapi
@@ -12,6 +12,7 @@ class AudioBus;
12
12
  class AudioBuffer : public std::enable_shared_from_this<AudioBuffer> {
13
13
  public:
14
14
  explicit AudioBuffer(int numberOfChannels, int length, int sampleRate);
15
+ explicit AudioBuffer(AudioBus *bus);
15
16
 
16
17
  [[nodiscard]] int getLength() const;
17
18
  [[nodiscard]] int getSampleRate() const;
@@ -1,9 +1,9 @@
1
1
  #include <algorithm>
2
2
 
3
- #include "AudioBus.h"
4
3
  #include "AudioArray.h"
5
- #include "BaseAudioContext.h"
6
4
  #include "AudioBufferSourceNode.h"
5
+ #include "AudioBus.h"
6
+ #include "BaseAudioContext.h"
7
7
 
8
8
  namespace audioapi {
9
9
 
@@ -28,7 +28,6 @@ void AudioBufferSourceNode::setLoop(bool loop) {
28
28
 
29
29
  void AudioBufferSourceNode::setBuffer(
30
30
  const std::shared_ptr<AudioBuffer> &buffer) {
31
-
32
31
  if (!buffer) {
33
32
  buffer_ = std::shared_ptr<AudioBuffer>(nullptr);
34
33
  return;
@@ -37,16 +36,20 @@ void AudioBufferSourceNode::setBuffer(
37
36
  buffer_ = buffer;
38
37
  }
39
38
 
40
- // Note: AudioBus copy method will use memcpy if the source buffer and system processing bus have same channel count,
41
- // otherwise it will use the summing function taking care of up/down mixing.
42
- void AudioBufferSourceNode::processNode(AudioBus* processingBus, int framesToProcess) {
39
+ // Note: AudioBus copy method will use memcpy if the source buffer and system
40
+ // processing bus have same channel count, otherwise it will use the summing
41
+ // function taking care of up/down mixing.
42
+ void AudioBufferSourceNode::processNode(
43
+ AudioBus *processingBus,
44
+ int framesToProcess) {
43
45
  // No audio data to fill, zero the output and return.
44
46
  if (!isPlaying() || !buffer_ || buffer_->getLength() == 0) {
45
47
  processingBus->zero();
46
48
  return;
47
49
  }
48
50
 
49
- // Easiest case, the buffer is the same length as the number of frames to process, just copy the data.
51
+ // Easiest case, the buffer is the same length as the number of frames to
52
+ // process, just copy the data.
50
53
  if (framesToProcess == buffer_->getLength()) {
51
54
  processingBus->copy(buffer_->bus_.get());
52
55
 
@@ -65,9 +68,12 @@ void AudioBufferSourceNode::processNode(AudioBus* processingBus, int framesToPro
65
68
  int framesToCopy = 0;
66
69
 
67
70
  while (framesToProcess - outputBusIndex > 0) {
68
- framesToCopy = std::min(framesToProcess - outputBusIndex, buffer_->getLength() - bufferIndex_);
71
+ framesToCopy = std::min(
72
+ framesToProcess - outputBusIndex,
73
+ buffer_->getLength() - bufferIndex_);
69
74
 
70
- processingBus->copy(buffer_->bus_.get(), bufferIndex_, outputBusIndex, framesToCopy);
75
+ processingBus->copy(
76
+ buffer_->bus_.get(), bufferIndex_, outputBusIndex, framesToCopy);
71
77
 
72
78
  bufferIndex_ += framesToCopy;
73
79
  outputBusIndex += framesToCopy;
@@ -76,12 +82,11 @@ void AudioBufferSourceNode::processNode(AudioBus* processingBus, int framesToPro
76
82
  continue;
77
83
  }
78
84
 
79
-
80
85
  bufferIndex_ %= buffer_->getLength();
81
86
 
82
87
  if (!loop_) {
83
- playbackState_ = PlaybackState::FINISHED;
84
- disable();
88
+ playbackState_ = PlaybackState::FINISHED;
89
+ disable();
85
90
 
86
91
  if (framesToProcess - outputBusIndex > 0) {
87
92
  processingBus->zero(outputBusIndex, framesToProcess - outputBusIndex);
@@ -94,9 +99,11 @@ void AudioBufferSourceNode::processNode(AudioBus* processingBus, int framesToPro
94
99
 
95
100
  // processing bus is longer than the source buffer
96
101
  if (!loop_) {
97
- // If we don't loop the buffer, copy it once and zero the remaining processing bus frames.
102
+ // If we don't loop the buffer, copy it once and zero the remaining
103
+ // processing bus frames.
98
104
  processingBus->copy(buffer_->bus_.get());
99
- processingBus->zero(buffer_->getLength(), framesToProcess - buffer_->getLength());
105
+ processingBus->zero(
106
+ buffer_->getLength(), framesToProcess - buffer_->getLength());
100
107
 
101
108
  playbackState_ = PlaybackState::FINISHED;
102
109
  disable();
@@ -104,9 +111,10 @@ void AudioBufferSourceNode::processNode(AudioBus* processingBus, int framesToPro
104
111
  return;
105
112
  }
106
113
 
107
- // If we loop the buffer, we need to loop the buffer framesToProcess / bufferSize times
108
- // There might also be a remainder of frames to copy after the loop,
109
- // which will also carry over some buffer frames to the next render quantum.
114
+ // If we loop the buffer, we need to loop the buffer framesToProcess /
115
+ // bufferSize times There might also be a remainder of frames to copy after
116
+ // the loop, which will also carry over some buffer frames to the next render
117
+ // quantum.
110
118
  int processingBusPosition = 0;
111
119
  int bufferSize = buffer_->getLength();
112
120
  int remainingFrames = framesToProcess - framesToProcess / bufferSize;
@@ -125,9 +133,11 @@ void AudioBufferSourceNode::processNode(AudioBus* processingBus, int framesToPro
125
133
  processingBusPosition += bufferSize;
126
134
  }
127
135
 
128
- // Fill in the remaining frames from the processing buffer and update buffer index for next render quantum.
136
+ // Fill in the remaining frames from the processing buffer and update buffer
137
+ // index for next render quantum.
129
138
  if (remainingFrames > 0) {
130
- processingBus->copy(buffer_->bus_.get(), 0, processingBusPosition, remainingFrames);
139
+ processingBus->copy(
140
+ buffer_->bus_.get(), 0, processingBusPosition, remainingFrames);
131
141
  bufferIndex_ = remainingFrames;
132
142
  }
133
143
  }
@@ -19,7 +19,7 @@ class AudioBufferSourceNode : public AudioScheduledSourceNode {
19
19
  void setBuffer(const std::shared_ptr<AudioBuffer> &buffer);
20
20
 
21
21
  protected:
22
- void processNode(AudioBus* processingBus, int framesToProcess) override;
22
+ void processNode(AudioBus *processingBus, int framesToProcess) override;
23
23
 
24
24
  private:
25
25
  bool loop_;