react-native-audio-api 0.11.0-nightly-568a154-20251222 → 0.11.0-nightly-94b7f30-20251224
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/core/AndroidAudioRecorder.cpp +1 -1
- package/android/src/main/cpp/audioapi/android/core/utils/AndroidRecorderCallback.cpp +11 -3
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.cpp +47 -79
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.h +3 -2
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +2 -0
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.cpp +9 -1
- package/common/cpp/audioapi/HostObjects/BaseAudioContextHostObject.h +1 -0
- package/common/cpp/audioapi/HostObjects/effects/DelayNodeHostObject.cpp +6 -2
- package/common/cpp/audioapi/HostObjects/effects/WaveShaperNodeHostObject.cpp +72 -0
- package/common/cpp/audioapi/HostObjects/effects/WaveShaperNodeHostObject.h +23 -0
- package/common/cpp/audioapi/core/AudioContext.cpp +15 -13
- package/common/cpp/audioapi/core/AudioContext.h +2 -1
- package/common/cpp/audioapi/core/AudioNode.cpp +39 -24
- package/common/cpp/audioapi/core/AudioNode.h +3 -3
- package/common/cpp/audioapi/core/AudioParam.cpp +9 -6
- package/common/cpp/audioapi/core/AudioParam.h +2 -2
- package/common/cpp/audioapi/core/BaseAudioContext.cpp +32 -21
- package/common/cpp/audioapi/core/BaseAudioContext.h +5 -1
- package/common/cpp/audioapi/core/analysis/AnalyserNode.cpp +8 -11
- package/common/cpp/audioapi/core/analysis/AnalyserNode.h +1 -1
- package/common/cpp/audioapi/core/destinations/AudioDestinationNode.cpp +9 -3
- package/common/cpp/audioapi/core/destinations/AudioDestinationNode.h +1 -1
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +18 -9
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.h +1 -1
- package/common/cpp/audioapi/core/effects/ConvolverNode.cpp +3 -3
- package/common/cpp/audioapi/core/effects/ConvolverNode.h +1 -1
- package/common/cpp/audioapi/core/effects/DelayNode.cpp +20 -11
- package/common/cpp/audioapi/core/effects/DelayNode.h +1 -1
- package/common/cpp/audioapi/core/effects/GainNode.cpp +12 -4
- package/common/cpp/audioapi/core/effects/GainNode.h +1 -1
- package/common/cpp/audioapi/core/effects/IIRFilterNode.cpp +6 -3
- package/common/cpp/audioapi/core/effects/IIRFilterNode.h +1 -1
- package/common/cpp/audioapi/core/effects/StereoPannerNode.cpp +7 -4
- package/common/cpp/audioapi/core/effects/StereoPannerNode.h +1 -1
- package/common/cpp/audioapi/core/effects/WaveShaperNode.cpp +79 -0
- package/common/cpp/audioapi/core/effects/WaveShaperNode.h +66 -0
- package/common/cpp/audioapi/core/effects/WorkletNode.cpp +2 -2
- package/common/cpp/audioapi/core/effects/WorkletNode.h +2 -2
- package/common/cpp/audioapi/core/effects/WorkletProcessingNode.cpp +7 -4
- package/common/cpp/audioapi/core/effects/WorkletProcessingNode.h +6 -2
- package/common/cpp/audioapi/core/sources/AudioBuffer.cpp +2 -3
- package/common/cpp/audioapi/core/sources/AudioBuffer.h +1 -1
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.cpp +59 -25
- package/common/cpp/audioapi/core/sources/AudioBufferBaseSourceNode.h +4 -2
- package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.cpp +18 -11
- package/common/cpp/audioapi/core/sources/AudioBufferQueueSourceNode.h +3 -1
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.cpp +37 -21
- package/common/cpp/audioapi/core/sources/AudioBufferSourceNode.h +3 -3
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.cpp +11 -11
- package/common/cpp/audioapi/core/sources/AudioScheduledSourceNode.h +4 -2
- package/common/cpp/audioapi/core/sources/ConstantSourceNode.cpp +16 -8
- package/common/cpp/audioapi/core/sources/ConstantSourceNode.h +1 -1
- package/common/cpp/audioapi/core/sources/OscillatorNode.cpp +30 -18
- package/common/cpp/audioapi/core/sources/OscillatorNode.h +1 -1
- package/common/cpp/audioapi/core/sources/RecorderAdapterNode.cpp +4 -4
- package/common/cpp/audioapi/core/sources/RecorderAdapterNode.h +1 -1
- package/common/cpp/audioapi/core/sources/StreamerNode.cpp +24 -10
- package/common/cpp/audioapi/core/sources/StreamerNode.h +4 -3
- package/common/cpp/audioapi/core/sources/WorkletSourceNode.cpp +11 -4
- package/common/cpp/audioapi/core/sources/WorkletSourceNode.h +6 -2
- package/common/cpp/audioapi/core/types/OverSampleType.h +7 -0
- package/common/cpp/audioapi/core/utils/AudioRecorderCallback.cpp +1 -0
- package/common/cpp/audioapi/dsp/Resampler.cpp +200 -0
- package/common/cpp/audioapi/dsp/Resampler.h +65 -0
- package/common/cpp/audioapi/dsp/WaveShaper.cpp +105 -0
- package/common/cpp/audioapi/dsp/WaveShaper.h +46 -0
- package/common/cpp/audioapi/utils/AudioArray.cpp +5 -0
- package/common/cpp/audioapi/utils/AudioArray.h +6 -0
- package/common/cpp/test/RunTests.sh +1 -1
- package/common/cpp/test/src/AudioParamTest.cpp +10 -10
- package/common/cpp/test/src/AudioScheduledSourceTest.cpp +31 -15
- package/common/cpp/test/src/ConstantSourceTest.cpp +16 -14
- package/common/cpp/test/src/DelayTest.cpp +14 -13
- package/common/cpp/test/src/GainTest.cpp +10 -9
- package/common/cpp/test/src/IIRFilterTest.cpp +4 -4
- package/common/cpp/test/src/OscillatorTest.cpp +2 -2
- package/common/cpp/test/src/StereoPannerTest.cpp +14 -12
- package/common/cpp/test/src/biquad/BiquadFilterTest.cpp +25 -25
- package/common/cpp/test/src/biquad/BiquadFilterTest.h +3 -5
- package/common/cpp/test/src/core/effects/WaveShaperNodeTest.cpp +76 -0
- package/common/cpp/test/src/dsp/ResamplerTest.cpp +117 -0
- package/ios/audioapi/ios/AudioAPIModule.mm +4 -4
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +1 -1
- package/ios/audioapi/ios/core/utils/IOSRecorderCallback.mm +9 -3
- package/lib/commonjs/AudioAPIModule/AudioAPIModule.js +0 -3
- package/lib/commonjs/AudioAPIModule/AudioAPIModule.js.map +1 -1
- package/lib/commonjs/AudioAPIModule/AudioAPIModule.web.js +20 -0
- package/lib/commonjs/AudioAPIModule/AudioAPIModule.web.js.map +1 -0
- package/lib/commonjs/AudioAPIModule/ModuleInterfaces.js +6 -0
- package/lib/commonjs/AudioAPIModule/ModuleInterfaces.js.map +1 -0
- package/lib/commonjs/api.js +16 -0
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/api.web.js +23 -0
- package/lib/commonjs/api.web.js.map +1 -1
- package/lib/commonjs/core/BaseAudioContext.js +4 -0
- package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
- package/lib/commonjs/core/WaveShaperNode.js +38 -0
- package/lib/commonjs/core/WaveShaperNode.js.map +1 -0
- package/lib/commonjs/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/commonjs/specs/NativeAudioAPIModule.web.js +47 -0
- package/lib/commonjs/specs/NativeAudioAPIModule.web.js.map +1 -0
- package/lib/commonjs/system/AudioManager.js.map +1 -1
- package/lib/commonjs/system/types.js +4 -0
- package/lib/commonjs/web-core/AudioContext.js +4 -0
- package/lib/commonjs/web-core/AudioContext.js.map +1 -1
- package/lib/commonjs/web-core/OfflineAudioContext.js +4 -0
- package/lib/commonjs/web-core/OfflineAudioContext.js.map +1 -1
- package/lib/commonjs/web-core/WaveShaperNode.js +38 -0
- package/lib/commonjs/web-core/WaveShaperNode.js.map +1 -0
- package/lib/commonjs/web-system/AudioManager.js +30 -0
- package/lib/commonjs/web-system/AudioManager.js.map +1 -0
- package/lib/commonjs/web-system/index.js +12 -0
- package/lib/commonjs/web-system/index.js.map +1 -1
- package/lib/module/AudioAPIModule/AudioAPIModule.js +0 -4
- package/lib/module/AudioAPIModule/AudioAPIModule.js.map +1 -1
- package/lib/module/AudioAPIModule/AudioAPIModule.web.js +16 -0
- package/lib/module/AudioAPIModule/AudioAPIModule.web.js.map +1 -0
- package/lib/module/AudioAPIModule/ModuleInterfaces.js +4 -0
- package/lib/module/AudioAPIModule/ModuleInterfaces.js.map +1 -0
- package/lib/module/AudioAPIModule/index.js +1 -1
- package/lib/module/AudioAPIModule/index.js.map +1 -1
- package/lib/module/api.js +2 -0
- package/lib/module/api.js.map +1 -1
- package/lib/module/api.web.js +3 -1
- package/lib/module/api.web.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +4 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/core/WaveShaperNode.js +32 -0
- package/lib/module/core/WaveShaperNode.js.map +1 -0
- package/lib/module/specs/NativeAudioAPIModule.js.map +1 -1
- package/lib/module/specs/NativeAudioAPIModule.web.js +44 -0
- package/lib/module/specs/NativeAudioAPIModule.web.js.map +1 -0
- package/lib/module/specs/index.js +1 -1
- package/lib/module/specs/index.js.map +1 -1
- package/lib/module/system/AudioManager.js.map +1 -1
- package/lib/module/system/types.js +2 -0
- package/lib/module/web-core/AudioContext.js +4 -0
- package/lib/module/web-core/AudioContext.js.map +1 -1
- package/lib/module/web-core/OfflineAudioContext.js +4 -0
- package/lib/module/web-core/OfflineAudioContext.js.map +1 -1
- package/lib/module/web-core/WaveShaperNode.js +32 -0
- package/lib/module/web-core/WaveShaperNode.js.map +1 -0
- package/lib/module/web-system/AudioManager.js +26 -0
- package/lib/module/web-system/AudioManager.js.map +1 -0
- package/lib/module/web-system/index.js +1 -0
- package/lib/module/web-system/index.js.map +1 -1
- package/lib/typescript/AudioAPIModule/AudioAPIModule.d.ts +2 -10
- package/lib/typescript/AudioAPIModule/AudioAPIModule.d.ts.map +1 -1
- package/lib/typescript/AudioAPIModule/AudioAPIModule.web.d.ts +13 -0
- package/lib/typescript/AudioAPIModule/AudioAPIModule.web.d.ts.map +1 -0
- package/lib/typescript/AudioAPIModule/ModuleInterfaces.d.ts +18 -0
- package/lib/typescript/AudioAPIModule/ModuleInterfaces.d.ts.map +1 -0
- package/lib/typescript/api.d.ts +2 -0
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/api.web.d.ts +3 -1
- package/lib/typescript/api.web.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts +2 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/core/WaveShaperNode.d.ts +9 -0
- package/lib/typescript/core/WaveShaperNode.d.ts.map +1 -0
- package/lib/typescript/interfaces.d.ts +8 -2
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.d.ts.map +1 -1
- package/lib/typescript/specs/NativeAudioAPIModule.web.d.ts +34 -0
- package/lib/typescript/specs/NativeAudioAPIModule.web.d.ts.map +1 -0
- package/lib/typescript/system/AudioManager.d.ts +2 -2
- package/lib/typescript/system/AudioManager.d.ts.map +1 -1
- package/lib/typescript/system/notification/types.d.ts +1 -1
- package/lib/typescript/system/notification/types.d.ts.map +1 -1
- package/lib/typescript/system/types.d.ts +17 -0
- package/lib/typescript/system/types.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/AudioContext.d.ts +2 -0
- package/lib/typescript/web-core/AudioContext.d.ts.map +1 -1
- package/lib/typescript/web-core/BaseAudioContext.d.ts +3 -1
- package/lib/typescript/web-core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/web-core/OfflineAudioContext.d.ts +2 -0
- package/lib/typescript/web-core/OfflineAudioContext.d.ts.map +1 -1
- package/lib/typescript/web-core/WaveShaperNode.d.ts +9 -0
- package/lib/typescript/web-core/WaveShaperNode.d.ts.map +1 -0
- package/lib/typescript/web-system/AudioManager.d.ts +24 -0
- package/lib/typescript/web-system/AudioManager.d.ts.map +1 -0
- package/lib/typescript/web-system/index.d.ts +1 -0
- package/lib/typescript/web-system/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/AudioAPIModule/AudioAPIModule.ts +6 -17
- package/src/AudioAPIModule/AudioAPIModule.web.ts +18 -0
- package/src/AudioAPIModule/ModuleInterfaces.ts +25 -0
- package/src/api.ts +2 -0
- package/src/api.web.ts +3 -0
- package/src/core/BaseAudioContext.ts +5 -0
- package/src/core/WaveShaperNode.ts +43 -0
- package/src/interfaces.ts +9 -1
- package/src/specs/NativeAudioAPIModule.ts +5 -3
- package/src/specs/NativeAudioAPIModule.web.ts +93 -0
- package/src/system/AudioManager.ts +19 -14
- package/src/system/notification/types.ts +1 -1
- package/src/system/types.ts +22 -0
- package/src/types.ts +2 -0
- package/src/web-core/AudioContext.tsx +5 -0
- package/src/web-core/BaseAudioContext.tsx +3 -1
- package/src/web-core/OfflineAudioContext.tsx +5 -0
- package/src/web-core/WaveShaperNode.tsx +42 -0
- package/src/web-system/AudioManager.ts +33 -0
- package/src/web-system/index.ts +1 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#include <audioapi/core/BaseAudioContext.h>
|
|
2
|
+
#include <audioapi/core/effects/WaveShaperNode.h>
|
|
3
|
+
#include <audioapi/dsp/VectorMath.h>
|
|
4
|
+
#include <audioapi/utils/AudioArray.h>
|
|
5
|
+
#include <audioapi/utils/AudioBus.h>
|
|
6
|
+
|
|
7
|
+
#include <algorithm>
|
|
8
|
+
#include <memory>
|
|
9
|
+
#include <string>
|
|
10
|
+
|
|
11
|
+
namespace audioapi {
|
|
12
|
+
|
|
13
|
+
WaveShaperNode::WaveShaperNode(std::shared_ptr<BaseAudioContext> context)
|
|
14
|
+
: AudioNode(context), oversample_(OverSampleType::OVERSAMPLE_NONE) {
|
|
15
|
+
|
|
16
|
+
waveShapers_.reserve(6);
|
|
17
|
+
for (int i = 0; i < channelCount_; i++) {
|
|
18
|
+
waveShapers_.emplace_back(std::make_unique<WaveShaper>(nullptr));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// to change after graph processing improvement - should be max
|
|
22
|
+
channelCountMode_ = ChannelCountMode::CLAMPED_MAX;
|
|
23
|
+
isInitialized_ = true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
std::string WaveShaperNode::getOversample() const {
|
|
27
|
+
return overSampleTypeToString(oversample_.load(std::memory_order_acquire));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void WaveShaperNode::setOversample(const std::string &type) {
|
|
31
|
+
std::scoped_lock<std::mutex> lock(mutex_);
|
|
32
|
+
oversample_.store(overSampleTypeFromString(type), std::memory_order_release);
|
|
33
|
+
|
|
34
|
+
for (int i = 0; i < waveShapers_.size(); i++) {
|
|
35
|
+
waveShapers_[i]->setOversample(overSampleTypeFromString(type));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
std::shared_ptr<AudioArray> WaveShaperNode::getCurve() const {
|
|
40
|
+
std::scoped_lock<std::mutex> lock(mutex_);
|
|
41
|
+
return curve_;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void WaveShaperNode::setCurve(const std::shared_ptr<AudioArray> &curve) {
|
|
45
|
+
std::scoped_lock<std::mutex> lock(mutex_);
|
|
46
|
+
curve_ = curve;
|
|
47
|
+
|
|
48
|
+
for (int i = 0; i < waveShapers_.size(); i++) {
|
|
49
|
+
waveShapers_[i]->setCurve(curve);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
std::shared_ptr<AudioBus> WaveShaperNode::processNode(
|
|
54
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
55
|
+
int framesToProcess) {
|
|
56
|
+
if (!isInitialized_) {
|
|
57
|
+
return processingBus;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
std::unique_lock<std::mutex> lock(mutex_, std::try_to_lock);
|
|
61
|
+
|
|
62
|
+
if (!lock.owns_lock()) {
|
|
63
|
+
return processingBus;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (curve_ == nullptr) {
|
|
67
|
+
return processingBus;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (int channel = 0; channel < processingBus->getNumberOfChannels(); channel++) {
|
|
71
|
+
auto channelData = processingBus->getSharedChannel(channel);
|
|
72
|
+
|
|
73
|
+
waveShapers_[channel]->process(channelData, framesToProcess);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return processingBus;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <audioapi/core/AudioNode.h>
|
|
4
|
+
#include <audioapi/core/types/OverSampleType.h>
|
|
5
|
+
#include <audioapi/dsp/Resampler.h>
|
|
6
|
+
#include <audioapi/dsp/WaveShaper.h>
|
|
7
|
+
|
|
8
|
+
#include <algorithm>
|
|
9
|
+
#include <atomic>
|
|
10
|
+
#include <memory>
|
|
11
|
+
#include <mutex>
|
|
12
|
+
#include <string>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
namespace audioapi {
|
|
16
|
+
|
|
17
|
+
class AudioBus;
|
|
18
|
+
class AudioArray;
|
|
19
|
+
|
|
20
|
+
class WaveShaperNode : public AudioNode {
|
|
21
|
+
public:
|
|
22
|
+
explicit WaveShaperNode(std::shared_ptr<BaseAudioContext> context);
|
|
23
|
+
|
|
24
|
+
[[nodiscard]] std::string getOversample() const;
|
|
25
|
+
[[nodiscard]] std::shared_ptr<AudioArray> getCurve() const;
|
|
26
|
+
|
|
27
|
+
void setOversample(const std::string &type);
|
|
28
|
+
void setCurve(const std::shared_ptr<AudioArray> &curve);
|
|
29
|
+
|
|
30
|
+
protected:
|
|
31
|
+
std::shared_ptr<AudioBus> processNode(
|
|
32
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
33
|
+
int framesToProcess) override;
|
|
34
|
+
|
|
35
|
+
private:
|
|
36
|
+
std::atomic<OverSampleType> oversample_;
|
|
37
|
+
std::shared_ptr<AudioArray> curve_{};
|
|
38
|
+
mutable std::mutex mutex_;
|
|
39
|
+
|
|
40
|
+
std::vector<std::unique_ptr<WaveShaper>> waveShapers_{};
|
|
41
|
+
|
|
42
|
+
static OverSampleType overSampleTypeFromString(const std::string &type) {
|
|
43
|
+
std::string lowerType = type;
|
|
44
|
+
std::transform(lowerType.begin(), lowerType.end(), lowerType.begin(), ::tolower);
|
|
45
|
+
|
|
46
|
+
if (lowerType == "2x")
|
|
47
|
+
return OverSampleType::OVERSAMPLE_2X;
|
|
48
|
+
if (lowerType == "4x")
|
|
49
|
+
return OverSampleType::OVERSAMPLE_4X;
|
|
50
|
+
|
|
51
|
+
return OverSampleType::OVERSAMPLE_NONE;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static std::string overSampleTypeToString(OverSampleType type) {
|
|
55
|
+
switch (type) {
|
|
56
|
+
case OverSampleType::OVERSAMPLE_2X:
|
|
57
|
+
return "2x";
|
|
58
|
+
case OverSampleType::OVERSAMPLE_4X:
|
|
59
|
+
return "4x";
|
|
60
|
+
default:
|
|
61
|
+
return "none";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
} // namespace audioapi
|
|
@@ -7,16 +7,16 @@
|
|
|
7
7
|
namespace audioapi {
|
|
8
8
|
|
|
9
9
|
WorkletNode::WorkletNode(
|
|
10
|
-
BaseAudioContext
|
|
10
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
11
11
|
size_t bufferLength,
|
|
12
12
|
size_t inputChannelCount,
|
|
13
13
|
WorkletsRunner &&runtime)
|
|
14
14
|
: AudioNode(context),
|
|
15
15
|
workletRunner_(std::move(runtime)),
|
|
16
|
+
bus_(std::make_shared<AudioBus>(bufferLength, inputChannelCount, context->getSampleRate())),
|
|
16
17
|
bufferLength_(bufferLength),
|
|
17
18
|
inputChannelCount_(inputChannelCount),
|
|
18
19
|
curBuffIndex_(0) {
|
|
19
|
-
bus_ = std::make_shared<AudioBus>(bufferLength, inputChannelCount, context->getSampleRate());
|
|
20
20
|
isInitialized_ = true;
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -17,7 +17,7 @@ namespace audioapi {
|
|
|
17
17
|
class WorkletNode : public AudioNode {
|
|
18
18
|
public:
|
|
19
19
|
explicit WorkletNode(
|
|
20
|
-
BaseAudioContext
|
|
20
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
21
21
|
size_t bufferLength,
|
|
22
22
|
size_t inputChannelCount,
|
|
23
23
|
WorkletsRunner &&workletRunner)
|
|
@@ -37,7 +37,7 @@ using namespace facebook;
|
|
|
37
37
|
class WorkletNode : public AudioNode {
|
|
38
38
|
public:
|
|
39
39
|
explicit WorkletNode(
|
|
40
|
-
BaseAudioContext
|
|
40
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
41
41
|
size_t bufferLength,
|
|
42
42
|
size_t inputChannelCount,
|
|
43
43
|
WorkletsRunner &&workletRunner);
|
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
namespace audioapi {
|
|
7
7
|
|
|
8
8
|
WorkletProcessingNode::WorkletProcessingNode(
|
|
9
|
-
BaseAudioContext
|
|
9
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
10
10
|
WorkletsRunner &&workletRunner)
|
|
11
11
|
: AudioNode(context), workletRunner_(std::move(workletRunner)) {
|
|
12
|
-
isInitialized_ = true;
|
|
13
|
-
|
|
14
12
|
// Pre-allocate buffers for max 128 frames and 2 channels (stereo)
|
|
15
13
|
size_t maxChannelCount = 2;
|
|
16
14
|
inputBuffsHandles_.resize(maxChannelCount);
|
|
@@ -23,6 +21,7 @@ WorkletProcessingNode::WorkletProcessingNode(
|
|
|
23
21
|
auto outputAudioArray = std::make_shared<AudioArray>(RENDER_QUANTUM_SIZE);
|
|
24
22
|
outputBuffsHandles_[i] = std::make_shared<AudioArrayBuffer>(outputAudioArray);
|
|
25
23
|
}
|
|
24
|
+
isInitialized_ = true;
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
std::shared_ptr<AudioBus> WorkletProcessingNode::processNode(
|
|
@@ -60,11 +59,15 @@ std::shared_ptr<AudioBus> WorkletProcessingNode::processNode(
|
|
|
60
59
|
// We call unsafely here because we are already on the runtime thread
|
|
61
60
|
// and the runtime is locked by executeOnRuntimeSync (if
|
|
62
61
|
// shouldLockRuntime is true)
|
|
62
|
+
float time = 0.0f;
|
|
63
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
64
|
+
time = context->getCurrentTime();
|
|
65
|
+
}
|
|
63
66
|
return workletRunner_.callUnsafe(
|
|
64
67
|
inputJsArray,
|
|
65
68
|
outputJsArray,
|
|
66
69
|
jsi::Value(rt, static_cast<int>(framesToProcess)),
|
|
67
|
-
jsi::Value(rt,
|
|
70
|
+
jsi::Value(rt, time));
|
|
68
71
|
});
|
|
69
72
|
|
|
70
73
|
// Copy processed output data back to the processing bus or zero on failure
|
|
@@ -16,7 +16,9 @@ namespace audioapi {
|
|
|
16
16
|
#if RN_AUDIO_API_TEST
|
|
17
17
|
class WorkletProcessingNode : public AudioNode {
|
|
18
18
|
public:
|
|
19
|
-
explicit WorkletProcessingNode(
|
|
19
|
+
explicit WorkletProcessingNode(
|
|
20
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
21
|
+
WorkletsRunner &&workletRunner)
|
|
20
22
|
: AudioNode(context) {}
|
|
21
23
|
|
|
22
24
|
protected:
|
|
@@ -32,7 +34,9 @@ using namespace facebook;
|
|
|
32
34
|
|
|
33
35
|
class WorkletProcessingNode : public AudioNode {
|
|
34
36
|
public:
|
|
35
|
-
explicit WorkletProcessingNode(
|
|
37
|
+
explicit WorkletProcessingNode(
|
|
38
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
39
|
+
WorkletsRunner &&workletRunner);
|
|
36
40
|
|
|
37
41
|
protected:
|
|
38
42
|
std::shared_ptr<AudioBus> processNode(
|
|
@@ -8,9 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
namespace audioapi {
|
|
10
10
|
|
|
11
|
-
AudioBuffer::AudioBuffer(int numberOfChannels, size_t length, float sampleRate)
|
|
12
|
-
|
|
13
|
-
}
|
|
11
|
+
AudioBuffer::AudioBuffer(int numberOfChannels, size_t length, float sampleRate)
|
|
12
|
+
: bus_(std::make_shared<AudioBus>(length, numberOfChannels, sampleRate)) {}
|
|
14
13
|
|
|
15
14
|
AudioBuffer::AudioBuffer(std::shared_ptr<AudioBus> bus) {
|
|
16
15
|
bus_ = std::move(bus);
|
|
@@ -11,7 +11,7 @@ namespace audioapi {
|
|
|
11
11
|
|
|
12
12
|
class AudioBus;
|
|
13
13
|
|
|
14
|
-
class AudioBuffer
|
|
14
|
+
class AudioBuffer {
|
|
15
15
|
public:
|
|
16
16
|
explicit AudioBuffer(int numberOfChannels, size_t length, float sampleRate);
|
|
17
17
|
explicit AudioBuffer(std::shared_ptr<AudioBus> bus);
|
|
@@ -11,21 +11,30 @@
|
|
|
11
11
|
|
|
12
12
|
namespace audioapi {
|
|
13
13
|
AudioBufferBaseSourceNode::AudioBufferBaseSourceNode(
|
|
14
|
-
BaseAudioContext
|
|
14
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
15
15
|
bool pitchCorrection)
|
|
16
|
-
: AudioScheduledSourceNode(context),
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
: AudioScheduledSourceNode(context),
|
|
17
|
+
pitchCorrection_(pitchCorrection),
|
|
18
|
+
stretch_(std::make_shared<signalsmith::stretch::SignalsmithStretch<float>>()),
|
|
19
|
+
playbackRateBus_(
|
|
20
|
+
std::make_shared<AudioBus>(
|
|
21
|
+
RENDER_QUANTUM_SIZE * 3,
|
|
22
|
+
channelCount_,
|
|
23
|
+
context->getSampleRate())),
|
|
24
|
+
detuneParam_(
|
|
25
|
+
std::make_shared<AudioParam>(
|
|
26
|
+
0.0,
|
|
27
|
+
MOST_NEGATIVE_SINGLE_FLOAT,
|
|
28
|
+
MOST_POSITIVE_SINGLE_FLOAT,
|
|
29
|
+
context)),
|
|
30
|
+
playbackRateParam_(
|
|
31
|
+
std::make_shared<AudioParam>(
|
|
32
|
+
1.0,
|
|
33
|
+
MOST_NEGATIVE_SINGLE_FLOAT,
|
|
34
|
+
MOST_POSITIVE_SINGLE_FLOAT,
|
|
35
|
+
context)),
|
|
36
|
+
vReadIndex_(0.0),
|
|
37
|
+
onPositionChangedInterval_(static_cast<int>(context->getSampleRate() * 0.1f)) {}
|
|
29
38
|
|
|
30
39
|
std::shared_ptr<AudioParam> AudioBufferBaseSourceNode::getDetuneParam() const {
|
|
31
40
|
return detuneParam_;
|
|
@@ -44,8 +53,10 @@ void AudioBufferBaseSourceNode::setOnPositionChangedCallbackId(uint64_t callback
|
|
|
44
53
|
}
|
|
45
54
|
|
|
46
55
|
void AudioBufferBaseSourceNode::setOnPositionChangedInterval(int interval) {
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
57
|
+
onPositionChangedInterval_ =
|
|
58
|
+
static_cast<int>(context->getSampleRate() * static_cast<float>(interval) / 1000);
|
|
59
|
+
}
|
|
49
60
|
}
|
|
50
61
|
|
|
51
62
|
int AudioBufferBaseSourceNode::getOnPositionChangedInterval() const {
|
|
@@ -58,14 +69,22 @@ std::mutex &AudioBufferBaseSourceNode::getBufferLock() {
|
|
|
58
69
|
|
|
59
70
|
double AudioBufferBaseSourceNode::getInputLatency() const {
|
|
60
71
|
if (pitchCorrection_) {
|
|
61
|
-
|
|
72
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
73
|
+
return static_cast<double>(stretch_->inputLatency()) / context->getSampleRate();
|
|
74
|
+
} else {
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
62
77
|
}
|
|
63
78
|
return 0;
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
double AudioBufferBaseSourceNode::getOutputLatency() const {
|
|
67
82
|
if (pitchCorrection_) {
|
|
68
|
-
|
|
83
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
84
|
+
return static_cast<double>(stretch_->outputLatency()) / context->getSampleRate();
|
|
85
|
+
} else {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
69
88
|
}
|
|
70
89
|
return 0;
|
|
71
90
|
}
|
|
@@ -91,7 +110,12 @@ void AudioBufferBaseSourceNode::processWithPitchCorrection(
|
|
|
91
110
|
size_t startOffset = 0;
|
|
92
111
|
size_t offsetLength = 0;
|
|
93
112
|
|
|
94
|
-
|
|
113
|
+
std::shared_ptr<BaseAudioContext> context = context_.lock();
|
|
114
|
+
if (context == nullptr) {
|
|
115
|
+
processingBus->zero();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
auto time = context->getCurrentTime();
|
|
95
119
|
auto playbackRate =
|
|
96
120
|
std::clamp(playbackRateParam_->processKRateParam(framesToProcess, time), 0.0f, 3.0f);
|
|
97
121
|
auto detune =
|
|
@@ -101,7 +125,13 @@ void AudioBufferBaseSourceNode::processWithPitchCorrection(
|
|
|
101
125
|
|
|
102
126
|
auto framesNeededToStretch = static_cast<int>(playbackRate * static_cast<float>(framesToProcess));
|
|
103
127
|
|
|
104
|
-
updatePlaybackInfo(
|
|
128
|
+
updatePlaybackInfo(
|
|
129
|
+
playbackRateBus_,
|
|
130
|
+
framesNeededToStretch,
|
|
131
|
+
startOffset,
|
|
132
|
+
offsetLength,
|
|
133
|
+
context->getSampleRate(),
|
|
134
|
+
context->getCurrentSampleFrame());
|
|
105
135
|
|
|
106
136
|
if (playbackRate == 0.0f || (!isPlaying() && !isStopScheduled())) {
|
|
107
137
|
processingBus->zero();
|
|
@@ -126,8 +156,14 @@ void AudioBufferBaseSourceNode::processWithoutPitchCorrection(
|
|
|
126
156
|
size_t startOffset = 0;
|
|
127
157
|
size_t offsetLength = 0;
|
|
128
158
|
|
|
129
|
-
|
|
130
|
-
|
|
159
|
+
std::shared_ptr<BaseAudioContext> context = context_.lock();
|
|
160
|
+
if (context == nullptr) {
|
|
161
|
+
processingBus->zero();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
auto computedPlaybackRate =
|
|
165
|
+
getComputedPlaybackRateValue(framesToProcess, context->getCurrentTime());
|
|
166
|
+
updatePlaybackInfo(processingBus, framesToProcess, startOffset, offsetLength, context->getSampleRate(), context->getCurrentSampleFrame());
|
|
131
167
|
|
|
132
168
|
if (computedPlaybackRate == 0.0f || (!isPlaying() && !isStopScheduled())) {
|
|
133
169
|
processingBus->zero();
|
|
@@ -143,9 +179,7 @@ void AudioBufferBaseSourceNode::processWithoutPitchCorrection(
|
|
|
143
179
|
sendOnPositionChangedEvent();
|
|
144
180
|
}
|
|
145
181
|
|
|
146
|
-
float AudioBufferBaseSourceNode::getComputedPlaybackRateValue(int framesToProcess) {
|
|
147
|
-
auto time = context_->getCurrentTime();
|
|
148
|
-
|
|
182
|
+
float AudioBufferBaseSourceNode::getComputedPlaybackRateValue(int framesToProcess, double time) {
|
|
149
183
|
auto playbackRate = playbackRateParam_->processKRateParam(framesToProcess, time);
|
|
150
184
|
auto detune = std::pow(2.0f, detuneParam_->processKRateParam(framesToProcess, time) / 1200.0f);
|
|
151
185
|
|
|
@@ -14,7 +14,9 @@ class AudioParam;
|
|
|
14
14
|
|
|
15
15
|
class AudioBufferBaseSourceNode : public AudioScheduledSourceNode {
|
|
16
16
|
public:
|
|
17
|
-
explicit AudioBufferBaseSourceNode(
|
|
17
|
+
explicit AudioBufferBaseSourceNode(
|
|
18
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
19
|
+
bool pitchCorrection);
|
|
18
20
|
|
|
19
21
|
[[nodiscard]] std::shared_ptr<AudioParam> getDetuneParam() const;
|
|
20
22
|
[[nodiscard]] std::shared_ptr<AudioParam> getPlaybackRateParam() const;
|
|
@@ -58,7 +60,7 @@ class AudioBufferBaseSourceNode : public AudioScheduledSourceNode {
|
|
|
58
60
|
const std::shared_ptr<AudioBus> &processingBus,
|
|
59
61
|
int framesToProcess);
|
|
60
62
|
|
|
61
|
-
float getComputedPlaybackRateValue(int framesToProcess);
|
|
63
|
+
float getComputedPlaybackRateValue(int framesToProcess, double time);
|
|
62
64
|
|
|
63
65
|
virtual void processWithoutInterpolation(
|
|
64
66
|
const std::shared_ptr<AudioBus> &processingBus,
|
|
@@ -18,11 +18,10 @@
|
|
|
18
18
|
namespace audioapi {
|
|
19
19
|
|
|
20
20
|
AudioBufferQueueSourceNode::AudioBufferQueueSourceNode(
|
|
21
|
-
BaseAudioContext
|
|
21
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
22
22
|
bool pitchCorrection)
|
|
23
|
-
: AudioBufferBaseSourceNode(context, pitchCorrection) {
|
|
24
|
-
|
|
25
|
-
stretch_->presetDefault(channelCount_, context_->getSampleRate());
|
|
23
|
+
: AudioBufferBaseSourceNode(context, pitchCorrection), buffers_() {
|
|
24
|
+
stretch_->presetDefault(channelCount_, context->getSampleRate());
|
|
26
25
|
|
|
27
26
|
if (pitchCorrection) {
|
|
28
27
|
// If pitch correction is enabled, add extra frames at the end
|
|
@@ -31,7 +30,7 @@ AudioBufferQueueSourceNode::AudioBufferQueueSourceNode(
|
|
|
31
30
|
|
|
32
31
|
int extraTailFrames = static_cast<int>(stretch_->inputLatency() + stretch_->outputLatency());
|
|
33
32
|
tailBuffer_ =
|
|
34
|
-
std::make_shared<AudioBuffer>(channelCount_, extraTailFrames,
|
|
33
|
+
std::make_shared<AudioBuffer>(channelCount_, extraTailFrames, context->getSampleRate());
|
|
35
34
|
|
|
36
35
|
tailBuffer_->bus_->zero();
|
|
37
36
|
}
|
|
@@ -148,8 +147,12 @@ std::shared_ptr<AudioBus> AudioBufferQueueSourceNode::processNode(
|
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
double AudioBufferQueueSourceNode::getCurrentPosition() const {
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
151
|
+
return dsp::sampleFrameToTime(static_cast<int>(vReadIndex_), context->getSampleRate()) +
|
|
152
|
+
playedBuffersDuration_;
|
|
153
|
+
} else {
|
|
154
|
+
return 0.0;
|
|
155
|
+
}
|
|
153
156
|
}
|
|
154
157
|
|
|
155
158
|
/**
|
|
@@ -192,8 +195,10 @@ void AudioBufferQueueSourceNode::processWithoutInterpolation(
|
|
|
192
195
|
|
|
193
196
|
std::unordered_map<std::string, EventValue> body = {
|
|
194
197
|
{"bufferId", std::to_string(bufferId)}, {"isLast", buffers_.empty()}};
|
|
195
|
-
context_
|
|
196
|
-
|
|
198
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
199
|
+
context->audioEventHandlerRegistry_->invokeHandlerWithEventBody(
|
|
200
|
+
"ended", onEndedCallbackId_, body);
|
|
201
|
+
}
|
|
197
202
|
|
|
198
203
|
if (buffers_.empty()) {
|
|
199
204
|
if (addExtraTailFrames_) {
|
|
@@ -277,8 +282,10 @@ void AudioBufferQueueSourceNode::processWithInterpolation(
|
|
|
277
282
|
buffers_.pop();
|
|
278
283
|
|
|
279
284
|
std::unordered_map<std::string, EventValue> body = {{"bufferId", std::to_string(bufferId)}};
|
|
280
|
-
context_
|
|
281
|
-
|
|
285
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
286
|
+
context->audioEventHandlerRegistry_->invokeHandlerWithEventBody(
|
|
287
|
+
"ended", onEndedCallbackId_, body);
|
|
288
|
+
}
|
|
282
289
|
|
|
283
290
|
if (buffers_.empty()) {
|
|
284
291
|
processingBus->zero(writeIndex, framesLeft);
|
|
@@ -17,7 +17,9 @@ class AudioParam;
|
|
|
17
17
|
|
|
18
18
|
class AudioBufferQueueSourceNode : public AudioBufferBaseSourceNode {
|
|
19
19
|
public:
|
|
20
|
-
explicit AudioBufferQueueSourceNode(
|
|
20
|
+
explicit AudioBufferQueueSourceNode(
|
|
21
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
22
|
+
bool pitchCorrection);
|
|
21
23
|
~AudioBufferQueueSourceNode() override;
|
|
22
24
|
|
|
23
25
|
void stop(double when) override;
|
|
@@ -12,15 +12,16 @@
|
|
|
12
12
|
|
|
13
13
|
namespace audioapi {
|
|
14
14
|
|
|
15
|
-
AudioBufferSourceNode::AudioBufferSourceNode(
|
|
15
|
+
AudioBufferSourceNode::AudioBufferSourceNode(
|
|
16
|
+
std::shared_ptr<BaseAudioContext> context,
|
|
17
|
+
bool pitchCorrection)
|
|
16
18
|
: AudioBufferBaseSourceNode(context, pitchCorrection),
|
|
17
19
|
loop_(false),
|
|
18
20
|
loopSkip_(false),
|
|
19
21
|
loopStart_(0),
|
|
20
|
-
loopEnd_(0)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
loopEnd_(0),
|
|
23
|
+
buffer_(nullptr),
|
|
24
|
+
alignedBus_(nullptr) {
|
|
24
25
|
isInitialized_ = true;
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -61,7 +62,9 @@ void AudioBufferSourceNode::setLoopSkip(bool loopSkip) {
|
|
|
61
62
|
|
|
62
63
|
void AudioBufferSourceNode::setLoopStart(double loopStart) {
|
|
63
64
|
if (loopSkip_) {
|
|
64
|
-
|
|
65
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
66
|
+
vReadIndex_ = loopStart * context->getSampleRate();
|
|
67
|
+
}
|
|
65
68
|
}
|
|
66
69
|
loopStart_ = loopStart;
|
|
67
70
|
}
|
|
@@ -72,8 +75,9 @@ void AudioBufferSourceNode::setLoopEnd(double loopEnd) {
|
|
|
72
75
|
|
|
73
76
|
void AudioBufferSourceNode::setBuffer(const std::shared_ptr<AudioBuffer> &buffer) {
|
|
74
77
|
Locker locker(getBufferLock());
|
|
78
|
+
std::shared_ptr<BaseAudioContext> context = context_.lock();
|
|
75
79
|
|
|
76
|
-
if (
|
|
80
|
+
if (buffer == nullptr || context == nullptr) {
|
|
77
81
|
buffer_ = std::shared_ptr<AudioBuffer>(nullptr);
|
|
78
82
|
alignedBus_ = std::shared_ptr<AudioBus>(nullptr);
|
|
79
83
|
loopEnd_ = 0;
|
|
@@ -87,7 +91,7 @@ void AudioBufferSourceNode::setBuffer(const std::shared_ptr<AudioBuffer> &buffer
|
|
|
87
91
|
|
|
88
92
|
if (pitchCorrection_) {
|
|
89
93
|
int extraTailFrames =
|
|
90
|
-
static_cast<int>((getInputLatency() + getOutputLatency()) *
|
|
94
|
+
static_cast<int>((getInputLatency() + getOutputLatency()) * context->getSampleRate());
|
|
91
95
|
size_t totalSize = buffer_->getLength() + extraTailFrames;
|
|
92
96
|
|
|
93
97
|
alignedBus_ = std::make_shared<AudioBus>(totalSize, channelCount_, buffer_->getSampleRate());
|
|
@@ -97,11 +101,10 @@ void AudioBufferSourceNode::setBuffer(const std::shared_ptr<AudioBuffer> &buffer
|
|
|
97
101
|
} else {
|
|
98
102
|
alignedBus_ = std::make_shared<AudioBus>(*buffer_->bus_);
|
|
99
103
|
}
|
|
100
|
-
|
|
101
104
|
audioBus_ =
|
|
102
|
-
std::make_shared<AudioBus>(RENDER_QUANTUM_SIZE, channelCount_,
|
|
103
|
-
playbackRateBus_ =
|
|
104
|
-
|
|
105
|
+
std::make_shared<AudioBus>(RENDER_QUANTUM_SIZE, channelCount_, context->getSampleRate());
|
|
106
|
+
playbackRateBus_ = std::make_shared<AudioBus>(
|
|
107
|
+
RENDER_QUANTUM_SIZE * 3, channelCount_, context->getSampleRate());
|
|
105
108
|
|
|
106
109
|
loopEnd_ = buffer_->getDuration();
|
|
107
110
|
}
|
|
@@ -189,8 +192,15 @@ void AudioBufferSourceNode::processWithoutInterpolation(
|
|
|
189
192
|
auto readIndex = static_cast<size_t>(vReadIndex_);
|
|
190
193
|
size_t writeIndex = startOffset;
|
|
191
194
|
|
|
192
|
-
|
|
193
|
-
|
|
195
|
+
size_t frameStart;
|
|
196
|
+
size_t frameEnd;
|
|
197
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
198
|
+
frameStart = static_cast<size_t>(getVirtualStartFrame(context->getSampleRate()));
|
|
199
|
+
frameEnd = static_cast<size_t>(getVirtualEndFrame(context->getSampleRate()));
|
|
200
|
+
} else {
|
|
201
|
+
processingBus->zero();
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
194
204
|
size_t frameDelta = frameEnd - frameStart;
|
|
195
205
|
|
|
196
206
|
size_t framesLeft = offsetLength;
|
|
@@ -257,8 +267,15 @@ void AudioBufferSourceNode::processWithInterpolation(
|
|
|
257
267
|
|
|
258
268
|
size_t writeIndex = startOffset;
|
|
259
269
|
|
|
260
|
-
|
|
261
|
-
|
|
270
|
+
double vFrameStart;
|
|
271
|
+
double vFrameEnd;
|
|
272
|
+
if (std::shared_ptr<BaseAudioContext> context = context_.lock()) {
|
|
273
|
+
vFrameStart = getVirtualStartFrame(context->getSampleRate());
|
|
274
|
+
vFrameEnd = getVirtualEndFrame(context->getSampleRate());
|
|
275
|
+
} else {
|
|
276
|
+
processingBus->zero();
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
262
279
|
auto vFrameDelta = vFrameEnd - vFrameStart;
|
|
263
280
|
|
|
264
281
|
auto frameStart = static_cast<size_t>(vFrameStart);
|
|
@@ -305,15 +322,14 @@ void AudioBufferSourceNode::processWithInterpolation(
|
|
|
305
322
|
}
|
|
306
323
|
}
|
|
307
324
|
|
|
308
|
-
double AudioBufferSourceNode::getVirtualStartFrame() {
|
|
309
|
-
auto loopStartFrame = loopStart_ *
|
|
310
|
-
|
|
325
|
+
double AudioBufferSourceNode::getVirtualStartFrame(float sampleRate) {
|
|
326
|
+
auto loopStartFrame = loopStart_ * sampleRate;
|
|
311
327
|
return loop_ && loopStartFrame >= 0 && loopStart_ < loopEnd_ ? loopStartFrame : 0.0;
|
|
312
328
|
}
|
|
313
329
|
|
|
314
|
-
double AudioBufferSourceNode::getVirtualEndFrame() {
|
|
330
|
+
double AudioBufferSourceNode::getVirtualEndFrame(float sampleRate) {
|
|
315
331
|
auto inputBufferLength = static_cast<double>(alignedBus_->getSize());
|
|
316
|
-
auto loopEndFrame = loopEnd_ *
|
|
332
|
+
auto loopEndFrame = loopEnd_ * sampleRate;
|
|
317
333
|
|
|
318
334
|
return loop_ && loopEndFrame > 0 && loopStart_ < loopEnd_
|
|
319
335
|
? std::min(loopEndFrame, inputBufferLength)
|
|
@@ -16,7 +16,7 @@ class AudioParam;
|
|
|
16
16
|
|
|
17
17
|
class AudioBufferSourceNode : public AudioBufferBaseSourceNode {
|
|
18
18
|
public:
|
|
19
|
-
explicit AudioBufferSourceNode(BaseAudioContext
|
|
19
|
+
explicit AudioBufferSourceNode(std::shared_ptr<BaseAudioContext> context, bool pitchCorrection);
|
|
20
20
|
~AudioBufferSourceNode() override;
|
|
21
21
|
|
|
22
22
|
[[nodiscard]] bool getLoop() const;
|
|
@@ -69,8 +69,8 @@ class AudioBufferSourceNode : public AudioBufferBaseSourceNode {
|
|
|
69
69
|
size_t offsetLength,
|
|
70
70
|
float playbackRate) override;
|
|
71
71
|
|
|
72
|
-
double getVirtualStartFrame();
|
|
73
|
-
double getVirtualEndFrame();
|
|
72
|
+
double getVirtualStartFrame(float sampleRate);
|
|
73
|
+
double getVirtualEndFrame(float sampleRate);
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
} // namespace audioapi
|