aboutsummaryrefslogtreecommitdiff
path: root/source/vowel~.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/vowel~.c')
-rw-r--r--source/vowel~.c118
1 files changed, 118 insertions, 0 deletions
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);
+}