diff options
-rw-r--r-- | voicing_detector~/count.pd | 43 | ||||
-rw-r--r-- | voicing_detector~/help-voicing_detector~.pd | 115 | ||||
-rw-r--r-- | voicing_detector~/makefile | 106 | ||||
-rw-r--r-- | voicing_detector~/voicing_detector~.c | 131 |
4 files changed, 395 insertions, 0 deletions
diff --git a/voicing_detector~/count.pd b/voicing_detector~/count.pd new file mode 100644 index 0000000..9be4cf8 --- /dev/null +++ b/voicing_detector~/count.pd @@ -0,0 +1,43 @@ +#N canvas 529 241 271 210 10; +#X obj 69 42 inlet; +#X obj 180 76 inlet; +#X obj 69 59 f; +#X obj 92 59 + 1; +#X msg 172 148 0; +#X obj 92 76 t f f; +#X obj 106 103 f; +#X obj 150 93 >= \$1; +#X obj 150 131 sel 0 1; +#X obj 172 114 inlet; +#X obj 25 139 outlet; +#X obj 69 139 outlet; +#X obj 69 122 sel 0; +#X text 16 25 INLETS: bang/set reset limit; +#X obj 25 76 t f f; +#X obj 139 59 loadbang; +#X msg 25 93 1; +#X obj 55 99 spigot; +#X msg 139 76 0; +#X text 20 170 OUTLETS: count bang-when-done; +#X connect 0 0 2 0; +#X connect 1 0 7 1; +#X connect 2 0 3 0; +#X connect 2 0 14 0; +#X connect 3 0 5 0; +#X connect 4 0 2 1; +#X connect 4 0 17 1; +#X connect 5 0 7 0; +#X connect 5 1 6 1; +#X connect 6 0 2 1; +#X connect 7 0 8 0; +#X connect 8 0 6 0; +#X connect 8 1 4 0; +#X connect 9 0 4 0; +#X connect 12 0 11 0; +#X connect 14 0 10 0; +#X connect 14 0 16 0; +#X connect 14 1 17 0; +#X connect 15 0 18 0; +#X connect 16 0 17 1; +#X connect 17 0 12 0; +#X connect 18 0 17 1; diff --git a/voicing_detector~/help-voicing_detector~.pd b/voicing_detector~/help-voicing_detector~.pd new file mode 100644 index 0000000..c5028ac --- /dev/null +++ b/voicing_detector~/help-voicing_detector~.pd @@ -0,0 +1,115 @@ +#N canvas 0 22 725 399 10; +#N canvas 0 22 462 312 voicing_detect 0; +#X obj 89 148 voicing_detector~; +#X obj 329 147 block~ 1024; +#X obj 89 91 inlet~; +#X obj 203 93 inlet; +#X obj 88 194 outlet; +#X msg 233 120 bound \$1 \$2; +#X msg 341 124 method \$1; +#X obj 273 76 t b f; +#X obj 254 104 pack 60 500; +#X obj 255 45 inlet; +#X obj 297 45 inlet; +#X text 258 12 frequency; +#X text 255 25 constraints; +#X obj 341 93 inlet; +#X obj 341 109 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X text 341 57 0=avg-mag; +#X text 341 70 1=mag-diff; +#X connect 0 0 4 0; +#X connect 2 0 0 0; +#X connect 3 0 0 1; +#X connect 5 0 0 0; +#X connect 6 0 0 0; +#X connect 7 0 8 0; +#X connect 7 1 8 1; +#X connect 8 0 5 0; +#X connect 9 0 8 0; +#X connect 10 0 7 0; +#X connect 13 0 14 0; +#X connect 14 0 6 0; +#X restore 106 203 pd voicing_detect; +#N canvas 0 22 555 302 playload 0; +#X obj 28 132 tabplay~ testinput; +#X obj 28 180 outlet~; +#X obj 27 78 inlet; +#X obj 177 74 inlet; +#X obj 177 105 openpanel; +#X msg 264 150 read -resize ../sound/voice.wav testinput; +#X obj 177 139 soundfiler; +#X msg 177 122 read -resize \$1 testinput; +#X obj 360 134 loadbang; +#X connect 0 0 1 0; +#X connect 2 0 0 0; +#X connect 3 0 4 0; +#X connect 4 0 7 0; +#X connect 5 0 6 0; +#X connect 7 0 6 0; +#X connect 8 0 5 0; +#X restore 106 64 pd playload; +#X msg 178 41 bang; +#X text 210 40 load file; +#N canvas 0 0 450 300 graph1 0; +#X array testinput 1.31596e+06 float 0; +#X coords 0 1 1.31596e+06 -1 300 100 1; +#X restore 402 28 graph; +#N canvas 0 22 454 304 graph1 0; +#X array voicing 300 float 0; +#X coords 0 1.1 299 -0.1 300 50 1; +#X restore 402 130 graph; +#N canvas 0 22 454 304 graphit 1; +#X obj 105 53 inlet; +#X obj 132 153 count 300; +#X obj 104 82 t f b; +#X obj 161 53 inlet; +#X obj 104 187 tabwrite voicing; +#X connect 0 0 2 0; +#X connect 1 0 4 1; +#X connect 2 0 4 0; +#X connect 2 1 1 0; +#X connect 3 0 1 1; +#X restore 107 274 pd graphit; +#X text 133 321 AMDF Voicing Detector - uses the difference between +the average and the magnitude of an autocorrelation function to determine +whether speech is voiced or not.; +#X text 130 367 (C) 2005 Edward Kelly and Nicolas Chetry; +#X msg 105 23 bang; +#X text 141 20 play file; +#X obj 139 91 adc~; +#X floatatom 204 114 5 0 0 1 threshold - -; +#X msg 204 98 20; +#X obj 204 82 loadbang; +#X obj 139 114 *~ 0; +#X obj 179 95 tgl 15 0 empty empty mic 0 -6 0 8 -262144 -1 -1 0 1; +#X floatatom 106 237 5 0 0 0 - - -; +#X text 42 228 voiced/; +#X text 35 241 unvoiced; +#X floatatom 179 163 5 0 0 0 - - -; +#X floatatom 220 163 5 0 0 1 constraints - -; +#X msg 186 139 60; +#X msg 223 139 500; +#X text 273 173 (Hz); +#X obj 250 204 tgl 15 0 empty empty method 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 262 141 loadbang; +#X connect 0 0 17 0; +#X connect 1 0 0 0; +#X connect 2 0 1 1; +#X connect 9 0 1 0; +#X connect 9 0 6 1; +#X connect 11 0 15 0; +#X connect 12 0 0 1; +#X connect 13 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 0 0; +#X connect 16 0 15 1; +#X connect 17 0 6 0; +#X connect 20 0 0 2; +#X connect 21 0 0 3; +#X connect 22 0 20 0; +#X connect 23 0 21 0; +#X connect 25 0 0 4; +#X connect 26 0 23 0; +#X connect 26 0 22 0; diff --git a/voicing_detector~/makefile b/voicing_detector~/makefile new file mode 100644 index 0000000..87572aa --- /dev/null +++ b/voicing_detector~/makefile @@ -0,0 +1,106 @@ +current: + echo make pd_linux, pd_nt, pd_irix5, pd_irix6 or pd_darwin + +clean: ; rm -f *.pd_* *.o + +# ----------------------- NT ----------------------- + +pd_nt: voicing_detector~.dll + +INSTALL_PREFIX = "C:\pd\extra" +EXT = dll +.SUFFIXES: .obj .dll + +PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo +VC="D:\Program Files\Microsoft Visual Studio\Vc98" + +PDNTINCLUDE = /I. /I\tcl\include /I..\..\src /I$(VC)\include + +PDNTLDIR = $(VC)\lib +PDNTLIB = $(PDNTLDIR)\libc.lib \ + $(PDNTLDIR)\oldnames.lib \ + $(PDNTLDIR)\kernel32.lib \ + ..\..\bin\pd.lib + +.c.dll: + cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c + link /dll /export:$*_setup $*.obj $(PDNTLIB) + +# ----------------------- IRIX 5.x ----------------------- + +pd_irix5: voicing_detector~.pd_irix5 + +INSTALL_PREFIX = /usr/local +EXT = pd_irix5 +.SUFFIXES: .pd_irix5 + +SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 + +SGIINCLUDE = -I/usr/local/include + +.c.pd_irix5: + cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c + ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o + rm $*.o + +# ----------------------- IRIX 5.x ----------------------- + +pd_irix6: voicing_detector~.pd_irix6 + +INSTALL_PREFIX = /usr/local +EXT = pd_irix6 +.SUFFIXES: .pd_irix6 + +SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 + +SGIINCLUDE = -I/usr/local/include + +.c.pd_irix6: + cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c + ld -elf -shared -rdata_shared -o $*.pd_irix6 $*.o + rm $*.o + +# ----------------------- LINUX i386 ----------------------- + +pd_linux: voicing_detector~.pd_linux + +INSTALL_PREFIX = /usr +EXT = pd_linux +.SUFFIXES: .pd_linux + +LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +LINUXINCLUDE = -I/usr/local/include + +.c.pd_linux: + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm + strip --strip-unneeded $*.pd_linux + rm $*.o + +# ----------------------- Mac OSX ----------------------- + +pd_darwin: voicing_detector~.pd_darwin + +INSTALL_PREFIX = /usr/local +EXT = pd_darwin +.SUFFIXES: .pd_darwin + +DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ + -Wno-unused -Wno-parentheses -Wno-switch + +.c.pd_darwin: + cc $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o + rm -f $*.o + +# ---------------------------------------------- + +install:: + install -d $(INSTALL_PREFIX)/lib/pd/extra +# install -m 644 *.$(EXT) $(INSTALL_PREFIX)/lib/pd/externs + -install -m 644 voicing_detector~.$(EXT) $(INSTALL_PREFIX)/lib/pd/extra + install -m 644 *.pd $(INSTALL_PREFIX)/lib/pd/doc/5.reference + diff --git a/voicing_detector~/voicing_detector~.c b/voicing_detector~/voicing_detector~.c new file mode 100644 index 0000000..5ed5a3d --- /dev/null +++ b/voicing_detector~/voicing_detector~.c @@ -0,0 +1,131 @@ +#include "m_pd.h" +#include <math.h> + +static t_class *voicing_detector_tilde_class; + +typedef struct _voicing_control +{ + t_float *c_input; + t_float f_sum_abs; + t_atom otemp[4096]; + t_int method; +} t_voicing_control; + +typedef struct _voicing_detector_tilde +{ + t_object x_obj; + t_float f_dummy, f_thresh, f_low, f_high; + t_voicing_control x_ctl; + t_outlet *voiced, *prob; +} t_voicing_detector_tilde; + +static t_int *voicing_detector_tilde_perform(t_int *w) +{ + t_voicing_detector_tilde *x = (t_voicing_detector_tilde *)(w[1]); + t_voicing_control *ctl = (t_voicing_control *)(w[2]); + t_int n = (int)(w[3]); + t_float *in = ctl->c_input; + if (x->f_high < x->f_low) + { + float tmp = x->f_low; + x->f_low = x->f_high; + x->f_high = tmp; + } + t_float current, previous, next, temp0, avg, max, peak0; + current = previous = next = temp0 = avg = max = peak0 = 0; + t_float min = 1000; + t_float samplerate = sys_getsr(); + t_float start = samplerate / x->f_high; + start = start > 1 ? start : 1; + t_float end = samplerate / x->f_low; + end = end < (n-1) ? end : n-1; + t_float result, prob, diff, diff2; + t_int i = 0; + int j; + int l = n; + int maxp = 0; + int maxi = 0; + float temp[n]; + ctl->f_sum_abs = 0.0; + for (i=0;i<l;i++) + { + ctl->f_sum_abs += fabs(in[i]); /* I have to calculate f_sum_abs for the whole block before I can calculate amdf */ + temp[i] = 0.0; + SETFLOAT(&ctl->otemp[i], 0.0); + } + for (i=1;i<l;i++) + { + for (j=start;j<=end;j++) /* the Average Magnitude Difference Function */ + { + temp[j] = i + j < l ? in[i+j] : 0.0; + temp0 = atom_getfloatarg(i, 4096, ctl->otemp); + temp0 += i == 0 ? 0.0 : fabs(in[j] - temp[j]); + } + temp0 += ((float)i / (float)l) * ctl->f_sum_abs; + SETFLOAT(&ctl->otemp[i], temp0); + } + + for (i=start+1;i<end;i++) + { + previous= atom_getfloatarg(i-1, 2048, ctl->otemp); + current = atom_getfloatarg(i, 2048, ctl->otemp); + next = atom_getfloatarg(i+1, 2048, ctl->otemp); + max = current > max ? current : max; + min = current < min ? current : min; + avg += current; + } + avg = avg / (end-start); + diff = avg - min; + diff2 = max - min; + result = ctl->method == 0 ? ((avg - min) > (x->f_thresh) ? 1 : 0) : ((max - min) > x->f_thresh ? 1 : 0); + prob = diff2 / max; + outlet_float(x->prob, prob); + outlet_float(x->voiced, result); + return(w+4); +} + +void voicing_detector_tilde_bound(t_voicing_detector_tilde *x, t_floatarg f1, t_floatarg f2) +{ + x->f_low = f1; + x->f_high = f2; +} + +void voicing_detector_tilde_method(t_voicing_detector_tilde *x, t_floatarg f) +{ + x->x_ctl.method = f > 0 ? 1 : 0; +} + +void *voicing_detector_tilde_dsp(t_voicing_detector_tilde *x, t_signal **sp) +{ + x->x_ctl.c_input = sp[0]->s_vec; + dsp_add(voicing_detector_tilde_perform, 3, x, &x->x_ctl, sp[0]->s_n); + return (void *)x; +} + +void *voicing_detector_tilde_new(t_floatarg f) +{ + t_voicing_detector_tilde *x = (t_voicing_detector_tilde *)pd_new(voicing_detector_tilde_class); + x->f_thresh = f < 0 ? f : 25; + x->f_low = 60; + x->f_high = 500; + + floatinlet_new (&x->x_obj, &x->f_thresh); + x->voiced = outlet_new(&x->x_obj, gensym("float")); + x->prob = outlet_new(&x->x_obj, gensym("float")); + return (void *)x; +} + +void voicing_detector_tilde_setup(void) +{ + voicing_detector_tilde_class = class_new(gensym("voicing_detector~"), (t_newmethod)voicing_detector_tilde_new, 0, sizeof(t_voicing_detector_tilde), CLASS_DEFAULT, A_DEFFLOAT, 0); + + post("\n-->AMDF voicing detector v0.2"); + post("-->by Nicolas Chetry <okin@altern.org>"); + post("-->& Edward Kelly <morph_2016@yahoo.co.uk>"); + + class_addmethod(voicing_detector_tilde_class, (t_method)voicing_detector_tilde_bound, gensym("bound"), A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(voicing_detector_tilde_class, (t_method)voicing_detector_tilde_method, gensym("method"), A_DEFFLOAT, 0); + class_addmethod(voicing_detector_tilde_class, (t_method)voicing_detector_tilde_dsp, gensym("dsp"), 0); + class_sethelpsymbol(voicing_detector_tilde_class, gensym("help-voicing_detector~")); + CLASS_MAINSIGNALIN(voicing_detector_tilde_class, t_voicing_detector_tilde, f_dummy); +} |