react-native-audio-api 0.1.0 → 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 +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 +23 -2
- package/android/src/main/cpp/AudioPlayer/AudioPlayer.h +5 -2
- package/common/cpp/HostObjects/AudioBufferSourceNodeHostObject.cpp +13 -1
- package/common/cpp/HostObjects/AudioContextHostObject.cpp +11 -148
- package/common/cpp/HostObjects/AudioContextHostObject.h +4 -11
- package/common/cpp/HostObjects/AudioNodeHostObject.cpp +0 -6
- package/common/cpp/HostObjects/BaseAudioContextHostObject.cpp +214 -0
- package/common/cpp/HostObjects/BaseAudioContextHostObject.h +39 -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 +103 -0
- package/common/cpp/core/AudioArray.h +42 -0
- package/common/cpp/core/AudioBuffer.cpp +23 -83
- package/common/cpp/core/AudioBuffer.h +11 -13
- package/common/cpp/core/AudioBufferSourceNode.cpp +102 -25
- package/common/cpp/core/AudioBufferSourceNode.h +10 -6
- package/common/cpp/core/AudioBus.cpp +357 -0
- package/common/cpp/core/AudioBus.h +63 -0
- package/common/cpp/core/AudioContext.cpp +6 -72
- package/common/cpp/core/AudioContext.h +3 -60
- package/common/cpp/core/AudioDestinationNode.cpp +25 -15
- package/common/cpp/core/AudioDestinationNode.h +15 -7
- package/common/cpp/core/AudioNode.cpp +176 -22
- package/common/cpp/core/AudioNode.h +37 -37
- package/common/cpp/core/AudioNodeManager.cpp +72 -0
- package/common/cpp/core/AudioNodeManager.h +35 -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 +157 -0
- package/common/cpp/core/BaseAudioContext.h +80 -0
- package/common/cpp/core/BiquadFilterNode.cpp +90 -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 +28 -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 +63 -0
- package/common/cpp/utils/Locker.h +47 -0
- package/common/cpp/utils/VectorMath.cpp +72 -3
- package/common/cpp/utils/VectorMath.h +7 -1
- package/common/cpp/utils/android/FFTFrame.cpp +22 -0
- package/common/cpp/utils/ios/FFTFrame.cpp +24 -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 +76 -0
- package/common/cpp/wrappers/BaseAudioContextWrapper.h +49 -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 +3 -3
- package/ios/AudioPlayer/AudioPlayer.h +3 -2
- package/ios/AudioPlayer/AudioPlayer.m +15 -17
- package/ios/AudioPlayer/IOSAudioPlayer.h +8 -4
- package/ios/AudioPlayer/IOSAudioPlayer.mm +30 -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 +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.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 +13 -34
- package/lib/module/index.js.map +1 -1
- package/lib/module/interfaces.js +2 -0
- package/lib/module/interfaces.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 +13 -17
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +78 -0
- package/lib/typescript/interfaces.d.ts.map +1 -0
- package/package.json +1 -1
- 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 +19 -73
- package/src/interfaces.ts +120 -0
- package/src/modules/global.d.ts +3 -3
- 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
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
#include <algorithm>
|
|
2
|
+
|
|
3
|
+
#include "AudioBus.h"
|
|
4
|
+
#include "Constants.h"
|
|
5
|
+
#include "AudioArray.h"
|
|
6
|
+
#include "VectorMath.h"
|
|
7
|
+
#include "BaseAudioContext.h"
|
|
8
|
+
|
|
9
|
+
// Implementation of channel summing/mixing is based on the WebKit approach, source:
|
|
10
|
+
// https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/audio/AudioBus.cpp
|
|
11
|
+
|
|
12
|
+
const float SQRT_HALF = sqrtf(0.5f);
|
|
13
|
+
|
|
14
|
+
namespace audioapi {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Public interfaces - memory management
|
|
18
|
+
*/
|
|
19
|
+
AudioBus::AudioBus(int sampleRate, int size)
|
|
20
|
+
: sampleRate_(sampleRate), size_(size), numberOfChannels_(CHANNEL_COUNT) {
|
|
21
|
+
createChannels();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
AudioBus::AudioBus(int sampleRate, int size, int numberOfChannels)
|
|
25
|
+
: sampleRate_(sampleRate), size_(size), numberOfChannels_(numberOfChannels) {
|
|
26
|
+
createChannels();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
AudioBus::~AudioBus() {
|
|
30
|
+
channels_.clear();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Public interfaces - getters
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
int AudioBus::getNumberOfChannels() const {
|
|
38
|
+
return numberOfChannels_;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
int AudioBus::getSampleRate() const {
|
|
42
|
+
return sampleRate_;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
int AudioBus::getSize() const {
|
|
46
|
+
return size_;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
AudioArray* AudioBus::getChannel(int index) const {
|
|
50
|
+
return channels_[index].get();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
AudioArray* AudioBus::getChannelByType(int channelType) const {
|
|
54
|
+
switch (getNumberOfChannels()) {
|
|
55
|
+
case 1: // mono
|
|
56
|
+
if (channelType == ChannelMono || channelType == ChannelLeft) {
|
|
57
|
+
return getChannel(0);
|
|
58
|
+
}
|
|
59
|
+
return 0;
|
|
60
|
+
|
|
61
|
+
case 2: // stereo
|
|
62
|
+
switch (channelType) {
|
|
63
|
+
case ChannelLeft: return getChannel(0);
|
|
64
|
+
case ChannelRight: return getChannel(1);
|
|
65
|
+
default: return 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
case 4: // quad
|
|
69
|
+
switch (channelType) {
|
|
70
|
+
case ChannelLeft: return getChannel(0);
|
|
71
|
+
case ChannelRight: return getChannel(1);
|
|
72
|
+
case ChannelSurroundLeft: return getChannel(2);
|
|
73
|
+
case ChannelSurroundRight: return getChannel(3);
|
|
74
|
+
default: return 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
case 5: // 5.0
|
|
78
|
+
switch (channelType) {
|
|
79
|
+
case ChannelLeft: return getChannel(0);
|
|
80
|
+
case ChannelRight: return getChannel(1);
|
|
81
|
+
case ChannelCenter: return getChannel(2);
|
|
82
|
+
case ChannelSurroundLeft: return getChannel(3);
|
|
83
|
+
case ChannelSurroundRight: return getChannel(4);
|
|
84
|
+
default: return 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case 6: // 5.1
|
|
88
|
+
switch (channelType) {
|
|
89
|
+
case ChannelLeft: return getChannel(0);
|
|
90
|
+
case ChannelRight: return getChannel(1);
|
|
91
|
+
case ChannelCenter: return getChannel(2);
|
|
92
|
+
case ChannelLFE: return getChannel(3);
|
|
93
|
+
case ChannelSurroundLeft: return getChannel(4);
|
|
94
|
+
case ChannelSurroundRight: return getChannel(5);
|
|
95
|
+
default: return 0;
|
|
96
|
+
}
|
|
97
|
+
default:
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Public interfaces - audio processing and setters
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
void AudioBus::zero() {
|
|
107
|
+
zero(0, getSize());
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
void AudioBus::zero(int start, int length) {
|
|
111
|
+
for (auto it = channels_.begin(); it != channels_.end(); it += 1) {
|
|
112
|
+
it->get()->zero(start, length);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
void AudioBus::normalize() {
|
|
117
|
+
float maxAbsValue = this->maxAbsValue();
|
|
118
|
+
|
|
119
|
+
if (maxAbsValue == 0.0f || maxAbsValue == 1.0f) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
float scale = 1.0f / maxAbsValue;
|
|
124
|
+
this->scale(scale);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
void AudioBus::scale(float value) {
|
|
128
|
+
for (auto it = channels_.begin(); it != channels_.end(); ++it) {
|
|
129
|
+
it->get()->scale(value);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
float AudioBus::maxAbsValue() const {
|
|
134
|
+
float maxAbsValue = 1.0f;
|
|
135
|
+
|
|
136
|
+
for (auto it = channels_.begin(); it != channels_.end(); ++it) {
|
|
137
|
+
float channelMaxAbsValue = it->get()->getMaxAbsValue();
|
|
138
|
+
maxAbsValue = std::max(maxAbsValue, channelMaxAbsValue);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return maxAbsValue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
void AudioBus::sum(const AudioBus *source) {
|
|
145
|
+
sum(source, 0, 0, getSize());
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
void AudioBus::sum(const AudioBus *source, int start, int length) {
|
|
149
|
+
sum(source, start, start, length);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
void AudioBus::sum(const AudioBus *source, int sourceStart, int destinationStart, int length) {
|
|
153
|
+
if (source == this) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
int numberOfSourceChannels = source->getNumberOfChannels();
|
|
158
|
+
int numberOfChannels = getNumberOfChannels();
|
|
159
|
+
|
|
160
|
+
// TODO: consider adding ability to enforce discrete summing (if/when it will be useful).
|
|
161
|
+
// Source channel count is smaller than current bus, we need to up-mix.
|
|
162
|
+
if (numberOfSourceChannels < numberOfChannels) {
|
|
163
|
+
sumByUpMixing(source, sourceStart, destinationStart, length);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Source channel count is larger than current bus, we need to down-mix.
|
|
168
|
+
if (numberOfSourceChannels > numberOfChannels) {
|
|
169
|
+
sumByDownMixing(source, sourceStart, destinationStart, length);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Source and destination channel counts are the same. Just sum the channels.
|
|
174
|
+
for (int i = 0; i < numberOfChannels_; i += 1) {
|
|
175
|
+
getChannel(i)->sum(source->getChannel(i), sourceStart, destinationStart, length);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
void AudioBus::copy(const AudioBus *source) {
|
|
180
|
+
copy(source, 0, 0, getSize());
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
void AudioBus::copy(const AudioBus *source, int start, int length) {
|
|
184
|
+
copy(source, start, start, length);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
void AudioBus::copy(const AudioBus *source, int sourceStart, int destinationStart, int length) {
|
|
188
|
+
if (source == this) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (source->getNumberOfChannels() == getNumberOfChannels()) {
|
|
193
|
+
for (int i = 0; i < getNumberOfChannels(); i += 1) {
|
|
194
|
+
getChannel(i)->copy(source->getChannel(i), sourceStart, destinationStart, length);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// zero + sum is equivalent to copy, but takes care of up/down-mixing.
|
|
201
|
+
zero(destinationStart, length);
|
|
202
|
+
sum(source, sourceStart, destinationStart, length);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Internal tooling - channel initialization
|
|
207
|
+
*/
|
|
208
|
+
|
|
209
|
+
void AudioBus::createChannels() {
|
|
210
|
+
channels_ = std::vector<std::shared_ptr<AudioArray>>(numberOfChannels_);
|
|
211
|
+
|
|
212
|
+
for (int i = 0; i < numberOfChannels_; i += 1) {
|
|
213
|
+
channels_[i] = std::make_shared<AudioArray>(size_);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Internal tooling - channel summing
|
|
219
|
+
*/
|
|
220
|
+
|
|
221
|
+
void AudioBus::discreteSum(const AudioBus *source, int sourceStart, int destinationStart, int length) {
|
|
222
|
+
int numberOfChannels = std::min(getNumberOfChannels(), source->getNumberOfChannels());
|
|
223
|
+
|
|
224
|
+
// In case of source > destination, we "down-mix" and drop the extra channels.
|
|
225
|
+
// In case of source < destination, we "up-mix" as many channels as we have, leaving the remaining channels untouched.
|
|
226
|
+
for (int i = 0; i < numberOfChannels; i++) {
|
|
227
|
+
getChannel(i)->sum(source->getChannel(i), sourceStart, destinationStart, length);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
void AudioBus::sumByUpMixing(const AudioBus *source, int sourceStart, int destinationStart, int length) {
|
|
232
|
+
int numberOfSourceChannels = source->getNumberOfChannels();
|
|
233
|
+
int numberOfChannels = getNumberOfChannels();
|
|
234
|
+
|
|
235
|
+
// Mono to stereo (1 -> 2, 4)
|
|
236
|
+
if (numberOfSourceChannels == 1 && (numberOfChannels == 2 || numberOfChannels == 4)) {
|
|
237
|
+
AudioArray* sourceChannel = source->getChannelByType(ChannelMono);
|
|
238
|
+
|
|
239
|
+
getChannelByType(ChannelLeft)->sum(sourceChannel, sourceStart, destinationStart, length);
|
|
240
|
+
getChannelByType(ChannelRight)->sum(sourceChannel, sourceStart, destinationStart, length);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Mono to 5.1 (1 -> 6)
|
|
245
|
+
if (numberOfSourceChannels == 1 && numberOfChannels == 6) {
|
|
246
|
+
AudioArray* sourceChannel = source->getChannel(0);
|
|
247
|
+
|
|
248
|
+
getChannelByType(ChannelCenter)->sum(sourceChannel, sourceStart, destinationStart, length);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Stereo 2 to stereo 4 or 5.1 (2 -> 4, 6)
|
|
253
|
+
if (numberOfSourceChannels == 2 && (numberOfChannels == 4 || numberOfChannels == 6)) {
|
|
254
|
+
getChannelByType(ChannelLeft)->sum(source->getChannelByType(ChannelLeft), sourceStart, destinationStart, length);
|
|
255
|
+
getChannelByType(ChannelRight)->sum(source->getChannelByType(ChannelRight), sourceStart, destinationStart, length);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Stereo 4 to 5.1 (4 -> 6)
|
|
260
|
+
if (numberOfSourceChannels == 4 && numberOfChannels == 6) {
|
|
261
|
+
getChannelByType(ChannelLeft)->sum(source->getChannelByType(ChannelLeft), sourceStart, destinationStart, length);
|
|
262
|
+
getChannelByType(ChannelRight)->sum(source->getChannelByType(ChannelRight), sourceStart, destinationStart, length);
|
|
263
|
+
getChannelByType(ChannelSurroundLeft)->sum(source->getChannelByType(ChannelSurroundLeft), sourceStart, destinationStart, length);
|
|
264
|
+
getChannelByType(ChannelSurroundRight)->sum(source->getChannelByType(ChannelSurroundRight), sourceStart, destinationStart, length);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
discreteSum(source, sourceStart, destinationStart, length);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
void AudioBus::sumByDownMixing(const AudioBus *source, int sourceStart, int destinationStart, int length) {
|
|
272
|
+
int numberOfSourceChannels = source->getNumberOfChannels();
|
|
273
|
+
int numberOfChannels = getNumberOfChannels();
|
|
274
|
+
|
|
275
|
+
// Stereo to mono (2 -> 1): output += 0.5 * (input.left + input.right).
|
|
276
|
+
if (numberOfSourceChannels == 2 && numberOfChannels == 1) {
|
|
277
|
+
float* sourceLeft = source->getChannelByType(ChannelLeft)->getData();
|
|
278
|
+
float* sourceRight = source->getChannelByType(ChannelRight)->getData();
|
|
279
|
+
|
|
280
|
+
float* destinationData = getChannelByType(ChannelMono)->getData();
|
|
281
|
+
|
|
282
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceLeft + sourceStart, 0.5f, destinationData + destinationStart, length);
|
|
283
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceRight + sourceStart, 0.5f, destinationData + destinationStart, length);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Stereo 4 to mono: output += 0.25 * (input.left + input.right + input.surroundLeft + input.surroundRight)
|
|
288
|
+
if (numberOfSourceChannels == 4 && numberOfChannels == 1) {
|
|
289
|
+
float* sourceLeft = source->getChannelByType(ChannelLeft)->getData();
|
|
290
|
+
float* sourceRight = source->getChannelByType(ChannelRight)->getData();
|
|
291
|
+
float* sourceSurroundLeft = source->getChannelByType(ChannelSurroundLeft)->getData();
|
|
292
|
+
float* sourceSurroundRight = source->getChannelByType(ChannelSurroundRight)->getData();
|
|
293
|
+
|
|
294
|
+
float* destinationData = getChannelByType(ChannelMono)->getData();
|
|
295
|
+
|
|
296
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceLeft + sourceStart, 0.25f, destinationData + destinationStart, length);
|
|
297
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceRight + sourceStart, 0.25f, destinationData + destinationStart, length);
|
|
298
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceSurroundLeft + sourceStart, 0.25f, destinationData + destinationStart, length);
|
|
299
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceSurroundRight + sourceStart, 0.25f, destinationData + destinationStart, length);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// 5.1 to stereo:
|
|
304
|
+
// output.left += input.left + sqrt(1/2) * (input.center + input.surroundLeft)
|
|
305
|
+
// output.right += input.right + sqrt(1/2) * (input.center + input.surroundRight)
|
|
306
|
+
if (numberOfSourceChannels == 6 && numberOfChannels == 2) {
|
|
307
|
+
float* sourceLeft = source->getChannelByType(ChannelLeft)->getData();
|
|
308
|
+
float* sourceRight = source->getChannelByType(ChannelRight)->getData();
|
|
309
|
+
float* sourceCenter = source->getChannelByType(ChannelCenter)->getData();
|
|
310
|
+
float* sourceSurroundLeft = source->getChannelByType(ChannelSurroundLeft)->getData();
|
|
311
|
+
float* sourceSurroundRight = source->getChannelByType(ChannelSurroundRight)->getData();
|
|
312
|
+
|
|
313
|
+
float* destinationLeft = getChannelByType(ChannelLeft)->getData();
|
|
314
|
+
float* destinationRight = getChannelByType(ChannelRight)->getData();
|
|
315
|
+
|
|
316
|
+
VectorMath::add(sourceLeft + sourceStart, destinationLeft + destinationStart, destinationLeft + destinationStart, length);
|
|
317
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceCenter + sourceStart, SQRT_HALF, destinationLeft + destinationStart, length);
|
|
318
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceSurroundLeft + sourceStart, SQRT_HALF, destinationLeft + destinationStart, length);
|
|
319
|
+
|
|
320
|
+
VectorMath::add(sourceRight + sourceStart, destinationRight + destinationStart, destinationRight + destinationStart, length);
|
|
321
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceCenter + sourceStart, SQRT_HALF, destinationRight + destinationStart, length);
|
|
322
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceSurroundRight + sourceStart, SQRT_HALF, destinationRight + destinationStart, length);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// 5.1 to stereo 4:
|
|
327
|
+
// output.left += input.left + sqrt(1/2) * input.center
|
|
328
|
+
// output.right += input.right + sqrt(1/2) * input.center
|
|
329
|
+
// output.surroundLeft += input.surroundLeft
|
|
330
|
+
// output.surroundRight += input.surroundRight
|
|
331
|
+
if (numberOfSourceChannels == 6 && numberOfChannels == 4) {
|
|
332
|
+
float* sourceLeft = source->getChannelByType(ChannelLeft)->getData();
|
|
333
|
+
float* sourceRight = source->getChannelByType(ChannelRight)->getData();
|
|
334
|
+
float* sourceCenter = source->getChannelByType(ChannelCenter)->getData();
|
|
335
|
+
float* sourceSurroundLeft = source->getChannelByType(ChannelSurroundLeft)->getData();
|
|
336
|
+
float* sourceSurroundRight = source->getChannelByType(ChannelSurroundRight)->getData();
|
|
337
|
+
|
|
338
|
+
float* destinationLeft = getChannelByType(ChannelLeft)->getData();
|
|
339
|
+
float* destinationRight = getChannelByType(ChannelRight)->getData();
|
|
340
|
+
float* destinationSurroundLeft = getChannelByType(ChannelSurroundLeft)->getData();
|
|
341
|
+
float* destinationSurroundRight = getChannelByType(ChannelSurroundRight)->getData();
|
|
342
|
+
|
|
343
|
+
VectorMath::add(sourceLeft + sourceStart, destinationLeft + destinationStart, destinationLeft + destinationStart, length);
|
|
344
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceCenter, SQRT_HALF, destinationLeft + destinationStart, length);
|
|
345
|
+
|
|
346
|
+
VectorMath::add(sourceRight + sourceStart, destinationRight + destinationStart, destinationRight + destinationStart, length);
|
|
347
|
+
VectorMath::multiplyByScalarThenAddToOutput(sourceCenter, SQRT_HALF, destinationRight + destinationStart, length);
|
|
348
|
+
|
|
349
|
+
VectorMath::add(sourceSurroundLeft + sourceStart, destinationSurroundLeft + destinationStart, destinationSurroundLeft + destinationStart, length);
|
|
350
|
+
VectorMath::add(sourceSurroundRight + sourceStart, destinationSurroundRight + destinationStart, destinationSurroundRight + destinationStart, length);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
discreteSum(source, sourceStart, destinationStart, length);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
} // namespace audioapi
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <memory>
|
|
4
|
+
#include <vector>
|
|
5
|
+
#include <algorithm>
|
|
6
|
+
|
|
7
|
+
namespace audioapi {
|
|
8
|
+
|
|
9
|
+
class BaseAudioContext;
|
|
10
|
+
class AudioArray;
|
|
11
|
+
|
|
12
|
+
class AudioBus {
|
|
13
|
+
public:
|
|
14
|
+
enum {
|
|
15
|
+
ChannelMono = 0,
|
|
16
|
+
ChannelLeft = 0,
|
|
17
|
+
ChannelRight = 1,
|
|
18
|
+
ChannelCenter = 2,
|
|
19
|
+
ChannelLFE = 3,
|
|
20
|
+
ChannelSurroundLeft = 4,
|
|
21
|
+
ChannelSurroundRight = 5,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
explicit AudioBus(int sampleRate, int size);
|
|
25
|
+
explicit AudioBus(int sampleRate, int size, int numberOfChannels);
|
|
26
|
+
|
|
27
|
+
~AudioBus();
|
|
28
|
+
|
|
29
|
+
[[nodiscard]] int getNumberOfChannels() const;
|
|
30
|
+
[[nodiscard]] int getSampleRate() const;
|
|
31
|
+
[[nodiscard]] int getSize() const;
|
|
32
|
+
AudioArray* getChannel(int index) const;
|
|
33
|
+
AudioArray* getChannelByType(int channelType) const;
|
|
34
|
+
|
|
35
|
+
void normalize();
|
|
36
|
+
void scale(float value);
|
|
37
|
+
float maxAbsValue() const;
|
|
38
|
+
|
|
39
|
+
void zero();
|
|
40
|
+
void zero(int start, int length);
|
|
41
|
+
|
|
42
|
+
void sum(const AudioBus *source);
|
|
43
|
+
void sum(const AudioBus *source, int start, int length);
|
|
44
|
+
void sum(const AudioBus *source, int sourceStart, int destinationStart, int length);
|
|
45
|
+
|
|
46
|
+
void copy(const AudioBus *source);
|
|
47
|
+
void copy(const AudioBus *source, int start, int length);
|
|
48
|
+
void copy(const AudioBus *source, int sourceStart, int destinationStart, int length);
|
|
49
|
+
|
|
50
|
+
private:
|
|
51
|
+
std::vector<std::shared_ptr<AudioArray>> channels_;
|
|
52
|
+
|
|
53
|
+
int numberOfChannels_;
|
|
54
|
+
int sampleRate_;
|
|
55
|
+
int size_;
|
|
56
|
+
|
|
57
|
+
void createChannels();
|
|
58
|
+
void discreteSum(const AudioBus *source, int sourceStart, int destinationStart, int length);
|
|
59
|
+
void sumByUpMixing(const AudioBus *source, int sourceStart, int destinationStart, int length);
|
|
60
|
+
void sumByDownMixing(const AudioBus *source, int sourceStart, int destinationStart, int length);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
} // namespace audioapi
|
|
@@ -1,45 +1,18 @@
|
|
|
1
|
-
#include "AudioContext.h"
|
|
2
|
-
|
|
3
|
-
namespace audioapi {
|
|
4
|
-
|
|
5
|
-
AudioContext::AudioContext() {
|
|
6
1
|
#ifdef ANDROID
|
|
7
|
-
|
|
2
|
+
#include "AudioPlayer.h"
|
|
8
3
|
#else
|
|
9
|
-
|
|
4
|
+
#include "IOSAudioPlayer.h"
|
|
10
5
|
#endif
|
|
11
|
-
destination_ = std::make_shared<AudioDestinationNode>(this);
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
auto now = std::chrono::high_resolution_clock ::now();
|
|
16
|
-
contextStartTime_ =
|
|
17
|
-
static_cast<double>(std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
18
|
-
now.time_since_epoch())
|
|
19
|
-
.count());
|
|
7
|
+
#include "AudioContext.h"
|
|
20
8
|
|
|
21
|
-
audioPlayer_->start();
|
|
22
|
-
}
|
|
23
9
|
|
|
24
|
-
|
|
25
|
-
return AudioContext::toString(state_);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
int AudioContext::getSampleRate() const {
|
|
29
|
-
return sampleRate_;
|
|
30
|
-
}
|
|
10
|
+
namespace audioapi {
|
|
31
11
|
|
|
32
|
-
|
|
33
|
-
auto now = std::chrono::high_resolution_clock ::now();
|
|
34
|
-
auto currentTime =
|
|
35
|
-
static_cast<double>(std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
36
|
-
now.time_since_epoch())
|
|
37
|
-
.count());
|
|
38
|
-
return (currentTime - contextStartTime_) / 1e9;
|
|
39
|
-
}
|
|
12
|
+
AudioContext::AudioContext() : BaseAudioContext() {}
|
|
40
13
|
|
|
41
14
|
void AudioContext::close() {
|
|
42
|
-
state_ =
|
|
15
|
+
state_ = ContextState::CLOSED;
|
|
43
16
|
|
|
44
17
|
if (audioPlayer_) {
|
|
45
18
|
audioPlayer_->stop();
|
|
@@ -48,43 +21,4 @@ void AudioContext::close() {
|
|
|
48
21
|
audioPlayer_.reset();
|
|
49
22
|
destination_.reset();
|
|
50
23
|
}
|
|
51
|
-
|
|
52
|
-
std::shared_ptr<AudioDestinationNode> AudioContext::getDestination() {
|
|
53
|
-
return destination_;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
std::shared_ptr<OscillatorNode> AudioContext::createOscillator() {
|
|
57
|
-
return std::make_shared<OscillatorNode>(this);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
std::shared_ptr<GainNode> AudioContext::createGain() {
|
|
61
|
-
return std::make_shared<GainNode>(this);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
std::shared_ptr<StereoPannerNode> AudioContext::createStereoPanner() {
|
|
65
|
-
return std::make_shared<StereoPannerNode>(this);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
std::shared_ptr<BiquadFilterNode> AudioContext::createBiquadFilter() {
|
|
69
|
-
return std::make_shared<BiquadFilterNode>(this);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
std::shared_ptr<AudioBufferSourceNode> AudioContext::createBufferSource() {
|
|
73
|
-
return std::make_shared<AudioBufferSourceNode>(this);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
std::shared_ptr<AudioBuffer>
|
|
77
|
-
AudioContext::createBuffer(int numberOfChannels, int length, int sampleRate) {
|
|
78
|
-
return std::make_shared<AudioBuffer>(numberOfChannels, length, sampleRate);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
std::function<void(float *, int)> AudioContext::renderAudio() {
|
|
82
|
-
if (state_ == State::CLOSED) {
|
|
83
|
-
return [](float *, int) {};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return [this](float *data, int frames) {
|
|
87
|
-
destination_->renderAudio(data, frames);
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
24
|
} // namespace audioapi
|
|
@@ -1,73 +1,16 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <functional>
|
|
4
3
|
#include <memory>
|
|
5
|
-
#include <string>
|
|
6
|
-
#include <utility>
|
|
7
|
-
#include <vector>
|
|
8
4
|
|
|
9
|
-
#include "
|
|
10
|
-
#include "AudioBufferSourceNode.h"
|
|
11
|
-
#include "AudioDestinationNode.h"
|
|
12
|
-
#include "AudioScheduledSourceNode.h"
|
|
13
|
-
#include "BiquadFilterNode.h"
|
|
14
|
-
#include "Constants.h"
|
|
15
|
-
#include "GainNode.h"
|
|
16
|
-
#include "OscillatorNode.h"
|
|
17
|
-
#include "StereoPannerNode.h"
|
|
18
|
-
|
|
19
|
-
#ifdef ANDROID
|
|
20
|
-
#include "AudioPlayer.h"
|
|
21
|
-
#else
|
|
22
|
-
#include "IOSAudioPlayer.h"
|
|
23
|
-
#endif
|
|
5
|
+
#include "BaseAudioContext.h"
|
|
24
6
|
|
|
25
7
|
namespace audioapi {
|
|
26
8
|
|
|
27
|
-
class AudioContext {
|
|
9
|
+
class AudioContext : public BaseAudioContext {
|
|
28
10
|
public:
|
|
29
11
|
AudioContext();
|
|
30
|
-
std::string getState();
|
|
31
|
-
int getSampleRate() const;
|
|
32
|
-
double getCurrentTime() const;
|
|
33
|
-
void close();
|
|
34
|
-
|
|
35
|
-
std::shared_ptr<AudioDestinationNode> getDestination();
|
|
36
|
-
std::shared_ptr<OscillatorNode> createOscillator();
|
|
37
|
-
std::shared_ptr<GainNode> createGain();
|
|
38
|
-
std::shared_ptr<StereoPannerNode> createStereoPanner();
|
|
39
|
-
std::shared_ptr<BiquadFilterNode> createBiquadFilter();
|
|
40
|
-
std::shared_ptr<AudioBufferSourceNode> createBufferSource();
|
|
41
|
-
static std::shared_ptr<AudioBuffer>
|
|
42
|
-
createBuffer(int numberOfChannels, int length, int sampleRate);
|
|
43
|
-
std::function<void(float *, int)> renderAudio();
|
|
44
12
|
|
|
45
|
-
|
|
46
|
-
enum class State { SUSPENDED, RUNNING, CLOSED };
|
|
47
|
-
|
|
48
|
-
static std::string toString(State state) {
|
|
49
|
-
switch (state) {
|
|
50
|
-
case State::SUSPENDED:
|
|
51
|
-
return "suspended";
|
|
52
|
-
case State::RUNNING:
|
|
53
|
-
return "running";
|
|
54
|
-
case State::CLOSED:
|
|
55
|
-
return "closed";
|
|
56
|
-
default:
|
|
57
|
-
throw std::invalid_argument("Unknown context state");
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private:
|
|
62
|
-
std::shared_ptr<AudioDestinationNode> destination_;
|
|
63
|
-
#ifdef ANDROID
|
|
64
|
-
std::shared_ptr<AudioPlayer> audioPlayer_;
|
|
65
|
-
#else
|
|
66
|
-
std::shared_ptr<IOSAudioPlayer> audioPlayer_;
|
|
67
|
-
#endif
|
|
68
|
-
State state_ = State::RUNNING;
|
|
69
|
-
int sampleRate_;
|
|
70
|
-
double contextStartTime_;
|
|
13
|
+
void close();
|
|
71
14
|
};
|
|
72
15
|
|
|
73
16
|
} // namespace audioapi
|
|
@@ -1,35 +1,45 @@
|
|
|
1
|
+
#include "AudioBus.h"
|
|
2
|
+
#include "AudioNode.h"
|
|
3
|
+
#include "VectorMath.h"
|
|
4
|
+
#include "AudioNodeManager.h"
|
|
5
|
+
#include "BaseAudioContext.h"
|
|
1
6
|
#include "AudioDestinationNode.h"
|
|
2
|
-
#include "AudioContext.h"
|
|
3
7
|
|
|
4
8
|
namespace audioapi {
|
|
5
9
|
|
|
6
|
-
AudioDestinationNode::AudioDestinationNode(
|
|
7
|
-
: AudioNode(context) {
|
|
10
|
+
AudioDestinationNode::AudioDestinationNode(BaseAudioContext *context)
|
|
11
|
+
: AudioNode(context), currentSampleFrame_(0) {
|
|
8
12
|
numberOfOutputs_ = 0;
|
|
9
13
|
numberOfInputs_ = INT_MAX;
|
|
10
14
|
channelCountMode_ = ChannelCountMode::EXPLICIT;
|
|
15
|
+
isInitialized_ = true;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
std::size_t AudioDestinationNode::getCurrentSampleFrame() const {
|
|
19
|
+
return currentSampleFrame_;
|
|
15
20
|
}
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
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();
|
|
19
29
|
|
|
20
|
-
if (
|
|
21
|
-
|
|
30
|
+
if (!numFrames) {
|
|
31
|
+
return;
|
|
22
32
|
}
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
AudioBus* processedBus = processAudio(destinationBus, numFrames);
|
|
25
35
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
VectorMath::add(audioData, mixingBuffer.get(), audioData, numSamples);
|
|
29
|
-
}
|
|
36
|
+
if (processedBus && processedBus != destinationBus) {
|
|
37
|
+
destinationBus->copy(processedBus);
|
|
30
38
|
}
|
|
31
39
|
|
|
32
|
-
|
|
40
|
+
destinationBus->normalize();
|
|
41
|
+
|
|
42
|
+
currentSampleFrame_ += numFrames;
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
} // namespace audioapi
|
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <algorithm>
|
|
4
|
-
#include <memory>
|
|
5
3
|
#include <vector>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <algorithm>
|
|
6
6
|
|
|
7
7
|
#include "AudioNode.h"
|
|
8
|
-
#include "VectorMath.h"
|
|
9
8
|
|
|
10
9
|
namespace audioapi {
|
|
11
10
|
|
|
11
|
+
class AudioBus;
|
|
12
|
+
class BaseAudioContext;
|
|
13
|
+
|
|
12
14
|
class AudioDestinationNode : public AudioNode {
|
|
13
15
|
public:
|
|
14
|
-
explicit AudioDestinationNode(
|
|
16
|
+
explicit AudioDestinationNode(BaseAudioContext *context);
|
|
17
|
+
|
|
18
|
+
void renderAudio(AudioBus* audioData, int32_t numFrames);
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
std::size_t getCurrentSampleFrame() const;
|
|
21
|
+
double getCurrentTime() const;
|
|
17
22
|
|
|
18
23
|
protected:
|
|
19
|
-
|
|
24
|
+
// DestinationNode is triggered by AudioContext using renderAudio
|
|
25
|
+
// processNode function is not necessary and is never called.
|
|
26
|
+
void processNode(AudioBus*, int) final { };
|
|
20
27
|
|
|
21
28
|
private:
|
|
22
|
-
std::
|
|
29
|
+
std::size_t currentSampleFrame_;
|
|
23
30
|
};
|
|
31
|
+
|
|
24
32
|
} // namespace audioapi
|