Hi

I managed to finish my first extension (even while I haven't got a clue what pd is up to:-)).

It simply transforms output from notein to legato after these simple rules: left output: the last note that was pressed. right output: 0 if no notes are pressed other wise the velocity of the first played note. If you played a monophonic hardware synth, you'll understand my poor explanation...

Now, I have a couple of questions, just to round this off:

1) The makefile is the one IOhannes pointed me towards([1]), but with PDROOT hardcoded to "/home/atte/software/pd/current/". Isn't there a more elegant way so that someone trying to build it will have to edit the makefile?

2) It doesn't like to receive a bang (basically anything but float). It doesn't really make much sense to send it a float, but would it be nicer to handle this in some way? Right now it just prints "no method for 'bang'" in the pd window...

3) Feedback? I'd be happy if someone finds it even remotely useful. Any ideas I didn't think about?

4) Should I put it up somewhere, for instance on my servers svn-repo?

5) Did I reinvent the wheel? If so, at least I learned quite alot + had fun while doing so :-)

[1]
http://pure-data.cvs.sourceforge.net/pure-data/doc/tutorials/externals-howto/example1/Makefile

--
peace, love & harmony
Atte

http://atte.dk       | http://myspace.com/attejensen
http://anagrammer.dk | http://atte.dk/compositions
#include "m_pd.h"
#define NB_ELEMENTS 200
static t_class *legato_class;

typedef struct _legato {
    t_object  x_obj;
    t_int nb_elements;
    t_float buffer[NB_ELEMENTS];
    t_float note, velocity;
    t_inlet *note_in, *velocity_in;
    t_outlet *note_out, *velocity_out;
} t_legato;


void legato_float(t_legato *x, t_floatarg f1) {
    int i;
    int found = -1;

    // search buffer for note
    for(i=0; i<x->nb_elements; i++){
	if(x->buffer[i] == f1){
	    found = i;
	}
    }

    if(x->velocity != 0){
	// noteon
	if(NB_ELEMENTS == x->nb_elements){
	    //overflow, not doing anything...
	    return;
	}

	if(found == -1){
	    // note not in buffer,
	    // put it at the end...
	    x->buffer[x->nb_elements] = f1;
	    x->nb_elements++;
	    // ...save it...
	    x->note = f1;
	    // ...and send it out
	    outlet_float(x->note_out, f1);
	} else {
	    //post("this isn't supposed to happen...");
	    for(i=found; i<x->nb_elements;i++){
		x->buffer[i] = x->buffer[i+1];
	    }
	}

	if(x->nb_elements == 1){
	    // this is first note in buffer, send velocity
	    outlet_float(x->velocity_out, x->velocity);
	}
	

    } else {
	// noteoff
	if(found != -1){
	    for(i=found; i<x->nb_elements;i++){
		x->buffer[i] = x->buffer[i+1];
	    }
	    x->nb_elements--;
	    if(x->buffer[x->nb_elements-1] != x->note && x->nb_elements>0){
		x->note = x->buffer[x->nb_elements-1];
		outlet_float(x->note_out, x->note);
	    }

	}
	if(x->nb_elements == 0){
	    // this was the last note in buffer, send velocity 0
	    outlet_float(x->velocity_out, 0);
	}
    }
    
    /*
    post("nb_elements:%i",x->nb_elements);
    post("%f %f %f %f %f %f %f %f %f %f",
	 x->buffer[0],
	 x->buffer[1],
	 x->buffer[2],
	 x->buffer[3],
	 x->buffer[4],
	 x->buffer[5],
	 x->buffer[6],
	 x->buffer[7],
	 x->buffer[8],
	 x->buffer[9]
	 );
    */
}

void legato_velocity(t_legato *x, t_floatarg f1) {
    x->velocity = f1;
}


//void *legato_new(t_floatarg f) {
void *legato_new(t_symbol *s, int argc, t_atom *argv){
    t_legato *x = (t_legato *)pd_new(legato_class);

    inlet_new(&x->x_obj, &x->x_obj.ob_pd,
	      gensym("float"), gensym("velocity"));
    
    x->note_out = outlet_new(&x->x_obj, &s_float);
    x->velocity_out = outlet_new(&x->x_obj, &s_float);

    return (void *)x;
}

void legato_setup(void) {
    legato_class = class_new(gensym("legato"),
			     (t_newmethod)legato_new,
			     0, sizeof(t_legato),
			     CLASS_DEFAULT,
			     A_GIMME, 0);

    class_addfloat  (legato_class, legato_float);
    class_addmethod(legato_class,
		    (t_method)legato_velocity, gensym("velocity"),
		    A_DEFFLOAT, 0);
}

# Makefile
# (c) 2006 IOhannes m zmölnig

# path to pd
## change this according to your setup!
#PDROOT=../../../../pd
#PDROOT=/home/zmoelnig/src/pd/
PDROOT=/home/atte/software/pd/current/


# here we find the sources of pd (and evtl. the pd.lib)
PDSRCDIR=$(PDROOT)/src
PDLIBDIR=$(PDROOT)/bin

