react-native-audio-api 0.4.0 → 0.4.2

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 (83) hide show
  1. package/android/src/main/cpp/core/AudioPlayer.cpp +38 -11
  2. package/android/src/main/cpp/core/AudioPlayer.h +6 -2
  3. package/common/cpp/HostObjects/AnalyserNodeHostObject.h +19 -6
  4. package/common/cpp/HostObjects/AudioAPIInstallerHostObject.h +11 -3
  5. package/common/cpp/HostObjects/AudioBufferHostObject.h +6 -5
  6. package/common/cpp/HostObjects/AudioNodeHostObject.h +5 -0
  7. package/common/cpp/HostObjects/AudioParamHostObject.h +2 -1
  8. package/common/cpp/HostObjects/BaseAudioContextHostObject.h +4 -3
  9. package/common/cpp/core/AnalyserNode.cpp +56 -34
  10. package/common/cpp/core/AnalyserNode.h +51 -19
  11. package/common/cpp/core/AudioArray.cpp +14 -14
  12. package/common/cpp/core/AudioArray.h +16 -15
  13. package/common/cpp/core/AudioBuffer.cpp +12 -9
  14. package/common/cpp/core/AudioBuffer.h +9 -8
  15. package/common/cpp/core/AudioBufferSourceNode.cpp +25 -20
  16. package/common/cpp/core/AudioBufferSourceNode.h +1 -0
  17. package/common/cpp/core/AudioBus.cpp +22 -26
  18. package/common/cpp/core/AudioBus.h +24 -24
  19. package/common/cpp/core/AudioContext.cpp +41 -1
  20. package/common/cpp/core/AudioContext.h +17 -0
  21. package/common/cpp/core/AudioDecoder.h +2 -2
  22. package/common/cpp/core/AudioDestinationNode.cpp +1 -1
  23. package/common/cpp/core/AudioDestinationNode.h +2 -1
  24. package/common/cpp/core/AudioNode.cpp +22 -8
  25. package/common/cpp/core/AudioNode.h +10 -10
  26. package/common/cpp/core/AudioNodeManager.cpp +1 -3
  27. package/common/cpp/core/AudioNodeManager.h +1 -1
  28. package/common/cpp/core/AudioParam.cpp +6 -3
  29. package/common/cpp/core/AudioParam.h +2 -1
  30. package/common/cpp/core/AudioScheduledSourceNode.cpp +1 -1
  31. package/common/cpp/core/AudioScheduledSourceNode.h +1 -0
  32. package/common/cpp/core/BaseAudioContext.cpp +7 -43
  33. package/common/cpp/core/BaseAudioContext.h +10 -21
  34. package/common/cpp/core/BiquadFilterNode.cpp +13 -14
  35. package/common/cpp/core/Constants.h +26 -12
  36. package/common/cpp/core/GainNode.cpp +1 -1
  37. package/common/cpp/core/OscillatorNode.cpp +4 -3
  38. package/common/cpp/core/PeriodicWave.cpp +7 -6
  39. package/common/cpp/core/PeriodicWave.h +4 -4
  40. package/common/cpp/core/StereoPannerNode.cpp +4 -4
  41. package/common/cpp/jsi/JsiHostObject.h +1 -1
  42. package/common/cpp/jsi/JsiPromise.h +1 -0
  43. package/common/cpp/utils/AudioUtils.cpp +2 -2
  44. package/common/cpp/utils/AudioUtils.h +2 -2
  45. package/common/cpp/utils/Locker.h +2 -2
  46. package/common/cpp/utils/VectorMath.cpp +1 -1
  47. package/ios/core/AudioPlayer.h +3 -2
  48. package/ios/core/AudioPlayer.m +49 -15
  49. package/ios/core/IOSAudioPlayer.h +4 -2
  50. package/ios/core/IOSAudioPlayer.mm +47 -11
  51. package/lib/module/core/AnalyserNode.js +6 -0
  52. package/lib/module/core/AnalyserNode.js.map +1 -1
  53. package/lib/module/core/AudioContext.js +2 -2
  54. package/lib/module/core/AudioContext.js.map +1 -1
  55. package/lib/module/core/AudioNode.js +5 -5
  56. package/lib/module/core/AudioNode.js.map +1 -1
  57. package/lib/module/index.js +16 -6
  58. package/lib/module/index.js.map +1 -1
  59. package/lib/module/index.native.js +1 -1
  60. package/lib/module/index.native.js.map +1 -1
  61. package/lib/typescript/core/AnalyserNode.d.ts +3 -0
  62. package/lib/typescript/core/AnalyserNode.d.ts.map +1 -1
  63. package/lib/typescript/core/AudioContext.d.ts +1 -1
  64. package/lib/typescript/core/AudioContext.d.ts.map +1 -1
  65. package/lib/typescript/core/AudioNode.d.ts +2 -2
  66. package/lib/typescript/core/AudioNode.d.ts.map +1 -1
  67. package/lib/typescript/core/types.d.ts +1 -0
  68. package/lib/typescript/core/types.d.ts.map +1 -1
  69. package/lib/typescript/index.d.ts +6 -4
  70. package/lib/typescript/index.d.ts.map +1 -1
  71. package/lib/typescript/index.native.d.ts +1 -1
  72. package/lib/typescript/index.native.d.ts.map +1 -1
  73. package/lib/typescript/interfaces.d.ts +3 -2
  74. package/lib/typescript/interfaces.d.ts.map +1 -1
  75. package/package.json +1 -1
  76. package/src/core/AnalyserNode.ts +9 -0
  77. package/src/core/AudioContext.ts +2 -2
  78. package/src/core/AudioNode.ts +5 -5
  79. package/src/core/types.ts +2 -0
  80. package/src/index.native.ts +1 -0
  81. package/src/index.ts +26 -7
  82. package/src/interfaces.ts +3 -1
  83. package/src/specs/global.d.ts +1 -1
