react-native-audio-api 0.4.12-beta.4 → 0.4.12
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 +2 -3
- package/android/src/main/cpp/audioapi/android/core/AudioDecoder.cpp +3 -3
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +10 -11
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.h +1 -0
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +0 -1
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +1 -3
- package/common/cpp/audioapi/HostObjects/AnalyserNodeHostObject.h +24 -16
- package/common/cpp/audioapi/HostObjects/AudioBufferHostObject.h +4 -0
- package/common/cpp/audioapi/HostObjects/AudioBufferSourceNodeHostObject.h +20 -4
- package/common/cpp/audioapi/HostObjects/AudioContextHostObject.h +3 -2
- package/common/cpp/audioapi/HostObjects/AudioScheduledSourceNodeHostObject.h +32 -2
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +14 -21
- package/common/cpp/audioapi/HostObjects/OscillatorNodeHostObject.h +4 -2
- 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 +4 -12
- package/common/cpp/audioapi/core/BaseAudioContext.h +2 -4
- package/common/cpp/audioapi/core/Constants.h +8 -33
- package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +42 -45
- package/common/cpp/audioapi/core/analysis/AnalyserNode.h +8 -6
- package/common/cpp/audioapi/core/destinations/AudioDestinationNode.cpp +1 -1
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +12 -8
- package/common/cpp/audioapi/core/effects/GainNode.cpp +4 -3
- package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +32 -49
- package/common/cpp/audioapi/core/effects/PeriodicWave.h +8 -3
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +3 -3
- package/common/cpp/audioapi/core/sources/AudioBuffer.cpp +9 -2
- package/common/cpp/audioapi/core/sources/AudioBuffer.h +5 -2
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +72 -35
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +41 -8
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +18 -6
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +7 -0
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +12 -3
- package/common/cpp/audioapi/core/sources/OscillatorNode.h +1 -0
- package/common/cpp/audioapi/core/types/TimeStretchType.h +7 -0
- package/common/cpp/audioapi/dsp/AudioUtils.cpp +2 -2
- package/common/cpp/audioapi/dsp/AudioUtils.h +2 -2
- package/common/cpp/audioapi/dsp/FFT.cpp +41 -0
- package/common/cpp/audioapi/dsp/FFT.h +29 -0
- package/common/cpp/audioapi/dsp/VectorMath.cpp +3 -3
- package/common/cpp/audioapi/dsp/VectorMath.h +2 -2
- package/common/cpp/audioapi/dsp/Windows.cpp +80 -0
- package/common/cpp/audioapi/dsp/Windows.h +95 -0
- package/{android/src/main/cpp/audioapi/android/libs → common/cpp/audioapi/libs/pffft}/pffft.c +1 -1
- package/common/cpp/audioapi/libs/{dsp → signalsmith-stretch}/delay.h +9 -11
- package/common/cpp/audioapi/libs/{dsp → signalsmith-stretch}/fft.h +6 -7
- package/common/cpp/audioapi/libs/{dsp → signalsmith-stretch}/perf.h +0 -2
- package/common/cpp/audioapi/libs/{signalsmith-stretch.h → signalsmith-stretch/signalsmith-stretch.h} +3 -4
- package/common/cpp/audioapi/libs/{dsp → signalsmith-stretch}/spectral.h +10 -13
- package/common/cpp/audioapi/{core/utils → utils}/AudioArray.cpp +5 -5
- package/common/cpp/audioapi/{core/utils → utils}/AudioBus.cpp +29 -29
- package/ios/audioapi/ios/core/AudioDecoder.mm +3 -3
- package/ios/audioapi/ios/core/AudioPlayer.h +5 -2
- package/ios/audioapi/ios/core/AudioPlayer.m +9 -5
- package/ios/audioapi/ios/core/IOSAudioPlayer.h +1 -0
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +12 -10
- package/lib/module/api.js +30 -0
- package/lib/module/api.js.map +1 -0
- package/lib/module/{index.web.js → api.web.js} +4 -2
- package/lib/module/api.web.js.map +1 -0
- package/lib/module/core/AudioBufferSourceNode.js +6 -0
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/core/AudioScheduledSourceNode.js +5 -0
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +0 -4
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/index.js +1 -28
- package/lib/module/index.js.map +1 -1
- package/lib/module/web-core/AudioBuffer.js +1 -1
- package/lib/module/web-core/AudioBuffer.js.map +1 -1
- package/lib/module/web-core/AudioBufferSourceNode.js +6 -0
- package/lib/module/web-core/AudioBufferSourceNode.js.map +1 -1
- package/lib/module/web-core/AudioContext.js +7 -0
- package/lib/module/web-core/AudioContext.js.map +1 -1
- package/lib/module/web-core/AudioScheduledSourceNode.js +8 -0
- package/lib/module/web-core/AudioScheduledSourceNode.js.map +1 -1
- package/lib/module/web-core/StretcherNode.js +64 -0
- package/lib/module/web-core/StretcherNode.js.map +1 -0
- package/lib/module/web-core/custom/LoadCustomWasm.js +33 -0
- package/lib/module/web-core/custom/LoadCustomWasm.js.map +1 -0
- package/lib/module/web-core/custom/index.js +4 -0
- package/lib/module/web-core/custom/index.js.map +1 -0
- package/lib/module/web-core/custom/signalsmithStretch/LICENSE.txt +21 -0
- package/lib/module/web-core/custom/signalsmithStretch/README.md +46 -0
- package/lib/module/web-core/custom/signalsmithStretch/SignalsmithStretch.js +822 -0
- package/lib/module/web-core/custom/signalsmithStretch/SignalsmithStretch.js.map +1 -0
- package/lib/module/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs +826 -0
- package/lib/module/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs.map +1 -0
- package/lib/typescript/api.d.ts +20 -0
- package/lib/typescript/api.d.ts.map +1 -0
- package/lib/typescript/{index.web.d.ts → api.web.d.ts} +4 -2
- package/lib/typescript/api.web.d.ts.map +1 -0
- package/lib/typescript/core/AudioBufferSourceNode.d.ts +3 -0
- package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +1 -0
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +0 -2
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -20
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +3 -6
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +1 -0
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioBuffer.d.ts +1 -1
- package/lib/typescript/web-core/AudioBuffer.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioBufferSourceNode.d.ts +3 -0
- package/lib/typescript/web-core/AudioBufferSourceNode.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioContext.d.ts +2 -0
- package/lib/typescript/web-core/AudioContext.d.ts.map +1 -1
- package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts +1 -0
- package/lib/typescript/web-core/AudioScheduledSourceNode.d.ts.map +1 -1
- package/lib/typescript/web-core/StretcherNode.d.ts +45 -0
- package/lib/typescript/web-core/StretcherNode.d.ts.map +1 -0
- package/lib/typescript/web-core/custom/LoadCustomWasm.d.ts +5 -0
- package/lib/typescript/web-core/custom/LoadCustomWasm.d.ts.map +1 -0
- package/lib/typescript/web-core/custom/index.d.ts +2 -0
- package/lib/typescript/web-core/custom/index.d.ts.map +1 -0
- package/package.json +8 -5
- package/scripts/setup-custom-wasm.js +104 -0
- package/src/api.ts +51 -0
- package/src/{index.web.ts → api.web.ts} +4 -0
- package/src/core/AudioBufferSourceNode.ts +9 -0
- package/src/core/AudioScheduledSourceNode.ts +5 -0
- package/src/core/BaseAudioContext.ts +0 -5
- package/src/index.ts +1 -51
- package/src/interfaces.ts +3 -6
- package/src/types.ts +2 -0
- package/src/web-core/AudioBuffer.tsx +2 -2
- package/src/web-core/AudioBufferSourceNode.tsx +11 -0
- package/src/web-core/AudioContext.tsx +11 -0
- package/src/web-core/AudioScheduledSourceNode.tsx +9 -0
- package/src/web-core/StretcherNode.tsx +125 -0
- package/src/web-core/custom/LoadCustomWasm.ts +39 -0
- package/src/web-core/custom/index.ts +1 -0
- package/src/web-core/custom/signalsmithStretch/LICENSE.txt +21 -0
- package/src/web-core/custom/signalsmithStretch/README.md +46 -0
- package/src/web-core/custom/signalsmithStretch/SignalsmithStretch.js +945 -0
- package/src/web-core/custom/signalsmithStretch/SignalsmithStretch.mjs +949 -0
- package/common/cpp/audioapi/HostObjects/StretcherNodeHostObject.h +0 -35
- package/common/cpp/audioapi/core/effects/StretcherNode.cpp +0 -94
- package/common/cpp/audioapi/core/effects/StretcherNode.h +0 -35
- package/common/cpp/audioapi/dsp/FFTFrame.cpp +0 -100
- package/common/cpp/audioapi/dsp/FFTFrame.h +0 -74
- package/common/cpp/audioapi/libs/dsp/common.h +0 -47
- package/common/cpp/audioapi/libs/dsp/windows.h +0 -219
- package/lib/module/core/StretcherNode.js +0 -12
- package/lib/module/core/StretcherNode.js.map +0 -1
- package/lib/module/index.web.js.map +0 -1
- package/lib/typescript/core/StretcherNode.d.ts +0 -10
- package/lib/typescript/core/StretcherNode.d.ts.map +0 -1
- package/lib/typescript/index.web.d.ts.map +0 -1
- package/src/core/StretcherNode.ts +0 -15
- /package/common/cpp/audioapi/libs/{miniaudio.h → miniaudio/miniaudio.h} +0 -0
- /package/{android/src/main/cpp/audioapi/android/libs → common/cpp/audioapi/libs/pffft}/pffft.h +0 -0
- /package/common/cpp/audioapi/{core/utils → utils}/AudioArray.h +0 -0
- /package/common/cpp/audioapi/{core/utils → utils}/AudioBus.h +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cmath>
|
|
4
|
+
#include <algorithm>
|
|
5
|
+
|
|
6
|
+
namespace audioapi::dsp {
|
|
7
|
+
|
|
8
|
+
// https://en.wikipedia.org/wiki/Window_function
|
|
9
|
+
// https://personalpages.hs-kempten.de/~vollratj/InEl/pdf/Window%20function%20-%20Wikipedia.pdf
|
|
10
|
+
class WindowFunction {
|
|
11
|
+
public:
|
|
12
|
+
explicit WindowFunction(float amplitude = 1.0f): amplitude_(amplitude) {}
|
|
13
|
+
|
|
14
|
+
virtual void apply(float *data, int size) const = 0;
|
|
15
|
+
// forces STFT perfect-reconstruction (WOLA) on an existing window, for a given STFT interval.
|
|
16
|
+
static void forcePerfectReconstruction(float *data, int windowLength, int interval);
|
|
17
|
+
|
|
18
|
+
protected:
|
|
19
|
+
// 1/L = amplitude
|
|
20
|
+
float amplitude_;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
//https://en.wikipedia.org/wiki/Hann_function
|
|
24
|
+
// https://www.sciencedirect.com/topics/engineering/hanning-window
|
|
25
|
+
// https://docs.scipy.org/doc//scipy-1.2.3/reference/generated/scipy.signal.windows.hann.html#scipy.signal.windows.hann
|
|
26
|
+
class Hann: public WindowFunction {
|
|
27
|
+
public:
|
|
28
|
+
explicit Hann(float amplitude = 1.0f): WindowFunction(amplitude) {}
|
|
29
|
+
|
|
30
|
+
void apply(float *data, int size) const override;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// https://www.sciencedirect.com/topics/engineering/blackman-window
|
|
34
|
+
// https://docs.scipy.org/doc//scipy-1.2.3/reference/generated/scipy.signal.windows.blackman.html#scipy.signal.windows.blackman
|
|
35
|
+
class Blackman: public WindowFunction {
|
|
36
|
+
public:
|
|
37
|
+
explicit Blackman(float amplitude = 1.0f): WindowFunction(amplitude) {}
|
|
38
|
+
|
|
39
|
+
void apply(float *data, int size) const override;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
// https://en.wikipedia.org/wiki/Kaiser_window
|
|
44
|
+
class Kaiser: public WindowFunction {
|
|
45
|
+
public:
|
|
46
|
+
explicit Kaiser(float beta, float amplitude = 1.0f): WindowFunction(amplitude), beta_(beta), invB0_(1.0f / bessel0(beta)) {}
|
|
47
|
+
|
|
48
|
+
static Kaiser withBandwidth(float bandwidth, bool heuristicOptimal = false, float amplitude = 1.0f) {
|
|
49
|
+
return Kaiser(bandwidthToBeta(bandwidth, heuristicOptimal), amplitude);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void apply(float *data, int size) const override;
|
|
53
|
+
|
|
54
|
+
private:
|
|
55
|
+
// beta = pi * alpha
|
|
56
|
+
// invB0 = 1 / I0(beta)
|
|
57
|
+
float beta_;
|
|
58
|
+
float invB0_;
|
|
59
|
+
|
|
60
|
+
// https://en.wikipedia.org/wiki/Bessel_function#Modified_Bessel_functions:_I%CE%B1,_K%CE%B1
|
|
61
|
+
static inline float bessel0(float x) {
|
|
62
|
+
const double significanceLimit = 1e-4;
|
|
63
|
+
auto result = 0.0f;
|
|
64
|
+
auto term = 1.0f;
|
|
65
|
+
auto m = 1.0f;
|
|
66
|
+
while (term > significanceLimit) {
|
|
67
|
+
result += term;
|
|
68
|
+
++m;
|
|
69
|
+
term *= (x * x) / (4 * m * m);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
static float bandwidthToBeta(float bandwidth, bool heuristicOptimal = false);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// https://www.recordingblogs.com/wiki/gaussian-window
|
|
78
|
+
class ApproximateConfinedGaussian: public WindowFunction {
|
|
79
|
+
public:
|
|
80
|
+
explicit ApproximateConfinedGaussian(float sigma, float amplitude = 1.0f): WindowFunction(amplitude), gaussianFactor_(0.0625f/(sigma*sigma)) {}
|
|
81
|
+
|
|
82
|
+
static ApproximateConfinedGaussian withBandwidth(float bandwidth, float amplitude = 1.0f) {
|
|
83
|
+
return ApproximateConfinedGaussian(bandwidthToSigma(bandwidth), amplitude);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
void apply(float *data, int size) const override;
|
|
87
|
+
|
|
88
|
+
private:
|
|
89
|
+
float gaussianFactor_;
|
|
90
|
+
|
|
91
|
+
static float bandwidthToSigma(float bandwidth);
|
|
92
|
+
|
|
93
|
+
[[nodiscard]] float getGaussian(float x) const;
|
|
94
|
+
};
|
|
95
|
+
} // namespace audioapi::dsp
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
#include <audioapi/libs/dsp/common.h>
|
|
2
|
-
|
|
3
1
|
#ifndef SIGNALSMITH_DSP_DELAY_H
|
|
4
2
|
#define SIGNALSMITH_DSP_DELAY_H
|
|
5
3
|
|
|
@@ -7,10 +5,10 @@
|
|
|
7
5
|
#include <array>
|
|
8
6
|
#include <cmath> // for std::ceil()
|
|
9
7
|
#include <type_traits>
|
|
10
|
-
|
|
11
8
|
#include <complex>
|
|
12
|
-
|
|
13
|
-
#include <audioapi/libs/
|
|
9
|
+
|
|
10
|
+
#include <audioapi/libs/signalsmith-stretch/fft.h>
|
|
11
|
+
#include <audioapi/dsp/Windows.h>
|
|
14
12
|
|
|
15
13
|
namespace signalsmith {
|
|
16
14
|
namespace delay {
|
|
@@ -482,14 +480,14 @@ namespace delay {
|
|
|
482
480
|
InterpolatorKaiserSincN(double passFreq) : InterpolatorKaiserSincN(passFreq, 1 - passFreq) {}
|
|
483
481
|
InterpolatorKaiserSincN(double passFreq, double stopFreq) {
|
|
484
482
|
subSampleSteps = 2*n; // Heuristic again. Really it depends on the bandwidth as well.
|
|
485
|
-
|
|
486
|
-
kaiserBandwidth += 1.
|
|
487
|
-
double sincScale =
|
|
483
|
+
float kaiserBandwidth = (stopFreq - passFreq)*(n + 1.0/subSampleSteps);
|
|
484
|
+
kaiserBandwidth += 1.25f / kaiserBandwidth; // We want to place the first zero, but (because using this to window a sinc essentially integrates it in the freq-domain), our ripples (and therefore zeroes) are out of phase. This is a heuristic fix.
|
|
485
|
+
double sincScale = audioapi::PI*(passFreq + stopFreq);
|
|
488
486
|
|
|
489
487
|
double centreIndex = n*subSampleSteps*0.5, scaleFactor = 1.0/subSampleSteps;
|
|
490
488
|
std::vector<Sample> windowedSinc(subSampleSteps*n + 1);
|
|
491
489
|
|
|
492
|
-
|
|
490
|
+
audioapi::dsp::Kaiser::withBandwidth(kaiserBandwidth, false).apply(windowedSinc.data(), windowedSinc.size());
|
|
493
491
|
|
|
494
492
|
for (size_t i = 0; i < windowedSinc.size(); ++i) {
|
|
495
493
|
double x = (i - centreIndex)*scaleFactor;
|
|
@@ -504,7 +502,7 @@ namespace delay {
|
|
|
504
502
|
}
|
|
505
503
|
|
|
506
504
|
if (minimumPhase) {
|
|
507
|
-
signalsmith::fft::FFT<Sample> fft(windowedSinc.
|
|
505
|
+
signalsmith::fft::FFT<Sample> fft(windowedSinc.getSize()*2, 1);
|
|
508
506
|
windowedSinc.resize(fft.size(), 0);
|
|
509
507
|
std::vector<std::complex<Sample>> spectrum(fft.size());
|
|
510
508
|
std::vector<std::complex<Sample>> cepstrum(fft.size());
|
|
@@ -529,7 +527,7 @@ namespace delay {
|
|
|
529
527
|
}
|
|
530
528
|
fft.ifft(spectrum, cepstrum);
|
|
531
529
|
windowedSinc.resize(subSampleSteps*n + 1);
|
|
532
|
-
|
|
530
|
+
windowedSinc.shrink_to_fit();
|
|
533
531
|
for (size_t i = 0; i < windowedSinc.size(); ++i) {
|
|
534
532
|
windowedSinc[i] = cepstrum[i].real()*scaling;
|
|
535
533
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
#include <audioapi/libs/dsp/common.h>
|
|
2
|
-
|
|
3
1
|
#ifndef SIGNALSMITH_FFT_V5
|
|
4
2
|
#define SIGNALSMITH_FFT_V5
|
|
5
3
|
|
|
6
|
-
#include <audioapi/libs/
|
|
4
|
+
#include <audioapi/libs/signalsmith-stretch/perf.h>
|
|
5
|
+
#include <audioapi/core/Constants.h>
|
|
7
6
|
|
|
8
7
|
#include <vector>
|
|
9
8
|
#include <complex>
|
|
@@ -129,7 +128,7 @@ namespace signalsmith { namespace fft {
|
|
|
129
128
|
if (!foundStep) {
|
|
130
129
|
for (size_t i = 0; i < subLength; ++i) {
|
|
131
130
|
for (size_t f = 0; f < factor; ++f) {
|
|
132
|
-
double phase = 2*
|
|
131
|
+
double phase = 2*audioapi::PI*i*f/length;
|
|
133
132
|
complex twiddle = {V(std::cos(phase)), V(-std::sin(phase))};
|
|
134
133
|
twiddleVector.push_back(twiddle);
|
|
135
134
|
}
|
|
@@ -212,7 +211,7 @@ namespace signalsmith { namespace fft {
|
|
|
212
211
|
for (size_t f = 0; f < factor; ++f) {
|
|
213
212
|
complex sum = working[0];
|
|
214
213
|
for (size_t i = 1; i < factor; ++i) {
|
|
215
|
-
double phase = 2*
|
|
214
|
+
double phase = 2*audioapi::PI*f*i/factor;
|
|
216
215
|
complex twiddle = {V(std::cos(phase)), V(-std::sin(phase))};
|
|
217
216
|
sum += _fft_impl::complexMul<inverse>(working[i], twiddle);
|
|
218
217
|
}
|
|
@@ -431,13 +430,13 @@ namespace signalsmith { namespace fft {
|
|
|
431
430
|
size_t hhSize = size/4 + 1;
|
|
432
431
|
twiddlesMinusI.resize(hhSize);
|
|
433
432
|
for (size_t i = 0; i < hhSize; ++i) {
|
|
434
|
-
V rotPhase = -2*
|
|
433
|
+
V rotPhase = -2*audioapi::PI*(modified ? i + 0.5 : i)/size;
|
|
435
434
|
twiddlesMinusI[i] = {std::sin(rotPhase), -std::cos(rotPhase)};
|
|
436
435
|
}
|
|
437
436
|
if (modified) {
|
|
438
437
|
modifiedRotations.resize(size/2);
|
|
439
438
|
for (size_t i = 0; i < size/2; ++i) {
|
|
440
|
-
V rotPhase = -2*
|
|
439
|
+
V rotPhase = -2*audioapi::PI*i/size;
|
|
441
440
|
modifiedRotations[i] = {std::cos(rotPhase), std::sin(rotPhase)};
|
|
442
441
|
}
|
|
443
442
|
}
|
package/common/cpp/audioapi/libs/{signalsmith-stretch.h → signalsmith-stretch/signalsmith-stretch.h}
RENAMED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#ifndef SIGNALSMITH_STRETCH_H
|
|
2
2
|
#define SIGNALSMITH_STRETCH_H
|
|
3
3
|
|
|
4
|
-
#include <audioapi/libs/
|
|
5
|
-
#include <audioapi/libs/
|
|
6
|
-
#include <audioapi/libs/
|
|
7
|
-
SIGNALSMITH_DSP_VERSION_CHECK(1, 6, 0); // Check version is compatible
|
|
4
|
+
#include <audioapi/libs/signalsmith-stretch/spectral.h>
|
|
5
|
+
#include <audioapi/libs/signalsmith-stretch/delay.h>
|
|
6
|
+
#include <audioapi/libs/signalsmith-stretch/perf.h>
|
|
8
7
|
#include <vector>
|
|
9
8
|
#include <algorithm>
|
|
10
9
|
#include <functional>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
#include <audioapi/
|
|
1
|
+
#include <audioapi/core/Constants.h>
|
|
2
2
|
|
|
3
3
|
#ifndef SIGNALSMITH_DSP_SPECTRAL_H
|
|
4
4
|
#define SIGNALSMITH_DSP_SPECTRAL_H
|
|
5
5
|
|
|
6
|
-
#include <audioapi/libs/
|
|
7
|
-
#include <audioapi/libs/
|
|
8
|
-
#include <audioapi/libs/
|
|
9
|
-
|
|
6
|
+
#include <audioapi/libs/signalsmith-stretch/perf.h>
|
|
7
|
+
#include <audioapi/libs/signalsmith-stretch/fft.h>
|
|
8
|
+
#include <audioapi/libs/signalsmith-stretch/delay.h>
|
|
9
|
+
|
|
10
|
+
#include <audioapi/dsp/Windows.h>
|
|
10
11
|
|
|
11
12
|
#include <cmath>
|
|
12
13
|
|
|
@@ -76,7 +77,7 @@ namespace spectral {
|
|
|
76
77
|
/// Sets the size (using the default Blackman-Harris window)
|
|
77
78
|
void setSize(int size, int rotateSamples=0) {
|
|
78
79
|
setSize(size, [](double x) {
|
|
79
|
-
double phase = 2*
|
|
80
|
+
double phase = 2 * audioapi::PI * x;
|
|
80
81
|
// Blackman-Harris
|
|
81
82
|
return 0.35875 - 0.48829*std::cos(phase) + 0.14128*std::cos(phase*2) - 0.01168*std::cos(phase*3);
|
|
82
83
|
}, Sample(0.5), rotateSamples);
|
|
@@ -249,16 +250,12 @@ namespace spectral {
|
|
|
249
250
|
|
|
250
251
|
auto &window = fft.setSizeWindow(_fftSize, rotateToZero ? _windowSize/2 : 0);
|
|
251
252
|
if (windowShape == Window::kaiser) {
|
|
252
|
-
using Kaiser = ::signalsmith::windows::Kaiser;
|
|
253
253
|
/// Roughly optimal Kaiser for STFT analysis (forced to perfect reconstruction)
|
|
254
|
-
|
|
255
|
-
kaiser_.fill(window, _windowSize);
|
|
254
|
+
audioapi::dsp::Kaiser::withBandwidth(_windowSize/_interval, true).apply(window.data(), _windowSize);
|
|
256
255
|
} else {
|
|
257
|
-
|
|
258
|
-
auto confined = Confined::withBandwidth(_windowSize/double(_interval));
|
|
259
|
-
confined.fill(window, _windowSize);
|
|
256
|
+
audioapi::dsp::ApproximateConfinedGaussian::withBandwidth(_windowSize/_interval).apply(window.data(), _windowSize);
|
|
260
257
|
}
|
|
261
|
-
|
|
258
|
+
audioapi::dsp::WindowFunction::forcePerfectReconstruction(window.data(), _windowSize, _interval);
|
|
262
259
|
|
|
263
260
|
// TODO: fill extra bits of an input buffer with NaN/Infinity, to break this, and then fix by adding zero-padding to WindowedFFT (as opposed to zero-valued window sections)
|
|
264
261
|
for (int i = _windowSize; i < _fftSize; ++i) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#include <audioapi/core/utils/AudioArray.h>
|
|
2
1
|
#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
|
+
dsp::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
|
+
dsp::multiplyByScalar(data_, value, data_, size_);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
float AudioArray::getMaxAbsValue() const {
|
|
65
|
-
return
|
|
65
|
+
return dsp::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
|
+
dsp::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>
|
|
4
2
|
#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
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
379
379
|
sourceLeft + sourceStart,
|
|
380
380
|
0.5f,
|
|
381
381
|
destinationData + destinationStart,
|
|
382
382
|
length);
|
|
383
|
-
|
|
383
|
+
dsp::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
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
405
405
|
sourceLeft + sourceStart,
|
|
406
406
|
0.25f,
|
|
407
407
|
destinationData + destinationStart,
|
|
408
408
|
length);
|
|
409
|
-
|
|
409
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
410
410
|
sourceRight + sourceStart,
|
|
411
411
|
0.25f,
|
|
412
412
|
destinationData + destinationStart,
|
|
413
413
|
length);
|
|
414
|
-
|
|
414
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
415
415
|
sourceSurroundLeft + sourceStart,
|
|
416
416
|
0.25f,
|
|
417
417
|
destinationData + destinationStart,
|
|
418
418
|
length);
|
|
419
|
-
|
|
419
|
+
dsp::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
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
442
442
|
sourceLeft + sourceStart,
|
|
443
443
|
SQRT_HALF,
|
|
444
444
|
destinationData + destinationStart,
|
|
445
445
|
length);
|
|
446
|
-
|
|
446
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
447
447
|
sourceRight + sourceStart,
|
|
448
448
|
SQRT_HALF,
|
|
449
449
|
destinationData + destinationStart,
|
|
450
450
|
length);
|
|
451
|
-
|
|
451
|
+
dsp::add(
|
|
452
452
|
sourceCenter + sourceStart,
|
|
453
453
|
destinationData + destinationStart,
|
|
454
454
|
destinationData + destinationStart,
|
|
455
455
|
length);
|
|
456
|
-
|
|
456
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
457
457
|
sourceSurroundLeft + sourceStart,
|
|
458
458
|
0.5f,
|
|
459
459
|
destinationData + destinationStart,
|
|
460
460
|
length);
|
|
461
|
-
|
|
461
|
+
dsp::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
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
485
485
|
sourceLeft + sourceStart,
|
|
486
486
|
0.5f,
|
|
487
487
|
destinationLeft + destinationStart,
|
|
488
488
|
length);
|
|
489
|
-
|
|
489
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
490
490
|
sourceSurroundLeft + sourceStart,
|
|
491
491
|
0.5f,
|
|
492
492
|
destinationLeft + destinationStart,
|
|
493
493
|
length);
|
|
494
494
|
|
|
495
|
-
|
|
495
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
496
496
|
sourceRight + sourceStart,
|
|
497
497
|
0.5f,
|
|
498
498
|
destinationRight + destinationStart,
|
|
499
499
|
length);
|
|
500
|
-
|
|
500
|
+
dsp::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
|
+
dsp::add(
|
|
525
525
|
sourceLeft + sourceStart,
|
|
526
526
|
destinationLeft + destinationStart,
|
|
527
527
|
destinationLeft + destinationStart,
|
|
528
528
|
length);
|
|
529
|
-
|
|
529
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
530
530
|
sourceCenter + sourceStart,
|
|
531
531
|
SQRT_HALF,
|
|
532
532
|
destinationLeft + destinationStart,
|
|
533
533
|
length);
|
|
534
|
-
|
|
534
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
535
535
|
sourceSurroundLeft + sourceStart,
|
|
536
536
|
SQRT_HALF,
|
|
537
537
|
destinationLeft + destinationStart,
|
|
538
538
|
length);
|
|
539
539
|
|
|
540
|
-
|
|
540
|
+
dsp::add(
|
|
541
541
|
sourceRight + sourceStart,
|
|
542
542
|
destinationRight + destinationStart,
|
|
543
543
|
destinationRight + destinationStart,
|
|
544
544
|
length);
|
|
545
|
-
|
|
545
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
546
546
|
sourceCenter + sourceStart,
|
|
547
547
|
SQRT_HALF,
|
|
548
548
|
destinationRight + destinationStart,
|
|
549
549
|
length);
|
|
550
|
-
|
|
550
|
+
dsp::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
|
+
dsp::add(
|
|
580
580
|
sourceLeft + sourceStart,
|
|
581
581
|
destinationLeft + destinationStart,
|
|
582
582
|
destinationLeft + destinationStart,
|
|
583
583
|
length);
|
|
584
|
-
|
|
584
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
585
585
|
sourceCenter, SQRT_HALF, destinationLeft + destinationStart, length);
|
|
586
586
|
|
|
587
|
-
|
|
587
|
+
dsp::add(
|
|
588
588
|
sourceRight + sourceStart,
|
|
589
589
|
destinationRight + destinationStart,
|
|
590
590
|
destinationRight + destinationStart,
|
|
591
591
|
length);
|
|
592
|
-
|
|
592
|
+
dsp::multiplyByScalarThenAddToOutput(
|
|
593
593
|
sourceCenter, SQRT_HALF, destinationRight + destinationStart, length);
|
|
594
594
|
|
|
595
|
-
|
|
595
|
+
dsp::add(
|
|
596
596
|
sourceSurroundLeft + sourceStart,
|
|
597
597
|
destinationSurroundLeft + destinationStart,
|
|
598
598
|
destinationSurroundLeft + destinationStart,
|
|
599
599
|
length);
|
|
600
|
-
|
|
600
|
+
dsp::add(
|
|
601
601
|
sourceSurroundRight + sourceStart,
|
|
602
602
|
destinationSurroundRight + destinationStart,
|
|
603
603
|
destinationSurroundRight + destinationStart,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#define MINIAUDIO_IMPLEMENTATION
|
|
2
|
-
#import <audioapi/libs/miniaudio.h>
|
|
2
|
+
#import <audioapi/libs/miniaudio/miniaudio.h>
|
|
3
3
|
|
|
4
|
-
#include <audioapi/core/utils/AudioArray.h>
|
|
5
|
-
#include <audioapi/core/utils/AudioBus.h>
|
|
6
4
|
#include <audioapi/core/utils/AudioDecoder.h>
|
|
5
|
+
#include <audioapi/utils/AudioArray.h>
|
|
6
|
+
#include <audioapi/utils/AudioBus.h>
|
|
7
7
|
|
|
8
8
|
namespace audioapi {
|
|
9
9
|
|
|
@@ -14,11 +14,14 @@ typedef void (^RenderAudioBlock)(AudioBufferList *outputBuffer, int numFrames);
|
|
|
14
14
|
@property (nonatomic, strong) AVAudioSourceNode *sourceNode;
|
|
15
15
|
@property (nonatomic, copy) RenderAudioBlock renderAudio;
|
|
16
16
|
@property (nonatomic, assign) float sampleRate;
|
|
17
|
+
@property (nonatomic, assign) int channelCount;
|
|
17
18
|
@property (nonatomic, assign) bool isRunning;
|
|
18
19
|
|
|
19
|
-
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio;
|
|
20
|
+
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio channelCount:(int)channelCount;
|
|
20
21
|
|
|
21
|
-
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio
|
|
22
|
+
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio
|
|
23
|
+
sampleRate:(float)sampleRate
|
|
24
|
+
channelCount:(int)channelCount;
|
|
22
25
|
|
|
23
26
|
- (float)getSampleRate;
|
|
24
27
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
@implementation AudioPlayer
|
|
4
4
|
|
|
5
|
-
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio
|
|
5
|
+
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio channelCount:(int)channelCount
|
|
6
6
|
{
|
|
7
7
|
if (self = [super init]) {
|
|
8
8
|
self.renderAudio = [renderAudio copy];
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
[self setupAndInitNotificationHandlers];
|
|
15
15
|
|
|
16
16
|
self.sampleRate = [self.audioSession sampleRate];
|
|
17
|
+
self.channelCount = channelCount;
|
|
17
18
|
|
|
18
|
-
_format = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:self.sampleRate channels:
|
|
19
|
+
_format = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:self.sampleRate channels:self.channelCount];
|
|
19
20
|
|
|
20
21
|
__weak typeof(self) weakSelf = self;
|
|
21
22
|
_sourceNode = [[AVAudioSourceNode alloc] initWithFormat:self.format
|
|
@@ -34,7 +35,9 @@
|
|
|
34
35
|
return self;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio
|
|
38
|
+
- (instancetype)initWithRenderAudioBlock:(RenderAudioBlock)renderAudio
|
|
39
|
+
sampleRate:(float)sampleRate
|
|
40
|
+
channelCount:(int)channelCount
|
|
38
41
|
{
|
|
39
42
|
if (self = [super init]) {
|
|
40
43
|
self.renderAudio = [renderAudio copy];
|
|
@@ -46,8 +49,9 @@
|
|
|
46
49
|
[self setupAndInitNotificationHandlers];
|
|
47
50
|
|
|
48
51
|
self.sampleRate = sampleRate;
|
|
52
|
+
self.channelCount = channelCount;
|
|
49
53
|
|
|
50
|
-
_format = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:self.sampleRate channels:
|
|
54
|
+
_format = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:self.sampleRate channels:self.channelCount];
|
|
51
55
|
|
|
52
56
|
__weak typeof(self) weakSelf = self;
|
|
53
57
|
_sourceNode = [[AVAudioSourceNode alloc] initWithFormat:self.format
|
|
@@ -119,7 +123,7 @@
|
|
|
119
123
|
frameCount:(AVAudioFrameCount)frameCount
|
|
120
124
|
outputData:(AudioBufferList *)outputData
|
|
121
125
|
{
|
|
122
|
-
if (outputData->mNumberBuffers <
|
|
126
|
+
if (outputData->mNumberBuffers < self.channelCount) {
|
|
123
127
|
return noErr; // Ensure we have stereo output
|
|
124
128
|
}
|
|
125
129
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#import <AVFoundation/AVFoundation.h>
|
|
2
2
|
|
|
3
3
|
#include <audioapi/core/Constants.h>
|
|
4
|
-
#include <audioapi/core/utils/AudioArray.h>
|
|
5
|
-
#include <audioapi/core/utils/AudioBus.h>
|
|
6
4
|
#include <audioapi/ios/core/IOSAudioPlayer.h>
|
|
5
|
+
#include <audioapi/utils/AudioArray.h>
|
|
6
|
+
#include <audioapi/utils/AudioBus.h>
|
|
7
7
|
|
|
8
8
|
namespace audioapi {
|
|
9
9
|
|
|
10
10
|
IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus>, int)> &renderAudio)
|
|
11
|
-
: renderAudio_(renderAudio), audioBus_(0)
|
|
11
|
+
: channelCount_(2), renderAudio_(renderAudio), audioBus_(0)
|
|
12
12
|
{
|
|
13
13
|
RenderAudioBlock renderAudioBlock = ^(AudioBufferList *outputData, int numFrames) {
|
|
14
14
|
int processedFrames = 0;
|
|
@@ -18,7 +18,7 @@ IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus
|
|
|
18
18
|
renderAudio_(audioBus_, framesToProcess);
|
|
19
19
|
|
|
20
20
|
// TODO: optimize this with SIMD?
|
|
21
|
-
for (int channel = 0; channel <
|
|
21
|
+
for (int channel = 0; channel < channelCount_; channel += 1) {
|
|
22
22
|
float *outputChannel = (float *)outputData->mBuffers[channel].mData;
|
|
23
23
|
auto *inputChannel = audioBus_->getChannel(channel)->getData();
|
|
24
24
|
|
|
@@ -31,12 +31,12 @@ IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus
|
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
audioPlayer_ = [[AudioPlayer alloc] initWithRenderAudioBlock:renderAudioBlock];
|
|
35
|
-
audioBus_ = std::make_shared<AudioBus>(RENDER_QUANTUM_SIZE,
|
|
34
|
+
audioPlayer_ = [[AudioPlayer alloc] initWithRenderAudioBlock:renderAudioBlock channelCount:channelCount_];
|
|
35
|
+
audioBus_ = std::make_shared<AudioBus>(RENDER_QUANTUM_SIZE, channelCount_, getSampleRate());
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus>, int)> &renderAudio, float sampleRate)
|
|
39
|
-
: renderAudio_(renderAudio), audioBus_(0)
|
|
39
|
+
: channelCount_(2), renderAudio_(renderAudio), audioBus_(0)
|
|
40
40
|
{
|
|
41
41
|
RenderAudioBlock renderAudioBlock = ^(AudioBufferList *outputData, int numFrames) {
|
|
42
42
|
int processedFrames = 0;
|
|
@@ -46,7 +46,7 @@ IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus
|
|
|
46
46
|
renderAudio_(audioBus_, framesToProcess);
|
|
47
47
|
|
|
48
48
|
// TODO: optimize this with SIMD?
|
|
49
|
-
for (int channel = 0; channel <
|
|
49
|
+
for (int channel = 0; channel < channelCount_; channel += 1) {
|
|
50
50
|
float *outputChannel = (float *)outputData->mBuffers[channel].mData;
|
|
51
51
|
auto *inputChannel = audioBus_->getChannel(channel)->getData();
|
|
52
52
|
|
|
@@ -59,8 +59,10 @@ IOSAudioPlayer::IOSAudioPlayer(const std::function<void(std::shared_ptr<AudioBus
|
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
audioPlayer_ = [[AudioPlayer alloc] initWithRenderAudioBlock:renderAudioBlock
|
|
63
|
-
|
|
62
|
+
audioPlayer_ = [[AudioPlayer alloc] initWithRenderAudioBlock:renderAudioBlock
|
|
63
|
+
sampleRate:sampleRate
|
|
64
|
+
channelCount:channelCount_];
|
|
65
|
+
audioBus_ = std::make_shared<AudioBus>(RENDER_QUANTUM_SIZE, channelCount_, getSampleRate());
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
IOSAudioPlayer::~IOSAudioPlayer()
|