DSPRelated.com
Forums

Velocity problems in a parametric Equalizer

Started by Unknown December 16, 2003
I'm developing a parametric equalizer based on peaking filters whith
a c5409 board.
When I use 3 or more bands the filter is slow. It seems like the
music it's reproduced at low frequency. I'm working with TH000Hz,
16bits, mono and my Equalizer algoritm is presented at the end of
this mail.
Any people know what happening in my algoritm!!!

Thank you!

#ifndef EQPARAMETRIC
#define EQPARAMETRIC

#define PI 3.14159
#define NUM_FILTRES 6
#define FMOSTREIG 48000 typedef struct
{
float freq; //Frequencia centrada del filtre
float Q; //Factor Q
float O;
float mu;
float alpha;
float beta;
float gama;
float g; //guany
float x1, x2; //Senyal n-1 i n-2
float u1, u2; //Filtre n-1 i n-2
}Tfiltre;

Tfiltre filtre[NUM_FILTRES];

float guany[41]={
0.100000, 0.112202, 0.125893, 0.141254, 0.158489, 0.177828,
0.199526, 0.223872, 0.251189, 0.281838, 0.316228, 0.354813,
0.398107, 0.446684, 0.501187, 0.562341, 0.630957, 0.707946,
0.794328, 0.891251, 1.000000, 1.122018, 1.258925, 1.412538,
1.584893, 1.778279, 1.995262, 2.238721, 2.511886, 2.818383,
3.162278, 3.548134, 3.981072, 4.466836, 5.011872, 5.623413,
6.309573, 7.079458, 7.943282, 8.912509, 10.000000
};

float cosinus[63]={
-1, -0.989992, -0.970958, -0.942222, -0.904072, -0.856889,
-0.801144, -0.737394, -0.666276, -0.588501, -0.504846, -0.416147,
-0.323290, -0.227202, -0.128844, -0.029200, 0.070737, 0.169967,
0.267499, 0.362358, 0.453596, 0.540302, 0.621610, 0.696707,
0.764842,
0.825336, 0.877583, 0.921061, 0.955336, 0.980067, 0.995004,
1.000000,
0.995004, 0.980067, 0.955336, 0.921061, 0.877583, 0.825336,
0.764842,
0.696707, 0.621610, 0.540302, 0.453596, 0.362358, 0.267499,
0.169967,
0.070737, -0.029200, -0.128844, -0.227202, -0.323290, -0.416147,
-0.504846, -0.588501, -0.666276, -0.737394, -0.801144, -0.856889,
-0.904072, -0.942222, -0.970958, -0.989992, -1
};

float tangent[63]={
0.041617, 0.142547, 0.246405, 0.355530, 0.472728, 0.601597,
0.747022, 0.916014, 1.119214, 1.373823, 1.709847, 2.185040,
2.927098, 4.286262, 7.696602, 34.232533, -14.101420, -5.797884,
-3.602102, -2.572152, -1.964760, -1.557408, -1.260158, -1.029639,
-0.842288, -0.684137, -0.546302, -0.422793, -0.309336, -0.202710,
-0.100335, 0.000000, 0.100335, 0.202710, 0.309336, 0.422793,
0.546302,
0.684137, 0.842288, 1.029639, 1.260158, 1.557408, 1.964760,
2.572152,
3.602102, 5.797884, 14.101420, -34.232533, -7.696602, -4.286262,
-2.927098, -2.185040, -1.709847, -1.373823, -1.119214, -0.916014,
-0.747022, -0.601597, -0.472728, -0.355530, -0.246405, -0.142547,
-0.041617
};

//Definicide funcions i accions
void initEQ();
void calcularEQ();
short filtrarEQ(short inShort);

//Implementacio d'accions i funcions
void initEQ()
{
int i;
filtre[0].freq = 100;
filtre[1].freq = 200;
filtre[2].freq = 600;
filtre[3].freq = 1000;
filtre[2].freq = 5000;
filtre[3].freq = 10000;

for(i=0; i<NUM_FILTRES; i++)
{
filtre[i].g = 0;
filtre[i].Q = 1.2;
filtre[i].x1 = 0;
filtre[i].x2 = 0;
filtre[i].u1 = 0;
filtre[i].u2 = 0;
}
}

