react-native-audio-api 0.4.13 → 0.4.15
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/CMakeLists.txt +3 -2
- package/android/src/main/cpp/audioapi/android/core/AudioDecoder.cpp +3 -3
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +13 -12
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +0 -1
- package/{common/cpp/audioapi/libs/pffft → android/src/main/cpp/audioapi/android/libs}/pffft.c +1 -1
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +1 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +3 -1
- package/common/cpp/audioapi/HostObjects/AnalyserNodeHostObject.h +16 -24
- package/common/cpp/audioapi/HostObjects/AudioBufferHostObject.h +0 -4
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +4 -20
- package/common/cpp/audioapi/HostObjects/AudioContextHostObject.h +2 -3
- package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +2 -32
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +21 -14
- package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +2 -4
- package/common/cpp/audioapi/HostObjects/StretcherNodeHostObject.h +35 -0
- package/common/cpp/audioapi/core/AudioNode.cpp +2 -2
- package/common/cpp/audioapi/core/AudioParam.cpp +1 -1
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +12 -4
- package/common/cpp/audioapi/core/BaseAudioContext.h +4 -2
- package/common/cpp/audioapi/core/Constants.h +33 -8
- package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +45 -42
- package/common/cpp/audioapi/core/analysis/AnalyserNode.h +6 -8
- package/common/cpp/audioapi/core/destinations/AudioDestinationNode.cpp +1 -1
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +8 -12
- package/common/cpp/audioapi/core/effects/GainNode.cpp +3 -4
- package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +49 -32
- package/common/cpp/audioapi/core/effects/PeriodicWave.h +3 -8
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +3 -3
- package/common/cpp/audioapi/core/effects/StretcherNode.cpp +94 -0
- package/common/cpp/audioapi/core/effects/StretcherNode.h +35 -0
- package/common/cpp/audioapi/core/sources/AudioBuffer.cpp +2 -9
- package/common/cpp/audioapi/core/sources/AudioBuffer.h +2 -5
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +35 -72
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +8 -41
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +6 -18
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +0 -7
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +3 -12
- package/common/cpp/audioapi/core/sources/OscillatorNode.h +0 -1
- package/common/cpp/audioapi/{utils → core/utils}/AudioArray.cpp +5 -5
- package/common/cpp/audioapi/{utils → core/utils}/AudioBus.cpp +29 -29
- package/common/cpp/audioapi/dsp/AudioUtils.cpp +2 -2
- package/common/cpp/audioapi/dsp/AudioUtils.h +2 -2
- package/common/cpp/audioapi/dsp/FFTFrame.cpp +100 -0
- package/common/cpp/audioapi/dsp/FFTFrame.h +74 -0
- package/common/cpp/audioapi/dsp/VectorMath.cpp +3 -3
- package/common/cpp/audioapi/dsp/VectorMath.h +2 -2
- package/common/cpp/audioapi/libs/dsp/common.h +47 -0
- package/common/cpp/audioapi/libs/{signalsmith-stretch → dsp}/delay.h +11 -9
- package/common/cpp/audioapi/libs/{signalsmith-stretch → dsp}/fft.h +7 -6
- package/common/cpp/audioapi/libs/{signalsmith-stretch → dsp}/perf.h +2 -0
- package/common/cpp/audioapi/libs/{signalsmith-stretch → dsp}/spectral.h +13 -10
- package/common/cpp/audioapi/libs/dsp/windows.h +219 -0
- package/common/cpp/audioapi/libs/{signalsmith-stretch/signalsmith-stretch.h → signalsmith-stretch.h} +4 -3
- package/ios/audioapi/ios/core/AudioDecoder.mm +3 -3
- package/ios/audioapi/ios/core/AudioPlayer.h +2 -5
- package/ios/audioapi/ios/core/AudioPlayer.m +5 -9
- package/ios/audioapi/ios/core/IOSAudioPlayer.h +0 -1
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +10 -12
- package/lib/module/api.js +2 -1
- package/lib/module/api.js.map +1 -1
- package/lib/module/api.web.js +1 -1
- package/lib/module/api.web.js.map +1 -1
- package/lib/module/core/AudioBufferSourceNode.js +0 -6
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +0 -5
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +4 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/core/StretcherNode.js +12 -0
- package/lib/module/core/StretcherNode.js.map +1 -0
- package/lib/module/web-core/AudioBufferSourceNode.js +0 -6
- package/lib/module/web-core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/web-core/AudioScheduledSourceNode.js +0 -8
- package/lib/module/web-core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/web-core/StretcherNode.js +7 -24
- package/lib/module/web-core/StretcherNode.js.map +1 -1
- package/lib/module/web-core/custom/signalsmithStretch/README.md +1 -1
- package/lib/module/web-core/custom/signalsmithStretch/SignalsmithStretch.js +0 -1
- package/lib/module/web-core/custom/signalsmithStretch/SignalsmithStretch.js.map +1 -1
- package/lib/typescript/api.d.ts +2 -1
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/api.web.d.ts +1 -1
- package/lib/typescript/api.web.d.ts.map +1 -1
- package/lib/typescript/core/AudioBufferSourceNode.d.ts +0 -3
- package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +0 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/core/StretcherNode.d.ts +10 -0
- package/lib/typescript/core/StretcherNode.d.ts.map +1 -0
- package/lib/typescript/interfaces.d.ts +6 -3
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +0 -1
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioBufferSourceNode.d.ts +0 -3
- package/lib/typescript/web-core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts +0 -1
- package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/web-core/StretcherNode.d.ts +0 -3
- package/lib/typescript/web-core/StretcherNode.d.ts.map +1 -1
- package/package.json +4 -3
- package/scripts/setup-custom-wasm.js +104 -0
- package/src/api.ts +1 -1
- package/src/api.web.ts +0 -1
- package/src/core/AudioBufferSourceNode.ts +0 -9
- package/src/core/AudioScheduledSourceNode.ts +0 -5
- package/src/core/BaseAudioContext.ts +5 -0
- package/src/core/StretcherNode.ts +15 -0
- package/src/interfaces.ts +6 -3
- package/src/types.ts +0 -2
- package/src/web-core/AudioBufferSourceNode.tsx +0 -11
- package/src/web-core/AudioScheduledSourceNode.tsx +0 -9
- package/src/web-core/StretcherNode.tsx +8 -28
- package/src/web-core/custom/signalsmithStretch/README.md +1 -1
- package/src/web-core/custom/signalsmithStretch/SignalsmithStretch.js +0 -1
- package/common/cpp/audioapi/core/types/TimeStretchType.h +0 -7
- package/common/cpp/audioapi/dsp/FFT.cpp +0 -41
- package/common/cpp/audioapi/dsp/FFT.h +0 -29
- package/common/cpp/audioapi/dsp/Windows.cpp +0 -80
- package/common/cpp/audioapi/dsp/Windows.h +0 -95
- package/scripts/setup-rn-audio-api-web.js +0 -58
- /package/{common/cpp/audioapi/libs/pffft → android/src/main/cpp/audioapi/android/libs}/pffft.h +0 -0
- /package/common/cpp/audioapi/{utils → core/utils}/AudioArray.h +0 -0
- /package/common/cpp/audioapi/{utils → core/utils}/AudioBus.h +0 -0
- /package/common/cpp/audioapi/libs/{miniaudio/miniaudio.h → miniaudio.h} +0 -0
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
#include <audioapi/core/BaseAudioContext.h>
|
|
3
3
|
#include <audioapi/core/Constants.h>
|
|
4
4
|
#include <audioapi/core/sources/AudioBufferSourceNode.h>
|
|
5
|
+
#include <audioapi/core/utils/AudioArray.h>
|
|
6
|
+
#include <audioapi/core/utils/AudioBus.h>
|
|
5
7
|
#include <audioapi/core/utils/Locker.h>
|
|
6
8
|
#include <audioapi/dsp/AudioUtils.h>
|
|
7
|
-
#include <audioapi/utils/AudioArray.h>
|
|
8
|
-
#include <audioapi/utils/AudioBus.h>
|
|
9
9
|
|
|
10
10
|
namespace audioapi {
|
|
11
11
|
|
|
@@ -14,18 +14,15 @@ AudioBufferSourceNode::AudioBufferSourceNode(BaseAudioContext *context)
|
|
|
14
14
|
loop_(false),
|
|
15
15
|
loopStart_(0),
|
|
16
16
|
loopEnd_(0),
|
|
17
|
-
timeStretchType_(TimeStretchType::LINEAR),
|
|
18
17
|
vReadIndex_(0.0) {
|
|
19
18
|
buffer_ = std::shared_ptr<AudioBuffer>(nullptr);
|
|
19
|
+
alignedBus_ = std::make_shared<AudioBus>(
|
|
20
|
+
RENDER_QUANTUM_SIZE, 1, context_->getSampleRate());
|
|
20
21
|
|
|
21
|
-
detuneParam_ = std::make_shared<AudioParam>(
|
|
22
|
-
0.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT);
|
|
22
|
+
detuneParam_ = std::make_shared<AudioParam>(0.0, MIN_DETUNE, MAX_DETUNE);
|
|
23
23
|
playbackRateParam_ = std::make_shared<AudioParam>(
|
|
24
24
|
1.0, MOST_NEGATIVE_SINGLE_FLOAT, MOST_POSITIVE_SINGLE_FLOAT);
|
|
25
25
|
|
|
26
|
-
playbackRateBus_ = std::make_shared<AudioBus>(
|
|
27
|
-
RENDER_QUANTUM_SIZE * 3, channelCount_, context_->getSampleRate());
|
|
28
|
-
|
|
29
26
|
isInitialized_ = true;
|
|
30
27
|
}
|
|
31
28
|
|
|
@@ -54,10 +51,6 @@ std::shared_ptr<AudioBuffer> AudioBufferSourceNode::getBuffer() const {
|
|
|
54
51
|
return buffer_;
|
|
55
52
|
}
|
|
56
53
|
|
|
57
|
-
std::string AudioBufferSourceNode::getTimeStretchType() const {
|
|
58
|
-
return toString(timeStretchType_);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
54
|
void AudioBufferSourceNode::setLoop(bool loop) {
|
|
62
55
|
loop_ = loop;
|
|
63
56
|
}
|
|
@@ -76,6 +69,8 @@ void AudioBufferSourceNode::setBuffer(
|
|
|
76
69
|
|
|
77
70
|
if (!buffer) {
|
|
78
71
|
buffer_ = std::shared_ptr<AudioBuffer>(nullptr);
|
|
72
|
+
alignedBus_ = std::make_shared<AudioBus>(
|
|
73
|
+
RENDER_QUANTUM_SIZE, 1, context_->getSampleRate());
|
|
79
74
|
loopEnd_ = 0;
|
|
80
75
|
return;
|
|
81
76
|
}
|
|
@@ -83,18 +78,17 @@ void AudioBufferSourceNode::setBuffer(
|
|
|
83
78
|
buffer_ = buffer;
|
|
84
79
|
channelCount_ = buffer_->getNumberOfChannels();
|
|
85
80
|
|
|
81
|
+
alignedBus_ = std::make_shared<AudioBus>(
|
|
82
|
+
buffer_->getLength(), channelCount_, context_->getSampleRate());
|
|
83
|
+
alignedBus_->zero();
|
|
84
|
+
alignedBus_->sum(buffer_->bus_.get());
|
|
85
|
+
|
|
86
86
|
audioBus_ = std::make_shared<AudioBus>(
|
|
87
87
|
RENDER_QUANTUM_SIZE, channelCount_, context_->getSampleRate());
|
|
88
|
-
playbackRateBus_ = std::make_shared<AudioBus>(
|
|
89
|
-
RENDER_QUANTUM_SIZE * 3, channelCount_, context_->getSampleRate());
|
|
90
88
|
|
|
91
89
|
loopEnd_ = buffer_->getDuration();
|
|
92
90
|
}
|
|
93
91
|
|
|
94
|
-
void AudioBufferSourceNode::setTimeStretchType(const std::string &type) {
|
|
95
|
-
timeStretchType_ = fromString(type);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
92
|
void AudioBufferSourceNode::start(double when, double offset, double duration) {
|
|
99
93
|
AudioScheduledSourceNode::start(when);
|
|
100
94
|
|
|
@@ -123,7 +117,7 @@ void AudioBufferSourceNode::processNode(
|
|
|
123
117
|
const std::shared_ptr<AudioBus> &processingBus,
|
|
124
118
|
int framesToProcess) {
|
|
125
119
|
// No audio data to fill, zero the output and return.
|
|
126
|
-
if (!buffer_
|
|
120
|
+
if (!buffer_) {
|
|
127
121
|
processingBus->zero();
|
|
128
122
|
return;
|
|
129
123
|
}
|
|
@@ -136,58 +130,26 @@ void AudioBufferSourceNode::processNode(
|
|
|
136
130
|
size_t startOffset = 0;
|
|
137
131
|
size_t offsetLength = 0;
|
|
138
132
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
updatePlaybackInfo(
|
|
142
|
-
processingBus, framesToProcess, startOffset, offsetLength);
|
|
143
|
-
|
|
144
|
-
if (computedPlaybackRate == 0.0f || !isPlaying()) {
|
|
145
|
-
processingBus->zero();
|
|
146
|
-
return;
|
|
147
|
-
} else if (std::fabs(computedPlaybackRate) == 1.0) {
|
|
148
|
-
processWithoutInterpolation(
|
|
149
|
-
processingBus, startOffset, offsetLength, computedPlaybackRate);
|
|
150
|
-
} else {
|
|
151
|
-
processWithInterpolation(
|
|
152
|
-
processingBus, startOffset, offsetLength, computedPlaybackRate);
|
|
153
|
-
}
|
|
154
|
-
} else {
|
|
155
|
-
auto time = context_->getCurrentTime();
|
|
156
|
-
auto playbackRate =
|
|
157
|
-
std::clamp(playbackRateParam_->getValueAtTime(time), 0.0f, 3.0f);
|
|
158
|
-
auto detune =
|
|
159
|
-
std::clamp(detuneParam_->getValueAtTime(time) / 100.0f, -12.0f, 12.0f);
|
|
160
|
-
|
|
161
|
-
playbackRateBus_->zero();
|
|
133
|
+
updatePlaybackInfo(processingBus, framesToProcess, startOffset, offsetLength);
|
|
134
|
+
float playbackRate = getPlaybackRateValue(startOffset);
|
|
162
135
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
updatePlaybackInfo(
|
|
167
|
-
playbackRateBus_, framesNeededToStretch, startOffset, offsetLength);
|
|
136
|
+
assert(alignedBus_ != nullptr);
|
|
137
|
+
assert(alignedBus_->getSize() > 0);
|
|
168
138
|
|
|
139
|
+
if (playbackRate == 0.0f || !isPlaying()) {
|
|
140
|
+
processingBus->zero();
|
|
141
|
+
return;
|
|
142
|
+
} else if (std::fabs(playbackRate) == 1.0) {
|
|
169
143
|
processWithoutInterpolation(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
stretch->process(
|
|
175
|
-
playbackRateBus_.get()[0],
|
|
176
|
-
framesNeededToStretch,
|
|
177
|
-
processingBus.get()[0],
|
|
178
|
-
framesToProcess);
|
|
179
|
-
|
|
180
|
-
stretch->setTransposeSemitones(detune);
|
|
144
|
+
processingBus, startOffset, offsetLength, playbackRate);
|
|
145
|
+
} else {
|
|
146
|
+
processWithInterpolation(
|
|
147
|
+
processingBus, startOffset, offsetLength, playbackRate);
|
|
181
148
|
}
|
|
182
149
|
|
|
183
150
|
handleStopScheduled();
|
|
184
151
|
}
|
|
185
152
|
|
|
186
|
-
double AudioBufferSourceNode::getStopTime() const {
|
|
187
|
-
return dsp::sampleFrameToTime(
|
|
188
|
-
static_cast<int>(vReadIndex_), buffer_->getSampleRate());
|
|
189
|
-
}
|
|
190
|
-
|
|
191
153
|
/**
|
|
192
154
|
* Helper functions
|
|
193
155
|
*/
|
|
@@ -220,12 +182,12 @@ void AudioBufferSourceNode::processWithoutInterpolation(
|
|
|
220
182
|
// Direction is forward, we can normally copy the data
|
|
221
183
|
if (direction == 1) {
|
|
222
184
|
processingBus->copy(
|
|
223
|
-
|
|
185
|
+
alignedBus_.get(), readIndex, writeIndex, framesToCopy);
|
|
224
186
|
} else {
|
|
225
187
|
for (int i = 0; i < framesToCopy; i += 1) {
|
|
226
188
|
for (int j = 0; j < processingBus->getNumberOfChannels(); j += 1) {
|
|
227
189
|
(*processingBus->getChannel(j))[writeIndex + i] =
|
|
228
|
-
(*
|
|
190
|
+
(*alignedBus_->getChannel(j))[readIndex - i];
|
|
229
191
|
}
|
|
230
192
|
}
|
|
231
193
|
}
|
|
@@ -286,10 +248,10 @@ void AudioBufferSourceNode::processWithInterpolation(
|
|
|
286
248
|
|
|
287
249
|
for (int i = 0; i < processingBus->getNumberOfChannels(); i += 1) {
|
|
288
250
|
float *destination = processingBus->getChannel(i)->getData();
|
|
289
|
-
const float *source =
|
|
251
|
+
const float *source = alignedBus_->getChannel(i)->getData();
|
|
290
252
|
|
|
291
|
-
destination[writeIndex] =
|
|
292
|
-
|
|
253
|
+
destination[writeIndex] = AudioUtils::linearInterpolate(
|
|
254
|
+
source, readIndex, nextReadIndex, factor);
|
|
293
255
|
}
|
|
294
256
|
|
|
295
257
|
writeIndex += 1;
|
|
@@ -309,12 +271,13 @@ void AudioBufferSourceNode::processWithInterpolation(
|
|
|
309
271
|
}
|
|
310
272
|
}
|
|
311
273
|
|
|
312
|
-
float AudioBufferSourceNode::
|
|
313
|
-
auto time = context_->getCurrentTime()
|
|
274
|
+
float AudioBufferSourceNode::getPlaybackRateValue(size_t &startOffset) {
|
|
275
|
+
auto time = context_->getCurrentTime() +
|
|
276
|
+
static_cast<double>(startOffset) / context_->getSampleRate();
|
|
314
277
|
|
|
315
278
|
auto sampleRateFactor = buffer_->getSampleRate() / context_->getSampleRate();
|
|
316
|
-
auto playbackRate = playbackRateParam_->getValueAtTime(time);
|
|
317
279
|
auto detune = std::pow(2.0f, detuneParam_->getValueAtTime(time) / 1200.0f);
|
|
280
|
+
auto playbackRate = playbackRateParam_->getValueAtTime(time);
|
|
318
281
|
|
|
319
282
|
return playbackRate * sampleRateFactor * detune;
|
|
320
283
|
}
|
|
@@ -327,7 +290,7 @@ double AudioBufferSourceNode::getVirtualStartFrame() {
|
|
|
327
290
|
}
|
|
328
291
|
|
|
329
292
|
double AudioBufferSourceNode::getVirtualEndFrame() {
|
|
330
|
-
auto inputBufferLength = static_cast<double>(
|
|
293
|
+
auto inputBufferLength = static_cast<double>(alignedBus_->getSize());
|
|
331
294
|
auto loopEndFrame = loopEnd_ * context_->getSampleRate();
|
|
332
295
|
|
|
333
296
|
return loop_ && loopEndFrame > 0 && loopStart_ < loopEnd_
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
#include <audioapi/core/sources/AudioBuffer.h>
|
|
4
4
|
#include <audioapi/core/sources/AudioScheduledSourceNode.h>
|
|
5
|
-
#include <audioapi/core/types/TimeStretchType.h>
|
|
6
5
|
|
|
7
6
|
#include <memory>
|
|
8
7
|
#include <cstddef>
|
|
9
8
|
#include <algorithm>
|
|
10
|
-
#include <
|
|
9
|
+
#include <cassert>
|
|
11
10
|
|
|
12
11
|
namespace audioapi {
|
|
13
12
|
|
|
@@ -23,68 +22,41 @@ class AudioBufferSourceNode : public AudioScheduledSourceNode {
|
|
|
23
22
|
[[nodiscard]] double getLoopEnd() const;
|
|
24
23
|
[[nodiscard]] std::shared_ptr<AudioParam> getDetuneParam() const;
|
|
25
24
|
[[nodiscard]] std::shared_ptr<AudioParam> getPlaybackRateParam() const;
|
|
26
|
-
[[nodiscard]] std::shared_ptr<AudioParam> getSemitonesParam() const;
|
|
27
25
|
[[nodiscard]] std::shared_ptr<AudioBuffer> getBuffer() const;
|
|
28
|
-
[[nodiscard]] std::string getTimeStretchType() const;
|
|
29
26
|
|
|
30
27
|
void setLoop(bool loop);
|
|
31
28
|
void setLoopStart(double loopStart);
|
|
32
29
|
void setLoopEnd(double loopEnd);
|
|
33
30
|
void setBuffer(const std::shared_ptr<AudioBuffer> &buffer);
|
|
34
|
-
void setTimeStretchType(const std::string &type);
|
|
35
31
|
|
|
36
32
|
void start(double when, double offset, double duration = -1);
|
|
37
33
|
|
|
38
34
|
protected:
|
|
39
35
|
std::mutex &getBufferLock();
|
|
40
36
|
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
41
|
-
double getStopTime() const override;
|
|
42
37
|
|
|
43
38
|
private:
|
|
44
|
-
static TimeStretchType fromString(const std::string &type) {
|
|
45
|
-
std::string lowerType = type;
|
|
46
|
-
std::transform(
|
|
47
|
-
lowerType.begin(), lowerType.end(), lowerType.begin(), ::tolower);
|
|
48
|
-
|
|
49
|
-
if (lowerType == "linear")
|
|
50
|
-
return TimeStretchType::LINEAR;
|
|
51
|
-
if (lowerType == "speech-music")
|
|
52
|
-
return TimeStretchType::SPEECH_MUSIC;
|
|
53
|
-
|
|
54
|
-
throw std::invalid_argument("Unknown time stretch type: " + type);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
static std::string toString(TimeStretchType type) {
|
|
58
|
-
switch (type) {
|
|
59
|
-
case TimeStretchType::LINEAR:
|
|
60
|
-
return "linear";
|
|
61
|
-
case TimeStretchType::SPEECH_MUSIC:
|
|
62
|
-
return "speech-music";
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
throw std::invalid_argument("Unknown time stretch type");
|
|
66
|
-
}
|
|
67
|
-
|
|
68
39
|
// Looping related properties
|
|
69
40
|
bool loop_;
|
|
70
41
|
double loopStart_;
|
|
71
42
|
double loopEnd_;
|
|
72
43
|
std::mutex bufferLock_;
|
|
73
44
|
|
|
74
|
-
//
|
|
75
|
-
TimeStretchType timeStretchType_;
|
|
76
|
-
|
|
77
|
-
// k-rate params
|
|
45
|
+
// playback rate aka pitch change params
|
|
78
46
|
std::shared_ptr<AudioParam> detuneParam_;
|
|
79
47
|
std::shared_ptr<AudioParam> playbackRateParam_;
|
|
80
48
|
|
|
81
|
-
std::shared_ptr<AudioBus> playbackRateBus_;
|
|
82
|
-
|
|
83
49
|
// internal helper
|
|
84
50
|
double vReadIndex_;
|
|
85
51
|
|
|
86
52
|
// User provided buffer
|
|
87
53
|
std::shared_ptr<AudioBuffer> buffer_;
|
|
54
|
+
std::shared_ptr<AudioBus> alignedBus_;
|
|
55
|
+
|
|
56
|
+
float getPlaybackRateValue(size_t &startOffset);
|
|
57
|
+
|
|
58
|
+
double getVirtualStartFrame();
|
|
59
|
+
double getVirtualEndFrame();
|
|
88
60
|
|
|
89
61
|
void processWithoutInterpolation(
|
|
90
62
|
const std::shared_ptr<AudioBus>& processingBus,
|
|
@@ -97,11 +69,6 @@ class AudioBufferSourceNode : public AudioScheduledSourceNode {
|
|
|
97
69
|
size_t startOffset,
|
|
98
70
|
size_t offsetLength,
|
|
99
71
|
float playbackRate);
|
|
100
|
-
|
|
101
|
-
float getComputedPlaybackRateValue();
|
|
102
|
-
|
|
103
|
-
double getVirtualStartFrame();
|
|
104
|
-
double getVirtualEndFrame();
|
|
105
72
|
};
|
|
106
73
|
|
|
107
74
|
} // namespace audioapi
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#include <audioapi/core/BaseAudioContext.h>
|
|
2
2
|
#include <audioapi/core/sources/AudioScheduledSourceNode.h>
|
|
3
|
+
#include <audioapi/core/utils/AudioArray.h>
|
|
4
|
+
#include <audioapi/core/utils/AudioBus.h>
|
|
3
5
|
#include <audioapi/core/utils/AudioNodeManager.h>
|
|
4
6
|
#include <audioapi/dsp/AudioUtils.h>
|
|
5
|
-
#include <audioapi/utils/AudioArray.h>
|
|
6
|
-
#include <audioapi/utils/AudioBus.h>
|
|
7
7
|
|
|
8
8
|
namespace audioapi {
|
|
9
9
|
|
|
@@ -40,11 +40,6 @@ bool AudioScheduledSourceNode::isFinished() {
|
|
|
40
40
|
return playbackState_ == PlaybackState::FINISHED;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
void AudioScheduledSourceNode::setOnendedCallback(
|
|
44
|
-
const std::function<void(double)> &onendedCallback) {
|
|
45
|
-
onendedCallback_ = onendedCallback;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
43
|
void AudioScheduledSourceNode::updatePlaybackInfo(
|
|
49
44
|
const std::shared_ptr<AudioBus> &processingBus,
|
|
50
45
|
int framesToProcess,
|
|
@@ -63,11 +58,12 @@ void AudioScheduledSourceNode::updatePlaybackInfo(
|
|
|
63
58
|
size_t firstFrame = context_->getCurrentSampleFrame();
|
|
64
59
|
size_t lastFrame = firstFrame + framesToProcess;
|
|
65
60
|
|
|
66
|
-
size_t startFrame =
|
|
67
|
-
|
|
61
|
+
size_t startFrame = std::max(
|
|
62
|
+
AudioUtils::timeToSampleFrame(startTime_, sampleRate), firstFrame);
|
|
68
63
|
size_t stopFrame = stopTime_ == -1.0
|
|
69
64
|
? std::numeric_limits<size_t>::max()
|
|
70
|
-
: std::max(
|
|
65
|
+
: std::max(
|
|
66
|
+
AudioUtils::timeToSampleFrame(stopTime_, sampleRate), firstFrame);
|
|
71
67
|
|
|
72
68
|
if (isUnscheduled() || isFinished()) {
|
|
73
69
|
startOffset = 0;
|
|
@@ -109,11 +105,6 @@ void AudioScheduledSourceNode::updatePlaybackInfo(
|
|
|
109
105
|
if (stopFrame < firstFrame) {
|
|
110
106
|
startOffset = 0;
|
|
111
107
|
nonSilentFramesToProcess = 0;
|
|
112
|
-
|
|
113
|
-
if (onendedCallback_) {
|
|
114
|
-
onendedCallback_(getStopTime());
|
|
115
|
-
}
|
|
116
|
-
|
|
117
108
|
playbackState_ = PlaybackState::FINISHED;
|
|
118
109
|
disable();
|
|
119
110
|
return;
|
|
@@ -126,9 +117,6 @@ void AudioScheduledSourceNode::updatePlaybackInfo(
|
|
|
126
117
|
|
|
127
118
|
void AudioScheduledSourceNode::handleStopScheduled() {
|
|
128
119
|
if (isPlaying() && stopTime_ > 0 && context_->getCurrentTime() >= stopTime_) {
|
|
129
|
-
if (onendedCallback_) {
|
|
130
|
-
onendedCallback_(getStopTime());
|
|
131
|
-
}
|
|
132
120
|
playbackState_ = PlaybackState::FINISHED;
|
|
133
121
|
disable();
|
|
134
122
|
}
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
#include <thread>
|
|
13
13
|
#include <cstddef>
|
|
14
14
|
#include <cassert>
|
|
15
|
-
#include <utility>
|
|
16
15
|
|
|
17
16
|
namespace audioapi {
|
|
18
17
|
|
|
@@ -29,10 +28,6 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
29
28
|
bool isPlaying();
|
|
30
29
|
bool isFinished();
|
|
31
30
|
|
|
32
|
-
void setOnendedCallback(const std::function<void(double)> &onendedCallback);
|
|
33
|
-
|
|
34
|
-
virtual double getStopTime() const = 0;
|
|
35
|
-
|
|
36
31
|
protected:
|
|
37
32
|
PlaybackState playbackState_;
|
|
38
33
|
|
|
@@ -47,8 +42,6 @@ class AudioScheduledSourceNode : public AudioNode {
|
|
|
47
42
|
private:
|
|
48
43
|
double startTime_;
|
|
49
44
|
double stopTime_;
|
|
50
|
-
|
|
51
|
-
std::function<void(double)> onendedCallback_;
|
|
52
45
|
};
|
|
53
46
|
|
|
54
47
|
} // namespace audioapi
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#include <audioapi/core/BaseAudioContext.h>
|
|
2
2
|
#include <audioapi/core/sources/OscillatorNode.h>
|
|
3
|
-
#include <audioapi/
|
|
4
|
-
#include <audioapi/utils/
|
|
5
|
-
#include <audioapi/utils/AudioBus.h>
|
|
3
|
+
#include <audioapi/core/utils/AudioArray.h>
|
|
4
|
+
#include <audioapi/core/utils/AudioBus.h>
|
|
6
5
|
|
|
7
6
|
namespace audioapi {
|
|
8
7
|
|
|
@@ -10,10 +9,7 @@ OscillatorNode::OscillatorNode(BaseAudioContext *context)
|
|
|
10
9
|
: AudioScheduledSourceNode(context) {
|
|
11
10
|
frequencyParam_ = std::make_shared<AudioParam>(
|
|
12
11
|
444.0, -context_->getNyquistFrequency(), context_->getNyquistFrequency());
|
|
13
|
-
detuneParam_ = std::make_shared<AudioParam>(
|
|
14
|
-
0.0,
|
|
15
|
-
-1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT,
|
|
16
|
-
1200 * LOG2_MOST_POSITIVE_SINGLE_FLOAT);
|
|
12
|
+
detuneParam_ = std::make_shared<AudioParam>(0.0, -MAX_DETUNE, MAX_DETUNE);
|
|
17
13
|
type_ = OscillatorType::SINE;
|
|
18
14
|
periodicWave_ = context_->getBasicWaveForm(type_);
|
|
19
15
|
isInitialized_ = true;
|
|
@@ -85,9 +81,4 @@ void OscillatorNode::processNode(
|
|
|
85
81
|
handleStopScheduled();
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
double OscillatorNode::getStopTime() const {
|
|
89
|
-
return dsp::sampleFrameToTime(
|
|
90
|
-
static_cast<int>(phase_), context_->getSampleRate());
|
|
91
|
-
}
|
|
92
|
-
|
|
93
84
|
} // namespace audioapi
|
|
@@ -25,7 +25,6 @@ class OscillatorNode : public AudioScheduledSourceNode {
|
|
|
25
25
|
|
|
26
26
|
protected:
|
|
27
27
|
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
28
|
-
double getStopTime() const override;
|
|
29
28
|
|
|
30
29
|
private:
|
|
31
30
|
std::shared_ptr<AudioParam> frequencyParam_;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
#include <audioapi/core/utils/AudioArray.h>
|
|
1
2
|
#include <audioapi/dsp/VectorMath.h>
|
|
2
|
-
#include <audioapi/utils/AudioArray.h>
|
|
3
3
|
|
|
4
4
|
namespace audioapi {
|
|
5
5
|
|
|
@@ -37,7 +37,7 @@ void AudioArray::normalize() {
|
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
VectorMath::multiplyByScalar(data_, 1.0f / maxAbsValue, data_, size_);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
void AudioArray::resize(size_t size) {
|
|
@@ -58,11 +58,11 @@ void AudioArray::resize(size_t size) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
void AudioArray::scale(float value) {
|
|
61
|
-
|
|
61
|
+
VectorMath::multiplyByScalar(data_, value, data_, size_);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
float AudioArray::getMaxAbsValue() const {
|
|
65
|
-
return
|
|
65
|
+
return VectorMath::maximumMagnitude(data_, size_);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
void AudioArray::zero() {
|
|
@@ -86,7 +86,7 @@ void AudioArray::sum(
|
|
|
86
86
|
size_t sourceStart,
|
|
87
87
|
size_t destinationStart,
|
|
88
88
|
size_t length) {
|
|
89
|
-
|
|
89
|
+
VectorMath::add(
|
|
90
90
|
data_ + destinationStart,
|
|
91
91
|
source->getData() + sourceStart,
|
|
92
92
|
data_ + destinationStart,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#include <audioapi/core/Constants.h>
|
|
2
|
+
#include <audioapi/core/utils/AudioArray.h>
|
|
3
|
+
#include <audioapi/core/utils/AudioBus.h>
|
|
2
4
|
#include <audioapi/dsp/VectorMath.h>
|
|
3
|
-
#include <audioapi/utils/AudioArray.h>
|
|
4
|
-
#include <audioapi/utils/AudioBus.h>
|
|
5
5
|
|
|
6
6
|
// Implementation of channel summing/mixing is based on the WebKit approach,
|
|
7
7
|
// source:
|
|
@@ -375,12 +375,12 @@ void AudioBus::sumByDownMixing(
|
|
|
375
375
|
|
|
376
376
|
float *destinationData = getChannelByType(ChannelMono)->getData();
|
|
377
377
|
|
|
378
|
-
|
|
378
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
379
379
|
sourceLeft + sourceStart,
|
|
380
380
|
0.5f,
|
|
381
381
|
destinationData + destinationStart,
|
|
382
382
|
length);
|
|
383
|
-
|
|
383
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
384
384
|
sourceRight + sourceStart,
|
|
385
385
|
0.5f,
|
|
386
386
|
destinationData + destinationStart,
|
|
@@ -401,22 +401,22 @@ void AudioBus::sumByDownMixing(
|
|
|
401
401
|
|
|
402
402
|
float *destinationData = getChannelByType(ChannelMono)->getData();
|
|
403
403
|
|
|
404
|
-
|
|
404
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
405
405
|
sourceLeft + sourceStart,
|
|
406
406
|
0.25f,
|
|
407
407
|
destinationData + destinationStart,
|
|
408
408
|
length);
|
|
409
|
-
|
|
409
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
410
410
|
sourceRight + sourceStart,
|
|
411
411
|
0.25f,
|
|
412
412
|
destinationData + destinationStart,
|
|
413
413
|
length);
|
|
414
|
-
|
|
414
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
415
415
|
sourceSurroundLeft + sourceStart,
|
|
416
416
|
0.25f,
|
|
417
417
|
destinationData + destinationStart,
|
|
418
418
|
length);
|
|
419
|
-
|
|
419
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
420
420
|
sourceSurroundRight + sourceStart,
|
|
421
421
|
0.25f,
|
|
422
422
|
destinationData + destinationStart,
|
|
@@ -438,27 +438,27 @@ void AudioBus::sumByDownMixing(
|
|
|
438
438
|
|
|
439
439
|
float *destinationData = getChannelByType(ChannelMono)->getData();
|
|
440
440
|
|
|
441
|
-
|
|
441
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
442
442
|
sourceLeft + sourceStart,
|
|
443
443
|
SQRT_HALF,
|
|
444
444
|
destinationData + destinationStart,
|
|
445
445
|
length);
|
|
446
|
-
|
|
446
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
447
447
|
sourceRight + sourceStart,
|
|
448
448
|
SQRT_HALF,
|
|
449
449
|
destinationData + destinationStart,
|
|
450
450
|
length);
|
|
451
|
-
|
|
451
|
+
VectorMath::add(
|
|
452
452
|
sourceCenter + sourceStart,
|
|
453
453
|
destinationData + destinationStart,
|
|
454
454
|
destinationData + destinationStart,
|
|
455
455
|
length);
|
|
456
|
-
|
|
456
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
457
457
|
sourceSurroundLeft + sourceStart,
|
|
458
458
|
0.5f,
|
|
459
459
|
destinationData + destinationStart,
|
|
460
460
|
length);
|
|
461
|
-
|
|
461
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
462
462
|
sourceSurroundRight + sourceStart,
|
|
463
463
|
0.5f,
|
|
464
464
|
destinationData + destinationStart,
|
|
@@ -481,23 +481,23 @@ void AudioBus::sumByDownMixing(
|
|
|
481
481
|
float *destinationLeft = getChannelByType(ChannelLeft)->getData();
|
|
482
482
|
float *destinationRight = getChannelByType(ChannelRight)->getData();
|
|
483
483
|
|
|
484
|
-
|
|
484
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
485
485
|
sourceLeft + sourceStart,
|
|
486
486
|
0.5f,
|
|
487
487
|
destinationLeft + destinationStart,
|
|
488
488
|
length);
|
|
489
|
-
|
|
489
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
490
490
|
sourceSurroundLeft + sourceStart,
|
|
491
491
|
0.5f,
|
|
492
492
|
destinationLeft + destinationStart,
|
|
493
493
|
length);
|
|
494
494
|
|
|
495
|
-
|
|
495
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
496
496
|
sourceRight + sourceStart,
|
|
497
497
|
0.5f,
|
|
498
498
|
destinationRight + destinationStart,
|
|
499
499
|
length);
|
|
500
|
-
|
|
500
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
501
501
|
sourceSurroundRight + sourceStart,
|
|
502
502
|
0.5f,
|
|
503
503
|
destinationRight + destinationStart,
|
|
@@ -521,33 +521,33 @@ void AudioBus::sumByDownMixing(
|
|
|
521
521
|
float *destinationLeft = getChannelByType(ChannelLeft)->getData();
|
|
522
522
|
float *destinationRight = getChannelByType(ChannelRight)->getData();
|
|
523
523
|
|
|
524
|
-
|
|
524
|
+
VectorMath::add(
|
|
525
525
|
sourceLeft + sourceStart,
|
|
526
526
|
destinationLeft + destinationStart,
|
|
527
527
|
destinationLeft + destinationStart,
|
|
528
528
|
length);
|
|
529
|
-
|
|
529
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
530
530
|
sourceCenter + sourceStart,
|
|
531
531
|
SQRT_HALF,
|
|
532
532
|
destinationLeft + destinationStart,
|
|
533
533
|
length);
|
|
534
|
-
|
|
534
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
535
535
|
sourceSurroundLeft + sourceStart,
|
|
536
536
|
SQRT_HALF,
|
|
537
537
|
destinationLeft + destinationStart,
|
|
538
538
|
length);
|
|
539
539
|
|
|
540
|
-
|
|
540
|
+
VectorMath::add(
|
|
541
541
|
sourceRight + sourceStart,
|
|
542
542
|
destinationRight + destinationStart,
|
|
543
543
|
destinationRight + destinationStart,
|
|
544
544
|
length);
|
|
545
|
-
|
|
545
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
546
546
|
sourceCenter + sourceStart,
|
|
547
547
|
SQRT_HALF,
|
|
548
548
|
destinationRight + destinationStart,
|
|
549
549
|
length);
|
|
550
|
-
|
|
550
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
551
551
|
sourceSurroundRight + sourceStart,
|
|
552
552
|
SQRT_HALF,
|
|
553
553
|
destinationRight + destinationStart,
|
|
@@ -576,28 +576,28 @@ void AudioBus::sumByDownMixing(
|
|
|
576
576
|
float *destinationSurroundRight =
|
|
577
577
|
getChannelByType(ChannelSurroundRight)->getData();
|
|
578
578
|
|
|
579
|
-
|
|
579
|
+
VectorMath::add(
|
|
580
580
|
sourceLeft + sourceStart,
|
|
581
581
|
destinationLeft + destinationStart,
|
|
582
582
|
destinationLeft + destinationStart,
|
|
583
583
|
length);
|
|
584
|
-
|
|
584
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
585
585
|
sourceCenter, SQRT_HALF, destinationLeft + destinationStart, length);
|
|
586
586
|
|
|
587
|
-
|
|
587
|
+
VectorMath::add(
|
|
588
588
|
sourceRight + sourceStart,
|
|
589
589
|
destinationRight + destinationStart,
|
|
590
590
|
destinationRight + destinationStart,
|
|
591
591
|
length);
|
|
592
|
-
|
|
592
|
+
VectorMath::multiplyByScalarThenAddToOutput(
|
|
593
593
|
sourceCenter, SQRT_HALF, destinationRight + destinationStart, length);
|
|
594
594
|
|
|
595
|
-
|
|
595
|
+
VectorMath::add(
|
|
596
596
|
sourceSurroundLeft + sourceStart,
|
|
597
597
|
destinationSurroundLeft + destinationStart,
|
|
598
598
|
destinationSurroundLeft + destinationStart,
|
|
599
599
|
length);
|
|
600
|
-
|
|
600
|
+
VectorMath::add(
|
|
601
601
|
sourceSurroundRight + sourceStart,
|
|
602
602
|
destinationSurroundRight + destinationStart,
|
|
603
603
|
destinationSurroundRight + destinationStart,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#include <audioapi/dsp/AudioUtils.h>
|
|
2
2
|
|
|
3
|
-
namespace audioapi::
|
|
3
|
+
namespace audioapi::AudioUtils {
|
|
4
4
|
size_t timeToSampleFrame(double time, float sampleRate) {
|
|
5
5
|
return static_cast<size_t>(time * sampleRate);
|
|
6
6
|
}
|
|
@@ -30,4 +30,4 @@ float linearToDecibels(float value) {
|
|
|
30
30
|
float decibelsToLinear(float value) {
|
|
31
31
|
return powf(10, value / 20);
|
|
32
32
|
}
|
|
33
|
-
} // namespace audioapi::
|
|
33
|
+
} // namespace audioapi::AudioUtils
|