With my current version of the code it seems to work somewhat with the A, E, and I vowels, there is definitely some change between these parameter positions, however there is still a jump when the integer part changes. Also, as soon as I hit the O vowel the plugin becomes unstable, I thought perhaps this was a denormal issue so I added my usual method of inverting an anti denormal variable with each process() block and therefore adding either 1e-15 or -1e-15 to each sample, but I still get this problem so I assume something else must be causing it.
My Code:
Code: Select all
// FormantFilter.cpp: implementation of the FormantFilter class.
//
//////////////////////////////////////////////////////////////////////
#include "FormantFilter.h"
const double voweltable[5][11] = {
{ ///A
8.11044e-06,
8.943665402, -36.83889529, 92.01697887, -154.337906,
181.6233289,
-151.8651235, 89.09614114, -35.10298511, 8.388101016,
-0.923313471
},
{ ///E
4.36215e-06,
8.90438318, -36.55179099, 91.05750846, -152.422234,
179.1170248,
-149.6496211,87.78352223, -34.60687431, 8.282228154,
-0.914150747
},
{ ///I
3.33819e-06,
8.893102966, -36.49532826, 90.96543286, -152.4545478,
179.4835618,
-150.315433, 88.43409371, -34.98612086, 8.407803364,
-0.932568035
},
{ ///O
1.13572e-06,
8.994734087, -37.2084849, 93.22900521, -156.6929844,
184.596544,
-154.3755513, 90.49663749, -35.58964535, 8.478996281,
-0.929252233
},
{ ///U
4.09431e-07,
8.997322763, -37.20218544, 93.11385476, -156.2530937,
183.7080141,
-153.2631681, 89.59539726, -35.12454591, 8.338655623,
-0.910251753
}
};
static double memory[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
FormantFilter::FormantFilter()
{
vowel = 0;
for(int i=0; i<11; i++)
coeff[i] = voweltable[0][i]; // Initialize coefficient to A
}
FormantFilter::~FormantFilter()
{
}
float FormantFilter::process(float input)
{
float res = (float)( coeff[0] * input +
coeff[1] * memory[0] +
coeff[2] * memory[1] +
coeff[3] * memory[2] +
coeff[4] * memory[3] +
coeff[5] * memory[4] +
coeff[6] * memory[5] +
coeff[7] * memory[6] +
coeff[8] * memory[7] +
coeff[9] * memory[8] +
coeff[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;
}
void FormantFilter::setVowel(float vowelnum)
{
int intpart = (int)(vowelnum * 4.0f);
float fracpart = vowelnum - intpart;
for(int i=0; i<11; i++)
{
coeff[i] = voweltable[intpart][i] * (1.0f - fracpart)
+ (voweltable[intpart+1][i] * fracpart); // Linear Interpolation
}
}
Thanks
Dan