react-native-audio-api 0.8.3-nightly-ea268f4-20251006 → 0.9.0-nightly-96a5bcd-20251007

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 (74) hide show
  1. package/android/src/main/cpp/audioapi/android/core/{AudioDecoder.cpp → utils/AudioDecoder.cpp} +79 -75
  2. package/common/cpp/audioapi/AudioAPIModuleInstaller.h +99 -43
  3. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +1 -101
  4. package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +0 -3
  5. package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.cpp +107 -0
  6. package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.h +28 -0
  7. package/common/cpp/audioapi/core/AudioContext.cpp +0 -2
  8. package/common/cpp/audioapi/core/AudioNode.cpp +3 -3
  9. package/common/cpp/audioapi/core/AudioNode.h +1 -1
  10. package/common/cpp/audioapi/core/BaseAudioContext.cpp +0 -35
  11. package/common/cpp/audioapi/core/BaseAudioContext.h +4 -12
  12. package/common/cpp/audioapi/core/OfflineAudioContext.cpp +0 -2
  13. package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +3 -1
  14. package/common/cpp/audioapi/core/analysis/AnalyserNode.h +1 -1
  15. package/common/cpp/audioapi/core/destinations/AudioDestinationNode.h +1 -1
  16. package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +3 -1
  17. package/common/cpp/audioapi/core/effects/BiquadFilterNode.h +1 -1
  18. package/common/cpp/audioapi/core/effects/GainNode.cpp +3 -1
  19. package/common/cpp/audioapi/core/effects/GainNode.h +1 -1
  20. package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +17 -12
  21. package/common/cpp/audioapi/core/effects/StereoPannerNode.h +1 -1
  22. package/common/cpp/audioapi/core/effects/WorkletNode.cpp +3 -1
  23. package/common/cpp/audioapi/core/effects/WorkletNode.h +2 -2
  24. package/common/cpp/audioapi/core/effects/WorkletProcessingNode.cpp +3 -1
  25. package/common/cpp/audioapi/core/effects/WorkletProcessingNode.h +2 -2
  26. package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +4 -2
  27. package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.h +1 -1
  28. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +4 -2
  29. package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +1 -1
  30. package/common/cpp/audioapi/core/sources/ConstantSourceNode.cpp +4 -2
  31. package/common/cpp/audioapi/core/sources/ConstantSourceNode.h +1 -1
  32. package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +7 -2
  33. package/common/cpp/audioapi/core/sources/OscillatorNode.h +1 -1
  34. package/common/cpp/audioapi/core/sources/RecorderAdapterNode.cpp +3 -1
  35. package/common/cpp/audioapi/core/sources/RecorderAdapterNode.h +1 -1
  36. package/common/cpp/audioapi/core/sources/StreamerNode.cpp +9 -1
  37. package/common/cpp/audioapi/core/sources/StreamerNode.h +1 -1
  38. package/common/cpp/audioapi/core/sources/WorkletSourceNode.cpp +6 -4
  39. package/common/cpp/audioapi/core/sources/WorkletSourceNode.h +2 -2
  40. package/common/cpp/audioapi/core/types/AudioFormat.h +16 -0
  41. package/common/cpp/audioapi/core/utils/AudioDecoder.h +36 -90
  42. package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +241 -282
  43. package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.h +57 -19
  44. package/common/cpp/test/CMakeLists.txt +2 -1
  45. package/common/cpp/test/GainTest.cpp +9 -9
  46. package/common/cpp/test/StereoPannerTest.cpp +129 -0
  47. package/ios/audioapi/ios/core/IOSAudioRecorder.h +1 -2
  48. package/ios/audioapi/ios/core/utils/AudioDecoder.mm +160 -0
  49. package/lib/commonjs/api.js +14 -1
  50. package/lib/commonjs/api.js.map +1 -1
  51. package/lib/commonjs/core/AudioDecoder.js +48 -0
  52. package/lib/commonjs/core/AudioDecoder.js.map +1 -0
  53. package/lib/commonjs/core/BaseAudioContext.js +11 -18
  54. package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
  55. package/lib/module/api.js +2 -1
  56. package/lib/module/api.js.map +1 -1
  57. package/lib/module/core/AudioDecoder.js +42 -0
  58. package/lib/module/core/AudioDecoder.js.map +1 -0
  59. package/lib/module/core/BaseAudioContext.js +11 -18
  60. package/lib/module/core/BaseAudioContext.js.map +1 -1
  61. package/lib/typescript/api.d.ts +3 -1
  62. package/lib/typescript/api.d.ts.map +1 -1
  63. package/lib/typescript/core/AudioDecoder.d.ts +4 -0
  64. package/lib/typescript/core/AudioDecoder.d.ts.map +1 -0
  65. package/lib/typescript/core/BaseAudioContext.d.ts +3 -6
  66. package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
  67. package/lib/typescript/interfaces.d.ts +6 -3
  68. package/lib/typescript/interfaces.d.ts.map +1 -1
  69. package/package.json +1 -1
  70. package/src/api.ts +5 -0
  71. package/src/core/AudioDecoder.ts +78 -0
  72. package/src/core/BaseAudioContext.ts +26 -29
  73. package/src/interfaces.ts +18 -6
  74. package/ios/audioapi/ios/core/AudioDecoder.mm +0 -156