# this is the filename-extension
# people have to specify it at the cmdline: eg "make pd_linux"
EXTENSION=$(MAKECMDGOALS)

# if no filename-extension is supplied by the user
# try to guess one, based on what "uname" tells us
UNAME := $(shell uname -s)
ifeq ($(UNAME),Linux)
  DEFAULTEXTENSION= pd_linux
else
  ifeq ($(UNAME),Darwin)
    DEFAULTEXTENSION= pd_darwin
  else
    ifeq (MINGW,$(findstring MINGW,$(UNAME)))
      DEFAULTEXTENSION= pd_nt
    else
      ifeq ($(UNAME),IRIX)
        UNAMEV := $(shell uname -R)
        ifeq (6.,$(findstring 6.,$(UNAMEV)))
          DEFAULTEXTENSION= pd_irix6
        else
          DEFAULTEXTENSION= pd_irix5
        endif
      else
        DEFAULTEXTENSION=help
      endif
    endif
  endif
endif

# if no extension is given, call "make" again with a guessed extension
auto:
        make $(DEFAULTEXTENSION)

# just a stupid fallback
help: 
        @echo "choose one command:  make pd_linux (linux), make pd_darwin 
(osX), make pd_irix5 (IRIX5), make pd_irix6 (IRIX6), make dll (MSVC), make 
pd_nt (MinWG)"

# delete old build files
clean:
        -rm -f *.dll *.pd_* *.o *.obj *~

# we want to compile all C-files we find in the current directory
SOURCES=$(sort $(filter %.c, $(wildcard *.c)))
# each C-files maps will become an external with the given filename-extension
TARGETS=$(SOURCES:.c=.$(EXTENSION))


# ----------------------- Linux -----------------------

pd_linux: $(TARGETS)

LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \
    -Wall -W -Wshadow -Wstrict-prototypes -Werror \
    -Wno-unused -Wno-parentheses -Wno-switch

LINUXLDFLAGS =  -export_dynamic -shared  -lc -lm

LINUXINCLUDE =  -I$(PDSRCDIR)

%.pd_linux: %.c
        $(CC) $(LINUXLDFLAGS) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.pd_linux $*.c
        strip --strip-unneeded $*.pd_linux



# ----------------------- Mac OSX -----------------------

pd_darwin: $(TARGETS)

DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
    -Wno-unused -Wno-parentheses -Wno-switch

DARWININCLUDE = -I$(PDSRCDIR)

DARWINLDFLAGS = -bundle -undefined suppress -flat_namespace

%.pd_darwin: %.c
        $(CC) $(DARWINCFLAGS) $(DARWININCLUDE) $(DARWINLDFLAGS) -o $*.pd_darwin 
$*.c


# ----------------------- IRIX 5.x -----------------------
pd_irix5: $(TARGETS)

SGICFLAGS5 = -o32 -DPD -DSGI -O2

SGIINCLUDE =  -I$(PDSRCDIR)

SGILDFLAGS =  -elf -shared -rdata_shared

%.pd_irix5: %.c
        $(CC) $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c
        $(LD) $(SGILDFLAGS) -o $*.pd_irix5 $*.o
        rm $*.o


# ----------------------- IRIX 6.x -----------------------
pd_irix6: $(TARGETS)

SGICFLAGS6 = -DPD -DSGI -n32 \
        -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
        -Ofast=ip32

%.pd_irix6: %.c
        $(CC) $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c
        $(LD) $(SGILDFLAGS) -o $*.pd_irix6 $*.o
        rm $*.o


# ----------------------- NT -----------------------
dll: $(TARGETS)

PDNTCFLAGS = /W3 /WX /DPD /DNT /D__WIN32__ /DMSW /nologo

VC="C:\Programme\Microsoft Visual Studio\Vc98"

PDNTINCLUDE = /I. /I$(PDROOT)\tcl\include /I$(PDSRCDIR)\src /I$(VC)\include

PDNTLDIR = $(VC)\lib

PDNTLIB = $(PDNTLDIR)\libc.lib \
        $(PDNTLDIR)\oldnames.lib \
        $(PDNTLDIR)\kernel32.lib \
        $(PDLIBDIR)\pd.lib 

%.dll: %.c
        cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
        link /dll /export:$*_setup $*.obj $(PDNTLIB)


pd_nt: $(TARGETS)

MINGWCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \
    -Wall -W -Wshadow -Wstrict-prototypes -Werror \
    -Wno-unused -Wno-parentheses -Wno-switch -mms-bitfields

MINGWLDFLAGS =  -export_dynamic -shared -lm -lkernel32 -lcoldname -lcrtdll -lpd 
-L$(PDLIBDIR)

MINGWINCLUDE =  -I$(PDSRCDIR)

%.pd_nt: %.c
        $(CC) $(MINGWLDFLAGS) $(MINGWCFLAGS) $(MINGWINCLUDE) -o $*.dll $*.c
_______________________________________________
[email protected] mailing list
UNSUBSCRIBE and account-management -> 
http://lists.puredata.info/listinfo/pd-list

Reply via email to