Files
SubWave/src/engine/EqProcessor.cpp
T

83 lines
2.3 KiB
C++

#include "EqProcessor.h"
#include <cmath>
#include <numbers>
#include <algorithm>
#include <cstring>
namespace engine {
EqProcessor::EqProcessor() {
for (int b = 0; b < BANDS; ++b) {
m_gainDb[b] = 0.f;
recomputeBiquad(b);
}
}
void EqProcessor::setSampleRate(int sr) {
m_sampleRate = sr;
for (int b = 0; b < BANDS; ++b)
recomputeBiquad(b);
}
void EqProcessor::setBand(int band, float dB) {
if (band < 0 || band >= BANDS) return;
m_gainDb[band] = dB;
recomputeBiquad(band);
}
float EqProcessor::band(int band) const {
return (band >= 0 && band < BANDS) ? m_gainDb[band] : 0.f;
}
void EqProcessor::reset() {
std::memset(m_state, 0, sizeof(m_state));
}
void EqProcessor::process(AudioBuffer &buf) {
const int channels = buf.channels;
const int count = buf.sampleCount();
float *samples = buf.samples.data();
for (int band = 0; band < BANDS; ++band) {
if (std::abs(m_gainDb[band]) < 0.01f) continue;
const float b0 = m_coeff[band][0], b1 = m_coeff[band][1], b2 = m_coeff[band][2];
const float a1 = m_coeff[band][3], a2 = m_coeff[band][4];
for (int i = 0; i < count; ++i) {
const int ch = i % channels;
float &z1 = m_state[band][ch][0];
float &z2 = m_state[band][ch][1];
float x = samples[i];
float y = b0 * x + z1;
z1 = b1 * x - a1 * y + z2;
z2 = b2 * x - a2 * y;
samples[i] = y;
}
}
}
void EqProcessor::recomputeBiquad(int band) {
const float sr = static_cast<float>(m_sampleRate);
const float f0 = FREQS[band];
const float dBg = m_gainDb[band];
const float Q = 1.41421356f; // sqrt(2) , Butterworth Q
const float A = std::pow(10.f, dBg / 40.f);
const double w0 = 2.0 * std::numbers::pi * f0 / sr;
const double cW = std::cos(w0);
const double sW = std::sin(w0);
const double alp = sW / (2.0 * Q);
// Peaking EQ biquad
const double b0 = 1 + alp * A, b1 = -2 * cW, b2 = 1 - alp * A;
const double a0 = 1 + alp / A, a1 = -2 * cW, a2 = 1 - alp / A;
m_coeff[band][0] = float(b0 / a0);
m_coeff[band][1] = float(b1 / a0);
m_coeff[band][2] = float(b2 / a0);
m_coeff[band][3] = float(a1 / a0);
m_coeff[band][4] = float(a2 / a0);
}
} // namespace engine