@@ -0,0 +1,107 @@
1
+ #pragma once
2
+
3
+ #include <audioapi/HostObjects/sources/AudioBufferHostObject.h>
4
+ #include <audioapi/HostObjects/utils/AudioDecoderHostObject.h>
5
+ #include <audioapi/core/utils/AudioDecoder.h>
6
+ #include <audioapi/jsi/JsiPromise.h>
7
+
8
+ #include <jsi/jsi.h>
9
+ #include <memory>
10
+ #include <string>
11
+ #include <thread>
12
+ #include <utility>
13
+
14
+ namespace audioapi {
15
+ AudioDecoderHostObject::AudioDecoderHostObject(
16
+ jsi::Runtime *runtime,
17
+ const std::shared_ptr<react::CallInvoker> &callInvoker) {
18
+ promiseVendor_ = std::make_shared<PromiseVendor>(runtime, callInvoker);
19
+ addFunctions(
20
+ JSI_EXPORT_FUNCTION(AudioDecoderHostObject, decodeWithPCMInBase64),
21
+ JSI_EXPORT_FUNCTION(AudioDecoderHostObject, decodeWithFilePath),
22
+ JSI_EXPORT_FUNCTION(AudioDecoderHostObject, decodeWithMemoryBlock));
23
+ }
24
+
25
+ JSI_HOST_FUNCTION_IMPL(AudioDecoderHostObject, decodeWithMemoryBlock) {
26
+ auto arrayBuffer = args[0]
27
+ .getObject(runtime)
28
+ .getPropertyAsObject(runtime, "buffer")
29
+ .getArrayBuffer(runtime);
30
+ auto data = arrayBuffer.data(runtime);
31
+ auto size = static_cast<int>(arrayBuffer.size(runtime));
32
+
33
+ auto sampleRate = args[1].getNumber();
34
+
35
+ return promiseVendor_->createAsyncPromise(
36
+ [data, size, sampleRate](
37
+ jsi::Runtime &runtime) -> std::variant<jsi::Value, std::string> {
38
+ auto result =
39
+ AudioDecoder::decodeWithMemoryBlock(data, size, sampleRate);
40
+
41
+ if (!result) {
42
+ return std::string("Failed to decode audio data.");
43
+ }
44
+
45
+ auto audioBufferHostObject =
46
+ std::make_shared<AudioBufferHostObject>(result);
47
+
48
+ auto jsiObject =
49
+ jsi::Object::createFromHostObject(runtime, audioBufferHostObject);
50
+ jsiObject.setExternalMemoryPressure(
51
+ runtime, audioBufferHostObject->getSizeInBytes());
52
+ return jsiObject;
53
+ });
54
+ }
55
+
56
+ JSI_HOST_FUNCTION_IMPL(AudioDecoderHostObject, decodeWithFilePath) {
57
+ auto sourcePath = args[0].getString(runtime).utf8(runtime);
58
+ auto sampleRate = args[1].getNumber();
59
+
60
+ return promiseVendor_->createAsyncPromise(
61
+ [sourcePath, sampleRate](
62
+ jsi::Runtime &runtime) -> std::variant<jsi::Value, std::string> {
63
+ auto result = AudioDecoder::decodeWithFilePath(sourcePath, sampleRate);
64
+
65
+ if (!result) {
66
+ return std::string("Failed to decode audio data source.");
67
+ }
68
+
69
+ auto audioBufferHostObject =
70
+ std::make_shared<AudioBufferHostObject>(result);
71
+
72
+ auto jsiObject =
73
+ jsi::Object::createFromHostObject(runtime, audioBufferHostObject);
74
+ jsiObject.setExternalMemoryPressure(
75
+ runtime, audioBufferHostObject->getSizeInBytes());
76
+ return jsiObject;
77
+ });
78
+ }
79
+
80
+ JSI_HOST_FUNCTION_IMPL(AudioDecoderHostObject, decodeWithPCMInBase64) {
81
+ auto b64 = args[0].getString(runtime).utf8(runtime);
82
+ auto inputSampleRate = args[1].getNumber();
83
+ auto inputChannelCount = args[2].getNumber();
84
+ auto interleaved = args[3].getBool();
85
+
86
+ return promiseVendor_->createAsyncPromise(
87
+ [b64, inputSampleRate, inputChannelCount, interleaved](
88
+ jsi::Runtime &runtime) -> std::variant<jsi::Value, std::string> {
89
+ auto result = AudioDecoder::decodeWithPCMInBase64(
90
+ b64, inputSampleRate, inputChannelCount, interleaved);
91
+
92
+ if (!result) {
93
+ return std::string("Failed to decode audio data source.");
94
+ }
95
+
96
+ auto audioBufferHostObject =
97
+ std::make_shared<AudioBufferHostObject>(result);
98
+
99
+ auto jsiObject =
100
+ jsi::Object::createFromHostObject(runtime, audioBufferHostObject);
101
+ jsiObject.setExternalMemoryPressure(
102
+ runtime, audioBufferHostObject->getSizeInBytes());
103
+ return jsiObject;
104
+ });
105
+ }
106
+
107
+ } // namespace audioapi
@@ -0,0 +1,28 @@
1
+ #pragma once
2
+
3
+ #include <audioapi/HostObjects/sources/AudioBufferHostObject.h>
4
+ #include <audioapi/core/utils/AudioDecoder.h>
5
+ #include <audioapi/jsi/JsiPromise.h>
6
+
7
+ #include <jsi/jsi.h>
8
+ #include <memory>
9
+ #include <string>
10
+ #include <thread>
11
+ #include <utility>
12
+
13
+ namespace audioapi {
14
+ using namespace facebook;
15
+
16
+ class AudioDecoderHostObject : public JsiHostObject {
17
+ public:
18
+ explicit AudioDecoderHostObject(
19
+ jsi::Runtime *runtime,
20
+ const std::shared_ptr<react::CallInvoker> &callInvoker);
21
+ JSI_HOST_FUNCTION_DECL(decodeWithMemoryBlock);
22
+ JSI_HOST_FUNCTION_DECL(decodeWithFilePath);
23
+ JSI_HOST_FUNCTION_DECL(decodeWithPCMInBase64);
24
+
25
+ private:
26
+ std::shared_ptr<PromiseVendor> promiseVendor_;
27
+ };
28
+ } // namespace audioapi
@@ -6,7 +6,6 @@
6
6
 
