Автор Тема: RX EQ от UA3REO  (Прочитано 7721 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
RX EQ от UA3REO
« : Ноябрь 01, 2020, 05:23:25 pm »
Запустил эквалайзер по примеру нашего коллеги. (сильно ничего не искал)
Используется та же CMSIS DSP что и фир фильтрах


 
Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: RX EQ от UA3REO
« Ответ #1 : Ноябрь 01, 2020, 05:28:18 pm »
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);

Да да, я знаю, у меня ничего не получится )))

Оффлайн ra0ahc

  • Hero Member
  • *****
  • Сообщений: 4872
  • Сергей, RD6AH
Re: RX EQ от UA3REO
« Ответ #2 : Ноябрь 01, 2020, 05:50:34 pm »
Нравится пока так:

    calcBiquad(400, TRX_SAMPLERATE, 0.5f, 0.0f, EQ_RX_LOW_FILTER_Coeffs);
    calcBiquad(1900, TRX_SAMPLERATE, 1.0f, 7.0f, EQ_RX_MID_FILTER_Coeffs);
    calcBiquad(3300, TRX_SAMPLERATE, 1.5f, -5.0f, EQ_RX_HIG_FILTER_Coeffs);

(частота, 24000Гц, Q, db, коэффиценты)
Да да, я знаю, у меня ничего не получится )))