react-native-audio-api 0.0.1 → 0.2.0
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 +60 -1
- package/RNAudioAPI.podspec +46 -0
- package/android/CMakeLists.txt +74 -0
- package/android/build.gradle +194 -0
- package/android/gradle.properties +5 -0
- 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/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.cpp +22 -0
- package/android/src/main/cpp/AudioAPIInstaller/AudioAPIInstaller.h +48 -0
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.cpp +66 -0
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +33 -0
- package/android/src/main/cpp/OnLoad.cpp +9 -0
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIPackage.kt +14 -0
- package/android/src/main/java/com/swmansion/audioapi/module/AudioAPIInstaller.kt +21 -0
- package/android/src/main/java/com/swmansion/audioapi/nativemodules/AudioAPIModule.kt +25 -0
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.cpp +52 -0
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerHostObject.h +45 -0
- package/common/cpp/AudioAPIInstaller/AudioAPIInstallerWrapper.h +38 -0
- package/common/cpp/AudioAPIInstaller/android/AudioAPIInstallerWrapper.cpp +16 -0
- package/common/cpp/AudioAPIInstaller/ios/AudioAPIInstallerWrapper.cpp +12 -0
- package/common/cpp/HostObjects/AudioBufferHostObject.cpp +143 -0
- package/common/cpp/HostObjects/AudioBufferHostObject.h +33 -0
- package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +79 -0
- package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.h +37 -0
- package/common/cpp/HostObjects/AudioContextHostObject.cpp +54 -0
- package/common/cpp/HostObjects/AudioContextHostObject.h +36 -0
- package/common/cpp/HostObjects/AudioDestinationNodeHostObject.cpp +33 -0
- package/common/cpp/HostObjects/AudioDestinationNodeHostObject.h +31 -0
- package/common/cpp/HostObjects/AudioNodeHostObject.cpp +102 -0
- package/common/cpp/HostObjects/AudioNodeHostObject.h +29 -0
- package/common/cpp/HostObjects/AudioParamHostObject.cpp +115 -0
- package/common/cpp/HostObjects/AudioParamHostObject.h +34 -0
- package/common/cpp/HostObjects/AudioScheduledSourceNodeHostObject.cpp +73 -0
- package/common/cpp/HostObjects/AudioScheduledSourceNodeHostObject.h +31 -0
- package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +214 -0
- package/common/cpp/HostObjects/BaseAudioContextHostObject.h +39 -0
- package/common/cpp/HostObjects/BiquadFilterNodeHostObject.cpp +125 -0
- package/common/cpp/HostObjects/BiquadFilterNodeHostObject.h +42 -0
- package/common/cpp/HostObjects/Constants.h +22 -0
- package/common/cpp/HostObjects/GainNodeHostObject.cpp +41 -0
- package/common/cpp/HostObjects/GainNodeHostObject.h +32 -0
- package/common/cpp/HostObjects/OscillatorNodeHostObject.cpp +88 -0
- package/common/cpp/HostObjects/OscillatorNodeHostObject.h +41 -0
- package/common/cpp/HostObjects/PeriodicWaveHostObject.cpp +33 -0
- package/common/cpp/HostObjects/PeriodicWaveHostObject.h +33 -0
- package/common/cpp/HostObjects/StereoPannerNodeHostObject.cpp +41 -0
- package/common/cpp/HostObjects/StereoPannerNodeHostObject.h +36 -0
- package/common/cpp/core/AudioArray.cpp +103 -0
- package/common/cpp/core/AudioArray.h +42 -0
- package/common/cpp/core/AudioBuffer.cpp +55 -0
- package/common/cpp/core/AudioBuffer.h +40 -0
- package/common/cpp/core/AudioBufferSourceNode.cpp +135 -0
- package/common/cpp/core/AudioBufferSourceNode.h +30 -0
- package/common/cpp/core/AudioBus.cpp +357 -0
- package/common/cpp/core/AudioBus.h +63 -0
- package/common/cpp/core/AudioContext.cpp +24 -0
- package/common/cpp/core/AudioContext.h +16 -0
- package/common/cpp/core/AudioDestinationNode.cpp +45 -0
- package/common/cpp/core/AudioDestinationNode.h +32 -0
- package/common/cpp/core/AudioNode.cpp +222 -0
- package/common/cpp/core/AudioNode.h +74 -0
- package/common/cpp/core/AudioNodeManager.cpp +72 -0
- package/common/cpp/core/AudioNodeManager.h +35 -0
- package/common/cpp/core/AudioParam.cpp +133 -0
- package/common/cpp/core/AudioParam.h +50 -0
- package/common/cpp/core/AudioScheduledSourceNode.cpp +53 -0
- package/common/cpp/core/AudioScheduledSourceNode.h +34 -0
- package/common/cpp/core/BaseAudioContext.cpp +157 -0
- package/common/cpp/core/BaseAudioContext.h +80 -0
- package/common/cpp/core/BiquadFilterNode.cpp +385 -0
- package/common/cpp/core/BiquadFilterNode.h +124 -0
- package/common/cpp/core/GainNode.cpp +30 -0
- package/common/cpp/core/GainNode.h +25 -0
- package/common/cpp/core/OscillatorNode.cpp +75 -0
- package/common/cpp/core/OscillatorNode.h +72 -0
- package/common/cpp/core/ParamChange.cpp +46 -0
- package/common/cpp/core/ParamChange.h +34 -0
- package/common/cpp/core/PeriodicWave.cpp +362 -0
- package/common/cpp/core/PeriodicWave.h +119 -0
- package/common/cpp/core/StereoPannerNode.cpp +56 -0
- package/common/cpp/core/StereoPannerNode.h +26 -0
- 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 +63 -0
- package/common/cpp/utils/Locker.h +47 -0
- package/common/cpp/utils/VectorMath.cpp +678 -0
- package/common/cpp/utils/VectorMath.h +71 -0
- package/common/cpp/utils/android/FFTFrame.cpp +22 -0
- package/common/cpp/utils/ios/FFTFrame.cpp +24 -0
- package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.cpp +45 -0
- package/common/cpp/wrappers/AudioBufferSourceNodeWrapper.h +26 -0
- package/common/cpp/wrappers/AudioBufferWrapper.cpp +46 -0
- package/common/cpp/wrappers/AudioBufferWrapper.h +30 -0
- package/common/cpp/wrappers/AudioContextWrapper.cpp +17 -0
- package/common/cpp/wrappers/AudioContextWrapper.h +19 -0
- package/common/cpp/wrappers/AudioDestinationNodeWrapper.h +16 -0
- package/common/cpp/wrappers/AudioNodeWrapper.cpp +37 -0
- package/common/cpp/wrappers/AudioNodeWrapper.h +25 -0
- package/common/cpp/wrappers/AudioParamWrapper.cpp +42 -0
- package/common/cpp/wrappers/AudioParamWrapper.h +25 -0
- package/common/cpp/wrappers/AudioScheduledSourceNodeWrapper.cpp +23 -0
- package/common/cpp/wrappers/AudioScheduledSourceNodeWrapper.h +23 -0
- package/common/cpp/wrappers/BaseAudioContextWrapper.cpp +76 -0
- package/common/cpp/wrappers/BaseAudioContextWrapper.h +49 -0
- package/common/cpp/wrappers/BiquadFilterNodeWrapper.cpp +60 -0
- package/common/cpp/wrappers/BiquadFilterNodeWrapper.h +37 -0
- package/common/cpp/wrappers/GainNodeWrapper.cpp +14 -0
- package/common/cpp/wrappers/GainNodeWrapper.h +20 -0
- package/common/cpp/wrappers/OscillatorNodeWrapper.cpp +44 -0
- package/common/cpp/wrappers/OscillatorNodeWrapper.h +31 -0
- package/common/cpp/wrappers/PeriodicWaveWrapper.h +17 -0
- package/common/cpp/wrappers/StereoPannerNodeWrapper.cpp +16 -0
- package/common/cpp/wrappers/StereoPannerNodeWrapper.h +21 -0
- package/ios/AudioAPIModule.h +24 -0
- package/ios/AudioAPIModule.mm +44 -0
- package/ios/AudioPlayer/AudioPlayer.h +28 -0
- package/ios/AudioPlayer/AudioPlayer.m +119 -0
- package/ios/AudioPlayer/IOSAudioPlayer.h +33 -0
- package/ios/AudioPlayer/IOSAudioPlayer.mm +57 -0
- 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 +57 -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 +2 -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 +18 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/interfaces.js +2 -0
- package/lib/module/interfaces.js.map +1 -0
- package/lib/module/modules/global.d.js +2 -0
- package/lib/module/modules/global.d.js.map +1 -0
- package/lib/module/utils/install.js +22 -0
- package/lib/module/utils/install.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 +26 -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 +9 -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 +14 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/interfaces.d.ts +78 -0
- package/lib/typescript/interfaces.d.ts.map +1 -0
- package/lib/typescript/utils/install.d.ts +7 -0
- package/lib/typescript/utils/install.d.ts.map +1 -0
- package/package.json +104 -5
- 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 +97 -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 +26 -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.ts +25 -0
- package/src/interfaces.ts +120 -0
- package/src/modules/global.d.ts +10 -0
- package/src/utils/install.ts +39 -0
- package/index.ts +0 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#ifdef ANDROID
|
|
2
|
+
#include "AudioPlayer.h"
|
|
3
|
+
#else
|
|
4
|
+
#include "IOSAudioPlayer.h"
|
|
5
|
+
#endif
|
|
6
|
+
|
|
7
|
+
#include "AudioContext.h"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
namespace audioapi {
|
|
11
|
+
|
|
12
|
+
AudioContext::AudioContext() : BaseAudioContext() {}
|
|
13
|
+
|
|
14
|
+
void AudioContext::close() {
|
|
15
|
+
state_ = ContextState::CLOSED;
|
|
16
|
+
|
|
17
|
+
if (audioPlayer_) {
|
|
18
|
+
audioPlayer_->stop();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
audioPlayer_.reset();
|
|
22
|
+
destination_.reset();
|
|
23
|
+
}
|
|
24
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#include "AudioBus.h"
|
|
2
|
+
#include "AudioNode.h"
|
|
3
|
+
#include "VectorMath.h"
|
|
4
|
+
#include "AudioNodeManager.h"
|
|
5
|
+
#include "BaseAudioContext.h"
|
|
6
|
+
#include "AudioDestinationNode.h"
|
|
7
|
+
|
|
8
|
+
namespace audioapi {
|
|
9
|
+
|
|
10
|
+
AudioDestinationNode::AudioDestinationNode(BaseAudioContext *context)
|
|
11
|
+
: AudioNode(context), currentSampleFrame_(0) {
|
|
12
|
+
numberOfOutputs_ = 0;
|
|
13
|
+
numberOfInputs_ = INT_MAX;
|
|
14
|
+
channelCountMode_ = ChannelCountMode::EXPLICIT;
|
|
15
|
+
isInitialized_ = true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
std::size_t AudioDestinationNode::getCurrentSampleFrame() const {
|
|
19
|
+
return currentSampleFrame_;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
double AudioDestinationNode::getCurrentTime() const {
|
|
23
|
+
return static_cast<double>(currentSampleFrame_) / context_->getSampleRate();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void AudioDestinationNode::renderAudio(AudioBus *destinationBus, int32_t numFrames) {
|
|
27
|
+
context_->getNodeManager()->preProcessGraph();
|
|
28
|
+
destinationBus->zero();
|
|
29
|
+
|
|
30
|
+
if (!numFrames) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
AudioBus* processedBus = processAudio(destinationBus, numFrames);
|
|
35
|
+
|
|
36
|
+
if (processedBus && processedBus != destinationBus) {
|
|
37
|
+
destinationBus->copy(processedBus);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
destinationBus->normalize();
|
|
41
|
+
|
|
42
|
+
currentSampleFrame_ += numFrames;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <vector>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <algorithm>
|
|
6
|
+
|
|
7
|
+
#include "AudioNode.h"
|
|
8
|
+
|
|
9
|
+
namespace audioapi {
|
|
10
|
+
|
|
11
|
+
class AudioBus;
|
|
12
|
+
class BaseAudioContext;
|
|
13
|
+
|
|
14
|
+
class AudioDestinationNode : public AudioNode {
|
|
15
|
+
public:
|
|
16
|
+
explicit AudioDestinationNode(BaseAudioContext *context);
|
|
17
|
+
|
|
18
|
+
void renderAudio(AudioBus* audioData, int32_t numFrames);
|
|
19
|
+
|
|
20
|
+
std::size_t getCurrentSampleFrame() const;
|
|
21
|
+
double getCurrentTime() const;
|
|
22
|
+
|
|
23
|
+
protected:
|
|
24
|
+
// DestinationNode is triggered by AudioContext using renderAudio
|
|
25
|
+
// processNode function is not necessary and is never called.
|
|
26
|
+
void processNode(AudioBus*, int) final { };
|
|
27
|
+
|
|
28
|
+
private:
|
|
29
|
+
std::size_t currentSampleFrame_;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#include <memory>
|
|
2
|
+
|
|
3
|
+
#include "AudioBus.h"
|
|
4
|
+
#include "AudioNode.h"
|
|
5
|
+
#include "BaseAudioContext.h"
|
|
6
|
+
#include "AudioNodeManager.h"
|
|
7
|
+
|
|
8
|
+
namespace audioapi {
|
|
9
|
+
|
|
10
|
+
AudioNode::AudioNode(BaseAudioContext *context) : context_(context) {
|
|
11
|
+
audioBus_ = std::make_shared<AudioBus>(context->getSampleRate(), context->getBufferSizeInFrames(), channelCount_);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
AudioNode::~AudioNode() {
|
|
15
|
+
isInitialized_ = false;
|
|
16
|
+
cleanup();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
int AudioNode::getNumberOfInputs() const {
|
|
20
|
+
return numberOfInputs_;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
int AudioNode::getNumberOfOutputs() const {
|
|
24
|
+
return numberOfOutputs_;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
int AudioNode::getChannelCount() const {
|
|
28
|
+
return channelCount_;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
std::string AudioNode::getChannelCountMode() const {
|
|
32
|
+
return AudioNode::toString(channelCountMode_);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
std::string AudioNode::getChannelInterpretation() const {
|
|
36
|
+
return AudioNode::toString(channelInterpretation_);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
void AudioNode::connect(const std::shared_ptr<AudioNode> &node) {
|
|
40
|
+
context_->getNodeManager()->addPendingConnection(shared_from_this(), node, AudioNodeManager::ConnectionType::CONNECT);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void AudioNode::connectNode(const std::shared_ptr<AudioNode> &node) {
|
|
44
|
+
outputNodes_.push_back(node);
|
|
45
|
+
node->onInputConnected(this);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
void AudioNode::disconnect(const std::shared_ptr<AudioNode> &node) {
|
|
49
|
+
context_->getNodeManager()->addPendingConnection(shared_from_this(), node, AudioNodeManager::ConnectionType::DISCONNECT);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void AudioNode::disconnectNode(const std::shared_ptr<AudioNode> &node) {
|
|
53
|
+
node->onInputDisconnected(this);
|
|
54
|
+
|
|
55
|
+
auto position = std::find(outputNodes_.begin(), outputNodes_.end(), node);
|
|
56
|
+
|
|
57
|
+
if (position != outputNodes_.end()) {
|
|
58
|
+
outputNodes_.erase(position);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
bool AudioNode::isEnabled() const {
|
|
63
|
+
return isEnabled_;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void AudioNode::enable() {
|
|
67
|
+
isEnabled_ = true;
|
|
68
|
+
|
|
69
|
+
for (auto it = outputNodes_.begin(); it != outputNodes_.end(); ++it) {
|
|
70
|
+
it->get()->onInputEnabled();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void AudioNode::disable() {
|
|
75
|
+
isEnabled_ = false;
|
|
76
|
+
|
|
77
|
+
for (auto it = outputNodes_.begin(); it != outputNodes_.end(); ++it) {
|
|
78
|
+
it->get()->onInputDisabled();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
std::string AudioNode::toString(ChannelCountMode mode) {
|
|
83
|
+
switch (mode) {
|
|
84
|
+
case ChannelCountMode::MAX:
|
|
85
|
+
return "max";
|
|
86
|
+
case ChannelCountMode::CLAMPED_MAX:
|
|
87
|
+
return "clamped-max";
|
|
88
|
+
case ChannelCountMode::EXPLICIT:
|
|
89
|
+
return "explicit";
|
|
90
|
+
default:
|
|
91
|
+
throw std::invalid_argument("Unknown channel count mode");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
std::string AudioNode::toString(ChannelInterpretation interpretation) {
|
|
96
|
+
switch (interpretation) {
|
|
97
|
+
case ChannelInterpretation::SPEAKERS:
|
|
98
|
+
return "speakers";
|
|
99
|
+
case ChannelInterpretation::DISCRETE:
|
|
100
|
+
return "discrete";
|
|
101
|
+
default:
|
|
102
|
+
throw std::invalid_argument("Unknown channel interpretation");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
AudioBus* AudioNode::processAudio(AudioBus* outputBus, int framesToProcess) {
|
|
107
|
+
if (!isInitialized_) {
|
|
108
|
+
return outputBus;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
std::size_t currentSampleFrame = context_->getCurrentSampleFrame();
|
|
112
|
+
|
|
113
|
+
// check if the node has already been processed for this rendering quantum
|
|
114
|
+
bool isAlreadyProcessed = currentSampleFrame == lastRenderedFrame_;
|
|
115
|
+
|
|
116
|
+
// Node can't use output bus if:
|
|
117
|
+
// - outputBus is not provided, which means that next node is doing a multi-node summing.
|
|
118
|
+
// - it has more than one input, which means that it has to sum all inputs using internal bus.
|
|
119
|
+
// - it has more than one output, so each output node can get the processed data without re-calculating the node.
|
|
120
|
+
bool canUseOutputBus = outputBus != 0 && inputNodes_.size() < 2 && outputNodes_.size() < 2;
|
|
121
|
+
|
|
122
|
+
if (isAlreadyProcessed) {
|
|
123
|
+
// If it was already processed in the rendering quantum, return it.
|
|
124
|
+
return audioBus_.get();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Update the last rendered frame before processing node and its inputs.
|
|
128
|
+
lastRenderedFrame_ = currentSampleFrame;
|
|
129
|
+
|
|
130
|
+
AudioBus* processingBus = canUseOutputBus ? outputBus : audioBus_.get();
|
|
131
|
+
|
|
132
|
+
if (!canUseOutputBus) {
|
|
133
|
+
// Clear the bus before summing all connected nodes.
|
|
134
|
+
processingBus->zero();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (inputNodes_.empty()) {
|
|
138
|
+
// If there are no connected inputs, process the node just to advance the audio params.
|
|
139
|
+
// The node will output silence anyway.
|
|
140
|
+
processNode(processingBus, framesToProcess);
|
|
141
|
+
return processingBus;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (auto it = inputNodes_.begin(); it != inputNodes_.end(); ++it) {
|
|
145
|
+
if (!(*it)->isEnabled()) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Process first connected node, it can be directly connected to the processingBus,
|
|
150
|
+
// resulting in one less summing operation.
|
|
151
|
+
if (it == inputNodes_.begin()) {
|
|
152
|
+
AudioBus* inputBus = (*it)->processAudio(processingBus, framesToProcess);
|
|
153
|
+
|
|
154
|
+
if (inputBus != processingBus) {
|
|
155
|
+
processingBus->sum(inputBus);
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
// Enforce the summing to be done using the internal bus.
|
|
159
|
+
AudioBus* inputBus = (*it)->processAudio(0, framesToProcess);
|
|
160
|
+
if (inputBus) {
|
|
161
|
+
processingBus->sum(inputBus);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Finally, process the node itself.
|
|
167
|
+
processNode(processingBus, framesToProcess);
|
|
168
|
+
|
|
169
|
+
return processingBus;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
void AudioNode::cleanup() {
|
|
173
|
+
outputNodes_.clear();
|
|
174
|
+
inputNodes_.clear();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
void AudioNode::onInputEnabled() {
|
|
178
|
+
numberOfEnabledInputNodes_ += 1;
|
|
179
|
+
|
|
180
|
+
if (!isEnabled()) {
|
|
181
|
+
enable();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
void AudioNode::onInputDisabled() {
|
|
186
|
+
numberOfEnabledInputNodes_ -= 1;
|
|
187
|
+
|
|
188
|
+
if (isEnabled() && numberOfEnabledInputNodes_ == 0) {
|
|
189
|
+
disable();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
void AudioNode::onInputConnected(AudioNode *node) {
|
|
194
|
+
inputNodes_.push_back(node);
|
|
195
|
+
|
|
196
|
+
if (node->isEnabled()) {
|
|
197
|
+
onInputEnabled();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
void AudioNode::onInputDisconnected(AudioNode *node) {
|
|
202
|
+
auto position = std::find(inputNodes_.begin(), inputNodes_.end(), node);
|
|
203
|
+
|
|
204
|
+
if (position != inputNodes_.end()) {
|
|
205
|
+
inputNodes_.erase(position);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
if (inputNodes_.size() > 0) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (isEnabled()) {
|
|
214
|
+
node->onInputDisabled();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
for (auto outputNode : outputNodes_) {
|
|
218
|
+
disconnectNode(outputNode);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <memory>
|
|
4
|
+
#include <string>
|
|
5
|
+
#include <vector>
|
|
6
|
+
|
|
7
|
+
#include "Constants.h"
|
|
8
|
+
#include "ChannelCountMode.h"
|
|
9
|
+
#include "ChannelInterpretation.h"
|
|
10
|
+
|
|
11
|
+
namespace audioapi {
|
|
12
|
+
|
|
13
|
+
class AudioBus;
|
|
14
|
+
class BaseAudioContext;
|
|
15
|
+
|
|
16
|
+
class AudioNode : public std::enable_shared_from_this<AudioNode> {
|
|
17
|
+
public:
|
|
18
|
+
explicit AudioNode(BaseAudioContext *context);
|
|
19
|
+
virtual ~AudioNode();
|
|
20
|
+
int getNumberOfInputs() const;
|
|
21
|
+
int getNumberOfOutputs() const;
|
|
22
|
+
int getChannelCount() const;
|
|
23
|
+
std::string getChannelCountMode() const;
|
|
24
|
+
std::string getChannelInterpretation() const;
|
|
25
|
+
void connect(const std::shared_ptr<AudioNode> &node);
|
|
26
|
+
void disconnect(const std::shared_ptr<AudioNode> &node);
|
|
27
|
+
|
|
28
|
+
bool isEnabled() const;
|
|
29
|
+
void enable();
|
|
30
|
+
void disable();
|
|
31
|
+
|
|
32
|
+
protected:
|
|
33
|
+
friend class AudioNodeManager;
|
|
34
|
+
friend class AudioDestinationNode;
|
|
35
|
+
|
|
36
|
+
BaseAudioContext *context_;
|
|
37
|
+
std::shared_ptr<AudioBus> audioBus_;
|
|
38
|
+
|
|
39
|
+
int channelCount_ = CHANNEL_COUNT;
|
|
40
|
+
|
|
41
|
+
int numberOfInputs_ = 1;
|
|
42
|
+
int numberOfOutputs_ = 1;
|
|
43
|
+
int numberOfEnabledInputNodes_ = 0;
|
|
44
|
+
|
|
45
|
+
bool isInitialized_ = false;
|
|
46
|
+
bool isEnabled_ = true;
|
|
47
|
+
|
|
48
|
+
std::size_t lastRenderedFrame_ { SIZE_MAX };
|
|
49
|
+
|
|
50
|
+
ChannelCountMode channelCountMode_ = ChannelCountMode::MAX;
|
|
51
|
+
ChannelInterpretation channelInterpretation_ =
|
|
52
|
+
ChannelInterpretation::SPEAKERS;
|
|
53
|
+
|
|
54
|
+
std::vector<AudioNode*> inputNodes_ = {};
|
|
55
|
+
std::vector<std::shared_ptr<AudioNode>> outputNodes_ = {};
|
|
56
|
+
|
|
57
|
+
private:
|
|
58
|
+
static std::string toString(ChannelCountMode mode);
|
|
59
|
+
static std::string toString(ChannelInterpretation interpretation);
|
|
60
|
+
|
|
61
|
+
void cleanup();
|
|
62
|
+
AudioBus* processAudio(AudioBus* outputBus, int framesToProcess);
|
|
63
|
+
virtual void processNode(AudioBus* processingBus, int framesToProcess) = 0;
|
|
64
|
+
|
|
65
|
+
void connectNode(const std::shared_ptr<AudioNode> &node);
|
|
66
|
+
void disconnectNode(const std::shared_ptr<AudioNode> &node);
|
|
67
|
+
|
|
68
|
+
void onInputEnabled();
|
|
69
|
+
void onInputDisabled();
|
|
70
|
+
void onInputConnected(AudioNode *node);
|
|
71
|
+
void onInputDisconnected(AudioNode *node);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
|
|
2
|
+
#include "Locker.h"
|
|
3
|
+
#include "AudioNode.h"
|
|
4
|
+
#include "AudioNodeManager.h"
|
|
5
|
+
|
|
6
|
+
namespace audioapi {
|
|
7
|
+
|
|
8
|
+
AudioNodeManager::AudioNodeManager() {}
|
|
9
|
+
|
|
10
|
+
AudioNodeManager::~AudioNodeManager() {
|
|
11
|
+
audioNodesToConnect_.clear();
|
|
12
|
+
sourceNodes_.clear();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
void AudioNodeManager::addPendingConnection(const std::shared_ptr<AudioNode> &from, const std::shared_ptr<AudioNode> &to, ConnectionType type) {
|
|
16
|
+
Locker lock(getGraphLock());
|
|
17
|
+
|
|
18
|
+
audioNodesToConnect_.push_back(std::make_tuple(from, to, type));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
void AudioNodeManager::addSourceNode(const std::shared_ptr<AudioNode> &node) {
|
|
22
|
+
Locker lock(getGraphLock());
|
|
23
|
+
|
|
24
|
+
sourceNodes_.push_back(node);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
void AudioNodeManager::preProcessGraph() {
|
|
28
|
+
if (!Locker::tryLock(getGraphLock())) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
settlePendingConnections();
|
|
33
|
+
removeFinishedSourceNodes();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
std::mutex& AudioNodeManager::getGraphLock() {
|
|
37
|
+
return graphLock_;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
void AudioNodeManager::settlePendingConnections() {
|
|
41
|
+
for (auto& connection : audioNodesToConnect_) {
|
|
42
|
+
std::shared_ptr<AudioNode> from = std::get<0>(connection);
|
|
43
|
+
std::shared_ptr<AudioNode> to = std::get<1>(connection);
|
|
44
|
+
ConnectionType type = std::get<2>(connection);
|
|
45
|
+
|
|
46
|
+
if (type == ConnectionType::CONNECT) {
|
|
47
|
+
from->connectNode(to);
|
|
48
|
+
} else {
|
|
49
|
+
from->disconnectNode(to);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
audioNodesToConnect_.clear();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void AudioNodeManager::removeFinishedSourceNodes() {
|
|
57
|
+
for (auto it = sourceNodes_.begin(); it != sourceNodes_.end();) {
|
|
58
|
+
auto currentNode = it->get();
|
|
59
|
+
// Release the source node if use count is equal to 1 (this vector)
|
|
60
|
+
if (!currentNode->isEnabled() && it->use_count() == 1) {
|
|
61
|
+
for (auto& outputNode : currentNode->outputNodes_) {
|
|
62
|
+
currentNode->disconnectNode(outputNode);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
it = sourceNodes_.erase(it);
|
|
66
|
+
} else {
|
|
67
|
+
++it;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <mutex>
|
|
4
|
+
#include <tuple>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <vector>
|
|
7
|
+
|
|
8
|
+
namespace audioapi {
|
|
9
|
+
|
|
10
|
+
class AudioNode;
|
|
11
|
+
|
|
12
|
+
class AudioNodeManager {
|
|
13
|
+
public:
|
|
14
|
+
enum class ConnectionType { CONNECT, DISCONNECT };
|
|
15
|
+
AudioNodeManager();
|
|
16
|
+
~AudioNodeManager();
|
|
17
|
+
|
|
18
|
+
void preProcessGraph();
|
|
19
|
+
void addPendingConnection(const std::shared_ptr<AudioNode> &from, const std::shared_ptr<AudioNode> &to, ConnectionType type);
|
|
20
|
+
|
|
21
|
+
void addSourceNode(const std::shared_ptr<AudioNode> &node);
|
|
22
|
+
|
|
23
|
+
std::mutex& getGraphLock();
|
|
24
|
+
|
|
25
|
+
private:
|
|
26
|
+
std::mutex graphLock_;
|
|
27
|
+
|
|
28
|
+
std::vector<std::shared_ptr<AudioNode>> sourceNodes_;
|
|
29
|
+
std::vector<std::tuple<std::shared_ptr<AudioNode>, std::shared_ptr<AudioNode>, ConnectionType>> audioNodesToConnect_;
|
|
30
|
+
|
|
31
|
+
void settlePendingConnections();
|
|
32
|
+
void removeFinishedSourceNodes();
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#include "AudioParam.h"
|
|
2
|
+
#include "BaseAudioContext.h"
|
|
3
|
+
|
|
4
|
+
namespace audioapi {
|
|
5
|
+
|
|
6
|
+
AudioParam::AudioParam(
|
|
7
|
+
BaseAudioContext *context,
|
|
8
|
+
float defaultValue,
|
|
9
|
+
float minValue,
|
|
10
|
+
float maxValue)
|
|
11
|
+
: value_(defaultValue),
|
|
12
|
+
defaultValue_(defaultValue),
|
|
13
|
+
minValue_(minValue),
|
|
14
|
+
maxValue_(maxValue),
|
|
15
|
+
context_(context),
|
|
16
|
+
changesQueue_() {
|
|
17
|
+
startTime_ = 0;
|
|
18
|
+
endTime_ = 0;
|
|
19
|
+
startValue_ = 0;
|
|
20
|
+
endValue_ = 0;
|
|
21
|
+
calculateValue_ = [this](double, double, float, float, double) {
|
|
22
|
+
return value_;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
float AudioParam::getValue() const {
|
|
27
|
+
return value_;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
float AudioParam::getDefaultValue() const {
|
|
31
|
+
return defaultValue_;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
float AudioParam::getMinValue() const {
|
|
35
|
+
return minValue_;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
float AudioParam::getMaxValue() const {
|
|
39
|
+
return maxValue_;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void AudioParam::setValue(float value) {
|
|
43
|
+
value_ = checkValue(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
float AudioParam::getValueAtTime(double time) {
|
|
47
|
+
if (!changesQueue_.empty()) {
|
|
48
|
+
if (endTime_ < time) {
|
|
49
|
+
auto change = *changesQueue_.begin();
|
|
50
|
+
startTime_ = change.getStartTime();
|
|
51
|
+
endTime_ = change.getEndTime();
|
|
52
|
+
startValue_ = change.getStartValue();
|
|
53
|
+
endValue_ = change.getEndValue();
|
|
54
|
+
calculateValue_ = change.getCalculateValue();
|
|
55
|
+
changesQueue_.erase(changesQueue_.begin());
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (startTime_ <= time) {
|
|
60
|
+
value_ =
|
|
61
|
+
calculateValue_(startTime_, endTime_, startValue_, endValue_, time);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return value_;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
void AudioParam::setValueAtTime(float value, double time) {
|
|
68
|
+
value = checkValue(value);
|
|
69
|
+
auto calculateValue = [](double, double, float, float endValue, double) {
|
|
70
|
+
return endValue;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
auto paramChange = ParamChange(time, time, value, value, calculateValue);
|
|
74
|
+
changesQueue_.insert(paramChange);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void AudioParam::linearRampToValueAtTime(float value, double time) {
|
|
78
|
+
value = checkValue(value);
|
|
79
|
+
auto calculateValue = [](double startTime,
|
|
80
|
+
double endTime,
|
|
81
|
+
float startValue,
|
|
82
|
+
float endValue,
|
|
83
|
+
double time) {
|
|
84
|
+
return time >= endTime ? endValue
|
|
85
|
+
: startValue +
|
|
86
|
+
(endValue - startValue) * (time - startTime) /
|
|
87
|
+
(endTime - startTime);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
auto paramChange =
|
|
91
|
+
ParamChange(getStartTime(), time, getStartValue(), value, calculateValue);
|
|
92
|
+
changesQueue_.emplace(paramChange);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
void AudioParam::exponentialRampToValueAtTime(float value, double time) {
|
|
96
|
+
value = checkValue(value);
|
|
97
|
+
auto calculateValue = [](double startTime,
|
|
98
|
+
double endTime,
|
|
99
|
+
float startValue,
|
|
100
|
+
float endValue,
|
|
101
|
+
double time) {
|
|
102
|
+
return time >= endTime ? endValue
|
|
103
|
+
: startValue *
|
|
104
|
+
pow(endValue / startValue,
|
|
105
|
+
(time - startTime) / (endTime - startTime));
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
auto paramChange =
|
|
109
|
+
ParamChange(getStartTime(), time, getStartValue(), value, calculateValue);
|
|
110
|
+
changesQueue_.emplace(paramChange);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
float AudioParam::checkValue(float value) const {
|
|
114
|
+
return std::clamp(value, minValue_, maxValue_);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
double AudioParam::getStartTime() {
|
|
118
|
+
if (changesQueue_.empty()) {
|
|
119
|
+
return context_->getCurrentTime();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return changesQueue_.rbegin()->getEndTime();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
float AudioParam::getStartValue() {
|
|
126
|
+
if (changesQueue_.empty()) {
|
|
127
|
+
return this->value_;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return changesQueue_.rbegin()->getEndValue();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <memory>
|
|
4
|
+
#include <set>
|
|
5
|
+
#include <vector>
|
|
6
|
+
|
|
7
|
+
#include "ParamChange.h"
|
|
8
|
+
|
|
9
|
+
namespace audioapi {
|
|
10
|
+
|
|
11
|
+
class BaseAudioContext;
|
|
12
|
+
|
|
13
|
+
class AudioParam {
|
|
14
|
+
public:
|
|
15
|
+
explicit AudioParam(
|
|
16
|
+
BaseAudioContext *context,
|
|
17
|
+
float defaultValue,
|
|
18
|
+
float minValue,
|
|
19
|
+
float maxValue);
|
|
20
|
+
|
|
21
|
+
[[nodiscard]] float getValue() const;
|
|
22
|
+
float getValueAtTime(double time);
|
|
23
|
+
void setValue(float value);
|
|
24
|
+
[[nodiscard]] float getDefaultValue() const;
|
|
25
|
+
[[nodiscard]] float getMinValue() const;
|
|
26
|
+
[[nodiscard]] float getMaxValue() const;
|
|
27
|
+
void setValueAtTime(float value, double startTime);
|
|
28
|
+
void linearRampToValueAtTime(float value, double endTime);
|
|
29
|
+
void exponentialRampToValueAtTime(float value, double endTime);
|
|
30
|
+
|
|
31
|
+
private:
|
|
32
|
+
float value_;
|
|
33
|
+
float defaultValue_;
|
|
34
|
+
float minValue_;
|
|
35
|
+
float maxValue_;
|
|
36
|
+
BaseAudioContext *context_;
|
|
37
|
+
std::set<ParamChange> changesQueue_;
|
|
38
|
+
|
|
39
|
+
double startTime_;
|
|
40
|
+
double endTime_;
|
|
41
|
+
float startValue_;
|
|
42
|
+
float endValue_;
|
|
43
|
+
std::function<float(double, double, float, float, double)> calculateValue_;
|
|
44
|
+
|
|
45
|
+
float checkValue(float value) const;
|
|
46
|
+
double getStartTime();
|
|
47
|
+
float getStartValue();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
} // namespace audioapi
|