43template <
typename SampleT = int16_t,
typename AccT = int64_t,
44 int NUM_TAPS = 128,
int NUM_BANDS = 12>
124 for (
int band = 0; band < NUM_BANDS; band++) {
142 float vol_db = volume < 0 ? map<float>(volume, -1.0f, 0.0f, -90.0f, 0.0f) : map<float>(volume, 0.0f, 1.0f, 0.0f, 12.0f);
151 if (band < 0 || band >= NUM_BANDS)
return false;
152 float db = min(gainDb, 12.0f);
153 db = max(db, -90.0f);
161 for (
int band = 0; band < NUM_BANDS; band++) {
169 if (band < 0 || band >= NUM_BANDS)
return 0.0f;
170 return map<float>(
pendingGains[band], -12.0f, 12.0f, -1.0f, 1.0f);
177 if (band < 0 || band >= NUM_BANDS)
return 0.0f;
185 if (band < 0 || band >= NUM_BANDS)
return 0.0f;
199 size_t write(
const uint8_t* data,
size_t len)
override {
206 return filtered.readBytes(data, len);
230 LOGE(
"Kernel not set!");
240 for (
int n = 0; n < NUM_TAPS; n++) {
243 if (--idx < 0) idx = NUM_TAPS - 1;
259 if constexpr (std::numeric_limits<SampleT>::is_integer) {
261 if constexpr (std::numeric_limits<AccT>::is_integer) {
264 acc = acc / (AccT)(1 << 15);
268 const AccT hi = (AccT)std::numeric_limits<SampleT>::max();
269 const AccT lo = (AccT)std::numeric_limits<SampleT>::min();
270 if (acc > hi) acc = hi;
271 if (acc < lo) acc = lo;
275 return (SampleT)(acc / (AccT)(1 << 15));
329 template <
typename T>
330 float map(T x, T in_min, T in_max, T out_min, T out_max) {
331 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
336 if (fabsf(x) < 1e-8f)
return 1.0f;
337 return sinf(
PI * x) / (
PI * x);
342 if (NUM_BANDS <= 0)
return;
343 float fMin = log10f(20.0f);
344 float fMax = log10f(sampleRate / 2.0f);
345 if (NUM_BANDS == 1) {
346 centerFreqs[0] = powf(10.0f, (fMin + fMax) * 0.5f);
347 LOGD(
"Only one band: center frequency set to %.2f Hz",
centerFreqs[0]);
350 float step = (fMax - fMin) / (
float)(NUM_BANDS - 1);
351 for (
int i = 0; i < NUM_BANDS; i++) {
352 centerFreqs[i] = powf(10.0f, fMin + step * (
float)i);
359 const float N_minus_1 = (float)(NUM_TAPS - 1);
360 for (
int n = 0; n < NUM_TAPS; n++) {
361 windowCoeffs[n] = 0.42f - 0.5f * cosf(2.0f *
PI * n / N_minus_1) +
362 0.08f * cosf(4.0f *
PI * n / N_minus_1);
368 const int M = (NUM_TAPS - 1) / 2;
369 for (
int i = 0; i < NUM_TAPS; i++) {
402 const int M = (NUM_TAPS - 1) / 2;
408 for (
int i = 0; i < NUM_BANDS; i++) {
410 if (fabs(
gains[i]) < 0.1f)
continue;
414 float linGain = powf(10.0f,
gains[i] / 20.0f) - 1.0f;
425 float minBwHz = 4.0f * sampleRateFloat / (float)NUM_TAPS;
426 float actualBwHz = fH_hz - fL_hz;
427 if (actualBwHz < minBwHz) {
428 float expand = (minBwHz - actualBwHz) * 0.5f;
429 fL_hz = fL_hz - expand;
430 fH_hz = fH_hz + expand;
431 if (fL_hz < 1.0f) fL_hz = 1.0f;
434 float fL = fL_hz / sampleRateFloat;
435 float fH = fH_hz / sampleRateFloat;
438 if (fL < 0.0f) fL = 0.0f;
439 if (fH < 0.0f) fH = 0.0f;
440 if (fL > 0.5f) fL = 0.5f;
441 if (fH > 0.5f) fH = 0.5f;
442 if (fH <= fL)
continue;
448 float wCenter = 2.0f *
PI *
centerFreqs[i] / sampleRateFloat;
451 for (
int n = 0; n < NUM_TAPS; n++) {
452 float nM = (float)(n - M);
453 float bpW = ((2.0f * fH *
sinc(2.0f * fH * nM)) -
454 (2.0f * fL *
sinc(2.0f * fL * nM))) *
456 hReal += bpW * cosf(wCenter * n);
457 hImag -= bpW * sinf(wCenter * n);
459 float bpMag = sqrtf(hReal * hReal + hImag * hImag);
460 float normFactor = (bpMag > 1e-6f) ? (1.0f / bpMag) : 1.0f;
462 for (
int n = 0; n < NUM_TAPS; n++) {
463 float nM = (float)(n - M);
469 float bp = (2.0f * fH *
sinc(2.0f * fH * nM)) -
470 (2.0f * fL *
sinc(2.0f * fL * nM));
473 tempFloat[n] += bp * window * normFactor * linGain;
478 for (
int i = 0; i < NUM_TAPS; i++) {
484 if (q > 32767) q = 32767;
485 if (q < -32768) q = -32768;
508 LOGI(
"FIR kernel updated with new gains for %d bands /%d taps.", NUM_BANDS,
#define PI
Definition AudioEffectsSuite.h:28
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30