react-native-audio-api 0.1.0 → 0.3.0-rc1
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/README.md +10 -8
- package/RNAudioAPI.podspec +5 -0
- package/android/CMakeLists.txt +21 -10
- package/android/libs/fftw3/arm64-v8a/libfftw3.a +0 -0
- package/android/libs/fftw3/armeabi-v7a/libfftw3.a +0 -0
- package/android/libs/fftw3/x86/libfftw3.a +0 -0
- package/android/libs/fftw3/x86_64/libfftw3.a +0 -0
- package/android/libs/include/fftw3/fftw3.h +413 -0
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +32 -2
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +6 -2
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +5 -3
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +5 -1
- package/common/cpp/HostObjects/AudioBufferHostObject.cpp +6 -0
- package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +13 -1
- package/common/cpp/HostObjects/AudioContextHostObject.cpp +12 -149
- package/common/cpp/HostObjects/AudioContextHostObject.h +8 -14
- package/common/cpp/HostObjects/AudioNodeHostObject.cpp +0 -6
- package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +240 -0
- package/common/cpp/HostObjects/BaseAudioContextHostObject.h +41 -0
- package/common/cpp/HostObjects/BiquadFilterNodeHostObject.cpp +44 -0
- package/common/cpp/HostObjects/OscillatorNodeHostObject.cpp +21 -0
- package/common/cpp/HostObjects/OscillatorNodeHostObject.h +1 -0
- package/common/cpp/HostObjects/PeriodicWaveHostObject.cpp +33 -0
- package/common/cpp/HostObjects/PeriodicWaveHostObject.h +33 -0
- package/common/cpp/core/AudioArray.cpp +117 -0
- package/common/cpp/core/AudioArray.h +48 -0
- package/common/cpp/core/AudioBuffer.cpp +23 -80
- package/common/cpp/core/AudioBuffer.h +12 -13
- package/common/cpp/core/AudioBufferSourceNode.cpp +112 -25
- package/common/cpp/core/AudioBufferSourceNode.h +10 -6
- package/common/cpp/core/AudioBus.cpp +518 -0
- package/common/cpp/core/AudioBus.h +83 -0
- package/common/cpp/core/AudioContext.cpp +7 -77
- package/common/cpp/core/AudioContext.h +3 -60
- package/common/cpp/core/AudioDestinationNode.cpp +27 -15
- package/common/cpp/core/AudioDestinationNode.h +13 -5
- package/common/cpp/core/AudioNode.cpp +184 -22
- package/common/cpp/core/AudioNode.h +37 -37
- package/common/cpp/core/AudioNodeManager.cpp +75 -0
- package/common/cpp/core/AudioNodeManager.h +42 -0
- package/common/cpp/core/AudioParam.cpp +8 -11
- package/common/cpp/core/AudioParam.h +8 -8
- package/common/cpp/core/AudioScheduledSourceNode.cpp +19 -5
- package/common/cpp/core/AudioScheduledSourceNode.h +6 -2
- package/common/cpp/core/BaseAudioContext.cpp +191 -0
- package/common/cpp/core/BaseAudioContext.h +87 -0
- package/common/cpp/core/BiquadFilterNode.cpp +92 -69
- package/common/cpp/core/BiquadFilterNode.h +53 -57
- package/common/cpp/core/GainNode.cpp +12 -12
- package/common/cpp/core/GainNode.h +5 -3
- package/common/cpp/core/OscillatorNode.cpp +38 -29
- package/common/cpp/core/OscillatorNode.h +29 -69
- package/common/cpp/core/ParamChange.h +6 -6
- package/common/cpp/core/PeriodicWave.cpp +362 -0
- package/common/cpp/core/PeriodicWave.h +119 -0
- package/common/cpp/core/StereoPannerNode.cpp +31 -30
- package/common/cpp/core/StereoPannerNode.h +6 -6
- package/common/cpp/types/BiquadFilterType.h +19 -0
- package/common/cpp/types/ChannelCountMode.h +10 -0
- package/common/cpp/types/ChannelInterpretation.h +10 -0
- package/common/cpp/types/ContextState.h +10 -0
- package/common/cpp/types/OscillatorType.h +11 -0
- package/common/cpp/utils/FFTFrame.h +67 -0
- package/common/cpp/utils/JsiPromise.cpp +59 -0
- package/common/cpp/utils/JsiPromise.h +42 -0
- package/common/cpp/utils/Locker.h +49 -0
- package/common/cpp/utils/VectorMath.cpp +88 -3
- package/common/cpp/utils/VectorMath.h +7 -1
- package/common/cpp/utils/android/FFTFrame.cpp +23 -0
- package/common/cpp/utils/ios/FFTFrame.cpp +29 -0
- package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.cpp +10 -0
- package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.h +3 -2
- package/common/cpp/wrappers/AudioBufferWrapper.h +5 -5
- package/common/cpp/wrappers/AudioContextWrapper.cpp +7 -60
- package/common/cpp/wrappers/AudioContextWrapper.h +5 -26
- package/common/cpp/wrappers/AudioNodeWrapper.h +5 -5
- package/common/cpp/wrappers/AudioParamWrapper.h +4 -4
- package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +83 -0
- package/common/cpp/wrappers/BaseAudioContextWrapper.h +50 -0
- package/common/cpp/wrappers/BiquadFilterNodeWrapper.cpp +9 -0
- package/common/cpp/wrappers/BiquadFilterNodeWrapper.h +9 -4
- package/common/cpp/wrappers/GainNodeWrapper.h +1 -1
- package/common/cpp/wrappers/OscillatorNodeWrapper.cpp +6 -0
- package/common/cpp/wrappers/OscillatorNodeWrapper.h +5 -2
- package/common/cpp/wrappers/PeriodicWaveWrapper.h +17 -0
- package/common/cpp/wrappers/StereoPannerNodeWrapper.h +1 -1
- package/ios/AudioAPIModule.h +20 -1
- package/ios/AudioAPIModule.mm +6 -4
- package/ios/AudioDecoder/AudioDecoder.h +17 -0
- package/ios/AudioDecoder/AudioDecoder.m +167 -0
- package/ios/AudioDecoder/IOSAudioDecoder.h +26 -0
- package/ios/AudioDecoder/IOSAudioDecoder.mm +40 -0
- package/ios/AudioPlayer/AudioPlayer.h +3 -2
- package/ios/AudioPlayer/AudioPlayer.m +14 -17
- package/ios/AudioPlayer/IOSAudioPlayer.h +7 -3
- package/ios/AudioPlayer/IOSAudioPlayer.mm +31 -7
- package/lib/module/core/AudioBuffer.js +37 -0
- package/lib/module/core/AudioBuffer.js.map +1 -0
- package/lib/module/core/AudioBufferSourceNode.js +28 -0
- package/lib/module/core/AudioBufferSourceNode.js.map +1 -0
- package/lib/module/core/AudioContext.js +10 -0
- package/lib/module/core/AudioContext.js.map +1 -0
- package/lib/module/core/AudioDestinationNode.js +7 -0
- package/lib/module/core/AudioDestinationNode.js.map +1 -0
- package/lib/module/core/AudioNode.js +22 -0
- package/lib/module/core/AudioNode.js.map +1 -0
- package/lib/module/core/AudioParam.js +35 -0
- package/lib/module/core/AudioParam.js.map +1 -0
- package/lib/module/core/AudioScheduledSourceNode.js +28 -0
- package/lib/module/core/AudioScheduledSourceNode.js.map +1 -0
- package/lib/module/core/BaseAudioContext.js +62 -0
- package/lib/module/core/BaseAudioContext.js.map +1 -0
- package/lib/module/core/BiquadFilterNode.js +25 -0
- package/lib/module/core/BiquadFilterNode.js.map +1 -0
- package/lib/module/core/GainNode.js +9 -0
- package/lib/module/core/GainNode.js.map +1 -0
- package/lib/module/core/OscillatorNode.js +24 -0
- package/lib/module/core/OscillatorNode.js.map +1 -0
- package/lib/module/core/PeriodicWave.js +8 -0
- package/lib/module/core/PeriodicWave.js.map +1 -0
- package/lib/module/core/StereoPannerNode.js +9 -0
- package/lib/module/core/StereoPannerNode.js.map +1 -0
- package/lib/module/core/types.js.map +1 -0
- package/lib/module/errors/IndexSizeError.js +8 -0
- package/lib/module/errors/IndexSizeError.js.map +1 -0
- package/lib/module/errors/InvalidAccessError.js +8 -0
- package/lib/module/errors/InvalidAccessError.js.map +1 -0
- package/lib/module/errors/InvalidStateError.js +8 -0
- package/lib/module/errors/InvalidStateError.js.map +1 -0
- package/lib/module/errors/RangeError.js +8 -0
- package/lib/module/errors/RangeError.js.map +1 -0
- package/lib/module/errors/index.js +5 -0
- package/lib/module/errors/index.js.map +1 -0
- package/lib/module/index.js +212 -15
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.native.js +18 -0
- package/lib/module/index.native.js.map +1 -0
- package/lib/module/interfaces.js +2 -0
- package/lib/module/interfaces.js.map +1 -0
- package/lib/module/utils/resolveAudioSource.js +10 -0
- package/lib/module/utils/resolveAudioSource.js.map +1 -0
- package/lib/typescript/core/AudioBuffer.d.ts +12 -0
- package/lib/typescript/core/AudioBuffer.d.ts.map +1 -0
- package/lib/typescript/core/AudioBufferSourceNode.d.ts +12 -0
- package/lib/typescript/core/AudioBufferSourceNode.d.ts.map +1 -0
- package/lib/typescript/core/AudioContext.d.ts +6 -0
- package/lib/typescript/core/AudioContext.d.ts.map +1 -0
- package/lib/typescript/core/AudioDestinationNode.d.ts +7 -0
- package/lib/typescript/core/AudioDestinationNode.d.ts.map +1 -0
- package/lib/typescript/core/AudioNode.d.ts +16 -0
- package/lib/typescript/core/AudioNode.d.ts.map +1 -0
- package/lib/typescript/core/AudioParam.d.ts +14 -0
- package/lib/typescript/core/AudioParam.d.ts.map +1 -0
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts +10 -0
- package/lib/typescript/core/AudioScheduledSourceNode.d.ts.map +1 -0
- package/lib/typescript/core/BaseAudioContext.d.ts +27 -0
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -0
- package/lib/typescript/core/BiquadFilterNode.d.ts +16 -0
- package/lib/typescript/core/BiquadFilterNode.d.ts.map +1 -0
- package/lib/typescript/core/GainNode.d.ts +9 -0
- package/lib/typescript/core/GainNode.d.ts.map +1 -0
- package/lib/typescript/core/OscillatorNode.d.ts +15 -0
- package/lib/typescript/core/OscillatorNode.d.ts.map +1 -0
- package/lib/typescript/core/PeriodicWave.d.ts +5 -0
- package/lib/typescript/core/PeriodicWave.d.ts.map +1 -0
- package/lib/typescript/core/StereoPannerNode.d.ts +9 -0
- package/lib/typescript/core/StereoPannerNode.d.ts.map +1 -0
- package/lib/typescript/core/types.d.ts +15 -0
- package/lib/typescript/core/types.d.ts.map +1 -0
- package/lib/typescript/errors/IndexSizeError.d.ts +5 -0
- package/lib/typescript/errors/IndexSizeError.d.ts.map +1 -0
- package/lib/typescript/errors/InvalidAccessError.d.ts +5 -0
- package/lib/typescript/errors/InvalidAccessError.d.ts.map +1 -0
- package/lib/typescript/errors/InvalidStateError.d.ts +5 -0
- package/lib/typescript/errors/InvalidStateError.d.ts.map +1 -0
- package/lib/typescript/errors/RangeError.d.ts +5 -0
- package/lib/typescript/errors/RangeError.d.ts.map +1 -0
- package/lib/typescript/errors/index.d.ts +5 -0
- package/lib/typescript/errors/index.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +88 -5
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/index.native.d.ts +14 -0
- package/lib/typescript/index.native.d.ts.map +1 -0
- package/lib/typescript/interfaces.d.ts +79 -0
- package/lib/typescript/interfaces.d.ts.map +1 -0
- package/lib/typescript/utils/resolveAudioSource.d.ts +3 -0
- package/lib/typescript/utils/resolveAudioSource.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/core/AudioBuffer.ts +68 -0
- package/src/core/AudioBufferSourceNode.ts +35 -0
- package/src/core/AudioContext.ts +12 -0
- package/src/core/AudioDestinationNode.ts +9 -0
- package/src/core/AudioNode.ts +38 -0
- package/src/core/AudioParam.ts +55 -0
- package/src/core/AudioScheduledSourceNode.ts +43 -0
- package/src/core/BaseAudioContext.ts +108 -0
- package/src/core/BiquadFilterNode.ts +49 -0
- package/src/core/GainNode.ts +13 -0
- package/src/core/OscillatorNode.ts +37 -0
- package/src/core/PeriodicWave.ts +10 -0
- package/src/core/StereoPannerNode.ts +13 -0
- package/src/core/types.ts +33 -0
- package/src/errors/IndexSizeError.ts +8 -0
- package/src/errors/InvalidAccessError.ts +8 -0
- package/src/errors/InvalidStateError.ts +8 -0
- package/src/errors/RangeError.ts +8 -0
- package/src/errors/index.ts +4 -0
- package/src/index.native.ts +25 -0
- package/src/index.ts +380 -40
- package/src/interfaces.ts +121 -0
- package/src/modules/global.d.ts +3 -3
- package/src/utils/resolveAudioSource.ts +14 -0
- package/lib/module/types.js.map +0 -1
- package/lib/typescript/types.d.ts +0 -76
- package/lib/typescript/types.d.ts.map +0 -1
- package/src/types.ts +0 -108
- /package/lib/module/{types.js → core/types.js} +0 -0
|
@@ -8,22 +8,22 @@
|
|
|
8
8
|
|
|
9
9
|
namespace audioapi {
|
|
10
10
|
|
|
11
|
-
class
|
|
11
|
+
class BaseAudioContext;
|
|
12
12
|
|
|
13
13
|
class AudioParam {
|
|
14
14
|
public:
|
|
15
15
|
explicit AudioParam(
|
|
16
|
-
|
|
16
|
+
BaseAudioContext *context,
|
|
17
17
|
float defaultValue,
|
|
18
18
|
float minValue,
|
|
19
19
|
float maxValue);
|
|
20
20
|
|
|
21
|
-
float getValue() const;
|
|
21
|
+
[[nodiscard]] float getValue() const;
|
|
22
22
|
float getValueAtTime(double time);
|
|
23
23
|
void setValue(float value);
|
|
24
|
-
float getDefaultValue() const;
|
|
25
|
-
float getMinValue() const;
|
|
26
|
-
float getMaxValue() const;
|
|
24
|
+
[[nodiscard]] float getDefaultValue() const;
|
|
25
|
+
[[nodiscard]] float getMinValue() const;
|
|
26
|
+
[[nodiscard]] float getMaxValue() const;
|
|
27
27
|
void setValueAtTime(float value, double startTime);
|
|
28
28
|
void linearRampToValueAtTime(float value, double endTime);
|
|
29
29
|
void exponentialRampToValueAtTime(float value, double endTime);
|
|
@@ -33,7 +33,7 @@ class AudioParam {
|
|
|
33
33
|
float defaultValue_;
|
|
34
34
|
float minValue_;
|
|
35
35
|
float maxValue_;
|
|
36
|
-
|
|
36
|
+
BaseAudioContext *context_;
|
|
37
37
|
std::set<ParamChange> changesQueue_;
|
|
38
38
|
|
|
39
39
|
double startTime_;
|
|
@@ -42,7 +42,7 @@ class AudioParam {
|
|
|
42
42
|
float endValue_;
|
|
43
43
|
std::function<float(double, double, float, float, double)> calculateValue_;
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
float checkValue(float value) const;
|
|
46
46
|
double getStartTime();
|
|
47
47
|
float getStartValue();
|
|
48
48
|
};
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
#include "AudioScheduledSourceNode.h"
|
|
2
|
-
#include "
|
|
2
|
+
#include "AudioNodeManager.h"
|
|
3
|
+
#include "BaseAudioContext.h"
|
|
3
4
|
|
|
4
5
|
namespace audioapi {
|
|
5
6
|
|
|
6
|
-
AudioScheduledSourceNode::AudioScheduledSourceNode(
|
|
7
|
-
: AudioNode(context),
|
|
7
|
+
AudioScheduledSourceNode::AudioScheduledSourceNode(BaseAudioContext *context)
|
|
8
|
+
: AudioNode(context), playbackState_(PlaybackState::UNSCHEDULED) {
|
|
8
9
|
numberOfInputs_ = 0;
|
|
10
|
+
isInitialized_ = true;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
void AudioScheduledSourceNode::start(double time) {
|
|
14
|
+
context_->getNodeManager()->addSourceNode(shared_from_this());
|
|
15
|
+
|
|
16
|
+
playbackState_ = PlaybackState::SCHEDULED;
|
|
12
17
|
waitAndExecute(time, [this](double time) { startPlayback(); });
|
|
13
18
|
}
|
|
14
19
|
|
|
@@ -16,12 +21,21 @@ void AudioScheduledSourceNode::stop(double time) {
|
|
|
16
21
|
waitAndExecute(time, [this](double time) { stopPlayback(); });
|
|
17
22
|
}
|
|
18
23
|
|
|
24
|
+
bool AudioScheduledSourceNode::isPlaying() {
|
|
25
|
+
return playbackState_ == PlaybackState::PLAYING;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
bool AudioScheduledSourceNode::isFinished() {
|
|
29
|
+
return playbackState_ == PlaybackState::FINISHED;
|
|
30
|
+
}
|
|
31
|
+
|
|
19
32
|
void AudioScheduledSourceNode::startPlayback() {
|
|
20
|
-
|
|
33
|
+
playbackState_ = PlaybackState::PLAYING;
|
|
21
34
|
}
|
|
22
35
|
|
|
23
36
|
void AudioScheduledSourceNode::stopPlayback() {
|
|
24
|
-
|
|
37
|
+
playbackState_ = PlaybackState::FINISHED;
|
|
38
|
+
disable();
|
|
25
39
|
}
|
|
26
40
|
|
|
27
41
|
void AudioScheduledSourceNode::waitAndExecute(
|
|
@@ -13,13 +13,17 @@ namespace audioapi {
|
|
|
13
13
|
|
|
14
14
|
class AudioScheduledSourceNode : public AudioNode {
|
|
15
15
|
public:
|
|
16
|
-
|
|
16
|
+
enum class PlaybackState { UNSCHEDULED, SCHEDULED, PLAYING, FINISHED };
|
|
17
|
+
explicit AudioScheduledSourceNode(BaseAudioContext *context);
|
|
17
18
|
|
|
18
19
|
void start(double time);
|
|
19
20
|
void stop(double time);
|
|
20
21
|
|
|
22
|
+
bool isFinished();
|
|
23
|
+
bool isPlaying();
|
|
24
|
+
|
|
21
25
|
protected:
|
|
22
|
-
std::atomic<
|
|
26
|
+
std::atomic<PlaybackState> playbackState_;
|
|
23
27
|
|
|
24
28
|
private:
|
|
25
29
|
void startPlayback();
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#ifdef ANDROID
|
|
2
|
+
#include "AudioPlayer.h"
|
|
3
|
+
#else
|
|
4
|
+
#include "IOSAudioDecoder.h"
|
|
5
|
+
#include "IOSAudioPlayer.h"
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
#include "BaseAudioContext.h"
|
|
9
|
+
|
|
10
|
+
#include "AudioArray.h"
|
|
11
|
+
#include "AudioBuffer.h"
|
|
12
|
+
#include "AudioBufferSourceNode.h"
|
|
13
|
+
#include "AudioBus.h"
|
|
14
|
+
#include "AudioDestinationNode.h"
|
|
15
|
+
#include "AudioNodeManager.h"
|
|
16
|
+
#include "BiquadFilterNode.h"
|
|
17
|
+
#include "ContextState.h"
|
|
18
|
+
#include "GainNode.h"
|
|
19
|
+
#include "OscillatorNode.h"
|
|
20
|
+
#include "StereoPannerNode.h"
|
|
21
|
+
|
|
22
|
+
namespace audioapi {
|
|
23
|
+
|
|
24
|
+
BaseAudioContext::BaseAudioContext() {
|
|
25
|
+
#ifdef ANDROID
|
|
26
|
+
audioPlayer_ = std::make_shared<AudioPlayer>(this->renderAudio());
|
|
27
|
+
#else
|
|
28
|
+
audioPlayer_ = std::make_shared<IOSAudioPlayer>(this->renderAudio());
|
|
29
|
+
audioDecoder_ =
|
|
30
|
+
std::make_shared<IOSAudioDecoder>(audioPlayer_->getSampleRate());
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
sampleRate_ = audioPlayer_->getSampleRate();
|
|
34
|
+
bufferSizeInFrames_ = audioPlayer_->getBufferSizeInFrames();
|
|
35
|
+
|
|
36
|
+
nodeManager_ = std::make_shared<AudioNodeManager>();
|
|
37
|
+
destination_ = std::make_shared<AudioDestinationNode>(this);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
BaseAudioContext::~BaseAudioContext() {
|
|
41
|
+
if (isRunning()) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
state_ = ContextState::CLOSED;
|
|
46
|
+
audioPlayer_->stop();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
std::string BaseAudioContext::getState() {
|
|
50
|
+
return BaseAudioContext::toString(state_);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
int BaseAudioContext::getSampleRate() const {
|
|
54
|
+
return sampleRate_;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
int BaseAudioContext::getBufferSizeInFrames() const {
|
|
58
|
+
return bufferSizeInFrames_;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
std::size_t BaseAudioContext::getCurrentSampleFrame() const {
|
|
62
|
+
return destination_->getCurrentSampleFrame();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
double BaseAudioContext::getCurrentTime() const {
|
|
66
|
+
return destination_->getCurrentTime();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
std::shared_ptr<AudioDestinationNode> BaseAudioContext::getDestination() {
|
|
70
|
+
return destination_;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
std::shared_ptr<OscillatorNode> BaseAudioContext::createOscillator() {
|
|
74
|
+
return std::make_shared<OscillatorNode>(this);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
std::shared_ptr<GainNode> BaseAudioContext::createGain() {
|
|
78
|
+
return std::make_shared<GainNode>(this);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
std::shared_ptr<StereoPannerNode> BaseAudioContext::createStereoPanner() {
|
|
82
|
+
return std::make_shared<StereoPannerNode>(this);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
std::shared_ptr<BiquadFilterNode> BaseAudioContext::createBiquadFilter() {
|
|
86
|
+
return std::make_shared<BiquadFilterNode>(this);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
std::shared_ptr<AudioBufferSourceNode> BaseAudioContext::createBufferSource() {
|
|
90
|
+
return std::make_shared<AudioBufferSourceNode>(this);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
std::shared_ptr<AudioBuffer> BaseAudioContext::createBuffer(
|
|
94
|
+
int numberOfChannels,
|
|
95
|
+
int length,
|
|
96
|
+
int sampleRate) {
|
|
97
|
+
return std::make_shared<AudioBuffer>(numberOfChannels, length, sampleRate);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
std::shared_ptr<PeriodicWave> BaseAudioContext::createPeriodicWave(
|
|
101
|
+
float *real,
|
|
102
|
+
float *imag,
|
|
103
|
+
bool disableNormalization,
|
|
104
|
+
int length) {
|
|
105
|
+
return std::make_shared<PeriodicWave>(
|
|
106
|
+
sampleRate_, real, imag, length, disableNormalization);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#ifdef ANDROID
|
|
110
|
+
std::shared_ptr<AudioBuffer> BaseAudioContext::decodeAudioDataSource(
|
|
111
|
+
const std::string &source) {
|
|
112
|
+
return {nullptr};
|
|
113
|
+
}
|
|
114
|
+
#else
|
|
115
|
+
std::shared_ptr<AudioBuffer> BaseAudioContext::decodeAudioDataSource(
|
|
116
|
+
const std::string &source) {
|
|
117
|
+
auto audioBus = audioDecoder_->decodeWithFilePath(source);
|
|
118
|
+
return std::make_shared<AudioBuffer>(audioBus);
|
|
119
|
+
}
|
|
120
|
+
#endif
|
|
121
|
+
|
|
122
|
+
std::function<void(AudioBus *, int)> BaseAudioContext::renderAudio() {
|
|
123
|
+
if (isClosed()) {
|
|
124
|
+
return [](AudioBus *, int) {};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return [this](AudioBus *data, int frames) {
|
|
128
|
+
destination_->renderAudio(data, frames);
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
AudioNodeManager *BaseAudioContext::getNodeManager() {
|
|
133
|
+
return nodeManager_.get();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
bool BaseAudioContext::isRunning() const {
|
|
137
|
+
return state_ == ContextState::RUNNING;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
bool BaseAudioContext::isClosed() const {
|
|
141
|
+
return state_ == ContextState::CLOSED;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
std::string BaseAudioContext::toString(ContextState state) {
|
|
145
|
+
switch (state) {
|
|
146
|
+
case ContextState::SUSPENDED:
|
|
147
|
+
return "suspended";
|
|
148
|
+
case ContextState::RUNNING:
|
|
149
|
+
return "running";
|
|
150
|
+
case ContextState::CLOSED:
|
|
151
|
+
return "closed";
|
|
152
|
+
default:
|
|
153
|
+
throw std::invalid_argument("Unknown context state");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
std::shared_ptr<PeriodicWave> BaseAudioContext::getBasicWaveForm(
|
|
158
|
+
OscillatorType type) {
|
|
159
|
+
switch (type) {
|
|
160
|
+
case OscillatorType::SINE:
|
|
161
|
+
if (cachedSineWave_ == nullptr) {
|
|
162
|
+
cachedSineWave_ =
|
|
163
|
+
std::make_shared<PeriodicWave>(sampleRate_, type, false);
|
|
164
|
+
}
|
|
165
|
+
return cachedSineWave_;
|
|
166
|
+
case OscillatorType::SQUARE:
|
|
167
|
+
if (cachedSquareWave_ == nullptr) {
|
|
168
|
+
cachedSquareWave_ =
|
|
169
|
+
std::make_shared<PeriodicWave>(sampleRate_, type, false);
|
|
170
|
+
}
|
|
171
|
+
return cachedSquareWave_;
|
|
172
|
+
case OscillatorType::SAWTOOTH:
|
|
173
|
+
if (cachedSawtoothWave_ == nullptr) {
|
|
174
|
+
cachedSawtoothWave_ =
|
|
175
|
+
std::make_shared<PeriodicWave>(sampleRate_, type, false);
|
|
176
|
+
}
|
|
177
|
+
return cachedSawtoothWave_;
|
|
178
|
+
case OscillatorType::TRIANGLE:
|
|
179
|
+
if (cachedTriangleWave_ == nullptr) {
|
|
180
|
+
cachedTriangleWave_ =
|
|
181
|
+
std::make_shared<PeriodicWave>(sampleRate_, type, false);
|
|
182
|
+
}
|
|
183
|
+
return cachedTriangleWave_;
|
|
184
|
+
case OscillatorType::CUSTOM:
|
|
185
|
+
throw std::invalid_argument(
|
|
186
|
+
"You can't get a custom wave form. You need to create it.");
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <functional>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <string>
|
|
6
|
+
#include <utility>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
#include "ContextState.h"
|
|
10
|
+
#include "OscillatorType.h"
|
|
11
|
+
|
|
12
|
+
namespace audioapi {
|
|
13
|
+
|
|
14
|
+
class AudioBus;
|
|
15
|
+
class GainNode;
|
|
16
|
+
class AudioBuffer;
|
|
17
|
+
class PeriodicWave;
|
|
18
|
+
class OscillatorNode;
|
|
19
|
+
class StereoPannerNode;
|
|
20
|
+
class AudioNodeManager;
|
|
21
|
+
class BiquadFilterNode;
|
|
22
|
+
class AudioDestinationNode;
|
|
23
|
+
class AudioBufferSourceNode;
|
|
24
|
+
|
|
25
|
+
#ifdef ANDROID
|
|
26
|
+
class AudioPlayer;
|
|
27
|
+
#else
|
|
28
|
+
class IOSAudioPlayer;
|
|
29
|
+
class IOSAudioDecoder;
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
class BaseAudioContext {
|
|
33
|
+
public:
|
|
34
|
+
BaseAudioContext();
|
|
35
|
+
~BaseAudioContext();
|
|
36
|
+
std::string getState();
|
|
37
|
+
[[nodiscard]] int getSampleRate() const;
|
|
38
|
+
[[nodiscard]] double getCurrentTime() const;
|
|
39
|
+
[[nodiscard]] int getBufferSizeInFrames() const;
|
|
40
|
+
[[nodiscard]] std::size_t getCurrentSampleFrame() const;
|
|
41
|
+
|
|
42
|
+
std::shared_ptr<AudioDestinationNode> getDestination();
|
|
43
|
+
std::shared_ptr<OscillatorNode> createOscillator();
|
|
44
|
+
std::shared_ptr<GainNode> createGain();
|
|
45
|
+
std::shared_ptr<StereoPannerNode> createStereoPanner();
|
|
46
|
+
std::shared_ptr<BiquadFilterNode> createBiquadFilter();
|
|
47
|
+
std::shared_ptr<AudioBufferSourceNode> createBufferSource();
|
|
48
|
+
static std::shared_ptr<AudioBuffer>
|
|
49
|
+
createBuffer(int numberOfChannels, int length, int sampleRate);
|
|
50
|
+
std::shared_ptr<PeriodicWave> createPeriodicWave(
|
|
51
|
+
float *real,
|
|
52
|
+
float *imag,
|
|
53
|
+
bool disableNormalization,
|
|
54
|
+
int length);
|
|
55
|
+
std::shared_ptr<AudioBuffer> decodeAudioDataSource(const std::string &source);
|
|
56
|
+
|
|
57
|
+
std::shared_ptr<PeriodicWave> getBasicWaveForm(OscillatorType type);
|
|
58
|
+
std::function<void(AudioBus *, int)> renderAudio();
|
|
59
|
+
|
|
60
|
+
AudioNodeManager *getNodeManager();
|
|
61
|
+
[[nodiscard]] bool isRunning() const;
|
|
62
|
+
[[nodiscard]] bool isClosed() const;
|
|
63
|
+
|
|
64
|
+
protected:
|
|
65
|
+
static std::string toString(ContextState state);
|
|
66
|
+
std::shared_ptr<AudioDestinationNode> destination_;
|
|
67
|
+
|
|
68
|
+
#ifdef ANDROID
|
|
69
|
+
std::shared_ptr<AudioPlayer> audioPlayer_;
|
|
70
|
+
#else
|
|
71
|
+
std::shared_ptr<IOSAudioPlayer> audioPlayer_;
|
|
72
|
+
std::shared_ptr<IOSAudioDecoder> audioDecoder_;
|
|
73
|
+
#endif
|
|
74
|
+
|
|
75
|
+
int sampleRate_;
|
|
76
|
+
int bufferSizeInFrames_;
|
|
77
|
+
ContextState state_ = ContextState::RUNNING;
|
|
78
|
+
std::shared_ptr<AudioNodeManager> nodeManager_;
|
|
79
|
+
|
|
80
|
+
private:
|
|
81
|
+
std::shared_ptr<PeriodicWave> cachedSineWave_ = nullptr;
|
|
82
|
+
std::shared_ptr<PeriodicWave> cachedSquareWave_ = nullptr;
|
|
83
|
+
std::shared_ptr<PeriodicWave> cachedSawtoothWave_ = nullptr;
|
|
84
|
+
std::shared_ptr<PeriodicWave> cachedTriangleWave_ = nullptr;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
} // namespace audioapi
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
#include "BiquadFilterNode.h"
|
|
2
|
-
#include "
|
|
2
|
+
#include "AudioArray.h"
|
|
3
|
+
#include "AudioBus.h"
|
|
4
|
+
#include "BaseAudioContext.h"
|
|
3
5
|
|
|
4
6
|
// https://webaudio.github.io/Audio-EQ-Cookbook/audio-eq-cookbook.html - math
|
|
5
7
|
// formulas for filters
|
|
6
|
-
// https://github.com/LabSound/LabSound/blob/main/src/internal/src/Biquad.cpp -
|
|
7
|
-
// implementation of filters on which I based mine
|
|
8
8
|
|
|
9
9
|
namespace audioapi {
|
|
10
10
|
|
|
11
|
-
BiquadFilterNode::BiquadFilterNode(
|
|
11
|
+
BiquadFilterNode::BiquadFilterNode(BaseAudioContext *context)
|
|
12
|
+
: AudioNode(context) {
|
|
12
13
|
frequencyParam_ = std::make_shared<AudioParam>(
|
|
13
14
|
context, 350.0, MIN_FILTER_FREQUENCY, MAX_FILTER_FREQUENCY);
|
|
14
15
|
detuneParam_ =
|
|
@@ -17,10 +18,11 @@ BiquadFilterNode::BiquadFilterNode(AudioContext *context) : AudioNode(context) {
|
|
|
17
18
|
std::make_shared<AudioParam>(context, 1.0, -MAX_FILTER_Q, MAX_FILTER_Q);
|
|
18
19
|
gainParam_ = std::make_shared<AudioParam>(
|
|
19
20
|
context, 0.0, MIN_FILTER_GAIN, MAX_FILTER_GAIN);
|
|
20
|
-
type_ =
|
|
21
|
+
type_ = BiquadFilterType::LOWPASS;
|
|
22
|
+
isInitialized_ = true;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
std::string BiquadFilterNode::getType()
|
|
25
|
+
std::string BiquadFilterNode::getType() {
|
|
24
26
|
return BiquadFilterNode::toString(type_);
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -44,8 +46,37 @@ std::shared_ptr<AudioParam> BiquadFilterNode::getGainParam() const {
|
|
|
44
46
|
return gainParam_;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
// Compute Z-transform of the filter
|
|
50
|
+
// https://www.dsprelated.com/freebooks/filters/Frequency_Response_Analysis.html
|
|
51
|
+
// https://www.dsprelated.com/freebooks/filters/Transfer_Function_Analysis.html
|
|
52
|
+
//
|
|
53
|
+
// frequency response - H(z) = (b0 + b1*z^(-1) + b2*z^(-2))/(1 + a1*z^(-1) +
|
|
54
|
+
// a2*z^(-2)) = ((b0 * z + b1) * z + b2) / ((z + a1) * z + a2) phase response -
|
|
55
|
+
// angle of the frequency response
|
|
56
|
+
|
|
57
|
+
void BiquadFilterNode::getFrequencyResponse(
|
|
58
|
+
const std::vector<float> &frequencyArray,
|
|
59
|
+
std::vector<float> &magResponseOutput,
|
|
60
|
+
std::vector<float> &phaseResponseOutput) {
|
|
61
|
+
applyFilter();
|
|
62
|
+
|
|
63
|
+
auto frequencyArraySize = frequencyArray.size();
|
|
64
|
+
|
|
65
|
+
float b0 = b0_;
|
|
66
|
+
float b1 = b1_;
|
|
67
|
+
float b2 = b2_;
|
|
68
|
+
float a1 = a1_;
|
|
69
|
+
float a2 = a2_;
|
|
70
|
+
|
|
71
|
+
for (size_t i = 0; i < frequencyArraySize; i++) {
|
|
72
|
+
auto omega =
|
|
73
|
+
static_cast<float>(M_PI) * frequencyArray[i] / NYQUIST_FREQUENCY;
|
|
74
|
+
auto z = std::complex<float>(cos(omega), sin(omega));
|
|
75
|
+
auto response = ((b0 * z + b1) * z + b2) / ((z + a1) * z + a2);
|
|
76
|
+
magResponseOutput[i] = static_cast<float>(abs(response));
|
|
77
|
+
phaseResponseOutput[i] =
|
|
78
|
+
static_cast<float>(atan2(imag(response), real(response)));
|
|
79
|
+
}
|
|
49
80
|
}
|
|
50
81
|
|
|
51
82
|
void BiquadFilterNode::resetCoefficients() {
|
|
@@ -62,16 +93,16 @@ void BiquadFilterNode::setNormalizedCoefficients(
|
|
|
62
93
|
float a0,
|
|
63
94
|
float a1,
|
|
64
95
|
float a2) {
|
|
65
|
-
auto
|
|
66
|
-
b0_ = b0 *
|
|
67
|
-
b1_ = b1 *
|
|
68
|
-
b2_ = b2 *
|
|
69
|
-
a1_ = a1 *
|
|
70
|
-
a2_ = a2 *
|
|
96
|
+
auto a0Inverted = 1.0f / a0;
|
|
97
|
+
b0_ = b0 * a0Inverted;
|
|
98
|
+
b1_ = b1 * a0Inverted;
|
|
99
|
+
b2_ = b2 * a0Inverted;
|
|
100
|
+
a1_ = a1 * a0Inverted;
|
|
101
|
+
a2_ = a2 * a0Inverted;
|
|
71
102
|
}
|
|
72
103
|
|
|
73
104
|
void BiquadFilterNode::setLowpassCoefficients(float frequency, float Q) {
|
|
74
|
-
frequency = clamp(frequency, 0.
|
|
105
|
+
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
75
106
|
if (frequency == 1.0) {
|
|
76
107
|
setNormalizedCoefficients(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
77
108
|
return;
|
|
@@ -83,20 +114,18 @@ void BiquadFilterNode::setLowpassCoefficients(float frequency, float Q) {
|
|
|
83
114
|
|
|
84
115
|
Q = std::max(0.0f, Q);
|
|
85
116
|
float g = std::pow(10.0f, 0.05f * Q);
|
|
86
|
-
float d = std::sqrt((4 - std::sqrt(16 - 16 / (g * g))) / 2);
|
|
87
117
|
|
|
88
118
|
float theta = M_PI * frequency;
|
|
89
|
-
float
|
|
90
|
-
float
|
|
91
|
-
float
|
|
92
|
-
float alpha = 0.25f * (0.5f + beta - gamma);
|
|
119
|
+
float alpha = std::sin(theta) / (2 * g);
|
|
120
|
+
float cosW = std::cos(theta);
|
|
121
|
+
float beta = (1 - cosW) / 2;
|
|
93
122
|
|
|
94
123
|
setNormalizedCoefficients(
|
|
95
|
-
2 *
|
|
124
|
+
beta, 2 * beta, beta, 1 + alpha, -2 * cosW, 1 - alpha);
|
|
96
125
|
}
|
|
97
126
|
|
|
98
127
|
void BiquadFilterNode::setHighpassCoefficients(float frequency, float Q) {
|
|
99
|
-
frequency = clamp(frequency, 0.
|
|
128
|
+
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
100
129
|
if (frequency == 1.0) {
|
|
101
130
|
setNormalizedCoefficients(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
102
131
|
return;
|
|
@@ -108,20 +137,18 @@ void BiquadFilterNode::setHighpassCoefficients(float frequency, float Q) {
|
|
|
108
137
|
|
|
109
138
|
Q = std::max(0.0f, Q);
|
|
110
139
|
float g = std::pow(10.0f, 0.05f * Q);
|
|
111
|
-
float d = std::sqrt((4 - std::sqrt(16 - 16 / (g * g))) / 2);
|
|
112
140
|
|
|
113
141
|
float theta = M_PI * frequency;
|
|
114
|
-
float
|
|
115
|
-
float
|
|
116
|
-
float
|
|
117
|
-
float alpha = 0.25f * (0.5f + beta - gamma);
|
|
142
|
+
float alpha = std::sin(theta) / (2 * g);
|
|
143
|
+
float cosW = std::cos(theta);
|
|
144
|
+
float beta = (1 - cosW) / 2;
|
|
118
145
|
|
|
119
146
|
setNormalizedCoefficients(
|
|
120
|
-
|
|
147
|
+
beta, -2 * beta, beta, 1 + alpha, -2 * cosW, 1 - alpha);
|
|
121
148
|
}
|
|
122
149
|
|
|
123
150
|
void BiquadFilterNode::setBandpassCoefficients(float frequency, float Q) {
|
|
124
|
-
frequency = clamp(frequency, 0.
|
|
151
|
+
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
125
152
|
Q = std::max(0.0f, Q);
|
|
126
153
|
|
|
127
154
|
if (frequency <= 0.0 || frequency >= 1.0) {
|
|
@@ -143,7 +170,7 @@ void BiquadFilterNode::setBandpassCoefficients(float frequency, float Q) {
|
|
|
143
170
|
}
|
|
144
171
|
|
|
145
172
|
void BiquadFilterNode::setLowshelfCoefficients(float frequency, float gain) {
|
|
146
|
-
frequency = clamp(frequency, 0.
|
|
173
|
+
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
147
174
|
float A = std::pow(10.0f, gain / 40.0f);
|
|
148
175
|
|
|
149
176
|
if (frequency == 1.0) {
|
|
@@ -172,7 +199,7 @@ void BiquadFilterNode::setLowshelfCoefficients(float frequency, float gain) {
|
|
|
172
199
|
}
|
|
173
200
|
|
|
174
201
|
void BiquadFilterNode::setHighshelfCoefficients(float frequency, float gain) {
|
|
175
|
-
frequency = clamp(frequency, 0.
|
|
202
|
+
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
176
203
|
float A = std::pow(10.0f, gain / 40.0f);
|
|
177
204
|
|
|
178
205
|
if (frequency == 1.0) {
|
|
@@ -204,7 +231,7 @@ void BiquadFilterNode::setPeakingCoefficients(
|
|
|
204
231
|
float frequency,
|
|
205
232
|
float Q,
|
|
206
233
|
float gain) {
|
|
207
|
-
frequency = clamp(frequency, 0.
|
|
234
|
+
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
208
235
|
Q = std::max(0.0f, Q);
|
|
209
236
|
float A = std::pow(10.0f, gain / 40.0f);
|
|
210
237
|
|
|
@@ -232,7 +259,7 @@ void BiquadFilterNode::setPeakingCoefficients(
|
|
|
232
259
|
}
|
|
233
260
|
|
|
234
261
|
void BiquadFilterNode::setNotchCoefficients(float frequency, float Q) {
|
|
235
|
-
frequency = clamp(frequency, 0.
|
|
262
|
+
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
236
263
|
Q = std::max(0.0f, Q);
|
|
237
264
|
|
|
238
265
|
if (frequency <= 0.0 || frequency >= 1.0) {
|
|
@@ -253,7 +280,7 @@ void BiquadFilterNode::setNotchCoefficients(float frequency, float Q) {
|
|
|
253
280
|
}
|
|
254
281
|
|
|
255
282
|
void BiquadFilterNode::setAllpassCoefficients(float frequency, float Q) {
|
|
256
|
-
frequency = clamp(frequency, 0.
|
|
283
|
+
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
257
284
|
Q = std::max(0.0f, Q);
|
|
258
285
|
|
|
259
286
|
if (frequency <= 0.0 || frequency >= 1.0) {
|
|
@@ -286,37 +313,37 @@ void BiquadFilterNode::applyFilter() {
|
|
|
286
313
|
}
|
|
287
314
|
|
|
288
315
|
switch (type_) {
|
|
289
|
-
case
|
|
316
|
+
case BiquadFilterType::LOWPASS:
|
|
290
317
|
setLowpassCoefficients(
|
|
291
318
|
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
292
319
|
break;
|
|
293
|
-
case
|
|
320
|
+
case BiquadFilterType::HIGHPASS:
|
|
294
321
|
setHighpassCoefficients(
|
|
295
322
|
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
296
323
|
break;
|
|
297
|
-
case
|
|
324
|
+
case BiquadFilterType::BANDPASS:
|
|
298
325
|
setBandpassCoefficients(
|
|
299
326
|
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
300
327
|
break;
|
|
301
|
-
case
|
|
328
|
+
case BiquadFilterType::LOWSHELF:
|
|
302
329
|
setLowshelfCoefficients(
|
|
303
330
|
normalizedFrequency, gainParam_->getValueAtTime(currentTime));
|
|
304
331
|
break;
|
|
305
|
-
case
|
|
332
|
+
case BiquadFilterType::HIGHSHELF:
|
|
306
333
|
setHighshelfCoefficients(
|
|
307
334
|
normalizedFrequency, gainParam_->getValueAtTime(currentTime));
|
|
308
335
|
break;
|
|
309
|
-
case
|
|
336
|
+
case BiquadFilterType::PEAKING:
|
|
310
337
|
setPeakingCoefficients(
|
|
311
338
|
normalizedFrequency,
|
|
312
339
|
QParam_->getValueAtTime(currentTime),
|
|
313
340
|
gainParam_->getValueAtTime(currentTime));
|
|
314
341
|
break;
|
|
315
|
-
case
|
|
342
|
+
case BiquadFilterType::NOTCH:
|
|
316
343
|
setNotchCoefficients(
|
|
317
344
|
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
318
345
|
break;
|
|
319
|
-
case
|
|
346
|
+
case BiquadFilterType::ALLPASS:
|
|
320
347
|
setAllpassCoefficients(
|
|
321
348
|
normalizedFrequency, QParam_->getValueAtTime(currentTime));
|
|
322
349
|
break;
|
|
@@ -325,40 +352,36 @@ void BiquadFilterNode::applyFilter() {
|
|
|
325
352
|
}
|
|
326
353
|
}
|
|
327
354
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
|
|
355
|
+
void BiquadFilterNode::processNode(
|
|
356
|
+
AudioBus *processingBus,
|
|
357
|
+
int framesToProcess) {
|
|
333
358
|
resetCoefficients();
|
|
334
359
|
applyFilter();
|
|
335
360
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
361
|
+
for (int c = 0; c < processingBus->getNumberOfChannels(); c += 1) {
|
|
362
|
+
float x1 = x1_;
|
|
363
|
+
float x2 = x2_;
|
|
364
|
+
float y1 = y1_;
|
|
365
|
+
float y2 = y2_;
|
|
340
366
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
367
|
+
float b0 = b0_;
|
|
368
|
+
float b1 = b1_;
|
|
369
|
+
float b2 = b2_;
|
|
370
|
+
float a1 = a1_;
|
|
371
|
+
float a2 = a2_;
|
|
346
372
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
static_cast<float>(b0 * input + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2);
|
|
373
|
+
for (int i = 0; i < framesToProcess; i += 1) {
|
|
374
|
+
float input = (*processingBus->getChannel(c))[i];
|
|
375
|
+
float output = b0 * input + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
|
|
351
376
|
|
|
352
|
-
|
|
353
|
-
audioData[i * channelCount_ + j] = output;
|
|
354
|
-
}
|
|
377
|
+
(*processingBus->getChannel(c))[i] = output;
|
|
355
378
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
379
|
+
x2 = x1;
|
|
380
|
+
x1 = input;
|
|
381
|
+
y2 = y1;
|
|
382
|
+
y1 = output;
|
|
383
|
+
}
|
|
360
384
|
}
|
|
361
|
-
|
|
362
|
-
return true;
|
|
363
385
|
}
|
|
386
|
+
|
|
364
387
|
} // namespace audioapi
|