diff options
-rw-r--r-- | flib/makefile | 7 | ||||
-rw-r--r-- | flib/src/cross~.c | 131 | ||||
-rw-r--r-- | flib/src/flib.c | 5 |
3 files changed, 139 insertions, 4 deletions
diff --git a/flib/makefile b/flib/makefile index d690fc0..0974eb0 100644 --- a/flib/makefile +++ b/flib/makefile @@ -12,7 +12,7 @@ INSTALL_PREFIX = /usr/local PDLIBDIR = /lib/pd PDDIR = $(INSTALL_PREFIX)$(PDLIBDIR) -TARGETS = sc~ ss~ irreg~ mspec~ peak~ pspec~ sfm~ trist~ pp~ bmax~ melf~ clean~ wdv~ hca~ +TARGETS = sc~ ss~ irreg~ mspec~ peak~ pspec~ sfm~ trist~ pp~ bmax~ melf~ clean~ wdv~ hca~ cross~ # ----------------------- NT ----------------------- @@ -53,6 +53,7 @@ PDNTLIB = $(PDNTLDIR)\msvcrt.lib \ $(CC) $(PDNTCFLAGS) $(PDNTINCLUDE) -c src/clean~.c $(CC) $(PDNTCFLAGS) $(PDNTINCLUDE) -c src/wdv~.c $(CC) $(PDNTCFLAGS) $(PDNTINCLUDE) -c src/hca~.c + $(CC) $(PDNTCFLAGS) $(PDNTINCLUDE) -c src/cross~.c $(CC) $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c link /dll /export:$(CSYM)_setup $(NAME).obj $(PDNTOBJECTS) $(PDNTLIB) @@ -88,6 +89,7 @@ DARWINOBJECTS = $(TARGETS:%=%.o) $(CC) $(DARWINCFLAGS) $(DARWININCLUDE) -c src/clean~.c $(CC) $(DARWINCFLAGS) $(DARWININCLUDE) -c src/wdv~.c $(CC) $(DARWINCFLAGS) $(DARWININCLUDE) -c src/hca~.c + $(CC) $(DARWINCFLAGS) $(DARWININCLUDE) -c src/cross~.c $(CC) $(DARWINCFLAGS) $(DARWININCLUDE) -c $*.c $(CC) -bundle -undefined suppress -flat_namespace -o $(NAME).pd_darwin $(NAME).o $(DARWINOBJECTS) rm -f $(NAME).o ../$(NAME).pd_darwin @@ -125,7 +127,7 @@ endif $(LINUXOBJECTS): *.h -LINUXCFLAGS = -DPD -O2 -fPIC -funroll-loops -Wall -W -Wshadow -Wstrict-prototypes -Werror -fomit-frame-pointer -Wno-unused -Wno-parentheses -Wno-switch $(AFLAGS) +LINUXCFLAGS = -DPD -O3 -fPIC -funroll-loops -Wall -W -Wshadow -Wstrict-prototypes -Werror -fomit-frame-pointer -Wno-unused -Wno-parentheses -Wno-switch $(AFLAGS) LINUXINCLUDE = -I/usr/include @@ -145,6 +147,7 @@ LINUXINCLUDE = -I/usr/include $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -c src/clean~.c $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -c src/wdv~.c $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -c src/hca~.c + $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -c src/cross~.c $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -c $*.c ld -export_dynamic -shared -o $(NAME).pd_linux $(NAME).o $(LINUXOBJECTS) -lc -lm strip --strip-unneeded $(NAME).pd_linux diff --git a/flib/src/cross~.c b/flib/src/cross~.c new file mode 100644 index 0000000..d769e54 --- /dev/null +++ b/flib/src/cross~.c @@ -0,0 +1,131 @@ +/* flib - PD library for feature extraction + Copyright (C) 2005 Jamie Bullock + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +/*Calculate the (non optimized) cross correlation of two signal vectors*/ + +#include "flib.h" +#define SQ(a) (a * a) + +static t_class *cross_class; + +typedef struct _cross { + t_object x_obj; + t_float f; + t_int delay; +} t_cross; + +static t_int *cross_perform(t_int *w) +{ + t_sample *x = (t_sample *)(w[1]); + t_sample *y = (t_sample *)(w[2]); + t_sample *out = (t_sample *)(w[3]); + t_int N = (t_int)(w[4]), + i, j, delay; + t_int maxdelay = (t_int)(w[5]); + t_float mx, my, sx, sy, sxy, denom, r; + + if(maxdelay > N * .5){ + maxdelay = N * .5; + post("cross~: invalid maxdelay, must be <= blocksize/2"); + } + + /* Calculate the mean of the two series x[], y[] */ + mx = 0; + my = 0; + for (i=0;i<N;i++) { + mx += x[i]; + my += y[i]; + } + mx /= N; + my /= N; + + /* Calculate the denominator */ + sx = 0; + sy = 0; + for (i=0;i<N;i++) { + sx += (x[i] - mx) * (x[i] - mx); + sy += (y[i] - my) * (y[i] - my); + } + denom = sqrt(sx*sy); + + /* Calculate the correlation series */ + for (delay=-maxdelay;delay<maxdelay;delay++) { + sxy = 0; + for (i=0;i<N;i++) { + j = i + delay; + + /* circular correlation */ + while (j < 0) + j += N; + j %= N; + sxy += (x[i] - mx) * (y[j] - my); + + + /* + if (j < 0 || j >= N) + continue; + else + sxy += (x[i] - mx) * (y[j] - my); + */ + + + /* Or should it be (?) + if (j < 0 || j >= n) + sxy += (x[i] - mx) * (-my); + else + sxy += (x[i] - mx) * (y[j] - my); + */ + } + r = sxy / denom; + *out++ = r; + /* r is the correlation coefficient at "delay" */ + + } + + 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); +} + +static void *cross_new(t_floatarg f) +{ + t_cross *x = (t_cross *)pd_new(cross_class); + x->delay = (t_int)f; + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + outlet_new(&x->x_obj, &s_signal); + return (void *)x; +} + + +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_addmethod(cross_class, + (t_method)cross_dsp, gensym("dsp"), 0); + CLASS_MAINSIGNALIN(cross_class, t_cross,f); + class_sethelpsymbol(cross_class, gensym("help-flib")); +} diff --git a/flib/src/flib.c b/flib/src/flib.c index 6bb1015..8db11f4 100644 --- a/flib/src/flib.c +++ b/flib/src/flib.c @@ -36,7 +36,7 @@ void flib_setup(void) { int i; - char *ext[] = {"sc~\t\tSpectral Centroid", "ss~\t\tSpectral Smoothness", "irreg~\t\tSpectral Irregularity (methods 1 and 2)", "mspec~\t\tMagnitude Spectrum", "peak~\t\tAmplitude and Frequency of Spectral Peaks", "pspec~\t\tPhase Spectrum", "sfm~\t\tSpectral Flatness Measure", "trist~\t\tTristimulus (x,y,z)", "++~\t\tSum of the samples in each block", "bmax~\t\tThe maximum value and location(s) each block", "melf~\t\tGenerate a mel spaced filter for fft", "clean~\t\tRemoves NaN, inf and -inf from a signal vector", "wdv~\t\tCalculate a wavelet dispersion vector (requires creb)", "hca~\t\tHarmonic component analysis"}; + char *ext[] = {"sc~\t\tSpectral Centroid", "ss~\t\tSpectral Smoothness", "irreg~\t\tSpectral Irregularity (methods 1 and 2)", "mspec~\t\tMagnitude Spectrum", "peak~\t\tAmplitude and Frequency of Spectral Peaks", "pspec~\t\tPhase Spectrum", "sfm~\t\tSpectral Flatness Measure", "trist~\t\tTristimulus (x,y,z)", "++~\t\tSum of the samples in each block", "bmax~\t\tThe maximum value and location(s) each block", "melf~\t\tGenerate a mel spaced filter for fft", "clean~\t\tRemoves NaN, inf and -inf from a signal vector", "wdv~\t\tCalculate a wavelet dispersion vector (requires creb)", "hca~\t\tHarmonic component analysis", "cross~\t\tCross correlation"}; sc_tilde_setup(); ss_tilde_setup(); pp_tilde_setup(); @@ -51,10 +51,11 @@ void flib_setup(void) clean_tilde_setup(); wdv_tilde_setup(); hca_tilde_setup(); + cross_tilde_setup(); post("\n\tflib "VERSION" Feature Extraction Library\n\tby Jamie Bullock\n"); - for(i = 0; i < 14; i++) + for(i = 0; i < 15; i++) post("\t%s",ext[i]); flib_class = class_new(gensym("flib"), flib_new, 0, sizeof(t_flib), 0, 0); |