/* sIgpAck * for * pure-data * www.weiss-archiv.de */ #include "m_pd.h" #ifdef _MSC_VER #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif /* ------------------------ vowel~ ----------------------------- */ /* simple formant filter */ /* code from musicdsp.org posted by alex@smartelectronix.com */ static t_class *vowel_tilde_class; typedef struct _vowel_tilde { t_object x_obj; t_sample x_vowelnum; float x_f; } t_vowel_tilde; static void *vowel_tilde_new(t_floatarg vowelnum) { t_vowel_tilde *x = (t_vowel_tilde *)pd_new(vowel_tilde_class); x->x_vowelnum = vowelnum; outlet_new(&x->x_obj, gensym("signal")); floatinlet_new(&x->x_obj, &x->x_vowelnum); x->x_f = 0; if(vowelnum) x->x_vowelnum = vowelnum; else x->x_vowelnum = 0; return (x); } 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 }, { 4.36215e-06, 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 }, { 1.13572e-06, 8.994734087, -37.2084849, 93.22900521, -156.6929844, 184.596544, ///O -154.3755513, 90.49663749, -35.58964535, 8.478996281, -0.929252233 }, { 4.09431e-07, 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) { float res; 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; } static t_int *vowel_tilde_perform(t_int *w) { t_vowel_tilde *x = (t_vowel_tilde *)(w[1]); t_float *in = (t_float *)(w[2]); t_float *out = (t_float *)(w[3]); int n = (int)(w[4]); float f, value; while (n--) { f = *in++; value = formant_filter(f, (int)x->x_vowelnum); *out++ = value; } return (w+5); } static void vowel_tilde_dsp(t_vowel_tilde *x, t_signal **sp) { dsp_add(vowel_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); } void vowel_tilde_setup(void) { vowel_tilde_class = class_new(gensym("vowel~"), (t_newmethod)vowel_tilde_new, 0, sizeof(t_vowel_tilde), 0, A_DEFFLOAT, 0); CLASS_MAINSIGNALIN(vowel_tilde_class, t_vowel_tilde, x_f); class_addmethod(vowel_tilde_class, (t_method)vowel_tilde_dsp, gensym("dsp"), 0); class_addmethod(vowel_tilde_class, (t_method)formant_filter, gensym("formant_filter"), A_GIMME, A_NULL); }