react-native-audio-api 0.7.0-nightly-fba4835-20250721 → 0.7.0-nightly-4fc09d1-20250723
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.
|
@@ -26,6 +26,7 @@ BiquadFilterNode::BiquadFilterNode(BaseAudioContext *context)
|
|
|
26
26
|
context);
|
|
27
27
|
type_ = BiquadFilterType::LOWPASS;
|
|
28
28
|
isInitialized_ = true;
|
|
29
|
+
channelCountMode_ = ChannelCountMode::MAX;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
std::string BiquadFilterNode::getType() {
|
|
@@ -56,17 +57,28 @@ std::shared_ptr<AudioParam> BiquadFilterNode::getGainParam() const {
|
|
|
56
57
|
// https://www.dsprelated.com/freebooks/filters/Frequency_Response_Analysis.html
|
|
57
58
|
// https://www.dsprelated.com/freebooks/filters/Transfer_Function_Analysis.html
|
|
58
59
|
//
|
|
59
|
-
// frequency response - H(z)
|
|
60
|
-
//
|
|
61
|
-
//
|
|
60
|
+
// frequency response - H(z)
|
|
61
|
+
// b0 + b1 * z^(-1) + b2 * z^(-2)
|
|
62
|
+
// H(z) = -------------------------------
|
|
63
|
+
// 1 + a1 * z^(-1) + a2 * z^(-2)
|
|
64
|
+
//
|
|
65
|
+
// b0 + (b1 + b2 * z1) * z1
|
|
66
|
+
// = --------------------------
|
|
67
|
+
// (1 + (a1 + a2 * z1) * z1
|
|
68
|
+
//
|
|
69
|
+
// where z1 = 1/z and z = e^(j * pi * frequency)
|
|
70
|
+
// z1 = e^(-j * pi * frequency)
|
|
71
|
+
//
|
|
72
|
+
// phase response - angle of the frequency response
|
|
73
|
+
//
|
|
62
74
|
|
|
63
75
|
void BiquadFilterNode::getFrequencyResponse(
|
|
64
76
|
const float *frequencyArray,
|
|
65
77
|
float *magResponseOutput,
|
|
66
78
|
float *phaseResponseOutput,
|
|
67
79
|
const int length) {
|
|
68
|
-
applyFilter();
|
|
69
80
|
|
|
81
|
+
// Local copies for micro-optimization
|
|
70
82
|
float b0 = b0_;
|
|
71
83
|
float b1 = b1_;
|
|
72
84
|
float b2 = b2_;
|
|
@@ -74,10 +86,17 @@ void BiquadFilterNode::getFrequencyResponse(
|
|
|
74
86
|
float a2 = a2_;
|
|
75
87
|
|
|
76
88
|
for (size_t i = 0; i < length; i++) {
|
|
77
|
-
|
|
89
|
+
if (frequencyArray[i] < 0.0 || frequencyArray[i] > 1.0) {
|
|
90
|
+
magResponseOutput[i] = std::nanf("");
|
|
91
|
+
phaseResponseOutput[i] = std::nanf("");
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
auto omega = -PI * frequencyArray[i];
|
|
78
96
|
auto z = std::complex<float>(cos(omega), sin(omega));
|
|
79
|
-
auto response = (
|
|
80
|
-
|
|
97
|
+
auto response = (b0 + (b1 + b2 * z) * z) /
|
|
98
|
+
(std::complex<float>(1, 0) + (a1 + a2 * z) * z);
|
|
99
|
+
magResponseOutput[i] = static_cast<float>(std::abs(response));
|
|
81
100
|
phaseResponseOutput[i] =
|
|
82
101
|
static_cast<float>(atan2(imag(response), real(response)));
|
|
83
102
|
}
|
|
@@ -106,11 +125,12 @@ void BiquadFilterNode::setNormalizedCoefficients(
|
|
|
106
125
|
}
|
|
107
126
|
|
|
108
127
|
void BiquadFilterNode::setLowpassCoefficients(float frequency, float Q) {
|
|
109
|
-
|
|
110
|
-
if (frequency
|
|
128
|
+
// Limit frequency to [0, 1] range
|
|
129
|
+
if (frequency >= 1.0) {
|
|
111
130
|
setNormalizedCoefficients(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
112
131
|
return;
|
|
113
132
|
}
|
|
133
|
+
|
|
114
134
|
if (frequency <= 0.0) {
|
|
115
135
|
setNormalizedCoefficients(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
116
136
|
return;
|
|
@@ -129,8 +149,7 @@ void BiquadFilterNode::setLowpassCoefficients(float frequency, float Q) {
|
|
|
129
149
|
}
|
|
130
150
|
|
|
131
151
|
void BiquadFilterNode::setHighpassCoefficients(float frequency, float Q) {
|
|
132
|
-
|
|
133
|
-
if (frequency == 1.0) {
|
|
152
|
+
if (frequency >= 1.0) {
|
|
134
153
|
setNormalizedCoefficients(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
135
154
|
return;
|
|
136
155
|
}
|
|
@@ -152,14 +171,13 @@ void BiquadFilterNode::setHighpassCoefficients(float frequency, float Q) {
|
|
|
152
171
|
}
|
|
153
172
|
|
|
154
173
|
void BiquadFilterNode::setBandpassCoefficients(float frequency, float Q) {
|
|
155
|
-
|
|
156
|
-
Q = std::max(0.0f, Q);
|
|
157
|
-
|
|
174
|
+
// Limit frequency to [0, 1] range
|
|
158
175
|
if (frequency <= 0.0 || frequency >= 1.0) {
|
|
159
176
|
setNormalizedCoefficients(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
160
177
|
return;
|
|
161
178
|
}
|
|
162
179
|
|
|
180
|
+
// Limit Q to positive values
|
|
163
181
|
if (Q <= 0.0) {
|
|
164
182
|
setNormalizedCoefficients(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
165
183
|
return;
|
|
@@ -167,17 +185,16 @@ void BiquadFilterNode::setBandpassCoefficients(float frequency, float Q) {
|
|
|
167
185
|
|
|
168
186
|
float w0 = PI * frequency;
|
|
169
187
|
float alpha = std::sin(w0) / (2 * Q);
|
|
170
|
-
float
|
|
188
|
+
float cosW = std::cos(w0);
|
|
171
189
|
|
|
172
190
|
setNormalizedCoefficients(
|
|
173
|
-
alpha, 0.0f, -alpha, 1.0f + alpha, -2 *
|
|
191
|
+
alpha, 0.0f, -alpha, 1.0f + alpha, -2 * cosW, 1.0f - alpha);
|
|
174
192
|
}
|
|
175
193
|
|
|
176
194
|
void BiquadFilterNode::setLowshelfCoefficients(float frequency, float gain) {
|
|
177
|
-
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
178
195
|
float A = std::pow(10.0f, gain / 40.0f);
|
|
179
196
|
|
|
180
|
-
if (frequency
|
|
197
|
+
if (frequency >= 1.0) {
|
|
181
198
|
setNormalizedCoefficients(A * A, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
182
199
|
return;
|
|
183
200
|
}
|
|
@@ -188,25 +205,23 @@ void BiquadFilterNode::setLowshelfCoefficients(float frequency, float gain) {
|
|
|
188
205
|
}
|
|
189
206
|
|
|
190
207
|
float w0 = PI * frequency;
|
|
191
|
-
float alpha =
|
|
192
|
-
|
|
193
|
-
float
|
|
194
|
-
float k2 = 2.0f * std::sqrt(A) * alpha;
|
|
208
|
+
float alpha = 0.5f * std::sin(w0) * std::sqrt(2.0f);
|
|
209
|
+
float cosW = std::cos(w0);
|
|
210
|
+
float gamma = 2.0f * std::sqrt(A) * alpha;
|
|
195
211
|
|
|
196
212
|
setNormalizedCoefficients(
|
|
197
|
-
A * (A + 1 - (A - 1) *
|
|
198
|
-
2.0f * A * (A - 1 - (A + 1) *
|
|
199
|
-
A * (A + 1 - (A - 1) *
|
|
200
|
-
A + 1 + (A - 1) *
|
|
201
|
-
-2.0f * (A - 1 + (A + 1) *
|
|
202
|
-
A + 1 + (A - 1) *
|
|
213
|
+
A * (A + 1 - (A - 1) * cosW + gamma),
|
|
214
|
+
2.0f * A * (A - 1 - (A + 1) * cosW),
|
|
215
|
+
A * (A + 1 - (A - 1) * cosW - gamma),
|
|
216
|
+
A + 1 + (A - 1) * cosW + gamma,
|
|
217
|
+
-2.0f * (A - 1 + (A + 1) * cosW),
|
|
218
|
+
A + 1 + (A - 1) * cosW - gamma);
|
|
203
219
|
}
|
|
204
220
|
|
|
205
221
|
void BiquadFilterNode::setHighshelfCoefficients(float frequency, float gain) {
|
|
206
|
-
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
207
222
|
float A = std::pow(10.0f, gain / 40.0f);
|
|
208
223
|
|
|
209
|
-
if (frequency
|
|
224
|
+
if (frequency >= 1.0) {
|
|
210
225
|
setNormalizedCoefficients(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
211
226
|
return;
|
|
212
227
|
}
|
|
@@ -217,26 +232,25 @@ void BiquadFilterNode::setHighshelfCoefficients(float frequency, float gain) {
|
|
|
217
232
|
}
|
|
218
233
|
|
|
219
234
|
float w0 = PI * frequency;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
float
|
|
223
|
-
float
|
|
235
|
+
// In the original formula: sqrt((A + 1/A) * (1/S - 1) + 2), but we assume
|
|
236
|
+
// the maximum value S = 1, so it becomes 0 + 2 under the square root
|
|
237
|
+
float alpha = 0.5f * std::sin(w0) * std::sqrt(2.0f);
|
|
238
|
+
float cosW = std::cos(w0);
|
|
239
|
+
float gamma = 2.0f * std::sqrt(A) * alpha;
|
|
224
240
|
|
|
225
241
|
setNormalizedCoefficients(
|
|
226
|
-
A * (A + 1 + (A - 1) *
|
|
227
|
-
-2.0f * A * (A - 1 + (A + 1) *
|
|
228
|
-
A * (A + 1 + (A - 1) *
|
|
229
|
-
A + 1 - (A - 1) *
|
|
230
|
-
2.0f * (A - 1 - (A + 1) *
|
|
231
|
-
A + 1 - (A - 1) *
|
|
242
|
+
A * (A + 1 + (A - 1) * cosW + gamma),
|
|
243
|
+
-2.0f * A * (A - 1 + (A + 1) * cosW),
|
|
244
|
+
A * (A + 1 + (A - 1) * cosW - gamma),
|
|
245
|
+
A + 1 - (A - 1) * cosW + gamma,
|
|
246
|
+
2.0f * (A - 1 - (A + 1) * cosW),
|
|
247
|
+
A + 1 - (A - 1) * cosW - gamma);
|
|
232
248
|
}
|
|
233
249
|
|
|
234
250
|
void BiquadFilterNode::setPeakingCoefficients(
|
|
235
251
|
float frequency,
|
|
236
252
|
float Q,
|
|
237
253
|
float gain) {
|
|
238
|
-
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
239
|
-
Q = std::max(0.0f, Q);
|
|
240
254
|
float A = std::pow(10.0f, gain / 40.0f);
|
|
241
255
|
|
|
242
256
|
if (frequency <= 0.0 || frequency >= 1.0) {
|
|
@@ -251,21 +265,18 @@ void BiquadFilterNode::setPeakingCoefficients(
|
|
|
251
265
|
|
|
252
266
|
float w0 = PI * frequency;
|
|
253
267
|
float alpha = std::sin(w0) / (2 * Q);
|
|
254
|
-
float
|
|
268
|
+
float cosW = std::cos(w0);
|
|
255
269
|
|
|
256
270
|
setNormalizedCoefficients(
|
|
257
271
|
1 + alpha * A,
|
|
258
|
-
-2 *
|
|
272
|
+
-2 * cosW,
|
|
259
273
|
1 - alpha * A,
|
|
260
274
|
1 + alpha / A,
|
|
261
|
-
-2 *
|
|
275
|
+
-2 * cosW,
|
|
262
276
|
1 - alpha / A);
|
|
263
277
|
}
|
|
264
278
|
|
|
265
279
|
void BiquadFilterNode::setNotchCoefficients(float frequency, float Q) {
|
|
266
|
-
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
267
|
-
Q = std::max(0.0f, Q);
|
|
268
|
-
|
|
269
280
|
if (frequency <= 0.0 || frequency >= 1.0) {
|
|
270
281
|
setNormalizedCoefficients(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
271
282
|
return;
|
|
@@ -278,15 +289,13 @@ void BiquadFilterNode::setNotchCoefficients(float frequency, float Q) {
|
|
|
278
289
|
|
|
279
290
|
float w0 = PI * frequency;
|
|
280
291
|
float alpha = std::sin(w0) / (2 * Q);
|
|
281
|
-
float
|
|
292
|
+
float cosW = std::cos(w0);
|
|
282
293
|
|
|
283
|
-
setNormalizedCoefficients(
|
|
294
|
+
setNormalizedCoefficients(
|
|
295
|
+
1.0f, -2 * cosW, 1.0f, 1 + alpha, -2 * cosW, 1 - alpha);
|
|
284
296
|
}
|
|
285
297
|
|
|
286
298
|
void BiquadFilterNode::setAllpassCoefficients(float frequency, float Q) {
|
|
287
|
-
frequency = std::clamp(frequency, 0.0f, 1.0f);
|
|
288
|
-
Q = std::max(0.0f, Q);
|
|
289
|
-
|
|
290
299
|
if (frequency <= 0.0 || frequency >= 1.0) {
|
|
291
300
|
setNormalizedCoefficients(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
|
|
292
301
|
return;
|
|
@@ -299,55 +308,47 @@ void BiquadFilterNode::setAllpassCoefficients(float frequency, float Q) {
|
|
|
299
308
|
|
|
300
309
|
float w0 = PI * frequency;
|
|
301
310
|
float alpha = std::sin(w0) / (2 * Q);
|
|
302
|
-
float
|
|
311
|
+
float cosW = std::cos(w0);
|
|
303
312
|
|
|
304
313
|
setNormalizedCoefficients(
|
|
305
|
-
1 - alpha, -2 *
|
|
314
|
+
1 - alpha, -2 * cosW, 1 + alpha, 1 + alpha, -2 * cosW, 1 - alpha);
|
|
306
315
|
}
|
|
307
316
|
|
|
308
|
-
void BiquadFilterNode::
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
float normalizedFrequency =
|
|
314
|
-
frequencyParamValue / context_->getNyquistFrequency();
|
|
315
|
-
|
|
316
|
-
float detuneValue =
|
|
317
|
-
detuneParam_->processKRateParam(RENDER_QUANTUM_SIZE, currentTime);
|
|
317
|
+
void BiquadFilterNode::updateCoefficientsForFrame(
|
|
318
|
+
float frequency,
|
|
319
|
+
float detune,
|
|
320
|
+
float Q,
|
|
321
|
+
float gain) {
|
|
322
|
+
float normalizedFrequency = frequency / context_->getNyquistFrequency();
|
|
318
323
|
|
|
319
|
-
if (
|
|
320
|
-
normalizedFrequency *= std::pow(2.0f,
|
|
324
|
+
if (detune != 0.0f) {
|
|
325
|
+
normalizedFrequency *= std::pow(2.0f, detune / 1200.0f);
|
|
321
326
|
}
|
|
322
327
|
|
|
323
|
-
auto qparamValue =
|
|
324
|
-
QParam_->processKRateParam(RENDER_QUANTUM_SIZE, currentTime);
|
|
325
|
-
auto gainParamValue =
|
|
326
|
-
gainParam_->processKRateParam(RENDER_QUANTUM_SIZE, currentTime);
|
|
327
328
|
switch (type_) {
|
|
328
329
|
case BiquadFilterType::LOWPASS:
|
|
329
|
-
setLowpassCoefficients(normalizedFrequency,
|
|
330
|
+
setLowpassCoefficients(normalizedFrequency, Q);
|
|
330
331
|
break;
|
|
331
332
|
case BiquadFilterType::HIGHPASS:
|
|
332
|
-
setHighpassCoefficients(normalizedFrequency,
|
|
333
|
+
setHighpassCoefficients(normalizedFrequency, Q);
|
|
333
334
|
break;
|
|
334
335
|
case BiquadFilterType::BANDPASS:
|
|
335
|
-
setBandpassCoefficients(normalizedFrequency,
|
|
336
|
+
setBandpassCoefficients(normalizedFrequency, Q);
|
|
336
337
|
break;
|
|
337
338
|
case BiquadFilterType::LOWSHELF:
|
|
338
|
-
setLowshelfCoefficients(normalizedFrequency,
|
|
339
|
+
setLowshelfCoefficients(normalizedFrequency, gain);
|
|
339
340
|
break;
|
|
340
341
|
case BiquadFilterType::HIGHSHELF:
|
|
341
|
-
setHighshelfCoefficients(normalizedFrequency,
|
|
342
|
+
setHighshelfCoefficients(normalizedFrequency, gain);
|
|
342
343
|
break;
|
|
343
344
|
case BiquadFilterType::PEAKING:
|
|
344
|
-
setPeakingCoefficients(normalizedFrequency,
|
|
345
|
+
setPeakingCoefficients(normalizedFrequency, Q, gain);
|
|
345
346
|
break;
|
|
346
347
|
case BiquadFilterType::NOTCH:
|
|
347
|
-
setNotchCoefficients(normalizedFrequency,
|
|
348
|
+
setNotchCoefficients(normalizedFrequency, Q);
|
|
348
349
|
break;
|
|
349
350
|
case BiquadFilterType::ALLPASS:
|
|
350
|
-
setAllpassCoefficients(normalizedFrequency,
|
|
351
|
+
setAllpassCoefficients(normalizedFrequency, Q);
|
|
351
352
|
break;
|
|
352
353
|
default:
|
|
353
354
|
break;
|
|
@@ -357,24 +358,34 @@ void BiquadFilterNode::applyFilter() {
|
|
|
357
358
|
void BiquadFilterNode::processNode(
|
|
358
359
|
const std::shared_ptr<AudioBus> &processingBus,
|
|
359
360
|
int framesToProcess) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
361
|
+
double currentTime = context_->getCurrentTime();
|
|
362
|
+
auto frequencyValues =
|
|
363
|
+
frequencyParam_->processARateParam(framesToProcess, currentTime)
|
|
364
|
+
->getChannel(0)
|
|
365
|
+
->getData();
|
|
366
|
+
auto detuneValues =
|
|
367
|
+
detuneParam_->processARateParam(framesToProcess, currentTime)
|
|
368
|
+
->getChannel(0)
|
|
369
|
+
->getData();
|
|
370
|
+
auto qValues = QParam_->processARateParam(framesToProcess, currentTime)
|
|
371
|
+
->getChannel(0)
|
|
372
|
+
->getData();
|
|
373
|
+
auto gainValues = gainParam_->processARateParam(framesToProcess, currentTime)
|
|
374
|
+
->getChannel(0)
|
|
375
|
+
->getData();
|
|
376
|
+
|
|
377
|
+
for (int c = 0; c < processingBus->getNumberOfChannels(); c++) {
|
|
364
378
|
float x1 = x1_;
|
|
365
379
|
float x2 = x2_;
|
|
366
380
|
float y1 = y1_;
|
|
367
381
|
float y2 = y2_;
|
|
368
382
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
float a1 = a1_;
|
|
373
|
-
float a2 = a2_;
|
|
383
|
+
for (int i = 0; i < framesToProcess; i++) {
|
|
384
|
+
updateCoefficientsForFrame(
|
|
385
|
+
frequencyValues[i], detuneValues[i], qValues[i], gainValues[i]);
|
|
374
386
|
|
|
375
|
-
for (int i = 0; i < framesToProcess; i += 1) {
|
|
376
387
|
float input = (*processingBus->getChannel(c))[i];
|
|
377
|
-
float output =
|
|
388
|
+
float output = b0_ * input + b1_ * x1 + b2_ * x2 - a1_ * y1 - a2_ * y2;
|
|
378
389
|
|
|
379
390
|
(*processingBus->getChannel(c))[i] = output;
|
|
380
391
|
|
|
@@ -383,6 +394,10 @@ void BiquadFilterNode::processNode(
|
|
|
383
394
|
y2 = y1;
|
|
384
395
|
y1 = output;
|
|
385
396
|
}
|
|
397
|
+
x1_ = x1;
|
|
398
|
+
x2_ = x2;
|
|
399
|
+
y1_ = y1;
|
|
400
|
+
y2_ = y2;
|
|
386
401
|
}
|
|
387
402
|
}
|
|
388
403
|
|
|
@@ -33,7 +33,9 @@ class BiquadFilterNode : public AudioNode {
|
|
|
33
33
|
int length);
|
|
34
34
|
|
|
35
35
|
protected:
|
|
36
|
-
void processNode(
|
|
36
|
+
void processNode(
|
|
37
|
+
const std::shared_ptr<AudioBus> &processingBus,
|
|
38
|
+
int framesToProcess) override;
|
|
37
39
|
|
|
38
40
|
private:
|
|
39
41
|
std::shared_ptr<AudioParam> frequencyParam_;
|
|
@@ -119,7 +121,11 @@ class BiquadFilterNode : public AudioNode {
|
|
|
119
121
|
void setPeakingCoefficients(float frequency, float Q, float gain);
|
|
120
122
|
void setNotchCoefficients(float frequency, float Q);
|
|
121
123
|
void setAllpassCoefficients(float frequency, float Q);
|
|
122
|
-
void
|
|
124
|
+
void updateCoefficientsForFrame(
|
|
125
|
+
float frequency,
|
|
126
|
+
float detune,
|
|
127
|
+
float q,
|
|
128
|
+
float gain);
|
|
123
129
|
};
|
|
124
130
|
|
|
125
131
|
} // namespace audioapi
|
|
@@ -10,7 +10,7 @@ namespace audioapi {
|
|
|
10
10
|
|
|
11
11
|
StereoPannerNode::StereoPannerNode(BaseAudioContext *context)
|
|
12
12
|
: AudioNode(context) {
|
|
13
|
-
channelCountMode_ = ChannelCountMode::
|
|
13
|
+
channelCountMode_ = ChannelCountMode::CLAMPED_MAX;
|
|
14
14
|
panParam_ = std::make_shared<AudioParam>(0.0, -1.0f, 1.0f, context);
|
|
15
15
|
isInitialized_ = true;
|
|
16
16
|
}
|
|
@@ -31,26 +31,42 @@ void StereoPannerNode::processNode(
|
|
|
31
31
|
->getChannel(0)
|
|
32
32
|
->getData();
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
// Input is mono
|
|
35
|
+
if (processingBus->getNumberOfChannels() == 1) {
|
|
36
|
+
for (int i = 0; i < framesToProcess; i++) {
|
|
37
|
+
auto pan = std::clamp(panParamValues[i], -1.0f, 1.0f);
|
|
38
|
+
auto x = (pan + 1) / 2;
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
auto gainL = static_cast<float>(cos(x * PI / 2));
|
|
41
|
+
auto gainR = static_cast<float>(sin(x * PI / 2));
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
auto gainR = static_cast<float>(sin(x * PI / 2));
|
|
43
|
+
float input = (*left)[i];
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (pan <= 0) {
|
|
46
|
-
(*left)[i] = inputL + inputR * gainL;
|
|
47
|
-
(*right)[i] = inputR * gainR;
|
|
48
|
-
} else {
|
|
49
|
-
(*left)[i] = inputL * gainL;
|
|
50
|
-
(*right)[i] = inputR + inputL * gainR;
|
|
45
|
+
(*left)[i] = input * gainL;
|
|
46
|
+
(*right)[i] = input * gainR;
|
|
47
|
+
time += deltaTime;
|
|
51
48
|
}
|
|
49
|
+
} else { // Input is stereo
|
|
50
|
+
for (int i = 0; i < framesToProcess; i++) {
|
|
51
|
+
auto pan = std::clamp(panParamValues[i], -1.0f, 1.0f);
|
|
52
|
+
auto x = (pan <= 0 ? pan + 1 : pan);
|
|
53
|
+
|
|
54
|
+
auto gainL = static_cast<float>(cos(x * PI / 2));
|
|
55
|
+
auto gainR = static_cast<float>(sin(x * PI / 2));
|
|
56
|
+
|
|
57
|
+
float inputL = (*left)[i];
|
|
58
|
+
float inputR = (*right)[i];
|
|
52
59
|
|
|
53
|
-
|
|
60
|
+
if (pan <= 0) {
|
|
61
|
+
(*left)[i] = inputL + inputR * gainL;
|
|
62
|
+
(*right)[i] = inputR * gainR;
|
|
63
|
+
} else {
|
|
64
|
+
(*left)[i] = inputL * gainL;
|
|
65
|
+
(*right)[i] = inputR + inputL * gainR;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
time += deltaTime;
|
|
69
|
+
}
|
|
54
70
|
}
|
|
55
71
|
}
|
|
56
72
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-audio-api",
|
|
3
|
-
"version": "0.7.0-nightly-
|
|
3
|
+
"version": "0.7.0-nightly-4fc09d1-20250723",
|
|
4
4
|
"description": "react-native-audio-api provides system for controlling audio in React Native environment compatible with Web Audio API specification",
|
|
5
5
|
"bin": {
|
|
6
6
|
"setup-rn-audio-api-web": "./scripts/setup-rn-audio-api-web.js"
|