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