arm_biquad_cascade_df2T_f32
основа IIR фильтра низкого порядка.
Коэффициенты рассчитываются просто.
Вот код программы:
h
#define EQ_STAGES 1 // order of the biquad of the equalizer filter
#define BIQUAD_COEFF_IN_STAGE 5 // coefficients in manual Notch filter order
main.c
//EQ RX
float32_t EQ_RX_LOW_FILTER_State[2 * EQ_STAGES] = {0};
float32_t EQ_RX_MID_FILTER_State[2 * EQ_STAGES] = {0};
float32_t EQ_RX_HIG_FILTER_State[2 * EQ_STAGES] = {0};
float32_t EQ_RX_LOW_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0};
float32_t EQ_RX_MID_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0};
float32_t EQ_RX_HIG_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0};
arm_biquad_cascade_df2T_instance_f32 EQ_RX_LOW_FILTER = {EQ_STAGES, EQ_RX_LOW_FILTER_State, EQ_RX_LOW_FILTER_Coeffs};
arm_biquad_cascade_df2T_instance_f32 EQ_RX_MID_FILTER = {EQ_STAGES, EQ_RX_MID_FILTER_State, EQ_RX_MID_FILTER_Coeffs};
arm_biquad_cascade_df2T_instance_f32 EQ_RX_HIG_FILTER = {EQ_STAGES, EQ_RX_HIG_FILTER_State, EQ_RX_HIG_FILTER_Coeffs};
//ini RX EQ
rxEqIni();
Функции
// RX Equalizer
void doRX_EQ(float32_t *buffer, uint16_t size)
{
arm_biquad_cascade_df2T_f32(&EQ_RX_LOW_FILTER, buffer, buffer, size);
arm_biquad_cascade_df2T_f32(&EQ_RX_MID_FILTER, buffer, buffer, size);
arm_biquad_cascade_df2T_f32(&EQ_RX_HIG_FILTER, buffer, buffer, size);
}
// automatic calculation of the Biquad filter
void calcBiquad(uint32_t Fc, uint32_t Fs, float32_t Q, float32_t peakGain, float32_t *outCoeffs) {
float32_t a0, a1, a2, b1, b2, norm;
float32_t V = powf(10.0f, fabsf(peakGain) / 20.0f);
float32_t K = tanf(PI * Fc / Fs);
if (peakGain >= 0.0f) {
norm = 1.0f / (1.0f + 1.0f / Q * K + K * K);
a0 = (1.0f + V / Q * K + K * K) * norm;
a1 = 2.0f * (K * K - 1.0f) * norm;
a2 = (1.0f - V / Q * K + K * K) * norm;
b1 = a1;
b2 = (1.0f - 1.0f / Q * K + K * K) * norm;
} else {
norm = 1.0f / (1.0f + V / Q * K + K * K);
a0 = (1.0f + 1.0f / Q * K + K * K) * norm;
a1 = 2.0f * (K * K - 1.0f) * norm;
a2 = (1.0f - 1.0f / Q * K + K * K) * norm;
b1 = a1;
b2 = (1.0f - V / Q * K + K * K) * norm;
}
//save coefficients
outCoeffs[0] = a0;
outCoeffs[1] = a1;
outCoeffs[2] = a2;
outCoeffs[3] = -b1;
outCoeffs[4] = -b2;
}
// RX Equalizer
void rxEqIni(void)
{
uint16_t TRX_SAMPLERATE=24000;
calcBiquad(400, TRX_SAMPLERATE, 0.5f, 0.0f, EQ_RX_LOW_FILTER_Coeffs);
calcBiquad(1800, TRX_SAMPLERATE, 1.0f, 7.0f, EQ_RX_MID_FILTER_Coeffs);
calcBiquad(3200, TRX_SAMPLERATE, 1.5f, -3.0f, EQ_RX_HIG_FILTER_Coeffs);
}
it
//eq FRAME_SIZE=1024, pOutLms-массив оцифровки
doRX_EQ((float32_t *) pOutLms, FRAME_SIZE);