void calcularEQ()
{
int i;

for(i=0; i<NUM_FILTRES; i++)
{
//Comprovacide valors
if(filtre[i].g > 20)filtre[i].g = 20;
if(filtre[i].g < -20)filtre[i].g = -20;

//Calcul dels valors
filtre[i].O = 2*PI*filtre[i].freq/FMOSTREIG;
filtre[i].mu = guany[(int)(filtre[i].g + 20)];
filtre[i].beta = 1/2*((1-(4/(1+filtre[i].mu))*tangent[(int)((filtre
[i].O/(2*filtre[i].Q))*10)]/(1+(4/(1+filtre[i].mu))*tangent[(int)
((filtre[i].O/2*filtre[i].Q)*10)])));
filtre[i].gama = ((1/2)+filtre[i].beta)*cosinus[(int)(filtre
[i].O*10)];
filtre[i].alpha = ((1/2)-filtre[i].beta)/2;
}
}

short filtrarEQ(short inShort)
{
int i;
float out, fout;
float in = (float)(inShort);

for(i=0; i<NUM_FILTRES; i++)
{

//------------------THESE ARE A CRITICAL LINES---------
fout = 2*(filtre[i].alpha * (in - filtre[i].x2) + filtre
[i].gama*filtre[i].u1 - filtre[i].beta*filtre[i].u2);
out = in + (filtre[i].mu-1) * fout;
//-------------------------------
-------

filtre[i].x2 = filtre[i].x1;
filtre[i].x1 = in;
filtre[i].u2 = filtre[i].u1;
filtre[i].u1 = fout;

out = in;;
}

return (short)(out);
}

#endif




My guess is that with all that floating point math and manual data
shifting in the main throughput function (short filtrarEQ(short
inShort))you are running out of processsing cycles. i.e. the filter
output can't be computed fast enough to keep up with the sample rate.

You will need to implement the filter calculations in fixed point,
look for a C callable handwritten optimized library that gives you
the basic function of second order cascaded IIR filters.

