From d449d31030cfc4a3e06858bf877dcbfacad59f74 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 9 Jan 2006 21:24:28 +0000 Subject: checked in code from sIgpAck0.03.ZIP; cleaned up comment warnings and changed #ifdef NT to #ifdef _MSC_VER; removed sp. prefix and set up for namespaces svn path=/trunk/externals/sigpack/; revision=4381 --- source/vowel~.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 source/vowel~.c (limited to 'source/vowel~.c') diff --git a/source/vowel~.c b/source/vowel~.c new file mode 100644 index 0000000..3500ffc --- /dev/null +++ b/source/vowel~.c @@ -0,0 +1,118 @@ +/* sIgpAck + * for + * pure-data + * www.weiss-archiv.de */ + +#include "m_pd.h" +#ifdef _MSC_VER +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ sp.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("sp.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); +} -- cgit v1.2.1