react-native-audio-api 0.11.0-nightly-141c86f-20251118 → 0.11.0-nightly-4e6f25c-20251119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +10 -16
- package/android/src/main/cpp/audioapi/android/OnLoad.cpp +1 -2
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +4 -4
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +11 -20
- package/android/src/main/cpp/audioapi/android/core/utils/AudioDecoder.cpp +24 -46
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +48 -78
- package/common/cpp/audioapi/HostObjects/AudioContextHostObject.cpp +20 -21
- package/common/cpp/audioapi/HostObjects/AudioNodeHostObject.cpp +3 -4
- package/common/cpp/audioapi/HostObjects/AudioParamHostObject.cpp +6 -8
- package/common/cpp/audioapi/HostObjects/AudioParamHostObject.h +2 -2
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +42 -78
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +1 -1
- package/common/cpp/audioapi/HostObjects/OfflineAudioContextHostObject.cpp +14 -18
- package/common/cpp/audioapi/HostObjects/OfflineAudioContextHostObject.h +3 -3
- package/common/cpp/audioapi/HostObjects/WorkletNodeHostObject.h +1 -2
- package/common/cpp/audioapi/HostObjects/WorkletProcessingNodeHostObject.h +1 -2
- package/common/cpp/audioapi/HostObjects/analysis/AnalyserNodeHostObject.cpp +10 -18
- package/common/cpp/audioapi/HostObjects/destinations/AudioDestinationNodeHostObject.h +2 -3
- package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.cpp +16 -28
- package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.h +1 -2
- package/common/cpp/audioapi/HostObjects/effects/ConvolverNodeHostObject.cpp +4 -6
- package/common/cpp/audioapi/HostObjects/effects/GainNodeHostObject.cpp +2 -2
- package/common/cpp/audioapi/HostObjects/effects/PeriodicWaveHostObject.h +1 -2
- package/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.cpp +2 -2
- package/common/cpp/audioapi/HostObjects/effects/StereoPannerNodeHostObject.h +1 -2
- package/common/cpp/audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.cpp +6 -12
- package/common/cpp/audioapi/HostObjects/events/AudioEventHandlerRegistryHostObject.h +7 -7
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +8 -10
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +1 -1
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.cpp +13 -27
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferBaseSourceNodeHostObject.h +11 -12
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.cpp +15 -22
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferHostObject.h +5 -7
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.cpp +7 -12
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferQueueSourceNodeHostObject.h +8 -9
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.cpp +16 -30
- package/common/cpp/audioapi/HostObjects/sources/AudioBufferSourceNodeHostObject.h +2 -4
- package/common/cpp/audioapi/HostObjects/sources/AudioScheduledSourceNodeHostObject.cpp +6 -10
- package/common/cpp/audioapi/HostObjects/sources/ConstantSourceNodeHostObject.cpp +2 -2
- package/common/cpp/audioapi/HostObjects/sources/ConstantSourceNodeHostObject.h +1 -2
- package/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.cpp +6 -8
- package/common/cpp/audioapi/HostObjects/sources/OscillatorNodeHostObject.h +1 -2
- package/common/cpp/audioapi/HostObjects/sources/RecorderAdapterNodeHostObject.h +4 -5
- package/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.cpp +2 -2
- package/common/cpp/audioapi/HostObjects/sources/StreamerNodeHostObject.h +5 -6
- package/common/cpp/audioapi/HostObjects/sources/WorkletSourceNodeHostObject.h +1 -2
- package/common/cpp/audioapi/HostObjects/utils/AudioDecoderHostObject.cpp +39 -60
- package/common/cpp/audioapi/HostObjects/utils/AudioStretcherHostObject.cpp +4 -8
- package/common/cpp/audioapi/core/AudioContext.cpp +4 -4
- package/common/cpp/audioapi/core/AudioContext.h +5 -2
- package/common/cpp/audioapi/core/AudioNode.cpp +13 -19
- package/common/cpp/audioapi/core/AudioNode.h +14 -7
- package/common/cpp/audioapi/core/AudioParam.cpp +66 -98
- package/common/cpp/audioapi/core/AudioParam.h +20 -12
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +22 -34
- package/common/cpp/audioapi/core/BaseAudioContext.h +19 -15
- package/common/cpp/audioapi/core/OfflineAudioContext.cpp +12 -17
- package/common/cpp/audioapi/core/OfflineAudioContext.h +10 -5
- package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +13 -21
- package/common/cpp/audioapi/core/analysis/AnalyserNode.h +8 -6
- package/common/cpp/audioapi/core/destinations/AudioDestinationNode.cpp +1 -0
- package/common/cpp/audioapi/core/destinations/AudioDestinationNode.h +5 -3
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +17 -36
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.h +2 -9
- package/common/cpp/audioapi/core/effects/ConvolverNode.cpp +18 -28
- package/common/cpp/audioapi/core/effects/ConvolverNode.h +19 -10
- package/common/cpp/audioapi/core/effects/GainNode.cpp +1 -0
- package/common/cpp/audioapi/core/effects/GainNode.h +3 -1
- package/common/cpp/audioapi/core/effects/PeriodicWave.cpp +22 -35
- package/common/cpp/audioapi/core/effects/PeriodicWave.h +4 -9
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +4 -5
- package/common/cpp/audioapi/core/effects/StereoPannerNode.h +4 -2
- package/common/cpp/audioapi/core/effects/WorkletNode.cpp +11 -13
- package/common/cpp/audioapi/core/effects/WorkletNode.h +15 -12
- package/common/cpp/audioapi/core/effects/WorkletProcessingNode.cpp +4 -4
- package/common/cpp/audioapi/core/effects/WorkletProcessingNode.h +15 -14
- package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +9 -8
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +4 -5
- package/common/cpp/audioapi/core/sources/AudioBuffer.cpp +4 -6
- package/common/cpp/audioapi/core/sources/AudioBuffer.h +4 -7
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +31 -53
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +35 -33
- package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +19 -20
- package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.h +38 -36
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +25 -40
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +3 -1
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +9 -9
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +3 -3
- package/common/cpp/audioapi/core/sources/ConstantSourceNode.cpp +3 -4
- package/common/cpp/audioapi/core/sources/ConstantSourceNode.h +3 -1
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +12 -23
- package/common/cpp/audioapi/core/sources/OscillatorNode.h +6 -4
- package/common/cpp/audioapi/core/sources/RecorderAdapterNode.cpp +3 -4
- package/common/cpp/audioapi/core/sources/RecorderAdapterNode.h +18 -16
- package/common/cpp/audioapi/core/sources/StreamerNode.cpp +7 -4
- package/common/cpp/audioapi/core/sources/StreamerNode.h +38 -30
- package/common/cpp/audioapi/core/sources/WorkletSourceNode.cpp +5 -7
- package/common/cpp/audioapi/core/sources/WorkletSourceNode.h +15 -13
- package/common/cpp/audioapi/core/types/AudioFormat.h +1 -11
- package/common/cpp/audioapi/core/utils/AudioDecoder.h +15 -6
- package/common/cpp/audioapi/core/utils/AudioNodeDestructor.cpp +5 -6
- package/common/cpp/audioapi/core/utils/AudioNodeDestructor.h +7 -10
- package/common/cpp/audioapi/core/utils/AudioNodeManager.cpp +13 -22
- package/common/cpp/audioapi/core/utils/AudioNodeManager.h +8 -11
- package/common/cpp/audioapi/core/utils/AudioParamEventQueue.cpp +3 -3
- package/common/cpp/audioapi/core/utils/AudioParamEventQueue.h +5 -5
- package/common/cpp/audioapi/core/utils/AudioStretcher.cpp +6 -6
- package/common/cpp/audioapi/core/utils/Constants.h +5 -3
- package/common/cpp/audioapi/core/utils/ParamChangeEvent.cpp +1 -0
- package/common/cpp/audioapi/core/utils/ParamChangeEvent.h +9 -9
- package/common/cpp/audioapi/core/utils/worklets/SafeIncludes.h +29 -34
- package/common/cpp/audioapi/core/utils/worklets/WorkletsRunner.cpp +14 -16
- package/common/cpp/audioapi/core/utils/worklets/WorkletsRunner.h +23 -19
- package/common/cpp/audioapi/dsp/AudioUtils.cpp +3 -9
- package/common/cpp/audioapi/dsp/AudioUtils.h +1 -1
- package/common/cpp/audioapi/dsp/Convolver.cpp +13 -25
- package/common/cpp/audioapi/dsp/Convolver.h +26 -24
- package/common/cpp/audioapi/dsp/FFT.cpp +1 -1
- package/common/cpp/audioapi/dsp/FFT.h +5 -13
- package/common/cpp/audioapi/dsp/VectorMath.cpp +9 -43
- package/common/cpp/audioapi/dsp/VectorMath.h +35 -8
- package/common/cpp/audioapi/dsp/Windows.cpp +4 -9
- package/common/cpp/audioapi/dsp/Windows.h +24 -23
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.cpp +12 -17
- package/common/cpp/audioapi/events/AudioEventHandlerRegistry.h +44 -39
- package/common/cpp/audioapi/events/IAudioEventHandlerRegistry.h +15 -7
- package/common/cpp/audioapi/jsi/AudioArrayBuffer.h +4 -5
- package/common/cpp/audioapi/jsi/JsiHostObject.cpp +11 -13
- package/common/cpp/audioapi/jsi/JsiHostObject.h +26 -33
- package/common/cpp/audioapi/jsi/JsiPromise.cpp +11 -21
- package/common/cpp/audioapi/jsi/JsiPromise.h +55 -46
- package/common/cpp/audioapi/jsi/RuntimeLifecycleMonitor.cpp +7 -10
- package/common/cpp/audioapi/jsi/RuntimeLifecycleMonitor.h +1 -3
- package/common/cpp/audioapi/utils/AudioArray.cpp +3 -8
- package/common/cpp/audioapi/utils/AudioArray.h +3 -11
- package/common/cpp/audioapi/utils/AudioBus.cpp +51 -149
- package/common/cpp/audioapi/utils/AudioBus.h +15 -15
- package/common/cpp/audioapi/utils/CircularAudioArray.cpp +6 -18
- package/common/cpp/audioapi/utils/CircularOverflowableAudioArray.cpp +6 -10
- package/common/cpp/audioapi/utils/CircularOverflowableAudioArray.h +2 -2
- package/common/cpp/test/src/AudioParamTest.cpp +3 -2
- package/common/cpp/test/src/AudioScheduledSourceTest.cpp +14 -35
- package/common/cpp/test/src/ConstantSourceTest.cpp +4 -6
- package/common/cpp/test/src/GainTest.cpp +3 -4
- package/common/cpp/test/src/MockAudioEventHandlerRegistry.h +19 -11
- package/common/cpp/test/src/OscillatorTest.cpp +1 -0
- package/common/cpp/test/src/StereoPannerTest.cpp +5 -8
- package/common/cpp/test/src/biquad/BiquadFilterChromium.cpp +10 -27
- package/common/cpp/test/src/biquad/BiquadFilterChromium.h +7 -6
- package/common/cpp/test/src/biquad/BiquadFilterTest.cpp +16 -28
- package/common/cpp/test/src/biquad/BiquadFilterTest.h +13 -6
- package/ios/audioapi/ios/AudioAPIModule.h +4 -6
- package/ios/audioapi/ios/AudioAPIModule.mm +31 -46
- package/ios/audioapi/ios/core/IOSAudioPlayer.mm +24 -33
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +1 -2
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +4 -6
- package/ios/audioapi/ios/core/NativeAudioPlayer.m +3 -5
- package/ios/audioapi/ios/core/NativeAudioRecorder.h +1 -2
- package/ios/audioapi/ios/core/NativeAudioRecorder.m +21 -33
- package/ios/audioapi/ios/core/utils/AudioDecoder.mm +17 -37
- package/ios/audioapi/ios/system/AudioEngine.h +2 -4
- package/ios/audioapi/ios/system/AudioEngine.mm +7 -19
- package/ios/audioapi/ios/system/AudioSessionManager.h +2 -4
- package/ios/audioapi/ios/system/AudioSessionManager.mm +17 -32
- package/ios/audioapi/ios/system/LockScreenManager.mm +73 -105
- package/ios/audioapi/ios/system/NotificationManager.mm +43 -68
- package/package.json +2 -2
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
#include <audioapi/utils/AudioArray.h>
|
|
6
6
|
#include <audioapi/utils/AudioBus.h>
|
|
7
7
|
#include <cstdint>
|
|
8
|
+
#include <memory>
|
|
9
|
+
#include <vector>
|
|
8
10
|
|
|
9
11
|
namespace audioapi {
|
|
10
12
|
|
|
@@ -43,8 +45,8 @@ std::shared_ptr<AudioBuffer> AudioStretcher::changePlaybackSpeed(
|
|
|
43
45
|
outputChannels,
|
|
44
46
|
0x1);
|
|
45
47
|
|
|
46
|
-
int maxOutputFrames =
|
|
47
|
-
stretcher, static_cast<int>(numFrames), 1 / playbackSpeed);
|
|
48
|
+
int maxOutputFrames =
|
|
49
|
+
stretch_output_capacity(stretcher, static_cast<int>(numFrames), 1 / playbackSpeed);
|
|
48
50
|
std::vector<int16_t> stretchedBuffer(maxOutputFrames * outputChannels);
|
|
49
51
|
|
|
50
52
|
int outputFrames = stretch_samples(
|
|
@@ -54,13 +56,11 @@ std::shared_ptr<AudioBuffer> AudioStretcher::changePlaybackSpeed(
|
|
|
54
56
|
stretchedBuffer.data(),
|
|
55
57
|
1 / playbackSpeed);
|
|
56
58
|
|
|
57
|
-
outputFrames +=
|
|
58
|
-
stretch_flush(stretcher, stretchedBuffer.data() + (outputFrames));
|
|
59
|
+
outputFrames += stretch_flush(stretcher, stretchedBuffer.data() + (outputFrames));
|
|
59
60
|
stretchedBuffer.resize(outputFrames * outputChannels);
|
|
60
61
|
stretch_deinit(stretcher);
|
|
61
62
|
|
|
62
|
-
auto audioBus =
|
|
63
|
-
std::make_shared<AudioBus>(outputFrames, outputChannels, sampleRate);
|
|
63
|
+
auto audioBus = std::make_shared<AudioBus>(outputFrames, outputChannels, sampleRate);
|
|
64
64
|
|
|
65
65
|
for (int ch = 0; ch < outputChannels; ++ch) {
|
|
66
66
|
auto channelData = audioBus->getChannel(ch)->getData();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <numbers>
|
|
4
3
|
#include <cmath>
|
|
5
4
|
#include <limits>
|
|
5
|
+
#include <numbers>
|
|
6
6
|
|
|
7
7
|
// https://webaudio.github.io/web-audio-api/
|
|
8
8
|
|
|
@@ -16,8 +16,10 @@ static constexpr float UPPER_FREQUENCY_LIMIT_DETECTION = 333.0f;
|
|
|
16
16
|
static constexpr float LOWER_FREQUENCY_LIMIT_DETECTION = 55.0f;
|
|
17
17
|
|
|
18
18
|
// general
|
|
19
|
-
static constexpr float MOST_POSITIVE_SINGLE_FLOAT =
|
|
20
|
-
|
|
19
|
+
static constexpr float MOST_POSITIVE_SINGLE_FLOAT =
|
|
20
|
+
static_cast<float>(std::numeric_limits<float>::max());
|
|
21
|
+
static constexpr float MOST_NEGATIVE_SINGLE_FLOAT =
|
|
22
|
+
static_cast<float>(std::numeric_limits<float>::lowest());
|
|
21
23
|
static float LOG2_MOST_POSITIVE_SINGLE_FLOAT = std::log2(MOST_POSITIVE_SINGLE_FLOAT);
|
|
22
24
|
static float LOG10_MOST_POSITIVE_SINGLE_FLOAT = std::log10(MOST_POSITIVE_SINGLE_FLOAT);
|
|
23
25
|
static constexpr float PI = std::numbers::pi_v<float>;
|
|
@@ -20,16 +20,16 @@ class ParamChangeEvent {
|
|
|
20
20
|
ParamChangeEventType type);
|
|
21
21
|
|
|
22
22
|
ParamChangeEvent(const ParamChangeEvent &other) = delete;
|
|
23
|
-
ParamChangeEvent&
|
|
23
|
+
ParamChangeEvent &operator=(const ParamChangeEvent &other) = delete;
|
|
24
24
|
|
|
25
25
|
explicit ParamChangeEvent(ParamChangeEvent &&other) noexcept
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
ParamChangeEvent&
|
|
26
|
+
: startTime_(other.startTime_),
|
|
27
|
+
endTime_(other.endTime_),
|
|
28
|
+
calculateValue_(std::move(other.calculateValue_)),
|
|
29
|
+
startValue_(other.startValue_),
|
|
30
|
+
endValue_(other.endValue_),
|
|
31
|
+
type_(other.type_) {}
|
|
32
|
+
ParamChangeEvent &operator=(ParamChangeEvent &&other) noexcept {
|
|
33
33
|
if (this != &other) {
|
|
34
34
|
startTime_ = other.startTime_;
|
|
35
35
|
endTime_ = other.endTime_;
|
|
@@ -53,7 +53,7 @@ class ParamChangeEvent {
|
|
|
53
53
|
[[nodiscard]] inline float getStartValue() const noexcept {
|
|
54
54
|
return startValue_;
|
|
55
55
|
}
|
|
56
|
-
[[nodiscard]] inline const std::function<float(double, double, float, float, double)
|
|
56
|
+
[[nodiscard]] inline const std::function<float(double, double, float, float, double)> &
|
|
57
57
|
getCalculateValue() const noexcept {
|
|
58
58
|
return calculateValue_;
|
|
59
59
|
}
|
|
@@ -2,28 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
#include <jsi/jsi.h>
|
|
4
4
|
|
|
5
|
-
#include <string>
|
|
6
5
|
#include <memory>
|
|
6
|
+
#include <string>
|
|
7
7
|
|
|
8
8
|
#if ANDROID
|
|
9
|
-
|
|
9
|
+
#include <fbjni/detail/Environment.h>
|
|
10
10
|
#endif
|
|
11
11
|
|
|
12
12
|
#ifndef RN_AUDIO_API_TEST
|
|
13
|
-
|
|
13
|
+
#define RN_AUDIO_API_TEST 0
|
|
14
14
|
#endif
|
|
15
15
|
|
|
16
16
|
#if RN_AUDIO_API_ENABLE_WORKLETS
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
#include <worklets/NativeModules/WorkletsModuleProxy.h>
|
|
18
|
+
#include <worklets/SharedItems/Serializable.h>
|
|
19
|
+
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
|
20
|
+
#if ANDROID
|
|
21
|
+
#include <worklets/android/WorkletsModule.h>
|
|
22
|
+
#endif
|
|
23
23
|
#else
|
|
24
24
|
|
|
25
25
|
#define RN_AUDIO_API_WORKLETS_DISABLED_ERROR \
|
|
26
|
-
std::runtime_error(
|
|
26
|
+
std::runtime_error( \
|
|
27
27
|
"Worklets are disabled. Please install react-native-worklets or check if you have supported version to enable these features.");
|
|
28
28
|
|
|
29
29
|
/// @brief Dummy implementation of worklets for non-worklet builds they should do nothing and mock necessary methods
|
|
@@ -36,28 +36,24 @@ class MessageQueueThread {};
|
|
|
36
36
|
class WorkletsModuleProxy {};
|
|
37
37
|
class WorkletRuntime {
|
|
38
38
|
public:
|
|
39
|
-
explicit WorkletRuntime(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
jsi::Value executeSync(const std::function<jsi::Value(jsi::Runtime &)> &job) const {
|
|
39
|
+
explicit WorkletRuntime(
|
|
40
|
+
uint64_t,
|
|
41
|
+
const std::shared_ptr<MessageQueueThread> &,
|
|
42
|
+
const std::string &,
|
|
43
|
+
const bool){throw RN_AUDIO_API_WORKLETS_DISABLED_ERROR} jsi::Runtime &getJSIRuntime() const {
|
|
44
|
+
throw RN_AUDIO_API_WORKLETS_DISABLED_ERROR} jsi::Value
|
|
45
|
+
executeSync(jsi::Runtime &rt, const jsi::Value &worklet) const {
|
|
46
|
+
throw RN_AUDIO_API_WORKLETS_DISABLED_ERROR} jsi::Value
|
|
47
|
+
executeSync(std::function<jsi::Value(jsi::Runtime &)> &&job) const {
|
|
48
|
+
throw RN_AUDIO_API_WORKLETS_DISABLED_ERROR} jsi::Value
|
|
49
|
+
executeSync(const std::function<jsi::Value(jsi::Runtime &)> &job) const {
|
|
52
50
|
throw RN_AUDIO_API_WORKLETS_DISABLED_ERROR
|
|
53
51
|
}
|
|
54
52
|
};
|
|
55
53
|
class SerializableWorklet {
|
|
56
54
|
public:
|
|
57
|
-
SerializableWorklet(jsi::Runtime*, const jsi::Object &)
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
jsi::Value toJSValue(jsi::Runtime &rt) {
|
|
55
|
+
SerializableWorklet(jsi::Runtime *, const jsi::Object &){
|
|
56
|
+
throw RN_AUDIO_API_WORKLETS_DISABLED_ERROR} jsi::Value toJSValue(jsi::Runtime &rt) {
|
|
61
57
|
throw RN_AUDIO_API_WORKLETS_DISABLED_ERROR
|
|
62
58
|
}
|
|
63
59
|
};
|
|
@@ -74,12 +70,11 @@ struct RuntimeRegistry {
|
|
|
74
70
|
std::shared_ptr<worklets::WorkletRuntime> audioRuntime;
|
|
75
71
|
|
|
76
72
|
#if ANDROID
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
73
|
+
~RuntimeRegistry() {
|
|
74
|
+
facebook::jni::ThreadScope::WithClassLoader([this]() {
|
|
75
|
+
uiRuntime.reset();
|
|
76
|
+
audioRuntime.reset();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
84
79
|
#endif
|
|
85
80
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#include <audioapi/core/utils/worklets/WorkletsRunner.h>
|
|
2
|
+
#include <memory>
|
|
3
|
+
#include <utility>
|
|
2
4
|
|
|
3
5
|
namespace audioapi {
|
|
4
6
|
|
|
@@ -6,23 +8,21 @@ WorkletsRunner::WorkletsRunner(
|
|
|
6
8
|
std::weak_ptr<worklets::WorkletRuntime> weakRuntime,
|
|
7
9
|
const std::shared_ptr<worklets::SerializableWorklet> &shareableWorklet,
|
|
8
10
|
bool shouldLockRuntime)
|
|
9
|
-
: weakRuntime_(std::move(weakRuntime)),
|
|
10
|
-
shouldLockRuntime(shouldLockRuntime) {
|
|
11
|
+
: weakRuntime_(std::move(weakRuntime)), shouldLockRuntime(shouldLockRuntime) {
|
|
11
12
|
auto strongRuntime = weakRuntime_.lock();
|
|
12
13
|
if (strongRuntime == nullptr) {
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
15
16
|
#if RN_AUDIO_API_ENABLE_WORKLETS
|
|
16
17
|
unsafeRuntimePtr = &strongRuntime->getJSIRuntime();
|
|
17
|
-
strongRuntime->executeSync(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
18
|
+
strongRuntime->executeSync([this, shareableWorklet](jsi::Runtime &rt) -> jsi::Value {
|
|
19
|
+
/// Placement new to avoid dynamic memory allocation
|
|
20
|
+
new (reinterpret_cast<jsi::Function *>(&unsafeWorklet))
|
|
21
|
+
jsi::Function(shareableWorklet->toJSValue(*unsafeRuntimePtr)
|
|
22
|
+
.asObject(*unsafeRuntimePtr)
|
|
23
|
+
.asFunction(*unsafeRuntimePtr));
|
|
24
|
+
return jsi::Value::undefined();
|
|
25
|
+
});
|
|
26
26
|
workletInitialized = true;
|
|
27
27
|
#else
|
|
28
28
|
unsafeRuntimePtr = nullptr;
|
|
@@ -56,8 +56,7 @@ WorkletsRunner::~WorkletsRunner() {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
std::optional<jsi::Value> WorkletsRunner::executeOnRuntimeGuarded(
|
|
59
|
-
const std::function<jsi::Value(jsi::Runtime &)> &&job) const
|
|
60
|
-
noexcept(noexcept(job)) {
|
|
59
|
+
const std::function<jsi::Value(jsi::Runtime &)> &&job) const noexcept(noexcept(job)) {
|
|
61
60
|
auto strongRuntime = weakRuntime_.lock();
|
|
62
61
|
if (strongRuntime == nullptr) {
|
|
63
62
|
return std::nullopt;
|
|
@@ -70,13 +69,12 @@ std::optional<jsi::Value> WorkletsRunner::executeOnRuntimeGuarded(
|
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
std::optional<jsi::Value> WorkletsRunner::executeOnRuntimeUnsafe(
|
|
73
|
-
const std::function<jsi::Value(jsi::Runtime &)> &&job) const
|
|
74
|
-
noexcept(noexcept(job)) {
|
|
72
|
+
const std::function<jsi::Value(jsi::Runtime &)> &&job) const noexcept(noexcept(job)) {
|
|
75
73
|
#if RN_AUDIO_API_ENABLE_WORKLETS
|
|
76
74
|
return job(*unsafeRuntimePtr);
|
|
77
75
|
#else
|
|
78
76
|
return std::nullopt;
|
|
79
77
|
#endif
|
|
80
|
-
}
|
|
78
|
+
}
|
|
81
79
|
|
|
82
80
|
}; // namespace audioapi
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <jsi/jsi.h>
|
|
4
3
|
#include <audioapi/core/utils/worklets/SafeIncludes.h>
|
|
4
|
+
#include <jsi/jsi.h>
|
|
5
5
|
|
|
6
|
-
#include <functional>
|
|
7
6
|
#include <atomic>
|
|
7
|
+
#include <functional>
|
|
8
8
|
#include <memory>
|
|
9
|
-
#include <utility>
|
|
10
9
|
#include <optional>
|
|
10
|
+
#include <utility>
|
|
11
11
|
|
|
12
12
|
namespace audioapi {
|
|
13
13
|
using namespace facebook;
|
|
@@ -27,10 +27,10 @@ using namespace facebook;
|
|
|
27
27
|
class WorkletsRunner {
|
|
28
28
|
public:
|
|
29
29
|
explicit WorkletsRunner(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
WorkletsRunner(WorkletsRunner&&);
|
|
30
|
+
std::weak_ptr<worklets::WorkletRuntime> weakRuntime,
|
|
31
|
+
const std::shared_ptr<worklets::SerializableWorklet> &shareableWorklet,
|
|
32
|
+
bool shouldLockRuntime = true);
|
|
33
|
+
WorkletsRunner(WorkletsRunner &&);
|
|
34
34
|
~WorkletsRunner();
|
|
35
35
|
|
|
36
36
|
/// @brief Call the worklet function with the given arguments.
|
|
@@ -38,19 +38,18 @@ class WorkletsRunner {
|
|
|
38
38
|
/// @param ...args
|
|
39
39
|
/// @return The result of the worklet function call.
|
|
40
40
|
/// @note This method is unsafe and should be used with caution. It assumes that the runtime and worklet are valid and runtime is locked.
|
|
41
|
-
template<typename... Args>
|
|
42
|
-
inline jsi::Value callUnsafe(Args&&...
|
|
41
|
+
template <typename... Args>
|
|
42
|
+
inline jsi::Value callUnsafe(Args &&...args) {
|
|
43
43
|
return getUnsafeWorklet().call(*unsafeRuntimePtr, std::forward<Args>(args)...);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
47
46
|
/// @brief Call the worklet function with the given arguments.
|
|
48
47
|
/// @tparam ...Args
|
|
49
48
|
/// @param ...args
|
|
50
49
|
/// @return The result of the worklet function call.
|
|
51
50
|
/// @note This method is safe and will check if the runtime is available before calling the worklet. If the runtime is not available, it will return nullopt.
|
|
52
|
-
template<typename... Args>
|
|
53
|
-
inline std::optional<jsi::Value> call(Args&&...
|
|
51
|
+
template <typename... Args>
|
|
52
|
+
inline std::optional<jsi::Value> call(Args &&...args) {
|
|
54
53
|
return executeOnRuntimeGuarded([this, args...](jsi::Runtime &rt) -> jsi::Value {
|
|
55
54
|
return callUnsafe(std::forward<Args>(args)...);
|
|
56
55
|
});
|
|
@@ -60,14 +59,17 @@ class WorkletsRunner {
|
|
|
60
59
|
/// @param job
|
|
61
60
|
/// @return nullopt if the runtime is not available or the result of the job execution
|
|
62
61
|
/// @note Execution is synchronous and will be guarded if shouldLockRuntime is true.
|
|
63
|
-
inline std::optional<jsi::Value> executeOnRuntimeSync(
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
inline std::optional<jsi::Value> executeOnRuntimeSync(
|
|
63
|
+
const std::function<jsi::Value(jsi::Runtime &)> &&job) const noexcept(noexcept(job)) {
|
|
64
|
+
if (shouldLockRuntime)
|
|
65
|
+
return executeOnRuntimeGuarded(std::move(job));
|
|
66
|
+
else
|
|
67
|
+
return executeOnRuntimeUnsafe(std::move(job));
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
private:
|
|
69
71
|
std::weak_ptr<worklets::WorkletRuntime> weakRuntime_;
|
|
70
|
-
jsi::Runtime*
|
|
72
|
+
jsi::Runtime *unsafeRuntimePtr = nullptr;
|
|
71
73
|
|
|
72
74
|
/// @note We want to avoid automatic destruction as
|
|
73
75
|
/// when runtime is destroyed, underlying pointer will be invalid
|
|
@@ -76,12 +78,14 @@ class WorkletsRunner {
|
|
|
76
78
|
bool shouldLockRuntime = true;
|
|
77
79
|
|
|
78
80
|
inline jsi::Function &getUnsafeWorklet() {
|
|
79
|
-
return *reinterpret_cast<jsi::Function*>(&unsafeWorklet);
|
|
81
|
+
return *reinterpret_cast<jsi::Function *>(&unsafeWorklet);
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
std::optional<jsi::Value> executeOnRuntimeGuarded(
|
|
84
|
+
std::optional<jsi::Value> executeOnRuntimeGuarded(
|
|
85
|
+
const std::function<jsi::Value(jsi::Runtime &)> &&job) const noexcept(noexcept(job));
|
|
83
86
|
|
|
84
|
-
std::optional<jsi::Value> executeOnRuntimeUnsafe(
|
|
87
|
+
std::optional<jsi::Value> executeOnRuntimeUnsafe(
|
|
88
|
+
const std::function<jsi::Value(jsi::Runtime &)> &&job) const noexcept(noexcept(job));
|
|
85
89
|
};
|
|
86
90
|
|
|
87
91
|
} // namespace audioapi
|
|
@@ -9,18 +9,12 @@ double sampleFrameToTime(int sampleFrame, float sampleRate) {
|
|
|
9
9
|
return static_cast<double>(sampleFrame) / sampleRate;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
float linearInterpolate(
|
|
13
|
-
const float *source,
|
|
14
|
-
size_t firstIndex,
|
|
15
|
-
size_t secondIndex,
|
|
16
|
-
float factor) {
|
|
12
|
+
float linearInterpolate(const float *source, size_t firstIndex, size_t secondIndex, float factor) {
|
|
17
13
|
if (firstIndex == secondIndex && firstIndex >= 1) {
|
|
18
|
-
return source[firstIndex] +
|
|
19
|
-
factor * (source[firstIndex] - source[firstIndex - 1]);
|
|
14
|
+
return source[firstIndex] + factor * (source[firstIndex] - source[firstIndex - 1]);
|
|
20
15
|
}
|
|
21
16
|
|
|
22
|
-
return source[firstIndex] +
|
|
23
|
-
factor * (source[secondIndex] - source[firstIndex]);
|
|
17
|
+
return source[firstIndex] + factor * (source[secondIndex] - source[firstIndex]);
|
|
24
18
|
}
|
|
25
19
|
|
|
26
20
|
float linearToDecibels(float value) {
|
|
@@ -9,8 +9,10 @@
|
|
|
9
9
|
#include <audioapi/dsp/Convolver.h>
|
|
10
10
|
#include <audioapi/dsp/VectorMath.h>
|
|
11
11
|
#include <audioapi/utils/AudioArray.h>
|
|
12
|
+
#include <algorithm>
|
|
12
13
|
#include <chrono>
|
|
13
14
|
#include <iostream>
|
|
15
|
+
#include <memory>
|
|
14
16
|
|
|
15
17
|
namespace audioapi {
|
|
16
18
|
|
|
@@ -41,10 +43,7 @@ void Convolver::reset() {
|
|
|
41
43
|
_inputBuffer.zero();
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
bool Convolver::init(
|
|
45
|
-
size_t blockSize,
|
|
46
|
-
const audioapi::AudioArray &ir,
|
|
47
|
-
size_t irLen) {
|
|
46
|
+
bool Convolver::init(size_t blockSize, const audioapi::AudioArray &ir, size_t irLen) {
|
|
48
47
|
reset();
|
|
49
48
|
// blockSize must be a power of two
|
|
50
49
|
if ((blockSize & (blockSize - 1))) {
|
|
@@ -54,7 +53,8 @@ bool Convolver::init(
|
|
|
54
53
|
// Ignore zeros at the end of the impulse response because they only waste
|
|
55
54
|
// computation time
|
|
56
55
|
_blockSize = blockSize;
|
|
57
|
-
_trueSegmentCount =
|
|
56
|
+
_trueSegmentCount =
|
|
57
|
+
static_cast<size_t>((std::ceil(static_cast<float>(irLen) / static_cast<float>(_blockSize))));
|
|
58
58
|
while (irLen > 0 && ::fabs(ir[irLen - 1]) < 10e-3) {
|
|
59
59
|
--irLen;
|
|
60
60
|
}
|
|
@@ -64,12 +64,13 @@ bool Convolver::init(
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// The length-N is split into P = N/B length-B sub filters
|
|
67
|
-
_segCount =
|
|
67
|
+
_segCount =
|
|
68
|
+
static_cast<size_t>((std::ceil(static_cast<float>(irLen) / static_cast<float>(_blockSize))));
|
|
68
69
|
_segSize = 2 * _blockSize;
|
|
69
70
|
// size of the FFT is 2B, so the complex size is B+1, due to the
|
|
70
71
|
// complex-conjugate symmetricity
|
|
71
72
|
_fftComplexSize = _segSize / 2 + 1;
|
|
72
|
-
_fft = std::make_shared<dsp::FFT>((
|
|
73
|
+
_fft = std::make_shared<dsp::FFT>(static_cast<int>(_segSize));
|
|
73
74
|
_fftBuffer.resize(_segSize);
|
|
74
75
|
|
|
75
76
|
// segments preparation
|
|
@@ -85,10 +86,7 @@ bool Convolver::init(
|
|
|
85
86
|
const size_t samplesToCopy = std::min(_blockSize, remainingSamples);
|
|
86
87
|
|
|
87
88
|
if (samplesToCopy > 0) {
|
|
88
|
-
memcpy(
|
|
89
|
-
_fftBuffer.getData(),
|
|
90
|
-
ir.getData() + i * _blockSize,
|
|
91
|
-
samplesToCopy * sizeof(float));
|
|
89
|
+
memcpy(_fftBuffer.getData(), ir.getData() + i * _blockSize, samplesToCopy * sizeof(float));
|
|
92
90
|
}
|
|
93
91
|
// Each sub filter is zero-padded to length 2B and transformed using a
|
|
94
92
|
// 2B-point real-to-complex FFT.
|
|
@@ -171,10 +169,7 @@ void Convolver::process(float *data, float *outputData) {
|
|
|
171
169
|
// The input buffer acts as a 2B-point sliding window of the input signal.
|
|
172
170
|
// With each new input block, the right half of the input buffer is shifted
|
|
173
171
|
// to the left and the new block is stored in the right half.
|
|
174
|
-
memmove(
|
|
175
|
-
_inputBuffer.getData(),
|
|
176
|
-
_inputBuffer.getData() + _blockSize,
|
|
177
|
-
_blockSize * sizeof(float));
|
|
172
|
+
memmove(_inputBuffer.getData(), _inputBuffer.getData() + _blockSize, _blockSize * sizeof(float));
|
|
178
173
|
memcpy(_inputBuffer.getData() + _blockSize, data, _blockSize * sizeof(float));
|
|
179
174
|
|
|
180
175
|
// All contents (DFT spectra) in the FDL are shifted up by one slot.
|
|
@@ -188,26 +183,19 @@ void Convolver::process(float *data, float *outputData) {
|
|
|
188
183
|
|
|
189
184
|
// The P sub filter spectra are pairwisely multiplied with the input spectra
|
|
190
185
|
// in the FDL. The results are accumulated in the frequency-domain.
|
|
191
|
-
memset(
|
|
192
|
-
_preMultiplied.data(),
|
|
193
|
-
0,
|
|
194
|
-
_preMultiplied.size() * sizeof(std::complex<float>));
|
|
186
|
+
memset(_preMultiplied.data(), 0, _preMultiplied.size() * sizeof(std::complex<float>));
|
|
195
187
|
// this is a bottleneck of the algorithm
|
|
196
188
|
for (int i = 0; i < _segCount; ++i) {
|
|
197
189
|
const int indexAudio = (_current + i) % _segCount;
|
|
198
190
|
const auto &impulseResponseSegment = _segmentsIR[i];
|
|
199
191
|
const auto &audioSegment = _segments[indexAudio];
|
|
200
|
-
pairwise_complex_multiply_fast(
|
|
201
|
-
impulseResponseSegment, audioSegment, _preMultiplied);
|
|
192
|
+
pairwise_complex_multiply_fast(impulseResponseSegment, audioSegment, _preMultiplied);
|
|
202
193
|
}
|
|
203
194
|
// Of the accumulated spectral convolutions, an 2B-point complex-to-real
|
|
204
195
|
// IFFT is computed. From the resulting 2B samples, the left half is
|
|
205
196
|
// discarded and the right half is returned as the next output block.
|
|
206
197
|
_fft->doInverseFFT(_preMultiplied, _fftBuffer.getData());
|
|
207
198
|
|
|
208
|
-
memcpy(
|
|
209
|
-
outputData,
|
|
210
|
-
_fftBuffer.getData() + _blockSize,
|
|
211
|
-
_blockSize * sizeof(float));
|
|
199
|
+
memcpy(outputData, _fftBuffer.getData() + _blockSize, _blockSize * sizeof(float));
|
|
212
200
|
}
|
|
213
201
|
} // namespace audioapi
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <audioapi/utils/AudioArray.h>
|
|
4
3
|
#include <audioapi/dsp/FFT.h>
|
|
5
|
-
#include <
|
|
6
|
-
#include <
|
|
4
|
+
#include <audioapi/utils/AlignedAllocator.hpp>
|
|
5
|
+
#include <audioapi/utils/AudioArray.h>
|
|
7
6
|
#include <complex>
|
|
7
|
+
#include <cstring>
|
|
8
8
|
#include <memory>
|
|
9
|
-
#include <
|
|
9
|
+
#include <vector>
|
|
10
10
|
|
|
11
11
|
namespace audioapi {
|
|
12
12
|
|
|
@@ -17,29 +17,31 @@ class Convolver {
|
|
|
17
17
|
std::vector<std::complex<float>, AlignedAllocator<std::complex<float>, 16>>;
|
|
18
18
|
|
|
19
19
|
public:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
Convolver();
|
|
21
|
+
bool init(size_t blockSize, const AudioArray &ir, size_t irLen);
|
|
22
|
+
void process(float *inputData, float *outputData);
|
|
23
|
+
void reset();
|
|
24
|
+
inline size_t getSegCount() const {
|
|
25
|
+
return _trueSegmentCount;
|
|
26
|
+
}
|
|
25
27
|
|
|
26
28
|
private:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
size_t _trueSegmentCount;
|
|
30
|
+
size_t _blockSize;
|
|
31
|
+
size_t _segSize;
|
|
32
|
+
size_t _segCount;
|
|
33
|
+
size_t _fftComplexSize;
|
|
34
|
+
std::vector<aligned_vec_complex> _segments;
|
|
35
|
+
std::vector<aligned_vec_complex> _segmentsIR;
|
|
36
|
+
AudioArray _fftBuffer;
|
|
37
|
+
std::shared_ptr<dsp::FFT> _fft;
|
|
38
|
+
aligned_vec_complex _preMultiplied;
|
|
39
|
+
size_t _current;
|
|
40
|
+
AudioArray _inputBuffer;
|
|
39
41
|
|
|
40
42
|
friend void pairwise_complex_multiply_fast(
|
|
41
|
-
const aligned_vec_complex&
|
|
42
|
-
const aligned_vec_complex&
|
|
43
|
-
aligned_vec_complex&
|
|
43
|
+
const aligned_vec_complex &ir,
|
|
44
|
+
const aligned_vec_complex &audio,
|
|
45
|
+
aligned_vec_complex &pre);
|
|
44
46
|
};
|
|
45
47
|
} // namespace audioapi
|
|
@@ -4,7 +4,7 @@ namespace audioapi::dsp {
|
|
|
4
4
|
|
|
5
5
|
FFT::FFT(int size) : size_(size) {
|
|
6
6
|
pffftSetup_ = pffft_new_setup(size_, PFFFT_REAL);
|
|
7
|
-
work_ =
|
|
7
|
+
work_ = reinterpret_cast<float *>(pffft_aligned_malloc(size_ * sizeof(float)));
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
FFT::~FFT() {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
#include <algorithm>
|
|
7
7
|
#include <cmath>
|
|
8
|
-
#include <utility>
|
|
9
8
|
#include <complex>
|
|
9
|
+
#include <utility>
|
|
10
10
|
#include <vector>
|
|
11
11
|
|
|
12
12
|
namespace audioapi::dsp {
|
|
@@ -16,14 +16,10 @@ class FFT {
|
|
|
16
16
|
explicit FFT(int size);
|
|
17
17
|
~FFT();
|
|
18
18
|
|
|
19
|
-
template<typename Allocator>
|
|
19
|
+
template <typename Allocator>
|
|
20
20
|
void doFFT(float *in, std::vector<std::complex<float>, Allocator> &out) {
|
|
21
21
|
pffft_transform_ordered(
|
|
22
|
-
pffftSetup_,
|
|
23
|
-
in,
|
|
24
|
-
reinterpret_cast<float *>(&out[0]),
|
|
25
|
-
work_,
|
|
26
|
-
PFFFT_FORWARD);
|
|
22
|
+
pffftSetup_, in, reinterpret_cast<float *>(&out[0]), work_, PFFFT_FORWARD);
|
|
27
23
|
// this is a possible place for bugs and mistakes
|
|
28
24
|
// due to pffft implementation and how it stores results
|
|
29
25
|
// keep this information in mind
|
|
@@ -31,14 +27,10 @@ class FFT {
|
|
|
31
27
|
// out[0].imag = Nyquist component - should be pure real
|
|
32
28
|
}
|
|
33
29
|
|
|
34
|
-
template<typename Allocator>
|
|
30
|
+
template <typename Allocator>
|
|
35
31
|
void doInverseFFT(std::vector<std::complex<float>, Allocator> &in, float *out) {
|
|
36
32
|
pffft_transform_ordered(
|
|
37
|
-
pffftSetup_,
|
|
38
|
-
reinterpret_cast<float *>(&in[0]),
|
|
39
|
-
out,
|
|
40
|
-
work_,
|
|
41
|
-
PFFFT_BACKWARD);
|
|
33
|
+
pffftSetup_, reinterpret_cast<float *>(&in[0]), out, work_, PFFFT_BACKWARD);
|
|
42
34
|
|
|
43
35
|
dsp::multiplyByScalar(out, 1.0f / static_cast<float>(size_), out, size_);
|
|
44
36
|
}
|