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);
228 LOGE(
"Kernel not set!");
238 for (
int n = 0; n < NUM_TAPS; n++) {
241 if (--idx < 0) idx = NUM_TAPS - 1;
257 if constexpr (std::numeric_limits<SampleT>::is_integer) {
259 if constexpr (std::numeric_limits<AccT>::is_integer) {
262 acc = acc / (AccT)(1 << 15);
266 const AccT hi = (AccT)std::numeric_limits<SampleT>::max();
267 const AccT lo = (AccT)std::numeric_limits<SampleT>::min();
268 if (acc > hi) acc = hi;
269 if (acc < lo) acc = lo;
273 return (SampleT)(acc / (AccT)(1 << 15));
327 template <
typename T>
328 float map(T x, T in_min, T in_max, T out_min, T out_max) {
329 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
334 if (fabsf(x) < 1e-8f)
return 1.0f;
335 return sinf(
PI * x) / (
PI * x);
340 if (NUM_BANDS <= 0)
return;
341 float fMin = log10f(20.0f);
342 float fMax = log10f(sampleRate / 2.0f);
343 if (NUM_BANDS == 1) {
344 centerFreqs[0] = powf(10.0f, (fMin + fMax) * 0.5f);
345 LOGD(
"Only one band: center frequency set to %.2f Hz",
centerFreqs[0]);
348 float step = (fMax - fMin) / (
float)(NUM_BANDS - 1);
349 for (
int i = 0; i < NUM_BANDS; i++) {
350 centerFreqs[i] = powf(10.0f, fMin + step * (
float)i);
357 const float N_minus_1 = (float)(NUM_TAPS - 1);
358 for (
int n = 0; n < NUM_TAPS; n++) {
359 windowCoeffs[n] = 0.42f - 0.5f * cosf(2.0f *
PI * n / N_minus_1) +
360 0.08f * cosf(4.0f *
PI * n / N_minus_1);
366 const int M = (NUM_TAPS - 1) / 2;
367 for (
int i = 0; i < NUM_TAPS; i++) {
400 const int M = (NUM_TAPS - 1) / 2;
406 for (
int i = 0; i < NUM_BANDS; i++) {
408 if (fabs(
gains[i]) < 0.1f)
continue;
412 float linGain = powf(10.0f,
gains[i] / 20.0f) - 1.0f;
423 float minBwHz = 4.0f * sampleRateFloat / (float)NUM_TAPS;
424 float actualBwHz = fH_hz - fL_hz;
425 if (actualBwHz < minBwHz) {
426 float expand = (minBwHz - actualBwHz) * 0.5f;
427 fL_hz = fL_hz - expand;
428 fH_hz = fH_hz + expand;
429 if (fL_hz < 1.0f) fL_hz = 1.0f;
432 float fL = fL_hz / sampleRateFloat;
433 float fH = fH_hz / sampleRateFloat;
436 if (fL < 0.0f) fL = 0.0f;
437 if (fH < 0.0f) fH = 0.0f;
438 if (fL > 0.5f) fL = 0.5f;
439 if (fH > 0.5f) fH = 0.5f;
440 if (fH <= fL)
continue;
446 float wCenter = 2.0f *
PI *
centerFreqs[i] / sampleRateFloat;
449 for (
int n = 0; n < NUM_TAPS; n++) {
450 float nM = (float)(n - M);
451 float bpW = ((2.0f * fH *
sinc(2.0f * fH * nM)) -
452 (2.0f * fL *
sinc(2.0f * fL * nM))) *
454 hReal += bpW * cosf(wCenter * n);
455 hImag -= bpW * sinf(wCenter * n);
457 float bpMag = sqrtf(hReal * hReal + hImag * hImag);
458 float normFactor = (bpMag > 1e-6f) ? (1.0f / bpMag) : 1.0f;
460 for (
int n = 0; n < NUM_TAPS; n++) {
461 float nM = (float)(n - M);
467 float bp = (2.0f * fH *
sinc(2.0f * fH * nM)) -
468 (2.0f * fL *
sinc(2.0f * fL * nM));
471 tempFloat[n] += bp * window * normFactor * linGain;
476 for (
int i = 0; i < NUM_TAPS; i++) {
482 if (q > 32767) q = 32767;
483 if (q < -32768) q = -32768;
506 LOGI(
"FIR kernel updated with new gains for %d bands /%d taps.", NUM_BANDS,
#define PI
Definition AudioEffectsSuite.h:27
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30