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
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <audioapi/HostObjects/AudioNodeHostObject.h>
|
|
4
|
-
#include <audioapi/HostObjects/AudioParamHostObject.h>
|
|
5
|
-
#include <audioapi/core/effects/StretcherNode.h>
|
|
6
|
-
|
|
7
|
-
#include <memory>
|
|
8
|
-
#include <vector>
|
|
9
|
-
|
|
10
|
-
namespace audioapi {
|
|
11
|
-
|
|
12
|
-
using namespace facebook;
|
|
13
|
-
|
|
14
|
-
class StretcherNodeHostObject : public AudioNodeHostObject {
|
|
15
|
-
public:
|
|
16
|
-
explicit StretcherNodeHostObject(const std::shared_ptr<StretcherNode> &node): AudioNodeHostObject(node) {
|
|
17
|
-
addGetters(JSI_EXPORT_PROPERTY_GETTER(StretcherNodeHostObject, rate),
|
|
18
|
-
JSI_EXPORT_PROPERTY_GETTER(StretcherNodeHostObject, semitones));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
JSI_PROPERTY_GETTER(rate) {
|
|
22
|
-
auto stretcherNode = std::static_pointer_cast<StretcherNode>(node_);
|
|
23
|
-
auto rateParam =
|
|
24
|
-
std::make_shared<AudioParamHostObject>(stretcherNode->getRateParam());
|
|
25
|
-
return jsi::Object::createFromHostObject(runtime, rateParam);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
JSI_PROPERTY_GETTER(semitones) {
|
|
29
|
-
auto stretcherNode = std::static_pointer_cast<StretcherNode>(node_);
|
|
30
|
-
auto semitonesParam =
|
|
31
|
-
std::make_shared<AudioParamHostObject>(stretcherNode->getSemitonesParam());
|
|
32
|
-
return jsi::Object::createFromHostObject(runtime, semitonesParam);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
} // namespace audioapi
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
#include <audioapi/core/BaseAudioContext.h>
|
|
2
|
-
#include <audioapi/core/effects/StretcherNode.h>
|
|
3
|
-
#include <audioapi/core/utils/AudioArray.h>
|
|
4
|
-
#include <audioapi/core/utils/AudioBus.h>
|
|
5
|
-
|
|
6
|
-
namespace audioapi {
|
|
7
|
-
|
|
8
|
-
StretcherNode::StretcherNode(BaseAudioContext *context) : AudioNode(context) {
|
|
9
|
-
channelCountMode_ = ChannelCountMode::EXPLICIT;
|
|
10
|
-
rate_ = std::make_shared<AudioParam>(1.0, 0.0, 3.0);
|
|
11
|
-
semitones_ = std::make_shared<AudioParam>(0.0, -12.0, 12.0);
|
|
12
|
-
|
|
13
|
-
stretch_ =
|
|
14
|
-
std::make_shared<signalsmith::stretch::SignalsmithStretch<float>>();
|
|
15
|
-
stretch_->presetDefault(channelCount_, context->getSampleRate());
|
|
16
|
-
playbackRateBus_ = std::make_shared<AudioBus>(
|
|
17
|
-
RENDER_QUANTUM_SIZE * 3, channelCount_, context_->getSampleRate());
|
|
18
|
-
|
|
19
|
-
isInitialized_ = true;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
std::shared_ptr<AudioParam> StretcherNode::getRateParam() const {
|
|
23
|
-
return rate_;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
std::shared_ptr<AudioParam> StretcherNode::getSemitonesParam() const {
|
|
27
|
-
return semitones_;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
void StretcherNode::processNode(
|
|
31
|
-
const std::shared_ptr<AudioBus> &processingBus,
|
|
32
|
-
int framesToProcess) {
|
|
33
|
-
auto time = context_->getCurrentTime();
|
|
34
|
-
auto semitones = semitones_->getValueAtTime(time);
|
|
35
|
-
|
|
36
|
-
stretch_->setTransposeSemitones(semitones);
|
|
37
|
-
stretch_->process(
|
|
38
|
-
playbackRateBus_.get()[0],
|
|
39
|
-
framesNeededToStretch_,
|
|
40
|
-
audioBus_.get()[0],
|
|
41
|
-
framesToProcess);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
std::shared_ptr<AudioBus> StretcherNode::processAudio(
|
|
45
|
-
std::shared_ptr<AudioBus> outputBus,
|
|
46
|
-
int framesToProcess,
|
|
47
|
-
bool checkIsAlreadyProcessed) {
|
|
48
|
-
if (!isInitialized_) {
|
|
49
|
-
return outputBus;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (isAlreadyProcessed()) {
|
|
53
|
-
return audioBus_;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
auto time = context_->getCurrentTime();
|
|
57
|
-
|
|
58
|
-
auto rate = rate_->getValueAtTime(time);
|
|
59
|
-
framesNeededToStretch_ =
|
|
60
|
-
static_cast<int>(rate * static_cast<float>(framesToProcess));
|
|
61
|
-
|
|
62
|
-
playbackRateBus_->zero();
|
|
63
|
-
auto writeIndex = 0;
|
|
64
|
-
auto framesNeededToStretch = framesNeededToStretch_;
|
|
65
|
-
|
|
66
|
-
// Collecting frames needed to stretch
|
|
67
|
-
while (framesNeededToStretch > 0) {
|
|
68
|
-
auto framesToCopy = std::min(framesNeededToStretch, framesToProcess);
|
|
69
|
-
|
|
70
|
-
// Process inputs and return the bus with the most channels. We must not
|
|
71
|
-
// check if the node has already been processed, cause we need to process it
|
|
72
|
-
// multiple times in this case.
|
|
73
|
-
auto processingBus = processInputs(outputBus, framesToCopy, false);
|
|
74
|
-
|
|
75
|
-
// Apply channel count mode.
|
|
76
|
-
processingBus = applyChannelCountMode(processingBus);
|
|
77
|
-
|
|
78
|
-
// Mix all input buses into the processing bus.
|
|
79
|
-
mixInputsBuses(processingBus);
|
|
80
|
-
|
|
81
|
-
assert(processingBus != nullptr);
|
|
82
|
-
|
|
83
|
-
playbackRateBus_->copy(processingBus.get(), 0, writeIndex, framesToCopy);
|
|
84
|
-
|
|
85
|
-
writeIndex += framesToCopy;
|
|
86
|
-
framesNeededToStretch -= framesToCopy;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
processNode(audioBus_, framesToProcess);
|
|
90
|
-
|
|
91
|
-
return audioBus_;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
} // namespace audioapi
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <audioapi/libs/signalsmith-stretch.h>
|
|
4
|
-
#include <audioapi/core/AudioNode.h>
|
|
5
|
-
#include <audioapi/core/AudioParam.h>
|
|
6
|
-
|
|
7
|
-
#include <memory>
|
|
8
|
-
#include <string>
|
|
9
|
-
#include <cassert>
|
|
10
|
-
|
|
11
|
-
namespace audioapi {
|
|
12
|
-
class AudioBus;
|
|
13
|
-
|
|
14
|
-
class StretcherNode : public AudioNode {
|
|
15
|
-
public:
|
|
16
|
-
explicit StretcherNode(BaseAudioContext *context);
|
|
17
|
-
|
|
18
|
-
[[nodiscard]] std::shared_ptr<AudioParam> getRateParam() const;
|
|
19
|
-
[[nodiscard]] std::shared_ptr<AudioParam> getSemitonesParam() const;
|
|
20
|
-
|
|
21
|
-
protected:
|
|
22
|
-
void processNode(const std::shared_ptr<AudioBus>& processingBus, int framesToProcess) override;
|
|
23
|
-
std::shared_ptr<AudioBus> processAudio(std::shared_ptr<AudioBus> outputBus, int framesToProcess, bool checkIsAlreadyProcessed) override;
|
|
24
|
-
|
|
25
|
-
private:
|
|
26
|
-
// k-rate params
|
|
27
|
-
std::shared_ptr<AudioParam> rate_;
|
|
28
|
-
std::shared_ptr<AudioParam> semitones_;
|
|
29
|
-
|
|
30
|
-
std::shared_ptr<signalsmith::stretch::SignalsmithStretch<float>> stretch_;
|
|
31
|
-
std::shared_ptr<AudioBus> playbackRateBus_;
|
|
32
|
-
int framesNeededToStretch_ = RENDER_QUANTUM_SIZE;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
} // namespace audioapi
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
#include <audioapi/dsp/FFTFrame.h>
|
|
2
|
-
|
|
3
|
-
namespace audioapi {
|
|
4
|
-
#if defined(HAVE_ACCELERATE)
|
|
5
|
-
static std::unordered_map<size_t, FFTSetup> fftSetups_;
|
|
6
|
-
|
|
7
|
-
FFTFrame::FFTFrame(int size)
|
|
8
|
-
: size_(size), log2Size_(static_cast<int>(log2(size))) {
|
|
9
|
-
fftSetup_ = getFFTSetupForSize(log2Size_);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
FFTFrame::~FFTFrame() {}
|
|
13
|
-
|
|
14
|
-
FFTSetup FFTFrame::getFFTSetupForSize(size_t log2FFTSize) {
|
|
15
|
-
if (!fftSetups_.contains(log2FFTSize)) {
|
|
16
|
-
fftSetups_.emplace(
|
|
17
|
-
log2FFTSize, vDSP_create_fftsetup(log2FFTSize, FFT_RADIX2));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return fftSetups_.at(log2FFTSize);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
void FFTFrame::doFFT(float *data, float *realData, float *imaginaryData) {
|
|
24
|
-
frame_.realp = realData;
|
|
25
|
-
frame_.imagp = imaginaryData;
|
|
26
|
-
vDSP_ctoz(reinterpret_cast<DSPComplex *>(data), 2, &frame_, 1, size_ / 2);
|
|
27
|
-
vDSP_fft_zrip(fftSetup_, &frame_, 1, log2Size_, FFT_FORWARD);
|
|
28
|
-
|
|
29
|
-
VectorMath::multiplyByScalar(realData, 0.5f, realData, size_ / 2);
|
|
30
|
-
VectorMath::multiplyByScalar(imaginaryData, 0.5f, imaginaryData, size_ / 2);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
void FFTFrame::doInverseFFT(
|
|
34
|
-
float *data,
|
|
35
|
-
float *realData,
|
|
36
|
-
float *imaginaryData) {
|
|
37
|
-
frame_.realp = realData;
|
|
38
|
-
frame_.imagp = imaginaryData;
|
|
39
|
-
vDSP_fft_zrip(fftSetup_, &frame_, 1, log2Size_, FFT_INVERSE);
|
|
40
|
-
vDSP_ztoc(&frame_, 1, reinterpret_cast<DSPComplex *>(data), 2, size_ / 2);
|
|
41
|
-
|
|
42
|
-
// Scale the FFT data, beacuse of
|
|
43
|
-
// https://developer.apple.com/library/archive/documentation/Performance/Conceptual/vDSP_Programming_Guide/UsingFourierTransforms/UsingFourierTransforms.html#//apple_ref/doc/uid/TP40005147-CH3-15892
|
|
44
|
-
VectorMath::multiplyByScalar(
|
|
45
|
-
data, 1.0f / static_cast<float>(size_), data, size_);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
#elif defined(ANDROID)
|
|
49
|
-
|
|
50
|
-
FFTFrame::FFTFrame(int size)
|
|
51
|
-
: size_(size), log2Size_(static_cast<int>(log2(size))) {
|
|
52
|
-
pffftSetup_ = pffft_new_setup(size_, PFFFT_REAL);
|
|
53
|
-
work_ = (float *)pffft_aligned_malloc(size_ * sizeof(float));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
FFTFrame::~FFTFrame() {
|
|
57
|
-
pffft_destroy_setup(pffftSetup_);
|
|
58
|
-
pffft_aligned_free(work_);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
void FFTFrame::doFFT(float *data, float *realData, float *imaginaryData) {
|
|
62
|
-
std::vector<std::complex<float>> out(size_);
|
|
63
|
-
pffft_transform_ordered(
|
|
64
|
-
pffftSetup_,
|
|
65
|
-
data,
|
|
66
|
-
reinterpret_cast<float *>(&out[0]),
|
|
67
|
-
work_,
|
|
68
|
-
PFFFT_FORWARD);
|
|
69
|
-
|
|
70
|
-
for (int i = 0; i < size_ / 2; ++i) {
|
|
71
|
-
realData[i] = out[i].real();
|
|
72
|
-
imaginaryData[i] = out[i].imag();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
VectorMath::multiplyByScalar(realData, 0.5f, realData, size_ / 2);
|
|
76
|
-
VectorMath::multiplyByScalar(imaginaryData, 0.5f, imaginaryData, size_ / 2);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
void FFTFrame::doInverseFFT(
|
|
80
|
-
float *data,
|
|
81
|
-
float *realData,
|
|
82
|
-
float *imaginaryData) {
|
|
83
|
-
std::vector<std::complex<float>> out(size_ / 2);
|
|
84
|
-
for (int i = 0; i < size_ / 2; i++) {
|
|
85
|
-
out[i] = {realData[i], imaginaryData[i]};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
pffft_transform_ordered(
|
|
89
|
-
pffftSetup_,
|
|
90
|
-
reinterpret_cast<float *>(&out[0]),
|
|
91
|
-
data,
|
|
92
|
-
work_,
|
|
93
|
-
PFFFT_BACKWARD);
|
|
94
|
-
|
|
95
|
-
VectorMath::multiplyByScalar(
|
|
96
|
-
data, 1.0f / static_cast<float>(size_), data, size_);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
#endif
|
|
100
|
-
} // namespace audioapi
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (C) 2010 Google Inc. All rights reserved.
|
|
3
|
-
*
|
|
4
|
-
* Redistribution and use in source and binary forms, with or without
|
|
5
|
-
* modification, are permitted provided that the following conditions
|
|
6
|
-
* are met:
|
|
7
|
-
*
|
|
8
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
9
|
-
* notice, this list of conditions and the following disclaimer.
|
|
10
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
11
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
12
|
-
* documentation and/or other materials provided with the distribution.
|
|
13
|
-
* 3. Neither the name of Apple Inc. ("Apple") nor the names of
|
|
14
|
-
* its contributors may be used to endorse or promote products derived
|
|
15
|
-
* from this software without specific prior written permission.
|
|
16
|
-
*
|
|
17
|
-
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
|
18
|
-
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
-
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
-
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
|
21
|
-
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
22
|
-
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
-
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
24
|
-
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
25
|
-
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
26
|
-
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
#pragma once
|
|
30
|
-
|
|
31
|
-
#include <audioapi/dsp/VectorMath.h>
|
|
32
|
-
|
|
33
|
-
#include <algorithm>
|
|
34
|
-
#include <cmath>
|
|
35
|
-
#include <utility>
|
|
36
|
-
#include <unordered_map>
|
|
37
|
-
#include <complex>
|
|
38
|
-
|
|
39
|
-
#if defined(HAVE_ACCELERATE)
|
|
40
|
-
#include <Accelerate/Accelerate.h>
|
|
41
|
-
#endif
|
|
42
|
-
|
|
43
|
-
#if defined(ANDROID)
|
|
44
|
-
#include <audioapi/android/libs/pffft.h>
|
|
45
|
-
#endif
|
|
46
|
-
|
|
47
|
-
namespace audioapi {
|
|
48
|
-
|
|
49
|
-
class FFTFrame {
|
|
50
|
-
public:
|
|
51
|
-
explicit FFTFrame(int size);
|
|
52
|
-
~FFTFrame();
|
|
53
|
-
|
|
54
|
-
void doFFT(float *data, float *realData, float *imaginaryData);
|
|
55
|
-
void doInverseFFT(float *data, float *realData, float *imaginaryData);
|
|
56
|
-
|
|
57
|
-
private:
|
|
58
|
-
int size_;
|
|
59
|
-
int log2Size_;
|
|
60
|
-
|
|
61
|
-
#if defined(HAVE_ACCELERATE)
|
|
62
|
-
FFTSetup fftSetup_;
|
|
63
|
-
DSPSplitComplex frame_;
|
|
64
|
-
|
|
65
|
-
static FFTSetup getFFTSetupForSize(size_t log2FFTSize);
|
|
66
|
-
#endif
|
|
67
|
-
|
|
68
|
-
#if defined(ANDROID)
|
|
69
|
-
PFFFT_Setup *pffftSetup_;
|
|
70
|
-
float *work_;
|
|
71
|
-
#endif
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
} // namespace audioapi
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
#ifndef SIGNALSMITH_DSP_COMMON_H
|
|
2
|
-
#define SIGNALSMITH_DSP_COMMON_H
|
|
3
|
-
|
|
4
|
-
#if defined(__FAST_MATH__) && (__apple_build_version__ >= 16000000) && (__apple_build_version__ <= 16000099)
|
|
5
|
-
# error Apple Clang 16.0.0 generates incorrect SIMD for ARM. If you HAVE to use this version of Clang, turn off -ffast-math.
|
|
6
|
-
#endif
|
|
7
|
-
|
|
8
|
-
#ifndef M_PI
|
|
9
|
-
#define M_PI 3.14159265358979323846264338327950288
|
|
10
|
-
#endif
|
|
11
|
-
|
|
12
|
-
namespace signalsmith {
|
|
13
|
-
/** @defgroup Common Common
|
|
14
|
-
@brief Definitions and helper classes used by the rest of the library
|
|
15
|
-
|
|
16
|
-
@{
|
|
17
|
-
@file
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
#define SIGNALSMITH_DSP_VERSION_MAJOR 1
|
|
21
|
-
#define SIGNALSMITH_DSP_VERSION_MINOR 6
|
|
22
|
-
#define SIGNALSMITH_DSP_VERSION_PATCH 1
|
|
23
|
-
#define SIGNALSMITH_DSP_VERSION_STRING "1.6.1"
|
|
24
|
-
|
|
25
|
-
/** Version compatability check.
|
|
26
|
-
\code{.cpp}
|
|
27
|
-
static_assert(signalsmith::version(1, 4, 1), "version check");
|
|
28
|
-
\endcode
|
|
29
|
-
... or use the equivalent `SIGNALSMITH_DSP_VERSION_CHECK`.
|
|
30
|
-
Major versions are not compatible with each other. Minor and patch versions are backwards-compatible.
|
|
31
|
-
*/
|
|
32
|
-
constexpr bool versionCheck(int major, int minor, int patch=0) {
|
|
33
|
-
return major == SIGNALSMITH_DSP_VERSION_MAJOR
|
|
34
|
-
&& (SIGNALSMITH_DSP_VERSION_MINOR > minor
|
|
35
|
-
|| (SIGNALSMITH_DSP_VERSION_MINOR == minor && SIGNALSMITH_DSP_VERSION_PATCH >= patch));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/// Check the library version is compatible (semver).
|
|
39
|
-
#define SIGNALSMITH_DSP_VERSION_CHECK(major, minor, patch) \
|
|
40
|
-
static_assert(::signalsmith::versionCheck(major, minor, patch), "signalsmith library version is " SIGNALSMITH_DSP_VERSION_STRING);
|
|
41
|
-
|
|
42
|
-
/** @} */
|
|
43
|
-
} // signalsmith::
|
|
44
|
-
#else
|
|
45
|
-
// If we've already included it, check it's the same version
|
|
46
|
-
static_assert(SIGNALSMITH_DSP_VERSION_MAJOR == 1 && SIGNALSMITH_DSP_VERSION_MINOR == 6 && SIGNALSMITH_DSP_VERSION_PATCH == 1, "multiple versions of the Signalsmith DSP library");
|
|
47
|
-
#endif // include guard
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
#include <audioapi/libs/dsp/common.h>
|
|
2
|
-
|
|
3
|
-
#ifndef SIGNALSMITH_DSP_WINDOWS_H
|
|
4
|
-
#define SIGNALSMITH_DSP_WINDOWS_H
|
|
5
|
-
|
|
6
|
-
#include <cmath>
|
|
7
|
-
#include <algorithm>
|
|
8
|
-
|
|
9
|
-
namespace signalsmith {
|
|
10
|
-
namespace windows {
|
|
11
|
-
/** @defgroup Windows Window functions
|
|
12
|
-
@brief Windows for spectral analysis
|
|
13
|
-
|
|
14
|
-
These are generally double-precision, because they are mostly calculated during setup/reconfiguring, not real-time code.
|
|
15
|
-
|
|
16
|
-
@{
|
|
17
|
-
@file
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/** @brief The Kaiser window (almost) maximises the energy in the main-lobe compared to the side-lobes.
|
|
21
|
-
|
|
22
|
-
Kaiser windows can be constructing using the shape-parameter (beta) or using the static `with???()` methods.*/
|
|
23
|
-
class Kaiser {
|
|
24
|
-
// I_0(x)=\sum_{k=0}^{N}\frac{x^{2k}}{(k!)^2\cdot4^k}
|
|
25
|
-
inline static double bessel0(double x) {
|
|
26
|
-
const double significanceLimit = 1e-4;
|
|
27
|
-
double result = 0;
|
|
28
|
-
double term = 1;
|
|
29
|
-
double m = 0;
|
|
30
|
-
while (term > significanceLimit) {
|
|
31
|
-
result += term;
|
|
32
|
-
++m;
|
|
33
|
-
term *= (x*x)/(4*m*m);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return result;
|
|
37
|
-
}
|
|
38
|
-
double beta;
|
|
39
|
-
double invB0;
|
|
40
|
-
|
|
41
|
-
static double heuristicBandwidth(double bandwidth) {
|
|
42
|
-
// Good peaks
|
|
43
|
-
//return bandwidth + 8/((bandwidth + 3)*(bandwidth + 3));
|
|
44
|
-
// Good average
|
|
45
|
-
//return bandwidth + 14/((bandwidth + 2.5)*(bandwidth + 2.5));
|
|
46
|
-
// Compromise
|
|
47
|
-
return bandwidth + 8/((bandwidth + 3)*(bandwidth + 3)) + 0.25*std::max(3 - bandwidth, 0.0);
|
|
48
|
-
}
|
|
49
|
-
public:
|
|
50
|
-
/// Set up a Kaiser window with a given shape. `beta` is `pi*alpha` (since there is ambiguity about shape parameters)
|
|
51
|
-
Kaiser(double beta) : beta(beta), invB0(1/bessel0(beta)) {}
|
|
52
|
-
|
|
53
|
-
/// @name Bandwidth methods
|
|
54
|
-
/// @{
|
|
55
|
-
static Kaiser withBandwidth(double bandwidth, bool heuristicOptimal=false) {
|
|
56
|
-
return Kaiser(bandwidthToBeta(bandwidth, heuristicOptimal));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/** Returns the Kaiser shape where the main lobe has the specified bandwidth (as a factor of 1/window-length).
|
|
60
|
-
\diagram{kaiser-windows.svg,You can see that the main lobe matches the specified bandwidth.}
|
|
61
|
-
If `heuristicOptimal` is enabled, the main lobe width is _slightly_ wider, improving both the peak and total energy - see `bandwidthToEnergyDb()` and `bandwidthToPeakDb()`.
|
|
62
|
-
\diagram{kaiser-windows-heuristic.svg, The main lobe extends to ±bandwidth/2.} */
|
|
63
|
-
static double bandwidthToBeta(double bandwidth, bool heuristicOptimal=false) {
|
|
64
|
-
if (heuristicOptimal) { // Heuristic based on numerical search
|
|
65
|
-
bandwidth = heuristicBandwidth(bandwidth);
|
|
66
|
-
}
|
|
67
|
-
bandwidth = std::max(bandwidth, 2.0);
|
|
68
|
-
double alpha = std::sqrt(bandwidth*bandwidth*0.25 - 1);
|
|
69
|
-
return alpha*M_PI;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
static double betaToBandwidth(double beta) {
|
|
73
|
-
double alpha = beta*(1.0/M_PI);
|
|
74
|
-
return 2*std::sqrt(alpha*alpha + 1);
|
|
75
|
-
}
|
|
76
|
-
/// @}
|
|
77
|
-
|
|
78
|
-
/// @name Performance methods
|
|
79
|
-
/// @{
|
|
80
|
-
/** @brief Total energy ratio (in dB) between side-lobes and the main lobe.
|
|
81
|
-
\diagram{windows-kaiser-sidelobe-energy.svg,Measured main/side lobe energy ratio. You can see that the heuristic improves performance for all bandwidth values.}
|
|
82
|
-
This function uses an approximation which is accurate to ±0.5dB for 2 ⩽ bandwidth ≤ 10, or 1 ⩽ bandwidth ≤ 10 when `heuristicOptimal`is enabled.
|
|
83
|
-
*/
|
|
84
|
-
static double bandwidthToEnergyDb(double bandwidth, bool heuristicOptimal=false) {
|
|
85
|
-
// Horrible heuristic fits
|
|
86
|
-
if (heuristicOptimal) {
|
|
87
|
-
if (bandwidth < 3) bandwidth += (3 - bandwidth)*0.5;
|
|
88
|
-
return 12.9 + -3/(bandwidth + 0.4) - 13.4*bandwidth + (bandwidth < 3)*-9.6*(bandwidth - 3);
|
|
89
|
-
}
|
|
90
|
-
return 10.5 + 15/(bandwidth + 0.4) - 13.25*bandwidth + (bandwidth < 2)*13*(bandwidth - 2);
|
|
91
|
-
}
|
|
92
|
-
static double energyDbToBandwidth(double energyDb, bool heuristicOptimal=false) {
|
|
93
|
-
double bw = 1;
|
|
94
|
-
while (bw < 20 && bandwidthToEnergyDb(bw, heuristicOptimal) > energyDb) {
|
|
95
|
-
bw *= 2;
|
|
96
|
-
}
|
|
97
|
-
double step = bw/2;
|
|
98
|
-
while (step > 0.0001) {
|
|
99
|
-
if (bandwidthToEnergyDb(bw, heuristicOptimal) > energyDb) {
|
|
100
|
-
bw += step;
|
|
101
|
-
} else {
|
|
102
|
-
bw -= step;
|
|
103
|
-
}
|
|
104
|
-
step *= 0.5;
|
|
105
|
-
}
|
|
106
|
-
return bw;
|
|
107
|
-
}
|
|
108
|
-
/** @brief Peak ratio (in dB) between side-lobes and the main lobe.
|
|
109
|
-
\diagram{windows-kaiser-sidelobe-peaks.svg,Measured main/side lobe peak ratio. You can see that the heuristic improves performance, except in the bandwidth range 1-2 where peak ratio was sacrificed to improve total energy ratio.}
|
|
110
|
-
This function uses an approximation which is accurate to ±0.5dB for 2 ⩽ bandwidth ≤ 9, or 0.5 ⩽ bandwidth ≤ 9 when `heuristicOptimal`is enabled.
|
|
111
|
-
*/
|
|
112
|
-
static double bandwidthToPeakDb(double bandwidth, bool heuristicOptimal=false) {
|
|
113
|
-
// Horrible heuristic fits
|
|
114
|
-
if (heuristicOptimal) {
|
|
115
|
-
return 14.2 - 20/(bandwidth + 1) - 13*bandwidth + (bandwidth < 3)*-6*(bandwidth - 3) + (bandwidth < 2.25)*5.8*(bandwidth - 2.25);
|
|
116
|
-
}
|
|
117
|
-
return 10 + 8/(bandwidth + 2) - 12.75*bandwidth + (bandwidth < 2)*4*(bandwidth - 2);
|
|
118
|
-
}
|
|
119
|
-
static double peakDbToBandwidth(double peakDb, bool heuristicOptimal=false) {
|
|
120
|
-
double bw = 1;
|
|
121
|
-
while (bw < 20 && bandwidthToPeakDb(bw, heuristicOptimal) > peakDb) {
|
|
122
|
-
bw *= 2;
|
|
123
|
-
}
|
|
124
|
-
double step = bw/2;
|
|
125
|
-
while (step > 0.0001) {
|
|
126
|
-
if (bandwidthToPeakDb(bw, heuristicOptimal) > peakDb) {
|
|
127
|
-
bw += step;
|
|
128
|
-
} else {
|
|
129
|
-
bw -= step;
|
|
130
|
-
}
|
|
131
|
-
step *= 0.5;
|
|
132
|
-
}
|
|
133
|
-
return bw;
|
|
134
|
-
}
|
|
135
|
-
/** @} */
|
|
136
|
-
|
|
137
|
-
/** Equivalent noise bandwidth (ENBW), a measure of frequency resolution.
|
|
138
|
-
\diagram{windows-kaiser-enbw.svg,Measured ENBW\, with and without the heuristic bandwidth adjustment.}
|
|
139
|
-
This approximation is accurate to ±0.05 up to a bandwidth of 22.
|
|
140
|
-
*/
|
|
141
|
-
static double bandwidthToEnbw(double bandwidth, bool heuristicOptimal=false) {
|
|
142
|
-
if (heuristicOptimal) bandwidth = heuristicBandwidth(bandwidth);
|
|
143
|
-
double b2 = std::max<double>(bandwidth - 2, 0);
|
|
144
|
-
return 1 + b2*(0.2 + b2*(-0.005 + b2*(-0.000005 + b2*0.0000022)));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/// Return the window's value for position in the range [0, 1]
|
|
148
|
-
double operator ()(double unit) {
|
|
149
|
-
double r = 2*unit - 1;
|
|
150
|
-
double arg = std::sqrt(1 - r*r);
|
|
151
|
-
return bessel0(beta*arg)*invB0;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/// Fills an arbitrary container with a Kaiser window
|
|
155
|
-
template<typename Data>
|
|
156
|
-
void fill(Data &&data, int size) const {
|
|
157
|
-
double invSize = 1.0/size;
|
|
158
|
-
for (int i = 0; i < size; ++i) {
|
|
159
|
-
double r = (2*i + 1)*invSize - 1;
|
|
160
|
-
double arg = std::sqrt(1 - r*r);
|
|
161
|
-
data[i] = bessel0(beta*arg)*invB0;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
/** @brief The Approximate Confined Gaussian window is (almost) optimal
|
|
167
|
-
|
|
168
|
-
ACG windows can be constructing using the shape-parameter (sigma) or using the static `with???()` methods.*/
|
|
169
|
-
class ApproximateConfinedGaussian {
|
|
170
|
-
double gaussianFactor;
|
|
171
|
-
|
|
172
|
-
double gaussian(double x) const {
|
|
173
|
-
return std::exp(-x*x*gaussianFactor);
|
|
174
|
-
}
|
|
175
|
-
public:
|
|
176
|
-
/// Heuristic map from bandwidth to the appropriately-optimal sigma
|
|
177
|
-
static double bandwidthToSigma(double bandwidth) {
|
|
178
|
-
return 0.3/std::sqrt(bandwidth);
|
|
179
|
-
}
|
|
180
|
-
static ApproximateConfinedGaussian withBandwidth(double bandwidth) {
|
|
181
|
-
return ApproximateConfinedGaussian(bandwidthToSigma(bandwidth));
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
ApproximateConfinedGaussian(double sigma) : gaussianFactor(0.0625/(sigma*sigma)) {}
|
|
185
|
-
|
|
186
|
-
/// Fills an arbitrary container
|
|
187
|
-
template<typename Data>
|
|
188
|
-
void fill(Data &&data, int size) const {
|
|
189
|
-
double invSize = 1.0/size;
|
|
190
|
-
double offsetScale = gaussian(1)/(gaussian(3) + gaussian(-1));
|
|
191
|
-
double norm = 1/(gaussian(0) - 2*offsetScale*(gaussian(2)));
|
|
192
|
-
for (int i = 0; i < size; ++i) {
|
|
193
|
-
double r = (2*i + 1)*invSize - 1;
|
|
194
|
-
data[i] = norm*(gaussian(r) - offsetScale*(gaussian(r - 2) + gaussian(r + 2)));
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/** Forces STFT perfect-reconstruction (WOLA) on an existing window, for a given STFT interval.
|
|
200
|
-
For example, here are perfect-reconstruction versions of the approximately-optimal @ref Kaiser windows:
|
|
201
|
-
\diagram{kaiser-windows-heuristic-pr.svg,Note the lower overall energy\, and the pointy top for 2x bandwidth. Spectral performance is about the same\, though.}
|
|
202
|
-
*/
|
|
203
|
-
template<typename Data>
|
|
204
|
-
void forcePerfectReconstruction(Data &&data, int windowLength, int interval) {
|
|
205
|
-
for (int i = 0; i < interval; ++i) {
|
|
206
|
-
double sum2 = 0;
|
|
207
|
-
for (int index = i; index < windowLength; index += interval) {
|
|
208
|
-
sum2 += data[index]*data[index];
|
|
209
|
-
}
|
|
210
|
-
double factor = 1/std::sqrt(sum2);
|
|
211
|
-
for (int index = i; index < windowLength; index += interval) {
|
|
212
|
-
data[index] *= factor;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/** @} */
|
|
218
|
-
}} // signalsmith::windows
|
|
219
|
-
#endif // include guard
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import AudioNode from "./AudioNode.js";
|
|
4
|
-
import AudioParam from "./AudioParam.js";
|
|
5
|
-
export default class StretcherNode extends AudioNode {
|
|
6
|
-
constructor(context, stretcher) {
|
|
7
|
-
super(context, stretcher);
|
|
8
|
-
this.rate = new AudioParam(stretcher.rate);
|
|
9
|
-
this.semitones = new AudioParam(stretcher.semitones);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=StretcherNode.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["AudioNode","AudioParam","StretcherNode","constructor","context","stretcher","rate","semitones"],"sourceRoot":"../../../src","sources":["core/StretcherNode.ts"],"mappings":";;AACA,OAAOA,SAAS,MAAM,gBAAa;AACnC,OAAOC,UAAU,MAAM,iBAAc;AAGrC,eAAe,MAAMC,aAAa,SAASF,SAAS,CAAC;EAInDG,WAAWA,CAACC,OAAyB,EAAEC,SAAyB,EAAE;IAChE,KAAK,CAACD,OAAO,EAAEC,SAAS,CAAC;IACzB,IAAI,CAACC,IAAI,GAAG,IAAIL,UAAU,CAACI,SAAS,CAACC,IAAI,CAAC;IAC1C,IAAI,CAACC,SAAS,GAAG,IAAIN,UAAU,CAACI,SAAS,CAACE,SAAS,CAAC;EACtD;AACF","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["default","AudioBuffer","AudioBufferSourceNode","AudioContext","AudioDestinationNode","AudioNode","AnalyserNode","AudioParam","AudioScheduledSourceNode","BaseAudioContext","BiquadFilterNode","GainNode","OscillatorNode","StereoPannerNode","OscillatorType","BiquadFilterType","ChannelCountMode","ChannelInterpretation","ContextState","WindowType","PeriodicWaveConstraints","IndexSizeError","InvalidAccessError","InvalidStateError","RangeError","NotSupportedError"],"sourceRoot":"../../src","sources":["index.web.ts"],"mappings":";;AAAA,SAASA,OAAO,IAAIC,WAAW,QAAQ,2BAAwB;AAC/D,SAASD,OAAO,IAAIE,qBAAqB,QAAQ,qCAAkC;AACnF,SAASF,OAAO,IAAIG,YAAY,QAAQ,4BAAyB;AACjE,SAASH,OAAO,IAAII,oBAAoB,QAAQ,oCAAiC;AACjF,SAASJ,OAAO,IAAIK,SAAS,QAAQ,yBAAsB;AAC3D,SAASL,OAAO,IAAIM,YAAY,QAAQ,4BAAyB;AACjE,SAASN,OAAO,IAAIO,UAAU,QAAQ,0BAAuB;AAC7D,SAASP,OAAO,IAAIQ,wBAAwB,QAAQ,wCAAqC;AACzF,SAASR,OAAO,IAAIS,gBAAgB,QAAQ,gCAA6B;AACzE,SAAST,OAAO,IAAIU,gBAAgB,QAAQ,gCAA6B;AACzE,SAASV,OAAO,IAAIW,QAAQ,QAAQ,wBAAqB;AACzD,SAASX,OAAO,IAAIY,cAAc,QAAQ,8BAA2B;AACrE,SAASZ,OAAO,IAAIa,gBAAgB,QAAQ,gCAA6B;AAEzE,SACEC,cAAc,EACdC,gBAAgB,EAChBC,gBAAgB,EAChBC,qBAAqB,EACrBC,YAAY,EACZC,UAAU,EACVC,uBAAuB,QAClB,YAAS;AAEhB,SACEC,cAAc,EACdC,kBAAkB,EAClBC,iBAAiB,EACjBC,UAAU,EACVC,iBAAiB,QACZ,mBAAU","ignoreList":[]}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { IStretcherNode } from '../interfaces';
|
|
2
|
-
import AudioNode from './AudioNode';
|
|
3
|
-
import AudioParam from './AudioParam';
|
|
4
|
-
import BaseAudioContext from './BaseAudioContext';
|
|
5
|
-
export default class StretcherNode extends AudioNode {
|
|
6
|
-
readonly rate: AudioParam;
|
|
7
|
-
readonly semitones: AudioParam;
|
|
8
|
-
constructor(context: BaseAudioContext, stretcher: IStretcherNode);
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=StretcherNode.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"StretcherNode.d.ts","sourceRoot":"","sources":["../../../src/core/StretcherNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAElD,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,SAAS;IAClD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;gBAEnB,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc;CAKjE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../src/index.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACpF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACV,uBAAuB,GACxB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,iBAAiB,GAClB,MAAM,UAAU,CAAC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { IStretcherNode } from '../interfaces';
|
|
2
|
-
import AudioNode from './AudioNode';
|
|
3
|
-
import AudioParam from './AudioParam';
|
|
4
|
-
import BaseAudioContext from './BaseAudioContext';
|
|
5
|
-
|
|
6
|
-
export default class StretcherNode extends AudioNode {
|
|
7
|
-
readonly rate: AudioParam;
|
|
8
|
-
readonly semitones: AudioParam;
|
|
9
|
-
|
|
10
|
-
constructor(context: BaseAudioContext, stretcher: IStretcherNode) {
|
|
11
|
-
super(context, stretcher);
|
|
12
|
-
this.rate = new AudioParam(stretcher.rate);
|
|
13
|
-
this.semitones = new AudioParam(stretcher.semitones);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
File without changes
|
/package/{android/src/main/cpp/audioapi/android/libs → common/cpp/audioapi/libs/pffft}/pffft.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|