react-native-audio-api 0.6.0-rc.4 → 0.6.0
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.
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +35 -2
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +4 -0
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +31 -17
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +1 -3
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +56 -2
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +0 -12
- package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +35 -12
- package/android/src/main/java/com/swmansion/audioapi/system/LockScreenManager.kt +30 -29
- package/android/src/main/java/com/swmansion/audioapi/system/MediaNotificationManager.kt +20 -22
- package/android/src/main/java/com/swmansion/audioapi/system/MediaReceiver.kt +19 -9
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionCallback.kt +30 -11
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionManager.kt +53 -26
- package/android/src/main/java/com/swmansion/audioapi/system/VolumeChangeListener.kt +10 -5
- package/android/src/oldarch/NativeAudioAPIModuleSpec.java +39 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +20 -14
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +2 -3
- package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.h +24 -11
- package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +1 -0
- package/common/cpp/audioapi/HostObjects/AudioRecorderHostObject.h +10 -89
- package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +3 -24
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +2 -2
- package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +2 -3
- package/common/cpp/audioapi/core/AudioContext.cpp +4 -1
- package/common/cpp/audioapi/core/AudioContext.h +1 -1
- package/common/cpp/audioapi/core/AudioNode.cpp +31 -2
- package/common/cpp/audioapi/core/AudioNode.h +7 -1
- package/common/cpp/audioapi/core/AudioParam.cpp +84 -2
- package/common/cpp/audioapi/core/AudioParam.h +14 -1
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +7 -1
- package/common/cpp/audioapi/core/BaseAudioContext.h +7 -1
- package/common/cpp/audioapi/core/OfflineAudioContext.cpp +3 -2
- package/common/cpp/audioapi/core/OfflineAudioContext.h +1 -1
- package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +19 -56
- package/common/cpp/audioapi/core/analysis/AnalyserNode.h +3 -2
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +28 -26
- package/common/cpp/audioapi/core/effects/GainNode.cpp +9 -9
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +5 -2
- package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +56 -0
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +13 -13
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +14 -10
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +1 -1
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +7 -6
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +5 -3
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +15 -10
- package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +35 -1
- package/common/cpp/audioapi/core/utils/AudioNodeManager.h +15 -1
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +108 -0
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +62 -0
- package/common/cpp/audioapi/events/AudioEventHandlerRegistryHostObject.h +48 -0
- package/common/cpp/audioapi/jsi/JsiPromise.cpp +3 -4
- package/common/cpp/audioapi/utils/AudioArray.h +1 -1
- package/common/cpp/audioapi/utils/CircularAudioArray.cpp +94 -0
- package/common/cpp/audioapi/utils/CircularAudioArray.h +26 -0
- package/ios/audioapi/ios/AudioAPIModule.h +13 -0
- package/ios/audioapi/ios/AudioAPIModule.mm +115 -6
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +3 -10
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +15 -52
- package/ios/audioapi/ios/core/NativeAudioPlayer.m +2 -0
- package/ios/audioapi/ios/core/NativeAudioRecorder.m +7 -3
- package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.h +7 -0
- package/ios/audioapi/ios/events/IOSAudioEventHandlerRegistry.mm +12 -0
- package/ios/audioapi/ios/system/AudioEngine.h +5 -0
- package/ios/audioapi/ios/system/AudioEngine.mm +7 -15
- package/ios/audioapi/ios/system/AudioSessionManager.h +3 -1
- package/ios/audioapi/ios/system/AudioSessionManager.mm +36 -17
- package/ios/audioapi/ios/system/LockScreenManager.h +3 -3
- package/ios/audioapi/ios/system/LockScreenManager.mm +36 -48
- package/ios/audioapi/ios/system/NotificationManager.h +3 -3
- package/ios/audioapi/ios/system/NotificationManager.mm +21 -29
- package/lib/commonjs/api.js +4 -4
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/AudioBufferSourceNode.js +2 -2
- package/lib/commonjs/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/commonjs/core/AudioNode.js +8 -2
- package/lib/commonjs/core/AudioNode.js.map +1 -1
- package/lib/commonjs/core/AudioParam.js +2 -1
- package/lib/commonjs/core/AudioParam.js.map +1 -1
- package/lib/commonjs/core/AudioRecorder.js +11 -28
- package/lib/commonjs/core/AudioRecorder.js.map +1 -1
- package/lib/commonjs/core/AudioScheduledSourceNode.js +4 -1
- package/lib/commonjs/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/commonjs/core/BiquadFilterNode.js +4 -4
- package/lib/commonjs/core/BiquadFilterNode.js.map +1 -1
- package/lib/commonjs/core/GainNode.js +1 -1
- package/lib/commonjs/core/GainNode.js.map +1 -1
- package/lib/commonjs/core/OscillatorNode.js +2 -2
- package/lib/commonjs/core/OscillatorNode.js.map +1 -1
- package/lib/commonjs/core/StereoPannerNode.js +1 -1
- package/lib/commonjs/core/StereoPannerNode.js.map +1 -1
- package/lib/commonjs/events/AudioEventEmitter.js +22 -0
- package/lib/commonjs/events/AudioEventEmitter.js.map +1 -0
- package/lib/commonjs/events/AudioEventSubscription.js +20 -0
- package/lib/commonjs/events/AudioEventSubscription.js.map +1 -0
- package/lib/commonjs/events/index.js +21 -0
- package/lib/commonjs/events/index.js.map +1 -0
- package/lib/commonjs/events/types.js +6 -0
- package/lib/commonjs/events/types.js.map +1 -0
- package/lib/commonjs/hooks/useSytemVolume.js +1 -1
- package/lib/commonjs/hooks/useSytemVolume.js.map +1 -1
- package/lib/commonjs/specs/NativeAudioAPIModule.js +3 -3
- package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/commonjs/specs/index.js +2 -16
- package/lib/commonjs/specs/index.js.map +1 -1
- package/lib/commonjs/system/AudioManager.js +26 -26
- package/lib/commonjs/system/AudioManager.js.map +1 -1
- package/lib/module/api.js +2 -2
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +2 -2
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioNode.js +7 -2
- package/lib/module/core/AudioNode.js.map +1 -1
- package/lib/module/core/AudioParam.js +2 -1
- package/lib/module/core/AudioParam.js.map +1 -1
- package/lib/module/core/AudioRecorder.js +11 -28
- package/lib/module/core/AudioRecorder.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +4 -1
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/core/BiquadFilterNode.js +4 -4
- package/lib/module/core/BiquadFilterNode.js.map +1 -1
- package/lib/module/core/GainNode.js +1 -1
- package/lib/module/core/GainNode.js.map +1 -1
- package/lib/module/core/OscillatorNode.js +2 -2
- package/lib/module/core/OscillatorNode.js.map +1 -1
- package/lib/module/core/StereoPannerNode.js +1 -1
- package/lib/module/core/StereoPannerNode.js.map +1 -1
- package/lib/module/events/AudioEventEmitter.js +16 -0
- package/lib/module/events/AudioEventEmitter.js.map +1 -0
- package/lib/module/events/AudioEventSubscription.js +15 -0
- package/lib/module/events/AudioEventSubscription.js.map +1 -0
- package/lib/module/events/index.js +6 -0
- package/lib/module/events/index.js.map +1 -0
- package/lib/module/events/types.js +4 -0
- package/lib/module/events/types.js.map +1 -0
- package/lib/module/hooks/useSytemVolume.js +1 -1
- package/lib/module/hooks/useSytemVolume.js.map +1 -1
- package/lib/module/specs/NativeAudioAPIModule.js +3 -2
- package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/module/specs/index.js +2 -3
- package/lib/module/specs/index.js.map +1 -1
- package/lib/module/system/AudioManager.js +27 -27
- package/lib/module/system/AudioManager.js.map +1 -1
- package/lib/typescript/api.d.ts +2 -1
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/AudioNode.d.ts +2 -1
- package/lib/typescript/core/AudioNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioParam.d.ts +4 -2
- package/lib/typescript/core/AudioParam.d.ts.map +1 -1
- package/lib/typescript/core/AudioRecorder.d.ts +4 -14
- package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +3 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/events/AudioEventEmitter.d.ts +10 -0
- package/lib/typescript/events/AudioEventEmitter.d.ts.map +1 -0
- package/lib/typescript/events/AudioEventSubscription.d.ts +11 -0
- package/lib/typescript/events/AudioEventSubscription.d.ts.map +1 -0
- package/lib/typescript/events/index.d.ts +4 -0
- package/lib/typescript/events/index.d.ts.map +1 -0
- package/lib/typescript/events/types.d.ts +50 -0
- package/lib/typescript/events/types.d.ts.map +1 -0
- package/lib/typescript/hooks/useSytemVolume.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +10 -10
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts +15 -3
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
- package/lib/typescript/specs/index.d.ts +2 -3
- package/lib/typescript/specs/index.d.ts.map +1 -1
- package/lib/typescript/system/AudioManager.d.ts +8 -4
- package/lib/typescript/system/AudioManager.d.ts.map +1 -1
- package/lib/typescript/system/types.d.ts +1 -34
- package/lib/typescript/system/types.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +0 -1
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/api.ts +6 -3
- package/src/core/AudioBufferSourceNode.ts +2 -2
- package/src/core/AudioNode.ts +8 -3
- package/src/core/AudioParam.ts +5 -2
- package/src/core/AudioRecorder.ts +22 -62
- package/src/core/AudioScheduledSourceNode.ts +13 -2
- package/src/core/BiquadFilterNode.ts +4 -4
- package/src/core/GainNode.ts +1 -1
- package/src/core/OscillatorNode.ts +2 -2
- package/src/core/StereoPannerNode.ts +1 -1
- package/src/events/AudioEventEmitter.ts +29 -0
- package/src/events/AudioEventSubscription.ts +26 -0
- package/src/events/index.ts +4 -0
- package/src/events/types.ts +64 -0
- package/src/hooks/useSytemVolume.ts +2 -1
- package/src/interfaces.ts +19 -20
- package/src/specs/NativeAudioAPIModule.ts +23 -2
- package/src/specs/index.ts +2 -4
- package/src/system/AudioManager.ts +39 -38
- package/src/system/types.ts +1 -41
- package/src/types.ts +0 -8
- package/android/src/main/java/com/swmansion/audioapi/AudioManagerModule.kt +0 -64
- package/android/src/main/java/com/swmansion/audioapi/system/MediaSessionEventEmitter.kt +0 -88
- package/android/src/oldarch/NativeAudioManagerModuleSpec.java +0 -99
- package/ios/audioapi/ios/AudioManagerModule.h +0 -18
- package/ios/audioapi/ios/AudioManagerModule.mm +0 -93
- package/lib/commonjs/specs/NativeAudioManagerModule.js +0 -36
- package/lib/commonjs/specs/NativeAudioManagerModule.js.map +0 -1
- package/lib/module/specs/NativeAudioManagerModule.js +0 -33
- package/lib/module/specs/NativeAudioManagerModule.js.map +0 -1
- package/lib/typescript/specs/NativeAudioManagerModule.d.ts +0 -15
- package/lib/typescript/specs/NativeAudioManagerModule.d.ts.map +0 -1
- package/src/specs/NativeAudioManagerModule.ts +0 -45
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#include <audioapi/dsp/Windows.h>
|
|
6
6
|
#include <audioapi/utils/AudioArray.h>
|
|
7
7
|
#include <audioapi/utils/AudioBus.h>
|
|
8
|
+
#include <audioapi/utils/CircularAudioArray.h>
|
|
8
9
|
|
|
9
10
|
namespace audioapi {
|
|
10
11
|
AnalyserNode::AnalyserNode(audioapi::BaseAudioContext *context)
|
|
@@ -13,9 +14,9 @@ AnalyserNode::AnalyserNode(audioapi::BaseAudioContext *context)
|
|
|
13
14
|
minDecibels_(-100),
|
|
14
15
|
maxDecibels_(-30),
|
|
15
16
|
smoothingTimeConstant_(0.8),
|
|
16
|
-
windowType_(WindowType::BLACKMAN)
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
windowType_(WindowType::BLACKMAN) {
|
|
18
|
+
inputBuffer_ = std::make_unique<CircularAudioArray>(MAX_FFT_SIZE * 2);
|
|
19
|
+
tempBuffer_ = std::make_unique<AudioArray>(fftSize_);
|
|
19
20
|
magnitudeBuffer_ = std::make_unique<AudioArray>(fftSize_ / 2);
|
|
20
21
|
downMixBus_ = std::make_unique<AudioBus>(
|
|
21
22
|
RENDER_QUANTUM_SIZE, 1, context_->getSampleRate());
|
|
@@ -61,6 +62,7 @@ void AnalyserNode::setFftSize(int fftSize) {
|
|
|
61
62
|
fft_ = std::make_unique<dsp::FFT>(fftSize_);
|
|
62
63
|
complexData_ = std::vector<std::complex<float>>(fftSize_);
|
|
63
64
|
magnitudeBuffer_ = std::make_unique<AudioArray>(fftSize_ / 2);
|
|
65
|
+
tempBuffer_ = std::make_unique<AudioArray>(fftSize_);
|
|
64
66
|
setWindowData(windowType_, fftSize_);
|
|
65
67
|
}
|
|
66
68
|
|
|
@@ -116,21 +118,17 @@ void AnalyserNode::getByteFrequencyData(uint8_t *data, int length) {
|
|
|
116
118
|
|
|
117
119
|
void AnalyserNode::getFloatTimeDomainData(float *data, int length) {
|
|
118
120
|
auto size = std::min(fftSize_, length);
|
|
119
|
-
|
|
120
|
-
for (int i = 0; i < size; i++) {
|
|
121
|
-
data[i] = inputBuffer_->getData()
|
|
122
|
-
[(vWriteIndex_ + i - fftSize_ + inputBuffer_->getSize()) %
|
|
123
|
-
inputBuffer_->getSize()];
|
|
124
|
-
}
|
|
121
|
+
inputBuffer_->pop_back(data, size, std::max(0, fftSize_ - size), true);
|
|
125
122
|
}
|
|
126
123
|
|
|
127
124
|
void AnalyserNode::getByteTimeDomainData(uint8_t *data, int length) {
|
|
128
125
|
auto size = std::min(fftSize_, length);
|
|
129
126
|
|
|
127
|
+
inputBuffer_->pop_back(
|
|
128
|
+
tempBuffer_->getData(), fftSize_, std::max(0, fftSize_ - size), true);
|
|
129
|
+
|
|
130
130
|
for (int i = 0; i < size; i++) {
|
|
131
|
-
auto value =
|
|
132
|
-
[(vWriteIndex_ + i - fftSize_ + inputBuffer_->getSize()) %
|
|
133
|
-
inputBuffer_->getSize()];
|
|
131
|
+
auto value = tempBuffer_->getData()[i];
|
|
134
132
|
|
|
135
133
|
float scaledValue = 128 * (value + 1);
|
|
136
134
|
|
|
@@ -153,29 +151,9 @@ void AnalyserNode::processNode(
|
|
|
153
151
|
|
|
154
152
|
// Down mix the input bus to mono
|
|
155
153
|
downMixBus_->copy(processingBus.get());
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (vWriteIndex_ + framesToProcess > inputBuffer_->getSize()) {
|
|
160
|
-
framesToCopy = static_cast<int>(inputBuffer_->getSize()) - vWriteIndex_;
|
|
161
|
-
memcpy(
|
|
162
|
-
inputBuffer_->getData() + vWriteIndex_,
|
|
163
|
-
downMixBus_->getChannel(0)->getData(),
|
|
164
|
-
framesToCopy * sizeof(float));
|
|
165
|
-
|
|
166
|
-
vWriteIndex_ = 0;
|
|
167
|
-
framesToProcess -= framesToCopy;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
memcpy(
|
|
171
|
-
inputBuffer_->getData() + vWriteIndex_,
|
|
172
|
-
downMixBus_->getChannel(0)->getData() + framesToCopy,
|
|
173
|
-
framesToProcess * sizeof(float));
|
|
174
|
-
|
|
175
|
-
vWriteIndex_ += framesToProcess;
|
|
176
|
-
if (vWriteIndex_ >= inputBuffer_->getSize()) {
|
|
177
|
-
vWriteIndex_ = 0;
|
|
178
|
-
}
|
|
154
|
+
// Copy the down mixed bus to the input buffer (circular buffer)
|
|
155
|
+
inputBuffer_->push_back(
|
|
156
|
+
downMixBus_->getChannel(0)->getData(), framesToProcess, true);
|
|
179
157
|
|
|
180
158
|
shouldDoFFTAnalysis_ = true;
|
|
181
159
|
}
|
|
@@ -187,33 +165,18 @@ void AnalyserNode::doFFTAnalysis() {
|
|
|
187
165
|
|
|
188
166
|
shouldDoFFTAnalysis_ = false;
|
|
189
167
|
|
|
190
|
-
// We
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
// We want to copy last fftSize_ elements added to the input buffer(fftSize_
|
|
195
|
-
// elements before vWriteIndex_). However inputBuffer_ works like a circular
|
|
196
|
-
// buffer so we have two cases to consider.
|
|
197
|
-
if (vWriteIndex_ < fftSize_) {
|
|
198
|
-
tempBuffer.copy(
|
|
199
|
-
inputBuffer_.get(),
|
|
200
|
-
vWriteIndex_ - fftSize_ + inputBuffer_->getSize(),
|
|
201
|
-
0,
|
|
202
|
-
fftSize_ - vWriteIndex_);
|
|
203
|
-
tempBuffer.copy(
|
|
204
|
-
inputBuffer_.get(), 0, fftSize_ - vWriteIndex_, vWriteIndex_);
|
|
205
|
-
} else {
|
|
206
|
-
tempBuffer.copy(inputBuffer_.get(), vWriteIndex_ - fftSize_, 0, fftSize_);
|
|
207
|
-
}
|
|
168
|
+
// We want to copy last fftSize_ elements added to the input buffer to apply
|
|
169
|
+
// the window.
|
|
170
|
+
inputBuffer_->pop_back(tempBuffer_->getData(), fftSize_, 0, true);
|
|
208
171
|
|
|
209
172
|
dsp::multiply(
|
|
210
|
-
|
|
173
|
+
tempBuffer_->getData(),
|
|
211
174
|
windowData_->getData(),
|
|
212
|
-
|
|
175
|
+
tempBuffer_->getData(),
|
|
213
176
|
fftSize_);
|
|
214
177
|
|
|
215
178
|
// do fft analysis - get frequency domain data
|
|
216
|
-
fft_->doFFT(
|
|
179
|
+
fft_->doFFT(tempBuffer_->getData(), complexData_);
|
|
217
180
|
|
|
218
181
|
// Zero out nquist component
|
|
219
182
|
complexData_[0] = std::complex<float>(complexData_[0].real(), 0);
|
|
@@ -13,6 +13,7 @@ namespace audioapi {
|
|
|
13
13
|
|
|
14
14
|
class AudioBus;
|
|
15
15
|
class AudioArray;
|
|
16
|
+
class CircularAudioArray;
|
|
16
17
|
|
|
17
18
|
class AnalyserNode : public AudioNode {
|
|
18
19
|
public:
|
|
@@ -49,9 +50,9 @@ class AnalyserNode : public AudioNode {
|
|
|
49
50
|
WindowType windowType_;
|
|
50
51
|
std::shared_ptr<AudioArray> windowData_;
|
|
51
52
|
|
|
52
|
-
std::unique_ptr<
|
|
53
|
+
std::unique_ptr<CircularAudioArray> inputBuffer_;
|
|
53
54
|
std::unique_ptr<AudioBus> downMixBus_;
|
|
54
|
-
|
|
55
|
+
std::unique_ptr<AudioArray> tempBuffer_;
|
|
55
56
|
|
|
56
57
|
std::unique_ptr<dsp::FFT> fft_;
|
|
57
58
|
std::vector<std::complex<float>> complexData_;
|
|
@@ -10,16 +10,20 @@ namespace audioapi {
|
|
|
10
10
|
|
|
11
11
|
BiquadFilterNode::BiquadFilterNode(BaseAudioContext *context)
|
|
12
12
|
: AudioNode(context) {
|
|
13
|
-
frequencyParam_ =
|
|
14
|
-
|
|
13
|
+
frequencyParam_ = std::make_shared<AudioParam>(
|
|
14
|
+
350.0, 0.0f, context->getNyquistFrequency(), context);
|
|
15
15
|
detuneParam_ = std::make_shared<AudioParam>(
|
|
16
16
|
0.0,
|
|
17
17
|
-1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT,
|
|
18
|
-
1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT
|
|
18
|
+
1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT,
|
|
19
|
+
context);
|
|
19
20
|
QParam_ = std::make_shared<AudioParam>(
|
|
20
|
-
1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT);
|
|
21
|
+
1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
|
|
21
22
|
gainParam_ = std::make_shared<AudioParam>(
|
|
22
|
-
0.0,
|
|
23
|
+
0.0,
|
|
24
|
+
MOST_NEGATIVE_SINGLE_FLOAT,
|
|
25
|
+
40 * LOG10_MOST_POSITIVE_SINGLE_FLOAT,
|
|
26
|
+
context);
|
|
23
27
|
type_ = BiquadFilterType::LOWPASS;
|
|
24
28
|
isInitialized_ = true;
|
|
25
29
|
}
|
|
@@ -304,48 +308,46 @@ void BiquadFilterNode::setAllpassCoefficients(float frequency, float Q) {
|
|
|
304
308
|
void BiquadFilterNode::applyFilter() {
|
|
305
309
|
double currentTime = context_->getCurrentTime();
|
|
306
310
|
|
|
307
|
-
float
|
|
308
|
-
|
|
309
|
-
float
|
|
311
|
+
float frequencyParamValue =
|
|
312
|
+
frequencyParam_->processKRateParam(RENDER_QUANTUM_SIZE, currentTime);
|
|
313
|
+
float normalizedFrequency =
|
|
314
|
+
frequencyParamValue / context_->getNyquistFrequency();
|
|
315
|
+
|
|
316
|
+
float detuneValue =
|
|
317
|
+
detuneParam_->processKRateParam(RENDER_QUANTUM_SIZE, currentTime);
|
|
310
318
|
|
|
311
319
|
if (detuneValue != 0.0) {
|
|
312
320
|
normalizedFrequency *= std::pow(2.0f, detuneValue / 1200.0f);
|
|
313
321
|
}
|
|
314
322
|
|
|
323
|
+
auto qparamValue =
|
|
324
|
+
QParam_->processKRateParam(RENDER_QUANTUM_SIZE, currentTime);
|
|
325
|
+
auto gainParamValue =
|
|
326
|
+
gainParam_->processKRateParam(RENDER_QUANTUM_SIZE, currentTime);
|
|
315
327
|
switch (type_) {
|
|
316
328
|
case BiquadFilterType::LOWPASS:
|
|
317
|
-
setLowpassCoefficients(
|
|
318
|
-
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
329
|
+
setLowpassCoefficients(normalizedFrequency, qparamValue);
|
|
319
330
|
break;
|
|
320
331
|
case BiquadFilterType::HIGHPASS:
|
|
321
|
-
setHighpassCoefficients(
|
|
322
|
-
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
332
|
+
setHighpassCoefficients(normalizedFrequency, qparamValue);
|
|
323
333
|
break;
|
|
324
334
|
case BiquadFilterType::BANDPASS:
|
|
325
|
-
setBandpassCoefficients(
|
|
326
|
-
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
335
|
+
setBandpassCoefficients(normalizedFrequency, qparamValue);
|
|
327
336
|
break;
|
|
328
337
|
case BiquadFilterType::LOWSHELF:
|
|
329
|
-
setLowshelfCoefficients(
|
|
330
|
-
normalizedFrequency, gainParam_->getValueAtTime(currentTime));
|
|
338
|
+
setLowshelfCoefficients(normalizedFrequency, gainParamValue);
|
|
331
339
|
break;
|
|
332
340
|
case BiquadFilterType::HIGHSHELF:
|
|
333
|
-
setHighshelfCoefficients(
|
|
334
|
-
normalizedFrequency, gainParam_->getValueAtTime(currentTime));
|
|
341
|
+
setHighshelfCoefficients(normalizedFrequency, gainParamValue);
|
|
335
342
|
break;
|
|
336
343
|
case BiquadFilterType::PEAKING:
|
|
337
|
-
setPeakingCoefficients(
|
|
338
|
-
normalizedFrequency,
|
|
339
|
-
QParam_->getValueAtTime(currentTime),
|
|
340
|
-
gainParam_->getValueAtTime(currentTime));
|
|
344
|
+
setPeakingCoefficients(normalizedFrequency, qparamValue, gainParamValue);
|
|
341
345
|
break;
|
|
342
346
|
case BiquadFilterType::NOTCH:
|
|
343
|
-
setNotchCoefficients(
|
|
344
|
-
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
347
|
+
setNotchCoefficients(normalizedFrequency, qparamValue);
|
|
345
348
|
break;
|
|
346
349
|
case BiquadFilterType::ALLPASS:
|
|
347
|
-
setAllpassCoefficients(
|
|
348
|
-
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
350
|
+
setAllpassCoefficients(normalizedFrequency, qparamValue);
|
|
349
351
|
break;
|
|
350
352
|
default:
|
|
351
353
|
break;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include <audioapi/core/BaseAudioContext.h>
|
|
2
2
|
#include <audioapi/core/effects/GainNode.h>
|
|
3
|
+
#include <audioapi/dsp/VectorMath.h>
|
|
3
4
|
#include <audioapi/utils/AudioArray.h>
|
|
4
5
|
#include <audioapi/utils/AudioBus.h>
|
|
5
6
|
|
|
@@ -7,7 +8,7 @@ namespace audioapi {
|
|
|
7
8
|
|
|
8
9
|
GainNode::GainNode(BaseAudioContext *context) : AudioNode(context) {
|
|
9
10
|
gainParam_ = std::make_shared<AudioParam>(
|
|
10
|
-
1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT);
|
|
11
|
+
1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
|
|
11
12
|
isInitialized_ = true;
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -19,14 +20,13 @@ void GainNode::processNode(
|
|
|
19
20
|
const std::shared_ptr<AudioBus> &processingBus,
|
|
20
21
|
int framesToProcess) {
|
|
21
22
|
double time = context_->getCurrentTime();
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
time += deltaTime;
|
|
23
|
+
auto gainParamValues = gainParam_->processARateParam(framesToProcess, time);
|
|
24
|
+
for (int i = 0; i < processingBus->getNumberOfChannels(); i += 1) {
|
|
25
|
+
dsp::multiply(
|
|
26
|
+
processingBus->getChannel(i)->getData(),
|
|
27
|
+
gainParamValues->getChannel(0)->getData(),
|
|
28
|
+
processingBus->getChannel(i)->getData(),
|
|
29
|
+
framesToProcess);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -11,7 +11,7 @@ namespace audioapi {
|
|
|
11
11
|
StereoPannerNode::StereoPannerNode(BaseAudioContext *context)
|
|
12
12
|
: AudioNode(context) {
|
|
13
13
|
channelCountMode_ = ChannelCountMode::EXPLICIT;
|
|
14
|
-
panParam_ = std::make_shared<AudioParam>(0.0, -1.0f, 1.0f);
|
|
14
|
+
panParam_ = std::make_shared<AudioParam>(0.0, -1.0f, 1.0f, context);
|
|
15
15
|
isInitialized_ = true;
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -27,9 +27,12 @@ void StereoPannerNode::processNode(
|
|
|
27
27
|
|
|
28
28
|
AudioArray *left = processingBus->getChannelByType(AudioBus::ChannelLeft);
|
|
29
29
|
AudioArray *right = processingBus->getChannelByType(AudioBus::ChannelRight);
|
|
30
|
+
auto panParamValues = panParam_->processARateParam(framesToProcess, time)
|
|
31
|
+
->getChannel(0)
|
|
32
|
+
->getData();
|
|
30
33
|
|
|
31
34
|
for (int i = 0; i < framesToProcess; i += 1) {
|
|
32
|
-
auto pan =
|
|
35
|
+
auto pan = panParamValues[i];
|
|
33
36
|
|
|
34
37
|
auto x = (pan <= 0 ? pan + 1 : pan);
|
|
35
38
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#include <audioapi/HostObjects/AudioBufferHostObject.h>
|
|
2
|
+
#include <audioapi/core/inputs/AudioRecorder.h>
|
|
3
|
+
#include <audioapi/core/sources/AudioBuffer.h>
|
|
4
|
+
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
5
|
+
#include <audioapi/utils/AudioBus.h>
|
|
6
|
+
#include <audioapi/utils/CircularAudioArray.h>
|
|
7
|
+
|
|
8
|
+
namespace audioapi {
|
|
9
|
+
|
|
10
|
+
AudioRecorder::AudioRecorder(
|
|
11
|
+
float sampleRate,
|
|
12
|
+
int bufferLength,
|
|
13
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
|
|
14
|
+
: sampleRate_(sampleRate),
|
|
15
|
+
bufferLength_(bufferLength),
|
|
16
|
+
audioEventHandlerRegistry_(audioEventHandlerRegistry) {
|
|
17
|
+
circularBuffer_ =
|
|
18
|
+
std::make_shared<CircularAudioArray>(std::max(2 * bufferLength, 2048));
|
|
19
|
+
isRunning_.store(false);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void AudioRecorder::setOnAudioReadyCallbackId(uint64_t callbackId) {
|
|
23
|
+
onAudioReadyCallbackId_ = callbackId;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void AudioRecorder::invokeOnAudioReadyCallback(
|
|
27
|
+
const std::shared_ptr<AudioBus> &bus,
|
|
28
|
+
int numFrames,
|
|
29
|
+
double when) {
|
|
30
|
+
auto audioBuffer = std::make_shared<AudioBuffer>(bus);
|
|
31
|
+
auto audioBufferHostObject =
|
|
32
|
+
std::make_shared<AudioBufferHostObject>(audioBuffer);
|
|
33
|
+
|
|
34
|
+
std::unordered_map<std::string, EventValue> body = {};
|
|
35
|
+
body.insert({"buffer", audioBufferHostObject});
|
|
36
|
+
body.insert({"numFrames", numFrames});
|
|
37
|
+
body.insert({"when", when});
|
|
38
|
+
|
|
39
|
+
audioEventHandlerRegistry_->invokeHandlerWithEventBody(
|
|
40
|
+
"audioReady", onAudioReadyCallbackId_, body);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void AudioRecorder::sendRemainingData() {
|
|
44
|
+
auto bus = std::make_shared<AudioBus>(
|
|
45
|
+
circularBuffer_->getNumberOfAvailableFrames(), 1, sampleRate_);
|
|
46
|
+
auto *outputChannel = bus->getChannel(0)->getData();
|
|
47
|
+
auto availableFrames =
|
|
48
|
+
static_cast<int>(circularBuffer_->getNumberOfAvailableFrames());
|
|
49
|
+
|
|
50
|
+
circularBuffer_->pop_front(
|
|
51
|
+
outputChannel, circularBuffer_->getNumberOfAvailableFrames());
|
|
52
|
+
|
|
53
|
+
invokeOnAudioReadyCallback(bus, availableFrames, 0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
} // namespace audioapi
|
|
@@ -1,28 +1,26 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include <memory>
|
|
4
|
-
#include <functional>
|
|
5
4
|
|
|
6
5
|
namespace audioapi {
|
|
7
6
|
class AudioBus;
|
|
7
|
+
class CircularAudioArray;
|
|
8
|
+
class AudioEventHandlerRegistry;
|
|
8
9
|
|
|
9
10
|
class AudioRecorder {
|
|
10
11
|
public:
|
|
11
12
|
explicit AudioRecorder(
|
|
12
13
|
float sampleRate,
|
|
13
14
|
int bufferLength,
|
|
14
|
-
const std::
|
|
15
|
-
|
|
16
|
-
const std::function<void(std::shared_ptr<AudioBus>, int, double)> &onAudioReady
|
|
17
|
-
)
|
|
18
|
-
: sampleRate_(sampleRate),
|
|
19
|
-
bufferLength_(bufferLength),
|
|
20
|
-
onError_(onError),
|
|
21
|
-
onStatusChange_(onStatusChange),
|
|
22
|
-
onAudioReady_(onAudioReady) {}
|
|
15
|
+
const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry
|
|
16
|
+
);
|
|
23
17
|
|
|
24
18
|
virtual ~AudioRecorder() = default;
|
|
25
19
|
|
|
20
|
+
void setOnAudioReadyCallbackId(uint64_t callbackId);
|
|
21
|
+
void invokeOnAudioReadyCallback(const std::shared_ptr<AudioBus> &bus, int numFrames, double when);
|
|
22
|
+
void sendRemainingData();
|
|
23
|
+
|
|
26
24
|
virtual void start() = 0;
|
|
27
25
|
virtual void stop() = 0;
|
|
28
26
|
|
|
@@ -30,9 +28,11 @@ class AudioRecorder {
|
|
|
30
28
|
float sampleRate_;
|
|
31
29
|
int bufferLength_;
|
|
32
30
|
|
|
33
|
-
std::
|
|
34
|
-
std::
|
|
35
|
-
|
|
31
|
+
std::atomic<bool> isRunning_;
|
|
32
|
+
std::shared_ptr<CircularAudioArray> circularBuffer_;
|
|
33
|
+
|
|
34
|
+
std::shared_ptr<AudioEventHandlerRegistry> audioEventHandlerRegistry_;
|
|
35
|
+
uint64_t onAudioReadyCallbackId_ = 0;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
} // namespace audioapi
|
|
@@ -22,9 +22,9 @@ AudioBufferSourceNode::AudioBufferSourceNode(
|
|
|
22
22
|
alignedBus_ = std::shared_ptr<AudioBus>(nullptr);
|
|
23
23
|
|
|
24
24
|
detuneParam_ = std::make_shared<AudioParam>(
|
|
25
|
-
0.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT);
|
|
25
|
+
0.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
|
|
26
26
|
playbackRateParam_ = std::make_shared<AudioParam>(
|
|
27
|
-
1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT);
|
|
27
|
+
1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT, context);
|
|
28
28
|
|
|
29
29
|
playbackRateBus_ = std::make_shared<AudioBus>(
|
|
30
30
|
RENDER_QUANTUM_SIZE * 3, channelCount_, context_->getSampleRate());
|
|
@@ -173,7 +173,7 @@ void AudioBufferSourceNode::processWithoutPitchCorrection(
|
|
|
173
173
|
size_t startOffset = 0;
|
|
174
174
|
size_t offsetLength = 0;
|
|
175
175
|
|
|
176
|
-
auto computedPlaybackRate = getComputedPlaybackRateValue();
|
|
176
|
+
auto computedPlaybackRate = getComputedPlaybackRateValue(framesToProcess);
|
|
177
177
|
updatePlaybackInfo(processingBus, framesToProcess, startOffset, offsetLength);
|
|
178
178
|
|
|
179
179
|
if (computedPlaybackRate == 0.0f || (!isPlaying() && !isStopScheduled())) {
|
|
@@ -197,10 +197,12 @@ void AudioBufferSourceNode::processWithPitchCorrection(
|
|
|
197
197
|
size_t offsetLength = 0;
|
|
198
198
|
|
|
199
199
|
auto time = context_->getCurrentTime();
|
|
200
|
-
auto playbackRate =
|
|
201
|
-
|
|
202
|
-
auto detune =
|
|
203
|
-
|
|
200
|
+
auto playbackRate = std::clamp(
|
|
201
|
+
playbackRateParam_->processKRateParam(framesToProcess, time), 0.0f, 3.0f);
|
|
202
|
+
auto detune = std::clamp(
|
|
203
|
+
detuneParam_->processKRateParam(framesToProcess, time) / 100.0f,
|
|
204
|
+
-12.0f,
|
|
205
|
+
12.0f);
|
|
204
206
|
|
|
205
207
|
playbackRateBus_->zero();
|
|
206
208
|
|
|
@@ -349,13 +351,15 @@ void AudioBufferSourceNode::processWithInterpolation(
|
|
|
349
351
|
}
|
|
350
352
|
}
|
|
351
353
|
|
|
352
|
-
float AudioBufferSourceNode::getComputedPlaybackRateValue() {
|
|
354
|
+
float AudioBufferSourceNode::getComputedPlaybackRateValue(int framesToProcess) {
|
|
353
355
|
auto time = context_->getCurrentTime();
|
|
354
356
|
|
|
355
357
|
auto sampleRateFactor =
|
|
356
358
|
alignedBus_->getSampleRate() / context_->getSampleRate();
|
|
357
|
-
auto playbackRate =
|
|
358
|
-
|
|
359
|
+
auto playbackRate =
|
|
360
|
+
playbackRateParam_->processKRateParam(framesToProcess, time);
|
|
361
|
+
auto detune = std::pow(
|
|
362
|
+
2.0f, detuneParam_->processKRateParam(framesToProcess, time) / 1200.0f);
|
|
359
363
|
|
|
360
364
|
return playbackRate * sampleRateFactor * detune;
|
|
361
365
|
}
|
|
@@ -81,7 +81,7 @@ class AudioBufferSourceNode : public AudioScheduledSourceNode {
|
|
|
81
81
|
size_t offsetLength,
|
|
82
82
|
float playbackRate);
|
|
83
83
|
|
|
84
|
-
float getComputedPlaybackRateValue();
|
|
84
|
+
float getComputedPlaybackRateValue(int framesToProcess);
|
|
85
85
|
|
|
86
86
|
double getVirtualStartFrame();
|
|
87
87
|
double getVirtualEndFrame();
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#include <audioapi/core/sources/AudioScheduledSourceNode.h>
|
|
3
3
|
#include <audioapi/core/utils/AudioNodeManager.h>
|
|
4
4
|
#include <audioapi/dsp/AudioUtils.h>
|
|
5
|
+
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
5
6
|
#include <audioapi/utils/AudioArray.h>
|
|
6
7
|
#include <audioapi/utils/AudioBus.h>
|
|
7
8
|
|
|
@@ -44,9 +45,8 @@ bool AudioScheduledSourceNode::isStopScheduled() {
|
|
|
44
45
|
return playbackState_ == PlaybackState::STOP_SCHEDULED;
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
void AudioScheduledSourceNode::
|
|
48
|
-
|
|
49
|
-
onendedCallback_ = onendedCallback;
|
|
48
|
+
void AudioScheduledSourceNode::setOnEndedCallbackId(const uint64_t callbackId) {
|
|
49
|
+
onEndedCallbackId_ = callbackId;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
void AudioScheduledSourceNode::updatePlaybackInfo(
|
|
@@ -144,9 +144,10 @@ void AudioScheduledSourceNode::updatePlaybackInfo(
|
|
|
144
144
|
void AudioScheduledSourceNode::disable() {
|
|
145
145
|
AudioNode::disable();
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
std::unordered_map<std::string, EventValue> body = {{"value", getStopTime()}};
|
|
148
|
+
|
|
149
|
+
context_->audioEventHandlerRegistry_->invokeHandlerWithEventBody(
|
|
150
|
+
"ended", onEndedCallbackId_, body);
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
void AudioScheduledSourceNode::handleStopScheduled() {
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
namespace audioapi {
|
|
18
18
|
|
|
19
|
+
class AudioEventHandlerRegistry;
|
|
20
|
+
|
|
19
21
|
class AudioScheduledSourceNode : public AudioNode {
|
|
20
22
|
public:
|
|
21
23
|
// UNSCHEDULED: The node is not scheduled to play.
|
|
@@ -35,7 +37,7 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
35
37
|
bool isFinished();
|
|
36
38
|
bool isStopScheduled();
|
|
37
39
|
|
|
38
|
-
void
|
|
40
|
+
void setOnEndedCallbackId(uint64_t callbackId);
|
|
39
41
|
|
|
40
42
|
virtual double getStopTime() const = 0;
|
|
41
43
|
void disable() override;
|
|
@@ -43,8 +45,6 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
43
45
|
protected:
|
|
44
46
|
PlaybackState playbackState_;
|
|
45
47
|
|
|
46
|
-
std::function<void(double)> onendedCallback_;
|
|
47
|
-
|
|
48
48
|
void updatePlaybackInfo(
|
|
49
49
|
const std::shared_ptr<AudioBus>& processingBus,
|
|
50
50
|
int framesToProcess,
|
|
@@ -56,6 +56,8 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
56
56
|
private:
|
|
57
57
|
double startTime_;
|
|
58
58
|
double stopTime_;
|
|
59
|
+
|
|
60
|
+
uint64_t onEndedCallbackId_ = 0;
|
|
59
61
|
};
|
|
60
62
|
|
|
61
63
|
} // namespace audioapi
|
|
@@ -9,11 +9,15 @@ namespace audioapi {
|
|
|
9
9
|
OscillatorNode::OscillatorNode(BaseAudioContext *context)
|
|
10
10
|
: AudioScheduledSourceNode(context) {
|
|
11
11
|
frequencyParam_ = std::make_shared<AudioParam>(
|
|
12
|
-
444.0,
|
|
12
|
+
444.0,
|
|
13
|
+
-context_->getNyquistFrequency(),
|
|
14
|
+
context_->getNyquistFrequency(),
|
|
15
|
+
context);
|
|
13
16
|
detuneParam_ = std::make_shared<AudioParam>(
|
|
14
17
|
0.0,
|
|
15
18
|
-1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT,
|
|
16
|
-
1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT
|
|
19
|
+
1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT,
|
|
20
|
+
context);
|
|
17
21
|
type_ = OscillatorType::SINE;
|
|
18
22
|
periodicWave_ = context_->getBasicWaveForm(type_);
|
|
19
23
|
|
|
@@ -56,15 +60,18 @@ void OscillatorNode::processNode(
|
|
|
56
60
|
return;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
auto
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
auto time = context_->getCurrentTime() +
|
|
64
|
+
static_cast<double>(startOffset) * 1.0 / context_->getSampleRate();
|
|
65
|
+
auto detuneParamValues =
|
|
66
|
+
detuneParam_->processARateParam(framesToProcess, time);
|
|
67
|
+
auto frequencyParamValues =
|
|
68
|
+
frequencyParam_->processARateParam(framesToProcess, time);
|
|
62
69
|
|
|
63
70
|
for (size_t i = startOffset; i < offsetLength; i += 1) {
|
|
64
|
-
auto detuneRatio =
|
|
65
|
-
|
|
71
|
+
auto detuneRatio = std::pow(
|
|
72
|
+
2.0f, detuneParamValues->getChannel(0)->getData()[i] / 1200.0f);
|
|
66
73
|
auto detunedFrequency =
|
|
67
|
-
|
|
74
|
+
frequencyParamValues->getChannel(0)->getData()[i] * detuneRatio;
|
|
68
75
|
auto phaseIncrement = detunedFrequency * periodicWave_->getScale();
|
|
69
76
|
|
|
70
77
|
float sample =
|
|
@@ -79,8 +86,6 @@ void OscillatorNode::processNode(
|
|
|
79
86
|
floor(
|
|
80
87
|
phase_ / static_cast<float>(periodicWave_->getPeriodicWaveSize())) *
|
|
81
88
|
static_cast<float>(periodicWave_->getPeriodicWaveSize());
|
|
82
|
-
|
|
83
|
-
time += deltaTime;
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
handleStopScheduled();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include <audioapi/core/AudioNode.h>
|
|
2
|
+
#include <audioapi/core/AudioParam.h>
|
|
2
3
|
#include <audioapi/core/sources/AudioScheduledSourceNode.h>
|
|
3
4
|
#include <audioapi/core/utils/AudioNodeManager.h>
|
|
4
5
|
#include <audioapi/core/utils/Locker.h>
|
|
@@ -9,7 +10,7 @@ AudioNodeManager::~AudioNodeManager() {
|
|
|
9
10
|
cleanup();
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
void AudioNodeManager::
|
|
13
|
+
void AudioNodeManager::addPendingNodeConnection(
|
|
13
14
|
const std::shared_ptr<AudioNode> &from,
|
|
14
15
|
const std::shared_ptr<AudioNode> &to,
|
|
15
16
|
ConnectionType type) {
|
|
@@ -18,6 +19,15 @@ void AudioNodeManager::addPendingConnection(
|
|
|
18
19
|
audioNodesToConnect_.emplace_back(from, to, type);
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
void AudioNodeManager::addPendingParamConnection(
|
|
23
|
+
const std::shared_ptr<AudioNode> &from,
|
|
24
|
+
const std::shared_ptr<AudioParam> &to,
|
|
25
|
+
ConnectionType type) {
|
|
26
|
+
Locker lock(getGraphLock());
|
|
27
|
+
|
|
28
|
+
audioParamToConnect_.emplace_back(from, to, type);
|
|
29
|
+
}
|
|
30
|
+
|
|
21
31
|
void AudioNodeManager::preProcessGraph() {
|
|
22
32
|
if (auto locker = Locker::tryLock(getGraphLock())) {
|
|
23
33
|
settlePendingConnections();
|
|
@@ -41,6 +51,11 @@ void AudioNodeManager::addSourceNode(
|
|
|
41
51
|
sourceNodes_.insert(node);
|
|
42
52
|
}
|
|
43
53
|
|
|
54
|
+
void AudioNodeManager::addAudioParam(const std::shared_ptr<AudioParam> ¶m) {
|
|
55
|
+
Locker lock(getGraphLock());
|
|
56
|
+
audioParams_.insert(param);
|
|
57
|
+
}
|
|
58
|
+
|
|
44
59
|
void AudioNodeManager::settlePendingConnections() {
|
|
45
60
|
for (auto it = audioNodesToConnect_.begin(), end = audioNodesToConnect_.end();
|
|
46
61
|
it != end;
|
|
@@ -60,6 +75,25 @@ void AudioNodeManager::settlePendingConnections() {
|
|
|
60
75
|
}
|
|
61
76
|
|
|
62
77
|
audioNodesToConnect_.clear();
|
|
78
|
+
|
|
79
|
+
for (auto it = audioParamToConnect_.begin(), end = audioParamToConnect_.end();
|
|
80
|
+
it != end;
|
|
81
|
+
++it) {
|
|
82
|
+
std::shared_ptr<AudioNode> from = std::get<0>(*it);
|
|
83
|
+
std::shared_ptr<AudioParam> to = std::get<1>(*it);
|
|
84
|
+
ConnectionType type = std::get<2>(*it);
|
|
85
|
+
|
|
86
|
+
assert(from != nullptr);
|
|
87
|
+
assert(to != nullptr);
|
|
88
|
+
|
|
89
|
+
if (type == ConnectionType::CONNECT) {
|
|
90
|
+
from->connectParam(to);
|
|
91
|
+
} else {
|
|
92
|
+
from->disconnectParam(to);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
audioParamToConnect_.clear();
|
|
63
97
|
}
|
|
64
98
|
|
|
65
99
|
void AudioNodeManager::cleanupNode(const std::shared_ptr<AudioNode> &node) {
|