7
7
  #include <audioapi/core/AudioContext.h>
8
8
  #include <audioapi/core/destinations/AudioDestinationNode.h>
9
- #include <audioapi/core/utils/AudioDecoder.h>
10
9
  #include <audioapi/core/utils/AudioNodeManager.h>
11
10
 
12
11
  namespace audioapi {
@@ -26,7 +25,6 @@ AudioContext::AudioContext(
26
25
  #endif
27
26
 
28
27
  sampleRate_ = sampleRate;
29
- audioDecoder_ = std::make_shared<AudioDecoder>(sampleRate);
30
28
 
31
29
  if (initSuspended) {
32
30
  playerHasBeenStarted_ = false;
@@ -142,10 +142,10 @@ std::shared_ptr<AudioBus> AudioNode::processAudio(
142
142
  mixInputsBuses(processingBus);
143
143
 
144
144
  assert(processingBus != nullptr);
145
- // Finally, process the node itself.
146
- processNode(processingBus, framesToProcess);
147
145
 
148
- return processingBus;
146
+ // Finally, process the node itself.
147
+ return processNode(processingBus, framesToProcess);
148
+ ;
149
149
  }
150
150
 
151
151
  bool AudioNode::isAlreadyProcessed() {
@@ -68,7 +68,7 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {
68
68
  static std::string toString(ChannelCountMode mode);
69
69
  static std::string toString(ChannelInterpretation interpretation);
70
70
 
71
- virtual void processNode(const std::shared_ptr<AudioBus>&, int) = 0;
71
+ virtual std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>&, int) = 0;
72
72
 
73
73
  bool isAlreadyProcessed();
74
74
  std::shared_ptr<AudioBus> processInputs(const std::shared_ptr<AudioBus>& outputBus, int framesToProcess, bool checkIsAlreadyProcessed);
@@ -176,41 +176,6 @@ std::shared_ptr<AnalyserNode> BaseAudioContext::createAnalyser() {
176
176
  return analyser;
177
177
  }
178
178
 
179
- std::shared_ptr<AudioBuffer> BaseAudioContext::decodeAudioDataSource(
180
- const std::string &path) {
181
- auto audioBus = audioDecoder_->decodeWithFilePath(path);
182
-
183
- if (!audioBus) {
184
- return nullptr;
185
- }
186
-
187
- return std::make_shared<AudioBuffer>(audioBus);
188
- }
189
-
190
- std::shared_ptr<AudioBuffer> BaseAudioContext::decodeAudioData(
191
- const void *data,
192
- size_t size) {
193
- auto audioBus = audioDecoder_->decodeWithMemoryBlock(data, size);
194
-
195
- if (!audioBus) {
196
- return nullptr;
197
- }
198
-
199
- return std::make_shared<AudioBuffer>(audioBus);
200
- }
201
-
202
- std::shared_ptr<AudioBuffer> BaseAudioContext::decodeWithPCMInBase64(
203
- const std::string &data,
204
- float playbackSpeed) {
205
- auto audioBus = audioDecoder_->decodeWithPCMInBase64(data, playbackSpeed);
206
-
207
- if (!audioBus) {
208
- return nullptr;
209
- }
210
-
211
- return std::make_shared<AudioBuffer>(audioBus);
212
- }
213
-
214
179
  AudioNodeManager *BaseAudioContext::getNodeManager() {
215
180
  return nodeManager_.get();
216
181
  }
@@ -3,15 +3,14 @@
3
3
  #include <audioapi/core/types/ContextState.h>
4
4
  #include <audioapi/core/types/OscillatorType.h>
5
5
  #include <audioapi/core/utils/worklets/SafeIncludes.h>
6
-
6
+ #include <cassert>
7
+ #include <complex>
8
+ #include <cstddef>
7
9
  #include <functional>
8
10
  #include <memory>
9
11
  #include <string>
10
12
  #include <utility>
11
13
  #include <vector>
12
- #include <complex>
13
- #include <cstddef>
14
- #include <cassert>
15
14
 
16
15
  namespace audioapi {
17
16
 
@@ -27,7 +26,6 @@ class BiquadFilterNode;
27
26
  class AudioDestinationNode;
28
27
  class AudioBufferSourceNode;
29
28
  class AudioBufferQueueSourceNode;
30
- class AudioDecoder;
31
29
  class AnalyserNode;
32
30
  class AudioEventHandlerRegistry;
33
31
  class IAudioEventHandlerRegistry;
@@ -68,10 +66,6 @@ class BaseAudioContext {
68
66
  int length);
69
67
  std::shared_ptr<AnalyserNode> createAnalyser();
70
68
 
71
- std::shared_ptr<AudioBuffer> decodeAudioDataSource(const std::string &path);
72
- std::shared_ptr<AudioBuffer> decodeAudioData(const void *data, size_t size);
73
- std::shared_ptr<AudioBuffer> decodeWithPCMInBase64(const std::string &data, float playbackSpeed);
74
-
75
69
  std::shared_ptr<PeriodicWave> getBasicWaveForm(OscillatorType type);
76
70
  [[nodiscard]] float getNyquistFrequency() const;
77
71
  AudioNodeManager *getNodeManager();
@@ -85,9 +79,7 @@ class BaseAudioContext {
85
79
 
86
80
  std::shared_ptr<AudioDestinationNode> destination_;
87
81
  // init in AudioContext or OfflineContext constructor
88
- std::shared_ptr<AudioDecoder> audioDecoder_ {};
89
- // init in AudioContext or OfflineContext constructor
90
- float sampleRate_ {};
82
+ float sampleRate_{};
91
83
  ContextState state_ = ContextState::RUNNING;
92
84
  std::shared_ptr<AudioNodeManager> nodeManager_;
93
85
 
@@ -3,7 +3,6 @@
3
3
  #include <audioapi/core/AudioContext.h>
4
4
  #include <audioapi/core/destinations/AudioDestinationNode.h>
5
5
  #include <audioapi/core/sources/AudioBuffer.h>
6
- #include <audioapi/core/utils/AudioDecoder.h>
7
6
  #include <audioapi/core/utils/AudioNodeManager.h>
8
7
  #include <audioapi/core/utils/Constants.h>
9
8
  #include <audioapi/core/utils/Locker.h>
@@ -30,7 +29,6 @@ OfflineAudioContext::OfflineAudioContext(
30
29
  numberOfChannels_(numberOfChannels),
31
30
  currentSampleFrame_(0) {
32
31
  sampleRate_ = sampleRate;
33
- audioDecoder_ = std::make_shared<AudioDecoder>(sampleRate_);
34
32
  resultBus_ = std::make_shared<AudioBus>(
35
33
  static_cast<int>(length_), numberOfChannels_, sampleRate_);
36
34
  }
@@ -143,7 +143,7 @@ void AnalyserNode::getByteTimeDomainData(uint8_t *data, int length) {
143
143
  }
144
144
  }
145
145
 
146
- void AnalyserNode::processNode(
146
+ std::shared_ptr<AudioBus> AnalyserNode::processNode(
147
147
  const std::shared_ptr<AudioBus> &processingBus,
148
148
  int framesToProcess) {
149
149
  // Analyser should behave like a sniffer node, it should not modify the
@@ -156,6 +156,8 @@ void AnalyserNode::processNode(
156
156
  downMixBus_->getChannel(0)->getData(), framesToProcess, true);
157
157
 
158
158
  shouldDoFFTAnalysis_ = true;
159
+
160
+ return processingBus;
159
161
  }
160
162
 
161
163
  void AnalyserNode::doFFTAnalysis() {
@@ -39,7 +39,7 @@ class AnalyserNode : public AudioNode {
39
39
  void getByteTimeDomainData(uint8_t *data, int length);
40
40
 
41
41
  protected:
42
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
42
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
43
43
 
44
44
  private:
45
45
  int fftSize_;
@@ -24,7 +24,7 @@ class AudioDestinationNode : public AudioNode {
24
24
  protected:
25
25
  // DestinationNode is triggered by AudioContext using renderAudio
26
26
  // processNode function is not necessary and is never called.
27
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int) final {};
27
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int) final { return processingBus; };
28
28
 
29
29
  private:
30
30
  std::size_t currentSampleFrame_;
@@ -353,7 +353,7 @@ void BiquadFilterNode::applyFilter() {
353
353
  }
354
354
  }
355
355
 
356
- void BiquadFilterNode::processNode(
356
+ std::shared_ptr<AudioBus> BiquadFilterNode::processNode(
357
357
  const std::shared_ptr<AudioBus> &processingBus,
358
358
  int framesToProcess) {
359
359
  int numChannels = processingBus->getNumberOfChannels();
@@ -393,6 +393,8 @@ void BiquadFilterNode::processNode(
393
393
  x2_ = x2;
394
394
  y1_ = y1;
395
395
  y2_ = y2;
396
+
397
+ return processingBus;
396
398
  }
397
399
 
398
400
  } // namespace audioapi
@@ -33,7 +33,7 @@ class BiquadFilterNode : public AudioNode {
33
33
  int length);
34
34
 
35
35
  protected:
36
- void processNode(
36
+ std::shared_ptr<AudioBus> processNode(
37
37
  const std::shared_ptr<AudioBus> &processingBus,
38
38
  int framesToProcess) override;
39
39
 
@@ -16,7 +16,7 @@ std::shared_ptr<AudioParam> GainNode::getGainParam() const {
16
16
  return gainParam_;
17
17
  }
18
18
 
19
- void GainNode::processNode(
19
+ std::shared_ptr<AudioBus> GainNode::processNode(
20
20
  const std::shared_ptr<AudioBus> &processingBus,
21
21
  int framesToProcess) {
22
22
  double time = context_->getCurrentTime();
@@ -28,6 +28,8 @@ void GainNode::processNode(
28
28
  processingBus->getChannel(i)->getData(),
29
29
  framesToProcess);
30
30
  }
31
+
32
+ return processingBus;
31
33
  }
32
34
 
33
35
  } // namespace audioapi
@@ -16,7 +16,7 @@ class GainNode : public AudioNode {
16
16
  [[nodiscard]] std::shared_ptr<AudioParam> getGainParam() const;
17
17
 
18
18
  protected:
19
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
19
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
20
20
 
21
21
  private:
22
22
  std::shared_ptr<AudioParam> gainParam_;
@@ -19,18 +19,20 @@ std::shared_ptr<AudioParam> StereoPannerNode::getPanParam() const {
19
19
  return panParam_;
20
20
  }
21
21
 
22
- void StereoPannerNode::processNode(
22
+ std::shared_ptr<AudioBus> StereoPannerNode::processNode(
23
23
  const std::shared_ptr<AudioBus> &processingBus,
24
24
  int framesToProcess) {
25
25
  double time = context_->getCurrentTime();
26
26
  double deltaTime = 1.0 / context_->getSampleRate();
27
27
 
28
- AudioArray *left = processingBus->getChannelByType(AudioBus::ChannelLeft);
29
- AudioArray *right = processingBus->getChannelByType(AudioBus::ChannelRight);
28
+ auto *inputLeft = processingBus->getChannelByType(AudioBus::ChannelLeft);
30
29
  auto panParamValues = panParam_->processARateParam(framesToProcess, time)
31
30
  ->getChannel(0)
32
31
  ->getData();
33
32
 
33
+ auto *outputLeft = audioBus_->getChannelByType(AudioBus::ChannelLeft);
34
+ auto *outputRight = audioBus_->getChannelByType(AudioBus::ChannelRight);
35
+
34
36
  // Input is mono
35
37
  if (processingBus->getNumberOfChannels() == 1) {
36
38
  for (int i = 0; i < framesToProcess; i++) {
@@ -40,13 +42,14 @@ void StereoPannerNode::processNode(
40
42
  auto gainL = static_cast<float>(cos(x * PI / 2));
41
43
  auto gainR = static_cast<float>(sin(x * PI / 2));
42
44
 
43
- float input = (*left)[i];
45
+ float input = (*inputLeft)[i];
44
46
 
45
- (*left)[i] = input * gainL;
46
- (*right)[i] = input * gainR;
47
+ (*outputLeft)[i] = input * gainL;
48
+ (*outputRight)[i] = input * gainR;
47
49
  time += deltaTime;
48
50
  }
49
51
  } else { // Input is stereo
52
+ auto *inputRight = processingBus->getChannelByType(AudioBus::ChannelRight);
50
53
  for (int i = 0; i < framesToProcess; i++) {
51
54
  auto pan = std::clamp(panParamValues[i], -1.0f, 1.0f);
52
55
  auto x = (pan <= 0 ? pan + 1 : pan);
@@ -54,20 +57,22 @@ void StereoPannerNode::processNode(
54
57
  auto gainL = static_cast<float>(cos(x * PI / 2));
55
58
  auto gainR = static_cast<float>(sin(x * PI / 2));
56
59
 
57
- float inputL = (*left)[i];
58
- float inputR = (*right)[i];
60
+ float inputL = (*inputLeft)[i];
61
+ float inputR = (*inputRight)[i];
59
62
 
60
63
  if (pan <= 0) {
61
- (*left)[i] = inputL + inputR * gainL;
62
- (*right)[i] = inputR * gainR;
64
+ (*outputLeft)[i] = inputL + inputR * gainL;
65
+ (*outputRight)[i] = inputR * gainR;
63
66
  } else {
64
- (*left)[i] = inputL * gainL;
65
- (*right)[i] = inputR + inputL * gainR;
67
+ (*outputLeft)[i] = inputL * gainL;
68
+ (*outputRight)[i] = inputR + inputL * gainR;
66
69
  }
67
70
 
68
71
  time += deltaTime;
69
72
  }
70
73
  }
74
+
75
+ return audioBus_;
71
76
  }
72
77
 
73
78
  } // namespace audioapi
@@ -18,7 +18,7 @@ class StereoPannerNode : public AudioNode {
18
18
  [[nodiscard]] std::shared_ptr<AudioParam> getPanParam() const;
19
19
 
20
20
  protected:
21
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
21
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
22
22
 
23
23
  private:
24
24
  std::shared_ptr<AudioParam> panParam_;
@@ -28,7 +28,7 @@ WorkletNode::~WorkletNode() {
28
28
  }
29
29
  }
30
30
 
31
- void WorkletNode::processNode(
31
+ std::shared_ptr<AudioBus> WorkletNode::processNode(
32
32
  const std::shared_ptr<AudioBus> &processingBus,
33
33
  int framesToProcess) {
34
34
  size_t processed = 0;
@@ -82,6 +82,8 @@ void WorkletNode::processNode(
82
82
  });
83
83
  }
84
84
  }
85
+
86
+ return processingBus;
85
87
  }
86
88
 
87
89
  } // namespace audioapi
@@ -26,7 +26,7 @@ class WorkletNode : public AudioNode {
26
26
  ) : AudioNode(context) {}
27
27
 
28
28
  protected:
29
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override {}
29
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override { return processingBus; }
30
30
  };
31
31
  #else
32
32
 
@@ -45,7 +45,7 @@ class WorkletNode : public AudioNode {
45
45
  ~WorkletNode() override;
46
46
 
47
47
  protected:
48
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
48
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
49
49
 
50
50
 
51
51
  private:
@@ -26,7 +26,7 @@ WorkletProcessingNode::WorkletProcessingNode(
26
26
  }
27
27
  }
28
28
 
29
- void WorkletProcessingNode::processNode(
29
+ std::shared_ptr<AudioBus> WorkletProcessingNode::processNode(
30
30
  const std::shared_ptr<AudioBus> &processingBus,
31
31
  int framesToProcess) {
32
32
  size_t channelCount = std::min(
@@ -84,6 +84,8 @@ void WorkletProcessingNode::processNode(
84
84
  std::memset(channelData, 0, framesToProcess * sizeof(float));
85
85
  }
86
86
  }
87
+
88
+ return processingBus;
87
89
  }
88
90
 
89
91
  } // namespace audioapi
@@ -23,7 +23,7 @@ class WorkletProcessingNode : public AudioNode {
23
23
  ) : AudioNode(context) {}
24
24
 
25
25
  protected:
26
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override {}
26
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override { return processingBus; }
27
27
  };
28
28
  #else
29
29
 
@@ -38,7 +38,7 @@ class WorkletProcessingNode : public AudioNode {
38
38
  );
39
39
 
40
40
  protected:
41
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
41
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
42
42
 
43
43
  private:
44
44
  WorkletsRunner workletRunner_;
@@ -87,14 +87,14 @@ void AudioBufferQueueSourceNode::disable() {
87
87
  buffers_ = {};
88
88
  }
89
89
 
90
- void AudioBufferQueueSourceNode::processNode(
90
+ std::shared_ptr<AudioBus> AudioBufferQueueSourceNode::processNode(
91
91
  const std::shared_ptr<AudioBus> &processingBus,
92
92
  int framesToProcess) {
93
93
  if (auto locker = Locker::tryLock(getBufferLock())) {
94
94
  // no audio data to fill, zero the output and return.
95
95
  if (buffers_.empty()) {
96
96
  processingBus->zero();
97
- return;
97
+ return processingBus;
98
98
  }
99
99
 
100
100
  if (!pitchCorrection_) {
@@ -107,6 +107,8 @@ void AudioBufferQueueSourceNode::processNode(
107
107
  } else {
108
108
  processingBus->zero();
109
109
  }
110
+
111
+ return processingBus;
110
112
  }
111
113
 
112
114
  double AudioBufferQueueSourceNode::getCurrentPosition() const {
@@ -29,7 +29,7 @@ class AudioBufferQueueSourceNode : public AudioBufferBaseSourceNode {
29
29
  void disable() override;
30
30
 
31
31
  protected:
32
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
32
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
33
33
  double getCurrentPosition() const override;
34
34
 
35
35
  private:
@@ -140,14 +140,14 @@ void AudioBufferSourceNode::setOnLoopEndedCallbackId(uint64_t callbackId) {
140
140
  onLoopEndedCallbackId_ = callbackId;
141
141
  }
142
142
 
143
- void AudioBufferSourceNode::processNode(
143
+ std::shared_ptr<AudioBus> AudioBufferSourceNode::processNode(
144
144
  const std::shared_ptr<AudioBus> &processingBus,
145
145
  int framesToProcess) {
146
146
  if (auto locker = Locker::tryLock(getBufferLock())) {
147
147
  // No audio data to fill, zero the output and return.
148
148
  if (!alignedBus_) {
149
149
  processingBus->zero();
150
- return;
150
+ return processingBus;
151
151
  }
152
152
 
153
153
  if (!pitchCorrection_) {
@@ -160,6 +160,8 @@ void AudioBufferSourceNode::processNode(
160
160
  } else {
161
161
  processingBus->zero();
162
162
  }
163
+
164
+ return processingBus;
163
165
  }
164
166
 
165
167
  double AudioBufferSourceNode::getCurrentPosition() const {
@@ -38,7 +38,7 @@ class AudioBufferSourceNode : public AudioBufferBaseSourceNode {
38
38
  void setOnLoopEndedCallbackId(uint64_t callbackId);
39
39
 
40
40
  protected:
41
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
41
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
42
42
  double getCurrentPosition() const override;
43
43
 
44
44
  private:
@@ -16,7 +16,7 @@ std::shared_ptr<AudioParam> ConstantSourceNode::getOffsetParam() const {
16
16
  return offsetParam_;
17
17
  }
18
18
 
19
- void ConstantSourceNode::processNode(
19
+ std::shared_ptr<AudioBus> ConstantSourceNode::processNode(
20
20
  const std::shared_ptr<AudioBus> &processingBus,
21
21
  int framesToProcess) {
22
22
  size_t startOffset = 0;
@@ -26,7 +26,7 @@ void ConstantSourceNode::processNode(
26
26
 
27
27
  if (!isPlaying() && !isStopScheduled()) {
28
28
  processingBus->zero();
29
- return;
29
+ return processingBus;
30
30
  }
31
31
 
32
32
  auto offsetBus = offsetParam_->processARateParam(
@@ -47,5 +47,7 @@ void ConstantSourceNode::processNode(
47
47
  if (isStopScheduled()) {
48
48
  handleStopScheduled();
49
49
  }
50
+
51
+ return processingBus;
50
52
  }
51
53
  } // namespace audioapi
@@ -18,7 +18,7 @@ class ConstantSourceNode : public AudioScheduledSourceNode {
18
18
  [[nodiscard]] std::shared_ptr<AudioParam> getOffsetParam() const;
19
19
 
20
20
  protected:
21
- void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
21
+ std::shared_ptr<AudioBus> processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
22
22
 
23
23
  private:
24
24
  std::shared_ptr<AudioParam> offsetParam_;