Traçando a resposta de magnitude de um filtro biquad

7

Eu montei um equalizador de áudio para várias bandas usando filtros biquad. Estou recebendo os coeficientes usando os métodos do livro de receitas RBJ .

Agora eu quero traçar a curva mostrando a resposta de magnitude. Eu estou usando uma equação desta fonte

Aqui está minha função de obter os coeficientes e obter a resposta de magnitude nos pontos de interesse.

void GetCoefficients (double samplerate = 44100.0) {

    //from the rbj biquad coefficient cookbook by Robert Bristow-Johnson
    long double SR = (long double)samplerate;
    long double A = powl(10.0L, dBGain/40.0L);
    long double W0 = 2.0L * PI * Center / SR;
    long double alpha = sinl(W0)*sinhl( LN2/2.0L * WidthInOctaves * W0/sinl(W0));

    if (Type == "peaking") {
        b0 = 1.0L + alpha * A;
        b1 = -2.0L * cosl(W0);
        b2 = 1.0L - alpha * A;
        a0 = 1.0L + alpha / A;
        a1 = -2.0L * cosl(W0);
        a2 = 1.0L - alpha / A;
    }

    long double w;
    long double numerator;
    long double denominator;
    long double magnitude;

    for (int i = 0; i < 59; ++ i) {
        w = 2.0L*PI*FreqPoints[i] / SR;  
        numerator = b0*b0 + b1*b1 + b2*b2 + 2.0L*(b0*b1 + b1*b2)*cosl(w) + 2.0L*b0*b2*cosl(2.0L*w);
        denominator = 1.0L + a1*a1 + a2*a2 + 2.0L*(a1 + a1*a2)*cosl(w) + 2.0L*a2*cosl(2.0L*w);
        magnitude = sqrtl(numerator / denominator);
        FrequencyResponse[i] = magnitude;   
    }
}

Meus filtros parecem corretos, mas minha trama parece muito errada. Por exemplo, quando calculei os coeficientes para um filtro de pico com uma largura de2oitavas, centralizadas em , com ganho de ; minha resposta de magnitude usando esses coeficientes em é de cerca de . 4398 Hz3 dB349 Hz12

Eu devo estar fazendo algo errado, mas não consigo entender direito.

MVTC
fonte
11
Isso parece correto para mim. Não há nada obviamente errado. Debug dica: tente um filtro passa-tudo, numerador eo denominador devem vir a ser o mesmo e as de A & B deve ser fipped, ou seja, b2 = a0, b1 = a1, b0 = a2
Hilmar
11
Seria melhor se você mostrasse um exemplo completo e compilável. É possível que você tenha problemas ao inicializar a FreqPointsmatriz ou a PIconstante, por exemplo.
Jason R

Respostas:

4

Alguém no fórum do KRV apontou que eu preciso normalizar meus coeficientes para que a0 = 1.

b0 /= a0;
b1 /= a0;
b2 /= a0;
a1 /= a0;
a2 /= a0;
a0 = 1;

Resolveu o meu problema.

MVTC
fonte
olhem esta resposta . mostra uma maneira numericamente melhor para plotar a resposta de magnitude se você estiver usando o uso de flutuadores de precisão única.
Robert Bristow-johnson