-Shawn
www.appliedsignalprocessing.com
--- In , u1034199@c... wrote:
> I'm developing a parametric equalizer based on peaking filters
whith
> a c5409 board.
> When I use 3 or more bands the filter is slow. It seems like the
> music it's reproduced at low frequency. I'm working with TH000Hz,
> 16bits, mono and my Equalizer algoritm is presented at the end of
> this mail.
> Any people know what happening in my algoritm!!!
>
> Thank you!
>
> #ifndef EQPARAMETRIC
> #define EQPARAMETRIC
>
> #define PI 3.14159
> #define NUM_FILTRES 6
> #define FMOSTREIG 48000 > typedef struct
> {
> float freq; //Frequencia centrada del filtre
> float Q; //Factor Q
> float O;
> float mu;
> float alpha;
> float beta;
> float gama;
> float g; //guany
> float x1, x2; //Senyal n-1 i n-2
> float u1, u2; //Filtre n-1 i n-2
> }Tfiltre;
>
> Tfiltre filtre[NUM_FILTRES];
>
> float guany[41]={
> 0.100000, 0.112202, 0.125893, 0.141254, 0.158489, 0.177828,
> 0.199526, 0.223872, 0.251189, 0.281838, 0.316228, 0.354813,
> 0.398107, 0.446684, 0.501187, 0.562341, 0.630957, 0.707946,
> 0.794328, 0.891251, 1.000000, 1.122018, 1.258925, 1.412538,
> 1.584893, 1.778279, 1.995262, 2.238721, 2.511886, 2.818383,
> 3.162278, 3.548134, 3.981072, 4.466836, 5.011872, 5.623413,
> 6.309573, 7.079458, 7.943282, 8.912509, 10.000000
> };
>
> float cosinus[63]={
> -1, -0.989992, -0.970958, -0.942222, -0.904072, -0.856889,
> -0.801144, -0.737394, -0.666276, -0.588501, -0.504846, -0.416147,
> -0.323290, -0.227202, -0.128844, -0.029200, 0.070737, 0.169967,
> 0.267499, 0.362358, 0.453596, 0.540302, 0.621610, 0.696707,
> 0.764842,
> 0.825336, 0.877583, 0.921061, 0.955336, 0.980067, 0.995004,
> 1.000000,
> 0.995004, 0.980067, 0.955336, 0.921061, 0.877583, 0.825336,
> 0.764842,
> 0.696707, 0.621610, 0.540302, 0.453596, 0.362358, 0.267499,
> 0.169967,
> 0.070737, -0.029200, -0.128844, -0.227202, -0.323290, -0.416147,
> -0.504846, -0.588501, -0.666276, -0.737394, -0.801144, -0.856889,
> -0.904072, -0.942222, -0.970958, -0.989992, -1
> };
>
> float tangent[63]={
> 0.041617, 0.142547, 0.246405, 0.355530, 0.472728, 0.601597,
> 0.747022, 0.916014, 1.119214, 1.373823, 1.709847, 2.185040,
> 2.927098, 4.286262, 7.696602, 34.232533, -14.101420, -5.797884,
> -3.602102, -2.572152, -1.964760, -1.557408, -1.260158, -1.029639,
> -0.842288, -0.684137, -0.546302, -0.422793, -0.309336, -0.202710,
> -0.100335, 0.000000, 0.100335, 0.202710, 0.309336, 0.422793,
> 0.546302,
> 0.684137, 0.842288, 1.029639, 1.260158, 1.557408, 1.964760,
> 2.572152,
> 3.602102, 5.797884, 14.101420, -34.232533, -7.696602, -4.286262,
> -2.927098, -2.185040, -1.709847, -1.373823, -1.119214, -0.916014,
> -0.747022, -0.601597, -0.472728, -0.355530, -0.246405, -0.142547,
> -0.041617
> };
>
> //Definicide funcions i accions
> void initEQ();
> void calcularEQ();
> short filtrarEQ(short inShort);
>
> //Implementacio d'accions i funcions
> void initEQ()
> {
> int i;
> filtre[0].freq = 100;
> filtre[1].freq = 200;
> filtre[2].freq = 600;
> filtre[3].freq = 1000;
> filtre[2].freq = 5000;
> filtre[3].freq = 10000;
>
> for(i=0; i<NUM_FILTRES; i++)
> {
> filtre[i].g = 0;
> filtre[i].Q = 1.2;
> filtre[i].x1 = 0;
> filtre[i].x2 = 0;
> filtre[i].u1 = 0;
> filtre[i].u2 = 0;
> }
> }
>
> void calcularEQ()
> {
> int i;
>
> for(i=0; i<NUM_FILTRES; i++)
> {
> //Comprovacide valors
> if(filtre[i].g > 20)filtre[i].g = 20;
> if(filtre[i].g < -20)filtre[i].g = -20;
>
> //Calcul dels valors
> filtre[i].O = 2*PI*filtre[i].freq/FMOSTREIG;
> filtre[i].mu = guany[(int)(filtre[i].g + 20)];
> filtre[i].beta = 1/2*((1-(4/(1+filtre[i].mu))*tangent[(int)
((filtre
> [i].O/(2*filtre[i].Q))*10)]/(1+(4/(1+filtre[i].mu))*tangent[(int)
> ((filtre[i].O/2*filtre[i].Q)*10)])));
> filtre[i].gama = ((1/2)+filtre[i].beta)*cosinus[(int)(filtre
> [i].O*10)];
> filtre[i].alpha = ((1/2)-filtre[i].beta)/2;
> }
> }
>
> short filtrarEQ(short inShort)
> {
> int i;
> float out, fout;
> float in = (float)(inShort);
>
> for(i=0; i<NUM_FILTRES; i++)
> {
>
> //------------------THESE ARE A CRITICAL LINES---------
> fout = 2*(filtre[i].alpha * (in - filtre[i].x2) + filtre
> [i].gama*filtre[i].u1 - filtre[i].beta*filtre[i].u2);
> out = in + (filtre[i].mu-1) * fout;
> //------------------------------
-
> -------
>
> filtre[i].x2 = filtre[i].x1;
> filtre[i].x1 = in;
> filtre[i].u2 = filtre[i].u1;
> filtre[i].u1 = fout;
>
> out = in;;
> }
>
> return (short)(out);
> }
>
> #endif