diff options
author | Jamie Bullock <postlude@users.sourceforge.net> | 2006-04-19 17:48:38 +0000 |
---|---|---|
committer | Jamie Bullock <postlude@users.sourceforge.net> | 2006-04-19 17:48:38 +0000 |
commit | a1b3c0b4fa99bfd116f302fe74f1168c84d01f79 (patch) | |
tree | 2c5b948e0bdd920cab0f09de31cbbc42492421ce | |
parent | 929b0f5f58583d2916800df9cdfd55c2953fe55f (diff) |
Added frequency domain correlation to cross~
svn path=/trunk/externals/postlude/; revision=4940
-rw-r--r-- | flib/makefile | 69 | ||||
-rw-r--r-- | flib/src/cross~.c | 102 | ||||
-rw-r--r-- | flib/src/flib.h | 2 |
3 files changed, 158 insertions, 15 deletions
diff --git a/flib/makefile b/flib/makefile index 0974eb0..babda2f 100644 --- a/flib/makefile +++ b/flib/makefile @@ -1,6 +1,6 @@ -# Makefile hacked together from various others, mostly the old zexy makefile I think. All credit to IOhannes Zmoelnig and anyone else who understands make better than me. +# Makefile hacked together from various others, mostly the old zexy makefile and pique. All credit to IOhannes Zmoelnig, Miller Puckette and anyone else who understands make better than me. # -# Should work with Linux and OS X. No idea about Windows. +# Should work with Linux and OS X. No idea about Windows and Irix. NAME=flib CSYM=flib @@ -152,6 +152,71 @@ LINUXINCLUDE = -I/usr/include ld -export_dynamic -shared -o $(NAME).pd_linux $(NAME).o $(LINUXOBJECTS) -lc -lm strip --strip-unneeded $(NAME).pd_linux +# ----------------------- IRIX 5.x ----------------------- + +pd_irix5: src/$(NAME).pd_irix5 + +.SUFFIXES: .pd_irix5 + +SGIOBJECTS = $(TARGETS:%=%.o) + +SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 + +SGIINCLUDE = -I/usr/include/ -I/usr/local/include/ + +.c.pd_irix5: + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/sc~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/ss~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/irreg~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/mspec~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/peak~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/pspec~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/sfm~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/trist~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/pp~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/bmax~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/melf~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/clean~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/wdv~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/hca~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/cross~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c $*.c + ld -elf -shared -rdata_shared -o $(NAME).pd_irix5 $(NAME).o $(LINUXOBJECTS) -lm -lc + rm $*.o + +# ----------------------- IRIX 6.x ----------------------- + +pd_irix6: src/$(NAME).pd_irix6 + +.SUFFIXES: .pd_irix6 + +SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ + -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ + -Ofast=ip32 + +SGIOBJECTS = $(TARGETS:%=%.o) + +SGIINCLUDE = -I/usr/include/ -I/usr/local/include/ + +.c.pd_irix6: + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/ss~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/irreg~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/mspec~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/peak~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/pspec~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/sfm~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/trist~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/pp~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/bmax~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/melf~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/clean~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/wdv~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/hca~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c src/cross~.c + $(CC) $(SGICFLAGS) $(SGIINCLUDE) -c $*.c + ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $(NAME).o $(LINUXOBJECTS) -lm -lc + rm $*.o + # ---------------------------------------------------------- install: diff --git a/flib/src/cross~.c b/flib/src/cross~.c index d7ea4bb..2d06d9b 100644 --- a/flib/src/cross~.c +++ b/flib/src/cross~.c @@ -17,8 +17,14 @@ */ -/*Calculate the (non optimized) cross correlation of two signal vectors*/ -/*Based on code by Phil Bourke */ +/*Calculate the cross correlation of two signal vectors*/ + +/*The time domain implementation is based on code by Phil Bourke + * the frequency domain version is based on code by Charles Henry + * + * Specify a time delay as an argument for the time domain implemenation, for example an argument of 32 will give the correlation coefficients for delays from -32 to 32 samples between the two input vectors + * + * Specify an argument of 'f' for the frequency domain implementation*/ #include "flib.h" @@ -30,9 +36,10 @@ typedef struct _cross { t_object x_obj; t_float f; t_int delay; + t_int is_freq_domain; } t_cross; -static t_int *cross_perform(t_int *w) +static t_int *cross_perform_time_domain(t_int *w) { t_sample *x = (t_sample *)(w[1]); t_sample *y = (t_sample *)(w[2]); @@ -45,12 +52,9 @@ static t_int *cross_perform(t_int *w) if(maxdelay > N * .5){ maxdelay = N * .5; post("cross~: invalid maxdelay, must be <= blocksize/2"); - } - else if (!maxdelay){ - maxdelay = N * .5; } - /* Calculate the mean of the two series x[], y[] */ +/* Calculate the mean of the two series x[], y[] */ mx = 0; my = 0; for (i=0;i<N;i++) { @@ -92,16 +96,90 @@ static t_int *cross_perform(t_int *w) } + +t_int *cross_perform_freq_domain(t_int *w) +{ + t_cross *x = (t_cross *)(w[1]); + + t_sample *sig1 = (t_sample *)(w[2]); + t_sample *sig2 = (t_sample *)(w[3]); + t_sample *out = (t_sample *)(w[4]); + long int size = (long int) w[5]; + long int k = size/2; + float *expsig1 = NULL; + float *revsig2 = NULL; + float temp, temp2; + long int i=0; + int well_defined=1; + int qtr, thrqtr; + +// The two signals are created, nonzero on 0 to N/4 and 3N/4 to N +// This will be revised + + expsig1=(float *) alloca(size*sizeof(float)); + revsig2=(float *) alloca(size*sizeof(float)); + qtr = size/4; + thrqtr = 3*size/4; + for (i=0; i < qtr ; i++) + { + expsig1[i]=sig1[i]; + revsig2[i]=0; + } + for (i=qtr; i < thrqtr ; i++) + { + expsig1[i]=sig1[i]; + revsig2[i]=sig2[size-i]; + } + for (i=thrqtr; i < size ; i++) + { + expsig1[i]=sig1[i]; + revsig2[i]=0; + } + + mayer_realfft(size, expsig1); + mayer_realfft(size, revsig2); + expsig1[0]*=revsig2[0]; + expsig1[k]*=revsig2[k]; + for(i=1; i < k; i++) + { + temp=expsig1[i]; + temp2=expsig1[size-i]; + expsig1[i]=temp*revsig2[i]-temp2*revsig2[size-i]; + expsig1[size-i]=temp*revsig2[size-i]+temp2*revsig2[i]; + } + + mayer_realifft(size, expsig1); + for(i=0; i < size; i++) + { + out[i]=expsig1[i]; + } + + return(w+6); + +} + static void cross_dsp(t_cross *x, t_signal **sp) { - dsp_add(cross_perform, 5, - sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n, x->delay); + if(!x->is_freq_domain) + dsp_add(cross_perform_time_domain, 5, + sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n, x->delay); + else + dsp_add(cross_perform_freq_domain, 5, x, + sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n); } -static void *cross_new(t_floatarg f) +static void *cross_new(t_symbol *s, t_int argc, t_atom *argv) { t_cross *x = (t_cross *)pd_new(cross_class); - x->delay = (t_int)f; + + if(atom_getsymbol(argv) == gensym("f")){ + x->is_freq_domain = 1; + post("flib: cross: Frequency domain selected"); + } + else { + x->delay = atom_getfloat(argv); + post("flib: cross: Time domain selected"); + } inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); outlet_new(&x->x_obj, &s_signal); return (void *)x; @@ -112,7 +190,7 @@ void cross_tilde_setup(void) { cross_class = class_new(gensym("cross~"), (t_newmethod)cross_new, 0, sizeof(t_cross), - CLASS_DEFAULT, A_DEFFLOAT, 0); + CLASS_DEFAULT, A_GIMME, 0); class_addmethod(cross_class, (t_method)cross_dsp, gensym("dsp"), 0); diff --git a/flib/src/flib.h b/flib/src/flib.h index fba78f0..868f683 100644 --- a/flib/src/flib.h +++ b/flib/src/flib.h @@ -21,7 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <stdlib.h> #include <string.h> -#define VERSION "0.8" +#define VERSION "0.82" void sc_tilde_setup(void); void ss_tilde_setup(void); |