@@ -9,9 +9,7 @@ namespace audioapi {
9
9
 
10
10
  AudioNode::AudioNode(BaseAudioContext *context) : context_(context) {
11
11
  audioBus_ = std::make_shared<AudioBus>(
12
- context->getSampleRate(),
13
- context->getBufferSizeInFrames(),
14
- channelCount_);
12
+ context->getSampleRate(), RENDER_QUANTUM_SIZE, channelCount_);
15
13
  }
16
14
 
17
15
  AudioNode::~AudioNode() {
@@ -49,6 +47,12 @@ void AudioNode::connectNode(const std::shared_ptr<AudioNode> &node) {
49
47
  node->onInputConnected(this);
50
48
  }
51
49
 
50
+ void AudioNode::disconnect() {
51
+ for (auto &outputNode : outputNodes_) {
52
+ disconnectNode(outputNode);
53
+ }
54
+ }
55
+
52
56
  void AudioNode::disconnect(const std::shared_ptr<AudioNode> &node) {
53
57
  context_->getNodeManager()->addPendingConnection(
54
58
  shared_from_this(), node, AudioNodeManager::ConnectionType::DISCONNECT);
@@ -71,16 +75,16 @@ bool AudioNode::isEnabled() const {
71
75
  void AudioNode::enable() {
72
76
  isEnabled_ = true;
73
77
 
74
- for (auto it = outputNodes_.begin(); it != outputNodes_.end(); ++it) {
75
- it->get()->onInputEnabled();
78
+ for (auto &outputNode : outputNodes_) {
79
+ outputNode->onInputEnabled();
76
80
  }
77
81
  }
78
82
 
79
83
  void AudioNode::disable() {
80
84
  isEnabled_ = false;
81
85
 
82
- for (auto it = outputNodes_.begin(); it != outputNodes_.end(); ++it) {
83
- it->get()->onInputDisabled();
86
+ for (auto &outputNode : outputNodes_) {
87
+ outputNode->onInputDisabled();
84
88
  }
85
89
  }
86
90
 
@@ -162,12 +166,14 @@ AudioBus *AudioNode::processAudio(AudioBus *outputBus, int framesToProcess) {
162
166
  AudioBus *inputBus = (*it)->processAudio(processingBus, framesToProcess);
163
167
 
164
168
  if (inputBus != processingBus) {
169
+ // add assert
165
170
  processingBus->sum(inputBus);
166
171
  }
167
172
  } else {
168
173
  // Enforce the summing to be done using the internal bus.
169
- AudioBus *inputBus = (*it)->processAudio(0, framesToProcess);
174
+ AudioBus *inputBus = (*it)->processAudio(nullptr, framesToProcess);
170
175
  if (inputBus) {
176
+ // add assert
171
177
  processingBus->sum(inputBus);
172
178
  }
173
179
  }
@@ -201,6 +207,10 @@ void AudioNode::onInputDisabled() {
201
207
  }
202
208
 
203
209
  void AudioNode::onInputConnected(AudioNode *node) {
210
+ if (!isInitialized_) {
211
+ return;
212
+ }
213
+
204
214
  inputNodes_.push_back(node);
205
215
 
206
216
  if (node->isEnabled()) {
@@ -209,6 +219,10 @@ void AudioNode::onInputConnected(AudioNode *node) {
209
219
  }
210
220
 
211
221
  void AudioNode::onInputDisconnected(AudioNode *node) {
222
+ if (!isInitialized_) {
223
+ return;
224
+ }
225
+
212
226
  auto position = std::find(inputNodes_.begin(), inputNodes_.end(), node);
213
227
 
214
228
  if (position != inputNodes_.end()) {
@@ -3,6 +3,7 @@
3
3
  #include <memory>
4
4
  #include <string>
5
5
  #include <vector>
6
+ #include <cstddef>
6
7
 
7
8
  #include "ChannelCountMode.h"
8
9
  #include "ChannelInterpretation.h"
@@ -23,6 +24,7 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {
23
24
  std::string getChannelCountMode() const;
24
25
  std::string getChannelInterpretation() const;
25
26
  void connect(const std::shared_ptr<AudioNode> &node);
27
+ void disconnect();
26
28
  void disconnect(const std::shared_ptr<AudioNode> &node);
27
29
 
28
30
  bool isEnabled() const;
@@ -36,24 +38,22 @@ class AudioNode : public std::enable_shared_from_this<AudioNode> {
36
38
  BaseAudioContext *context_;
37
39
  std::shared_ptr<AudioBus> audioBus_;
38
40
 
39
- int channelCount_ = CHANNEL_COUNT;
40
-
41
41
  int numberOfInputs_ = 1;
42
42
  int numberOfOutputs_ = 1;
43
- int numberOfEnabledInputNodes_ = 0;
43
+ int channelCount_ = 2;
44
+ ChannelCountMode channelCountMode_ = ChannelCountMode::MAX;
45
+ ChannelInterpretation channelInterpretation_ =
46
+ ChannelInterpretation::SPEAKERS;
47
+
48
+ std::vector<AudioNode *> inputNodes_ = {};
49
+ std::vector<std::shared_ptr<AudioNode>> outputNodes_ = {};
44
50
 
51
+ int numberOfEnabledInputNodes_ = 0;
45
52
  bool isInitialized_ = false;
46
53
  bool isEnabled_ = true;
47
54
 
48
55
  std::size_t lastRenderedFrame_{SIZE_MAX};
49
56
 
50
- ChannelCountMode channelCountMode_ = ChannelCountMode::MAX;
51
- ChannelInterpretation channelInterpretation_ =
52
- ChannelInterpretation::SPEAKERS;
53
-
54
- std::vector<AudioNode *> inputNodes_ = {};
55
- std::vector<std::shared_ptr<AudioNode>> outputNodes_ = {};
56
-
57
57
  private:
58
58
  static std::string toString(ChannelCountMode mode);
59
59
  static std::string toString(ChannelInterpretation interpretation);
@@ -5,8 +5,6 @@
5
5
 
6
6
  namespace audioapi {
7
7
 
8
- AudioNodeManager::AudioNodeManager() {}
9
-
10
8
  AudioNodeManager::~AudioNodeManager() {
11
9
  audioNodesToConnect_.clear();
12
10
  sourceNodes_.clear();
@@ -18,7 +16,7 @@ void AudioNodeManager::addPendingConnection(
18
16
  ConnectionType type) {
19
17
  Locker lock(getGraphLock());
20
18
 
21
- audioNodesToConnect_.push_back(std::make_tuple(from, to, type));
19
+ audioNodesToConnect_.emplace_back(from, to, type);
22
20
  }
23
21
 
24
22
  void AudioNodeManager::addSourceNode(const std::shared_ptr<AudioNode> &node) {
@@ -12,7 +12,7 @@ class AudioNode;
12
12
  class AudioNodeManager {
13
13
  public:
14
14
  enum class ConnectionType { CONNECT, DISCONNECT };
15
- AudioNodeManager();
15
+ AudioNodeManager() = default;
16
16
  ~AudioNodeManager();
17
17
 
18
18
  void preProcessGraph();
@@ -181,7 +181,7 @@ void AudioParam::setTargetAtTime(
181
181
 
182
182
  void AudioParam::setValueCurveAtTime(
183
183
  const float *values,
184
- int length,
184
+ size_t length,
185
185
  double startTime,
186
186
  double duration) {
187
187
  if (startTime <= getQueueEndTime()) {
@@ -200,9 +200,12 @@ void AudioParam::setValueCurveAtTime(
200
200
 
201
201
  if (time < endTime) {
202
202
  auto k = static_cast<int>(std::floor(
203
- (length - 1) / (endTime - startTime) * (time - startTime)));
203
+ static_cast<double>(length - 1) / (endTime - startTime) *
204
+ (time - startTime)));
204
205
  auto factor = static_cast<float>(
205
- k - (time - startTime) * (length - 1) / (endTime - startTime));
206
+ k -
207
+ (time - startTime) * static_cast<double>(length - 1) /
208
+ (endTime - startTime));
206
209
 
207
210
  return AudioUtils::linearInterpolate(values, k, k + 1, factor);
208
211
  }
@@ -3,6 +3,7 @@
3
3
  #include <deque>
4
4
  #include <memory>
5
5
  #include <vector>
6
+ #include <cstddef>
6
7
 
7
8
  #include "ParamChangeEvent.h"
8
9
  #include "ParamChangeEventType.h"
@@ -27,7 +28,7 @@ class AudioParam {
27
28
  void setTargetAtTime(float target, double startTime, double timeConstant);
28
29
  void setValueCurveAtTime(
29
30
  const float *values,
30
- int length,
31
+ size_t length,
31
32
  double startTime,
32
33
  double duration);
33
34
  void cancelScheduledValues(double cancelTime);
@@ -53,7 +53,7 @@ void AudioScheduledSourceNode::updatePlaybackInfo(
53
53
  return;
54
54
  }
55
55
 
56
- int sampleRate = context_->getSampleRate();
56
+ auto sampleRate = context_->getSampleRate();
57
57
 
58
58
  size_t firstFrame = context_->getCurrentSampleFrame();
59
59
  size_t lastFrame = firstFrame + framesToProcess;
@@ -8,6 +8,7 @@
8
8
  #include <limits>
9
9
  #include <memory>
10
10
  #include <thread>
11
+ #include <cstddef>
11
12
 
12
13
  #include "AudioNode.h"
13
14
 
@@ -1,9 +1,3 @@
1
- #ifdef ANDROID
2
- #include "AudioPlayer.h"
3
- #else
4
- #include "IOSAudioPlayer.h"
5
- #endif
6
-
7
1
  #include "BaseAudioContext.h"
8
2
 
9
3
  #include "AnalyserNode.h"
@@ -23,42 +17,18 @@
23
17
  namespace audioapi {
24
18
 
25
19
  BaseAudioContext::BaseAudioContext() {
26
- #ifdef ANDROID
27
- audioPlayer_ = std::make_shared<AudioPlayer>(this->renderAudio());
28
- #else
29
- audioPlayer_ = std::make_shared<IOSAudioPlayer>(this->renderAudio());
30
- #endif
31
-
32
- audioDecoder_ = std::make_shared<AudioDecoder>(audioPlayer_->getSampleRate());
33
-
34
- sampleRate_ = audioPlayer_->getSampleRate();
35
- bufferSizeInFrames_ = audioPlayer_->getBufferSizeInFrames();
36
-
37
20
  nodeManager_ = std::make_shared<AudioNodeManager>();
38
21
  destination_ = std::make_shared<AudioDestinationNode>(this);
39
22
  }
40
23
 
41
- BaseAudioContext::~BaseAudioContext() {
42
- if (isRunning()) {
43
- return;
44
- }
45
-
46
- state_ = ContextState::CLOSED;
47
- audioPlayer_->stop();
48
- }
49
-
50
24
  std::string BaseAudioContext::getState() {
51
25
  return BaseAudioContext::toString(state_);
52
26
  }
53
27
 
54
- int BaseAudioContext::getSampleRate() const {
28
+ float BaseAudioContext::getSampleRate() const {
55
29
  return sampleRate_;
56
30
  }
57
31
 
58
- int BaseAudioContext::getBufferSizeInFrames() const {
59
- return bufferSizeInFrames_;
60
- }
61
-
62
32
  std::size_t BaseAudioContext::getCurrentSampleFrame() const {
63
33
  return destination_->getCurrentSampleFrame();
64
34
  }
@@ -93,8 +63,8 @@ std::shared_ptr<AudioBufferSourceNode> BaseAudioContext::createBufferSource() {
93
63
 
94
64
  std::shared_ptr<AudioBuffer> BaseAudioContext::createBuffer(
95
65
  int numberOfChannels,
96
- int length,
97
- int sampleRate) {
66
+ size_t length,
67
+ float sampleRate) {
98
68
  return std::make_shared<AudioBuffer>(numberOfChannels, length, sampleRate);
99
69
  }
100
70
 
@@ -117,16 +87,6 @@ std::shared_ptr<AudioBuffer> BaseAudioContext::decodeAudioDataSource(
117
87
  return std::make_shared<AudioBuffer>(audioBus);
118
88
  }
119
89
 
120
- std::function<void(AudioBus *, int)> BaseAudioContext::renderAudio() {
121
- if (!isRunning()) {
122
- return [](AudioBus *, int) {};
123
- }
124
-
125
- return [this](AudioBus *data, int frames) {
126
- destination_->renderAudio(data, frames);
127
- };
128
- }
129
-
130
90
  AudioNodeManager *BaseAudioContext::getNodeManager() {
131
91
  return nodeManager_.get();
132
92
  }
@@ -139,6 +99,10 @@ bool BaseAudioContext::isClosed() const {
139
99
  return state_ == ContextState::CLOSED;
140
100
  }
141
101
 
102
+ float BaseAudioContext::getNyquistFrequency() const {
103
+ return sampleRate_ / 2.0f;
104
+ }
105
+
142
106
  std::string BaseAudioContext::toString(ContextState state) {
143
107
  switch (state) {
144
108
  case ContextState::SUSPENDED:
@@ -5,6 +5,7 @@
5
5
  #include <string>
6
6
  #include <utility>
7
7
  #include <vector>
8
+ #include <cstddef>
8
9
 
9
10
  #include "ContextState.h"
10
11
  #include "OscillatorType.h"
@@ -24,21 +25,14 @@ class AudioBufferSourceNode;
24
25
  class AudioDecoder;
25
26
  class AnalyserNode;
26
27
 
27
- #ifdef ANDROID
28
- class AudioPlayer;
29
- #else
30
- class IOSAudioPlayer;
31
- #endif
32
-
33
28
  class BaseAudioContext {
34
29
  public:
35
30
  BaseAudioContext();
36
- ~BaseAudioContext();
31
+ virtual ~BaseAudioContext() = default;
37
32
 
38
33
  std::string getState();
39
- [[nodiscard]] int getSampleRate() const;
34
+ [[nodiscard]] float getSampleRate() const;
40
35
  [[nodiscard]] double getCurrentTime() const;
41
- [[nodiscard]] int getBufferSizeInFrames() const;
42
36
  [[nodiscard]] std::size_t getCurrentSampleFrame() const;
43
37
  std::shared_ptr<AudioDestinationNode> getDestination();
44
38
 
@@ -48,34 +42,29 @@ class BaseAudioContext {
48
42
  std::shared_ptr<BiquadFilterNode> createBiquadFilter();
49
43
  std::shared_ptr<AudioBufferSourceNode> createBufferSource();
50
44
  static std::shared_ptr<AudioBuffer>
51
- createBuffer(int numberOfChannels, int length, int sampleRate);
45
+ createBuffer(int numberOfChannels, size_t length, float sampleRate);
52
46
  std::shared_ptr<PeriodicWave> createPeriodicWave(
53
47
  float *real,
54
48
  float *imag,
55
49
  bool disableNormalization,
56
50
  int length);
57
51
  std::shared_ptr<AnalyserNode> createAnalyser();
58
-
59
52
  std::shared_ptr<AudioBuffer> decodeAudioDataSource(const std::string &path);
53
+
60
54
  std::shared_ptr<PeriodicWave> getBasicWaveForm(OscillatorType type);
61
- std::function<void(AudioBus *, int)> renderAudio();
62
55
  AudioNodeManager *getNodeManager();
63
56
  [[nodiscard]] bool isRunning() const;
64
57
  [[nodiscard]] bool isClosed() const;
58
+ [[nodiscard]] float getNyquistFrequency() const;
65
59
 
66
60
  protected:
67
61
  static std::string toString(ContextState state);
68
62
  std::shared_ptr<AudioDestinationNode> destination_;
69
- std::shared_ptr<AudioDecoder> audioDecoder_;
70
-
71
- #ifdef ANDROID
72
- std::shared_ptr<AudioPlayer> audioPlayer_;
73
- #else
74
- std::shared_ptr<IOSAudioPlayer> audioPlayer_;
75
- #endif
63
+ // init in AudioContext or OfflineContext constructor
64
+ std::shared_ptr<AudioDecoder> audioDecoder_ {};
76
65
 
77
- int sampleRate_;
78
- int bufferSizeInFrames_;
66
+ // init in AudioContext or OfflineContext constructor
67
+ float sampleRate_ {};
79
68
  ContextState state_ = ContextState::RUNNING;
80
69
  std::shared_ptr<AudioNodeManager> nodeManager_;
81
70
 
@@ -11,9 +11,9 @@ namespace audioapi {
11
11
  BiquadFilterNode::BiquadFilterNode(BaseAudioContext *context)
12
12
  : AudioNode(context) {
13
13
  frequencyParam_ = std::make_shared<AudioParam>(
14
- 350.0, MIN_FILTER_FREQUENCY, MAX_FILTER_FREQUENCY);
14
+ 350.0, MIN_FILTER_FREQUENCY, context->getNyquistFrequency());
15
15
  detuneParam_ = std::make_shared<AudioParam>(0.0, -MAX_DETUNE, MAX_DETUNE);
16
- QParam_ = std::make_shared<AudioParam>(1.0, -MAX_FILTER_Q, MAX_FILTER_Q);
16
+ QParam_ = std::make_shared<AudioParam>(1.0, MIN_FILTER_Q, MAX_FILTER_Q);
17
17
  gainParam_ =
18
18
  std::make_shared<AudioParam>(0.0, MIN_FILTER_GAIN, MAX_FILTER_GAIN);
19
19
  type_ = BiquadFilterType::LOWPASS;
@@ -67,8 +67,7 @@ void BiquadFilterNode::getFrequencyResponse(
67
67
  float a2 = a2_;
68
68
 
69
69
  for (size_t i = 0; i < frequencyArraySize; i++) {
70
- auto omega =
71
- static_cast<float>(M_PI) * frequencyArray[i] / NYQUIST_FREQUENCY;
70
+ auto omega = PI * frequencyArray[i] / context_->getNyquistFrequency();
72
71
  auto z = std::complex<float>(cos(omega), sin(omega));
73
72
  auto response = ((b0 * z + b1) * z + b2) / ((z + a1) * z + a2);
74
73
  magResponseOutput[i] = static_cast<float>(abs(response));
@@ -113,7 +112,7 @@ void BiquadFilterNode::setLowpassCoefficients(float frequency, float Q) {
113
112
  Q = std::max(0.0f, Q);
114
113
  float g = std::pow(10.0f, 0.05f * Q);
115
114
 
116
- float theta = M_PI * frequency;
115
+ float theta = PI * frequency;
117
116
  float alpha = std::sin(theta) / (2 * g);
118
117
  float cosW = std::cos(theta);
119
118
  float beta = (1 - cosW) / 2;
@@ -136,7 +135,7 @@ void BiquadFilterNode::setHighpassCoefficients(float frequency, float Q) {
136
135
  Q = std::max(0.0f, Q);
137
136
  float g = std::pow(10.0f, 0.05f * Q);
138
137
 
139
- float theta = M_PI * frequency;
138
+ float theta = PI * frequency;
140
139
  float alpha = std::sin(theta) / (2 * g);
141
140
  float cosW = std::cos(theta);
142
141
  float beta = (1 - cosW) / 2;
@@ -159,7 +158,7 @@ void BiquadFilterNode::setBandpassCoefficients(float frequency, float Q) {
159
158
  return;
160
159
  }
161
160
 
162
- float w0 = M_PI * frequency;
161
+ float w0 = PI * frequency;
163
162
  float alpha = std::sin(w0) / (2 * Q);
164
163
  float k = std::cos(w0);
165
164
 
@@ -181,7 +180,7 @@ void BiquadFilterNode::setLowshelfCoefficients(float frequency, float gain) {
181
180
  return;
182
181
  }
183
182
 
184
- float w0 = M_PI * frequency;
183
+ float w0 = PI * frequency;
185
184
  float alpha =
186
185
  0.5f * std::sin(w0) * std::sqrt((A + 1 / A) * (1 / 1.0f - 1) + 2);
187
186
  float k = std::cos(w0);
@@ -210,7 +209,7 @@ void BiquadFilterNode::setHighshelfCoefficients(float frequency, float gain) {
210
209
  return;
211
210
  }
212
211
 
213
- float w0 = M_PI * frequency;
212
+ float w0 = PI * frequency;
214
213
  float alpha =
215
214
  0.5f * std::sin(w0) * std::sqrt((A + 1 / A) * (1 / 1.0f - 1) + 2);
216
215
  float k = std::cos(w0);
@@ -243,7 +242,7 @@ void BiquadFilterNode::setPeakingCoefficients(
243
242
  return;
244
243
  }
245
244
 
246
- float w0 = M_PI * frequency;
245
+ float w0 = PI * frequency;
247
246
  float alpha = std::sin(w0) / (2 * Q);
248
247
  float k = std::cos(w0);
249
248
 
@@ -270,7 +269,7 @@ void BiquadFilterNode::setNotchCoefficients(float frequency, float Q) {
270
269
  return;
271
270
  }
272
271
 
273
- float w0 = M_PI * frequency;
272
+ float w0 = PI * frequency;
274
273
  float alpha = std::sin(w0) / (2 * Q);
275
274
  float k = std::cos(w0);
276
275
 
@@ -291,7 +290,7 @@ void BiquadFilterNode::setAllpassCoefficients(float frequency, float Q) {
291
290
  return;
292
291
  }
293
292
 
294
- float w0 = M_PI * frequency;
293
+ float w0 = PI * frequency;
295
294
  float alpha = std::sin(w0) / (2 * Q);
296
295
  float k = std::cos(w0);
297
296
 
@@ -302,8 +301,8 @@ void BiquadFilterNode::setAllpassCoefficients(float frequency, float Q) {
302
301
  void BiquadFilterNode::applyFilter() {
303
302
  double currentTime = context_->getCurrentTime();
304
303
 
305
- float normalizedFrequency =
306
- frequencyParam_->getValueAtTime(currentTime) / NYQUIST_FREQUENCY;
304
+ float normalizedFrequency = frequencyParam_->getValueAtTime(currentTime) /
305
+ context_->getNyquistFrequency();
307
306
  float detuneValue = detuneParam_->getValueAtTime(currentTime);
308
307
 
309
308
  if (detuneValue != 0.0) {
@@ -6,25 +6,39 @@
6
6
  // https://webaudio.github.io/web-audio-api/
7
7
 
8
8
  namespace audioapi {
9
- constexpr int SAMPLE_RATE = 48000;
9
+ // context
10
+ constexpr int RENDER_QUANTUM_SIZE = 128;
10
11
  constexpr int CHANNEL_COUNT = 2;
11
12
 
13
+ // general
12
14
  constexpr float MOST_POSITIVE_SINGLE_FLOAT = static_cast<float>(std::numeric_limits<float>::max());
13
15
  constexpr float MOST_NEGATIVE_SINGLE_FLOAT = static_cast<float>(std::numeric_limits<float>::lowest());
16
+ constexpr float PI = static_cast<float>(M_PI);
14
17
 
15
- constexpr float NYQUIST_FREQUENCY = SAMPLE_RATE / 2.0;
16
- static float MAX_DETUNE = 1200 * std::log2(MOST_POSITIVE_SINGLE_FLOAT);
17
- constexpr float MAX_GAIN = MOST_POSITIVE_SINGLE_FLOAT;
18
+ // pan
18
19
  constexpr float MAX_PAN = 1.0;
19
- constexpr float MAX_FILTER_Q = MOST_POSITIVE_SINGLE_FLOAT;
20
- constexpr float MAX_FILTER_FREQUENCY = NYQUIST_FREQUENCY;
20
+ constexpr float MIN_PAN = -1.0;
21
+
22
+ // gain
23
+ constexpr float MAX_GAIN = MOST_POSITIVE_SINGLE_FLOAT;
24
+ constexpr float MIN_GAIN = -MAX_GAIN;
25
+
26
+ // biquad filter
21
27
  constexpr float MIN_FILTER_FREQUENCY = 0.0;
22
28
  static float MAX_FILTER_GAIN = 40 * std::log10(MOST_POSITIVE_SINGLE_FLOAT);
23
- constexpr float MIN_FILTER_GAIN = -MAX_GAIN;
29
+ static float MIN_FILTER_GAIN = -MAX_GAIN;
30
+ constexpr float MAX_FILTER_Q = MOST_POSITIVE_SINGLE_FLOAT;
31
+ constexpr float MIN_FILTER_Q = -MAX_FILTER_Q;
32
+
33
+ //detune
34
+ static float MAX_DETUNE = 1200 * std::log2(MOST_POSITIVE_SINGLE_FLOAT);
35
+ static float MIN_DETUNE = -MAX_DETUNE;
24
36
 
25
- constexpr int MAX_FFT_SIZE = 32768;
26
- constexpr int DEFAULT_FFT_SIZE = 2048;
27
- constexpr double DEFAULT_MAX_DECIBELS = -30;
28
- constexpr double DEFAULT_MIN_DECIBELS = -100;
29
- const double DEFAULT_SMOOTHING_TIME_CONSTANT = 0.8;
37
+ // analyser node
38
+ constexpr size_t MAX_FFT_SIZE = 32768;
39
+ constexpr size_t MIN_FFT_SIZE = 32;
40
+ constexpr size_t DEFAULT_FFT_SIZE = 2048;
41
+ constexpr float DEFAULT_MAX_DECIBELS = -30;
42
+ constexpr float DEFAULT_MIN_DECIBELS = -100;
43
+ const float DEFAULT_SMOOTHING_TIME_CONSTANT = 0.8;
30
44
  } // namespace audioapi
@@ -6,7 +6,7 @@
6
6
  namespace audioapi {
7
7
 
8
8
  GainNode::GainNode(BaseAudioContext *context) : AudioNode(context) {
9
- gainParam_ = std::make_shared<AudioParam>(1.0, -MAX_GAIN, MAX_GAIN);
9
+ gainParam_ = std::make_shared<AudioParam>(1.0, MIN_GAIN, MAX_GAIN);
10
10
  isInitialized_ = true;
11
11
  }
12
12
 
@@ -8,7 +8,7 @@ namespace audioapi {
8
8
  OscillatorNode::OscillatorNode(BaseAudioContext *context)
9
9
  : AudioScheduledSourceNode(context) {
10
10
  frequencyParam_ = std::make_shared<AudioParam>(
11
- 444.0, -NYQUIST_FREQUENCY, NYQUIST_FREQUENCY);
11
+ 444.0, -context_->getNyquistFrequency(), context_->getNyquistFrequency());
12
12
  detuneParam_ = std::make_shared<AudioParam>(0.0, -MAX_DETUNE, MAX_DETUNE);
13
13
  type_ = OscillatorType::SINE;
14
14
  periodicWave_ = context_->getBasicWaveForm(type_);
@@ -49,8 +49,9 @@ void OscillatorNode::processNode(AudioBus *processingBus, int framesToProcess) {
49
49
  return;
50
50
  }
51
51
 
52
- double deltaTime = 1.0 / context_->getSampleRate();
53
- double time = context_->getCurrentTime() + startOffset * deltaTime;
52
+ auto deltaTime = 1.0 / context_->getSampleRate();
53
+ auto time =
54
+ context_->getCurrentTime() + static_cast<double>(startOffset) * deltaTime;
54
55
 
55
56
  for (size_t i = startOffset; i < offsetLength; i += 1) {
56
57
  auto detuneRatio =
@@ -27,6 +27,7 @@
27
27
  */
28
28
 
29
29
  #include "PeriodicWave.h"
30
+ #include "Constants.h"
30
31
 
31
32
  constexpr unsigned NumberOfOctaveBands = 3;
32
33
  constexpr float CentsPerRange = 1200.0f / NumberOfOctaveBands;
@@ -34,10 +35,10 @@ constexpr float interpolate2Point = 0.3;
34
35
  constexpr float interpolate3Point = 0.16;
35
36
 
36
37
  namespace audioapi {
37
- PeriodicWave::PeriodicWave(int sampleRate, bool disableNormalization)
38
+ PeriodicWave::PeriodicWave(float sampleRate, bool disableNormalization)
38
39
  : sampleRate_(sampleRate), disableNormalization_(disableNormalization) {
39
- numberOfRanges_ = lround(
40
- NumberOfOctaveBands * log2f(static_cast<float>(getPeriodicWaveSize())));
40
+ numberOfRanges_ = static_cast<int>(round(
41
+ NumberOfOctaveBands * log2f(static_cast<float>(getPeriodicWaveSize()))));
41
42
  auto nyquistFrequency = sampleRate_ / 2;
42
43
  lowestFundamentalFrequency_ = static_cast<float>(nyquistFrequency) /
43
44
  static_cast<float>(getMaxNumberOfPartials());
@@ -47,7 +48,7 @@ PeriodicWave::PeriodicWave(int sampleRate, bool disableNormalization)
47
48
  }
48
49
 
49
50
  PeriodicWave::PeriodicWave(
50
- int sampleRate,
51
+ float sampleRate,
51
52
  audioapi::OscillatorType type,
52
53
  bool disableNormalization)
53
54
  : PeriodicWave(sampleRate, disableNormalization) {
@@ -55,7 +56,7 @@ PeriodicWave::PeriodicWave(
55
56
  }
56
57
 
57
58
  PeriodicWave::PeriodicWave(
58
- int sampleRate,
59
+ float sampleRate,
59
60
  float *real,
60
61
  float *imaginary,
61
62
  int length,
@@ -147,7 +148,7 @@ void PeriodicWave::generateBasicWaveForm(OscillatorType type) {
147
148
  // Coefficient for sin()
148
149
  float b;
149
150
 
150
- auto piFactor = static_cast<float>(1.0f / (i * M_PI));
151
+ auto piFactor = 1.0f / (PI * static_cast<float>(i));
151
152
 
152
153
  switch (type) {
153
154
  case OscillatorType::SINE:
@@ -40,11 +40,11 @@ namespace audioapi {
40
40
  class PeriodicWave {
41
41
  public:
42
42
  explicit PeriodicWave(
43
- int sampleRate,
43
+ float sampleRate,
44
44
  OscillatorType type,
45
45
  bool disableNormalization);
46
46
  explicit PeriodicWave(
47
- int sampleRate,
47
+ float sampleRate,
48
48
  float *real,
49
49
  float *imaginary,
50
50
  int length,
@@ -57,7 +57,7 @@ class PeriodicWave {
57
57
  getSample(float fundamentalFrequency, float phase, float phaseIncrement);
58
58
 
59
59
  private:
60
- explicit PeriodicWave(int sampleRate, bool disableNormalization);
60
+ explicit PeriodicWave(float sampleRate, bool disableNormalization);
61
61
 
62
62
  // Partial is any frequency component of a sound.
63
63
  // Both harmonics(fundamentalFrequency * k) and overtones are partials.
@@ -102,7 +102,7 @@ class PeriodicWave {
102
102
  const float *higherWaveData) const;
103
103
 
104
104
  // determines the time resolution of the waveform.
105
- int sampleRate_;
105
+ float sampleRate_;
106
106
  // determines number of frequency segments (or bands) the signal is divided.
107
107
  int numberOfRanges_;
108
108
  // the lowest frequency (in hertz) where playback will include all of the
@@ -11,7 +11,7 @@ namespace audioapi {
11
11
  StereoPannerNode::StereoPannerNode(BaseAudioContext *context)
12
12
  : AudioNode(context) {
13
13
  channelCountMode_ = ChannelCountMode::CLAMPED_MAX;
14
- panParam_ = std::make_shared<AudioParam>(0.0, -MAX_PAN, MAX_PAN);
14
+ panParam_ = std::make_shared<AudioParam>(0.0, MIN_PAN, MAX_PAN);
15
15
  isInitialized_ = true;
16
16
  }
17
17
 
@@ -36,10 +36,10 @@ void StereoPannerNode::processNode(
36
36
 
37
37
  for (int i = 0; i < framesToProcess; i += 1) {
38
38
  float pan = panParam_->getValueAtTime(time);
39
- float x = (pan <= 0 ? pan + 1 : pan) * M_PI / 2;
39
+ float x = (pan <= 0 ? pan + 1 : pan) * PI / 2;
40
40
 
41
- float gainL = static_cast<float>(cos(x));
42
- float gainR = static_cast<float>(sin(x));
41
+ auto gainL = static_cast<float>(cos(x));
42
+ auto gainR = static_cast<float>(sin(x));
43
43
 
44
44
  float inputL = (*left)[i];
45
45
  float inputR = (*right)[i];