Formant filter

References : Posted by Alex
Code :
Public source code by
Simple example of implementation of formant filter
Vowelnum can be 0,1,2,3,4 <=> A,E,I,O,U
Good for spectral rich input like saw or square
//-------------------------------------------------------------VOWEL COEFFICIENTS
const double coeff[5][11]= {
{ 8.11044e-06,
8.943665402,    -36.83889529,    92.01697887,    -154.337906,    181.6233289,
-151.8651235,   89.09614114,    -35.10298511,    8.388101016,    -0.923313471  ///A
8.90438318,    -36.55179099,    91.05750846,    -152.422234,    179.1170248,  ///E
-149.6496211,87.78352223,    -34.60687431,    8.282228154,    -0.914150747
{ 3.33819e-06,
8.893102966,    -36.49532826,    90.96543286,    -152.4545478,    179.4835618,
-150.315433,    88.43409371,    -34.98612086,    8.407803364,    -0.932568035  ///I
8.994734087,    -37.2084849,    93.22900521,    -156.6929844,    184.596544,   ///O
-154.3755513,    90.49663749,    -35.58964535,    8.478996281,    -0.929252233
8.997322763,    -37.20218544,    93.11385476,    -156.2530937,    183.7080141,  ///U
-153.2631681,    89.59539726,    -35.12454591,    8.338655623,    -0.910251753
static double memory[10]={0,0,0,0,0,0,0,0,0,0};
float formant_filter(float *in, int vowelnum)
            res= (float) ( coeff[vowelnum][0]  *in +
                     coeff[vowelnum][1]  *memory[0] +  
                     coeff[vowelnum][2]  *memory[1] +
                     coeff[vowelnum][3]  *memory[2] +
                     coeff[vowelnum][4]  *memory[3] +
                     coeff[vowelnum][5]  *memory[4] +
                     coeff[vowelnum][6]  *memory[5] +
                     coeff[vowelnum][7]  *memory[6] +
                     coeff[vowelnum][8]  *memory[7] +
                     coeff[vowelnum][9]  *memory[8] +
                     coeff[vowelnum][10] *memory[9] );

memory[9]= memory[8];
memory[8]= memory[7];
memory[7]= memory[6];
memory[6]= memory[5];
memory[5]= memory[4];
memory[4]= memory[3];
memory[3]= memory[2];
memory[2]= memory[1];                    
memory[1]= memory[0];
memory[0]=(double) res;
return res;

from : rhettanderson[AT]yahoo[DOT]com
comment : Where did the coefficients come from? Do they relate to frequencies somehow? Are they male or female? Etc.

from : el98shn[AT]ing[DOT]umu[DOT]se
comment : And are the coeffiecients for 44k1hz? /stefancrs

from : meeloo[AT]meeloo[DOT]net
comment : It seem to be ok at 44KHz although I get quite lot of distortion with this filter. There are typos in the given code too, the correct version looks like this i think: float formant_filter(float *in, int vowelnum) { float res= (float) ( coeff[vowelnum][0]* (*in) + coeff[vowelnum][1] *memory[0] + coeff[vowelnum][2] *memory[1] + coeff[vowelnum][3] *memory[2] + coeff[vowelnum][4] *memory[3] + coeff[vowelnum][5] *memory[4] + coeff[vowelnum][6] *memory[5] + coeff[vowelnum][7] *memory[6] + coeff[vowelnum][8] *memory[7] + coeff[vowelnum][9] *memory[8] + coeff[vowelnum][10] *memory[9] ); ... (missing type and asterisk in the first calc line ;). I tried morphing from one vowel to another and it works ok except in between 'A' and 'U' as I get a lot of distortion and sometime (depending on the signal) the filter goes into auto-oscilation. Sebastien Metrot

from : larsby[AT]elak[DOT]org
comment : How did you get the coeffiecients? Did I miss something? /Larsby

from : stefan[DOT]hallen[AT]dice[DOT]se
comment : Yeah, morphing lineary between the coefficients works just fine. The distortion I only get when not lowering the amplitude of the input. So I lower it :) Larsby, you can approximate filter curves quite easily, check your dsp literature :)

from : alex[AT]smartelectronix[DOT]com
comment : Correct, it is for sampling rate of 44kHz. It supposed to be female (soprano), approximated with its five formants. --Alex.

from : ruiner33[AT]hotmail[DOT]com
comment : Can you tell us how you calculated the coefficients?

from : antiprosynthesis[AT]hotmail[DOT]com
comment : The distorting/sharp A vowel can be toned down easy by just changing the first coeff from 8.11044e-06 to 3.11044e-06. Sounds much better that way.

from : jnorberg [ AT ] gmail [ DOT] com
comment : Hi, I get the last formant (U) to self-oscillate and distort out of control whatever I feed it with. all the other ones sound fine... any sugesstions? Thanks, Jonas

from : texmex[AT]iki[DOT]fi
comment : I was playing around this filter, and after hours of debugging finally noticed that converting those coeffecients to float just won't do it. The resulting filter is not stable anymore. Doh... I don't have any idea how to convert them, though.

from : jayman_21[AT]hotmail[DOT]com
comment : How do you go about calculating the coefficients???

from : mysterious T
comment : Fantastic, it's all I can say! Done the linear blending and open blending matrix (a-e, a-i, a-o, a-u, e-i, e-o...etc..etc..). Too much fun! Thanks a lot, Alex!

from : Thiyana[DOT]Maitriya[AT]honeywell[DOT]com
comment : Could you tell us how you calculated the coefficients?

from : johnny
comment : What about input and output range? When I feed the filter with audio data in -1 to 1 range, output doesn't stay in the same range. Maybe the input or output needs to be scaled?

from : upahiro[AT]pop[DOT]eamale[DOT]com
comment : [url=][/url] <a href=""></a>

from : efgefize[AT]popp[DOT]eamale[DOT]com
comment : [url=][/url] <a href=""></a>

from : zeomogoqi[AT]emailer[DOT]printemailtext[DOT]com
comment : [url=][/url] <a href=""></a>

from : iqcoxagan[AT]pop3[DOT]printemailtext[DOT]com
comment : [url=][/url] <a href=""></a>