changeset 77:899c31350e8d

Added Max/MSP external to examples. There are problems (memory I think), but the basic code is there
author Jamie Bullock <jamie@postlude.co.uk>
date Tue, 31 Jul 2007 20:44:17 +0000
parents f913cf823628
children afb298ce1b4d
files examples/MSP/Info.plist examples/MSP/Makefile examples/MSP/PkgInfo examples/MSP/version.plist examples/MSP/xtract~.c
diffstat 5 files changed, 388 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/MSP/Info.plist	Tue Jul 31 20:44:17 2007 +0000
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>xtract~</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>co.uk.postlude</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>iLaX</string>
+	<key>CFBundleSignature</key>
+	<string>max2</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>CSResourcesFileMapped</key>
+	<true/>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/MSP/Makefile	Tue Jul 31 20:44:17 2007 +0000
@@ -0,0 +1,43 @@
+NAME=xtract~
+CSYM=xtract~
+
+all: universal
+current: universal
+
+MAXINCLUDE = /usr/local/include/max-includes 
+MSPINCLUDE = /usr/local/include/msp-includes 
+FRAMEWORKS = /Library/Frameworks
+INSTALLDIR = /Applications/MaxMSP\ 4.6/Cycling\ \'74/externals/
+
+LIPO = /usr/bin/lipo
+CC = gcc
+
+CFLAGS = -F$(FRAMEWORKS) -Wmost -Wno-four-char-constants -Wno-unknown-pragmas -x c -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -Os -fmessage-length=0 -I$(MAXINCLUDE) -I$(MSPINCLUDE) -include macho-prefix.h  -Werror
+
+I386CFLAGS = -arch i386 
+PPCCFLAGS = -arch ppc -faltivec -fasm-blocks
+
+LDFLAGS = -F$(FRAMEWORKS) -L$(MAXINCLUDE) -L$(MSPINCLUDE) -framework Carbon -framework MaxAPI -framework MaxAudioAPI -Wl,-Y,1455 -bundle -L/usr/local/lib -lxtract
+
+I386LDFLAGS = -arch i386
+PPCLDFLAGS = -arch ppc
+
+universal: 
+	$(CC) $(CFLAGS) $(I386CFLAGS) -o $(NAME)-i386.o -c $(NAME).c
+#	$(CC) $(CFLAGS) $(PPCCFLAGS) -o $(NAME)-ppc.o -c $(NAME).c
+	$(CC) $(LDFLAGS) $(I386LDFLAGS) -o $(NAME)-i386 $(NAME)-i386.o
+#	$(CC) $(LDFLAGS) $(PPCLDFLAGS) -o $(NAME)-ppc $(NAME)-ppc.o
+#	$(LIPO) -create $(NAME)-ppc $(NAME)-i386 -output $(NAME)
+	$(LIPO) -create $(NAME)-i386 -output $(NAME)
+	mkdir -p $(NAME).mxo/Contents/MacOS
+	cp Info.plist PkgInfo $(NAME).mxo/Contents/
+	cp $(NAME) $(NAME).mxo/Contents/MacOS
+
+clean:
+	rm -rf *i386* *ppc* xtract~ *.mxo
+
+maintainer-clean:
+	rm -rf *i386* *ppc* xtract~ *.mxo
+
+install:
+	$(INSTALL) cp -r $(NAME).mxo $(INSTALLDIR)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/MSP/PkgInfo	Tue Jul 31 20:44:17 2007 +0000
@@ -0,0 +1,1 @@
+iLaXmax2
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/MSP/version.plist	Tue Jul 31 20:44:17 2007 +0000
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildVersion</key>
+	<string>38</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>ProjectName</key>
+	<string>CarbonProjectTemplates</string>
+	<key>SourceVersion</key>
+	<string>140000</string>
+</dict>
+</plist>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/MSP/xtract~.c	Tue Jul 31 20:44:17 2007 +0000
@@ -0,0 +1,304 @@
+/* xtract~ - PD library for feature extraction 
+Copyright (C) 2006  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.
+*/
+
+/* calculates the spectral xtract of one frame, given peak frequency and amplitude to first and second inputs respectively */
+
+#include "ext.h"
+#include "z_dsp.h"
+#include <math.h>
+#include <string.h>
+
+#include "xtract/libxtract.h"
+
+#define BLOCKSIZE 1024 /* FIX: this should be dynamic - somehow */
+#define NYQUIST 22050.0f
+
+void *xtract_tilde_class;
+
+/* Struct for keeping track of memory allocations */
+typedef struct _tracked_memory {
+    char argv;
+} tracked_memory;
+
+typedef struct _xtract {
+    t_pxobject  x_obj;
+    void *outlet; /*Float outlet */
+    t_float f;
+    t_int feature;
+    t_int feature_type;
+    tracked_memory memory;
+    void *argv;
+} t_xtract_tilde;
+
+static t_int *xtract_perform(t_int *w) {
+    t_sample *in = (t_sample *)(w[1]);
+    t_xtract_tilde *x = (t_xtract_tilde *)(w[2]);
+    t_int N = (t_int)(w[3]);
+    t_int return_code = 0;
+    float result = 0;
+
+    return_code = xtract[x->feature]((float *)in, N, x->argv, &result);
+
+    if(return_code == XTRACT_FEATURE_NOT_IMPLEMENTED)
+	perror("Feature not implemented");
+
+    /* set nan, inf or -inf to 0 */
+    result = (isinf(result) || isnan(result) ? 0 : result);
+    
+    outlet_float(x->outlet, result);
+    return (w+4);
+}
+
+static t_int *xtract_perform_vector(t_int *w) {
+    t_sample *in = (t_sample *)(w[1]);
+    t_sample *out = (t_sample *)(w[2]);
+    float *temp_in, *temp_out;
+    t_xtract_tilde *x = (t_xtract_tilde *)(w[3]);
+    t_int N = (t_int)(w[4]), n;
+    t_int return_code = 0;
+
+    if(x->feature == XTRACT_PEAK_SPECTRUM)
+	N >>= 1;
+
+    n = N;
+    
+    temp_in = (float *)getbytes(N * sizeof(float));
+    temp_out= (float *)getbytes(N * sizeof(float));
+
+    while(n--)
+	temp_in[n] = in[n];
+
+    n = N;
+
+    return_code = xtract[x->feature](temp_in, N, x->argv, temp_out);
+    
+    while(n--)
+	out[n] = temp_out[n];
+
+    if(return_code == XTRACT_FEATURE_NOT_IMPLEMENTED)
+	perror("Feature not implemented");
+
+    freebytes(temp_in, sizeof(float) * N);
+    freebytes(temp_out, sizeof(float) * N);
+
+    return (w+5);
+}
+
+static void xtract_tilde_dsp(t_xtract_tilde *x, t_signal **sp) {
+
+    if(x->feature_type == XTRACT_VECTOR)
+        dsp_add(xtract_perform_vector, 4, 
+            sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
+            
+    else dsp_add(xtract_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
+
+}
+
+static void *xtract_tilde_new(t_symbol *me, t_int argc, t_atom *argv) {
+    
+    t_symbol *tmp;
+    t_xtract_tilde *x = (t_xtract_tilde *)newobject(xtract_tilde_class);
+    xtract_mel_filter *mf;
+    t_int n, N, f, F, n_args, type;
+    t_float *argv_max;
+    xtract_function_descriptor_t *fd;
+    char *p_name, *p_desc, *author;
+    int year;
+
+    p_name = p_desc = author = NULL;
+   
+    n_args = type = x->feature = 0;
+
+    f = F = XTRACT_FEATURES;
+
+    N = BLOCKSIZE;
+    
+    x->argv = NULL;
+    
+    tmp = argv->a_w.w_sym; /*atom_getsymbol(argv); */
+
+    /* get function descriptors */
+    fd = (xtract_function_descriptor_t *)xtract_make_descriptors();
+
+    /* iterate over descriptors */
+    while(f--){
+	/* map creation arg to feature */
+	if(tmp == gensym(fd[f].algo.name)){ 
+	    x->feature = f;
+	    break;
+	}
+    }
+
+    /* allocate memory for feature arguments */
+    n_args = fd[f].argc;
+    type = fd[f].argv.type;
+
+    if(n_args){
+	for(n = 0; n < n_args; n++){
+		    argv_max = &fd[f].argv.max[n]; 
+		    //post("Argument %d, max: %.2f", n, *argv_max);
+	}
+	if(type == XTRACT_MEL_FILTER){
+	    x->memory.argv = (size_t)(n_args * sizeof(xtract_mel_filter));
+	    x->argv = (xtract_mel_filter *)getbytes(x->memory.argv);
+	}
+	else if(type == XTRACT_INT){
+	    x->memory.argv = (size_t)(n_args * sizeof(t_int));
+	    x->argv = (t_int *)getbytes(x->memory.argv);
+	}
+	else if (type == XTRACT_FLOAT){
+	    x->memory.argv = (size_t)(n_args * sizeof(t_float));
+	    x->argv = (t_float *)getbytes(x->memory.argv);
+	}
+	else
+	    x->memory.argv = 0;
+    }
+
+
+    p_name = fd[f].algo.p_name;
+    p_desc = fd[f].algo.p_desc;
+    author = fd[f].algo.author;
+    year = fd[f].algo.year; 
+
+    if(argc){
+	if(strcmp(p_name, ""))	
+	    post("xtract~: %s", p_name );
+	if(strcmp(p_desc, ""))	
+	    post("xtract~: %s", p_desc );
+	if(strcmp(author, "") && year)	
+	    post("xtract~: %s(%d)", author, year);
+    }	
+    else
+	post("xtract~: No arguments given");
+    
+
+    /* do init if needed */
+    if(x->feature == XTRACT_MFCC){
+
+        mf = x->argv;
+        
+        mf->n_filters = 20;
+        
+        post("xtract~: mfcc: filters = %d", 
+		((xtract_mel_filter *)x->argv)->n_filters);
+        mf->filters = 
+            (t_float **)getbytes(mf->n_filters * sizeof(t_float *));
+        for(n = 0; n < mf->n_filters; n++)
+            mf->filters[n] = (float *)getbytes(N * sizeof(float));
+                 
+        xtract_init_mfcc(N, NYQUIST, XTRACT_EQUAL_GAIN, 80.0f,
+        18000.0f, mf->n_filters, mf->filters);
+    }
+    else if(x->feature == XTRACT_BARK_COEFFICIENTS)
+        xtract_init_bark(N, NYQUIST, x->argv);
+    
+    if(x->feature == XTRACT_AUTOCORRELATION || 
+	    x->feature == XTRACT_AUTOCORRELATION_FFT || 
+	    x->feature == XTRACT_MFCC || x->feature == XTRACT_AMDF || 
+	    x->feature == XTRACT_ASDF|| x->feature == XTRACT_DCT || 
+	    x->feature == XTRACT_BARK_COEFFICIENTS || 
+	    x->feature == XTRACT_SPECTRUM || 
+	    x->feature == XTRACT_PEAK_SPECTRUM || 
+	    x->feature == XTRACT_HARMONIC_SPECTRUM) 
+	x->feature_type = XTRACT_VECTOR;
+                
+    else if (x->feature == XTRACT_FLUX || x->feature == XTRACT_ATTACK_TIME || 
+            x->feature == XTRACT_DECAY_TIME || x->feature == XTRACT_DELTA) 
+        x->feature_type = XTRACT_DELTA;
+       
+    else x->feature_type = XTRACT_SCALAR;
+
+    /* argv through right inlet */
+    inlet_new((t_pxobject *)x, "argv"); 
+
+    /* DSP inlet */
+    dsp_setup((t_pxobject *)x, 1);
+
+
+    /* if feature is vector, create signal out */
+    if(x->feature_type == XTRACT_VECTOR)  
+	outlet_new((t_pxobject *)x, "signal");
+
+    /* otherwise: float */
+    else 
+	x->outlet = floatout((t_pxobject *)x);
+
+    
+    /* free the function descriptors */
+    xtract_free_descriptors(fd);
+    
+    return (void *)x;
+}
+
+static void xtract_tilde_get_args(t_xtract_tilde *x, t_symbol *selector, 
+t_int argc, t_atom *argv) {
+/*
+    if(argc > (t_int)sizeof(x->argv) / 
+                        (t_int)sizeof(t_float) || x->argv == NULL)
+        post("Too many parameters to right inlet");
+    else{*/
+
+    x->argv = getbytes(argc * sizeof(float));
+    
+        while(argc--)
+            ((t_float *)x->argv)[argc] = atom_getfloatarg(1, argc, argv);
+ /*   }*/
+}
+
+static void xtract_tilde_show_help(t_xtract_tilde *x, t_symbol *s){
+    
+    int i;
+
+    i = XTRACT_FEATURES;
+    xtract_function_descriptor_t *fd, *d;
+
+    fd = (xtract_function_descriptor_t *)xtract_make_descriptors();
+    post("\nxtract~: Feature List\n");
+   
+    while(i--){
+	d = &fd[i];
+	post("\t%s", d->algo.name);
+    }
+
+    xtract_free_descriptors(fd);
+}
+
+static void xtract_tilde_free(t_xtract_tilde *x) {
+
+    if(x->argv != NULL && x->memory.argv)
+        freebytes(x->argv, x->memory.argv);
+}
+
+int main(void) {
+
+    setup((t_messlist **)&xtract_tilde_class,
+    	(method)xtract_tilde_new,
+    	(method)xtract_tilde_free, 
+    	sizeof(t_xtract_tilde),
+    	0L, 
+    	A_GIMME, 0);
+
+    addmess((method)xtract_tilde_dsp, "dsp", A_CANT,  0);
+    addmess((method)xtract_tilde_get_args, "argv", A_GIMME, 0);
+    addmess((method)xtract_tilde_show_help, "help", A_DEFSYM, 0); 
+    dsp_initclass();
+    //class_setname("xtract~", "xtract~");
+
+    return 0;
+
+}