[PD-cvs] externals/hardware/multio Makefile, NONE, 1.1 help-multio.pd, NONE, 1.1 multio.c, NONE, 1.1
dmorelli
morellid at users.sourceforge.net
Wed Oct 19 01:25:59 CEST 2005
Update of /cvsroot/pure-data/externals/hardware/multio
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7896
Added Files:
Makefile help-multio.pd multio.c
Log Message:
checking in first usable version
--- NEW FILE: help-multio.pd ---
#N canvas 112 95 1011 631 12;
#X obj 132 124 tgl 30 0 empty empty empty 0 -6 0 8 -62784 -1 -1 0 1
;
#X obj 506 210 unpack f f;
#X floatatom 421 247 5 0 0 0 - - -;
#X floatatom 499 248 5 0 0 0 - - -;
#X msg 132 161 open;
#X obj 132 202 multio;
#X msg 132 69 readout_time 20;
#X msg 132 98 readout_time 1000;
#X msg 132 25 readout_time 1;
#X text 185 163 <-- open the device (opened by default if possible)
;
#X text 170 132 <-- start/stop readout of the device (on by default)
;
#X text 290 39 <--+ | <--+-> set the time between readouts (msec) |
20 msec is the default <--+;
#X obj 123 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 59 1;
#X obj 154 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 198 1;
#X obj 185 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 177 1;
#X obj 216 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 155 1;
#X obj 247 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 3 1;
#X obj 278 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 0 1;
#X obj 309 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 186 1;
#X obj 340 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 769 1;
#X obj 371 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 353 1;
#X obj 402 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 1659 1;
#X obj 433 357 vsl 30 128 0 4096 0 0 empty empty empty 0 -8 0 8 -128992
-1 -1 1380 1;
#X obj 123 274 route 0 1 2 3 4 5 6 7 8 9 10;
#X obj 433 311 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 445 256;
#X obj 402 330 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 535 256;
#X obj 371 311 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 114 256;
#X obj 340 330 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 248 256;
#X obj 309 311 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 60 256;
#X obj 278 330 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 0 256;
#X obj 247 311 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 1 256;
#X obj 216 330 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 50 256;
#X obj 185 311 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 57 256;
#X obj 154 330 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 64 256;
#X obj 123 311 nbx 4 16 -1e+037 1e+037 0 0 empty empty empty 0 -6 0
14 -262144 -1 -1 19 256;
#X msg 130 46 readout_time 5;
#X connect 0 0 5 0;
#X connect 1 0 2 0;
#X connect 1 1 3 0;
#X connect 4 0 5 0;
#X connect 5 0 23 0;
#X connect 5 1 1 0;
#X connect 6 0 5 0;
#X connect 7 0 5 0;
#X connect 8 0 5 0;
#X connect 23 0 34 0;
#X connect 23 1 33 0;
#X connect 23 2 32 0;
#X connect 23 3 31 0;
#X connect 23 4 30 0;
#X connect 23 5 29 0;
#X connect 23 6 28 0;
#X connect 23 7 27 0;
#X connect 23 8 26 0;
#X connect 23 9 25 0;
#X connect 23 10 24 0;
#X connect 24 0 22 0;
#X connect 25 0 21 0;
#X connect 26 0 20 0;
#X connect 27 0 19 0;
#X connect 28 0 18 0;
#X connect 29 0 17 0;
#X connect 30 0 16 0;
#X connect 31 0 15 0;
#X connect 32 0 14 0;
#X connect 33 0 13 0;
#X connect 34 0 12 0;
#X connect 35 0 5 0;
--- NEW FILE: multio.c ---
/*
multio
connects to multIO and listens..
left outlet for analog
middle for digital
output is a list of 2 floats (channel, value)
*/
#ifdef NT
#include <windows.h>
#endif
#include "m_pd.h"
#include "usb.h"
#include "pthread.h"
#define DEFDELTIME 20 // time between readouts in msec
#define TIMEOUT 1000 // timeout time in usb interrupts reading and writing
#define MAXBUF 1024
/* PICkit USB values */
static const int multio_vendorID=0xdead; // Microchip, Inc
static const int multio_productID=0xbeef; // PICkit 1 FLASH starter kit
static const int multio_configuration=2; /* 1: HID; 2: vendor specific */
static const int multio_interface=0;
static const int reqLen=8;
static char is_open;
typedef unsigned char byte;
static t_class *multio_class;
typedef struct _multio
{
t_object x_obj; // myself
usb_dev_handle *d; // handle to multIO
t_clock *x_clock; // as in metro
double x_deltime; // as in metro
int x_hit; // as in metro
pthread_attr_t multio_thread_attr;
pthread_t x_threadid;
unsigned char double_buffer[2][MAXBUF]; // a double buffer: thread writes one, cyclic read of the other one
// the second parameter should be deafult 1000 but setable via
// object parameters
int buf_count[2]; // how many bytes are in a buffer
unsigned char whichbuf; // which one to read from
char old_digi[8]; // buffer of digital input, is a byte, 8 values at a time
char digi_outs[8]; // buffer of digital input, is a byte, 8 values at a time
int analog_buffer[64]; // buffered analog outs
t_outlet *a_out, *d_out, *s_out; // outlets
} t_multio;
static void *usb_read_thread(void *w)
{
t_multio *x = (t_multio*) w;
int cnt = 0;
int bytesread = 0;
unsigned char mybuf = 1;
unsigned char buffer[8];
while(1) // never ending
{
pthread_testcancel();
if(x->d) // only read if the device is opened
{
if(x->buf_count[x->whichbuf] <= 0) // check if the read buffer is empty
{
mybuf = x->whichbuf; // if so, use it for writing
x->whichbuf = !(x->whichbuf &1); // and toggle the read buffer
}
bytesread = usb_interrupt_read(x->d, 0x81, buffer, 8, 1000);
if(bytesread > 0)
{
if(x->buf_count[mybuf]+bytesread > MAXBUF)
x->buf_count[mybuf] = 0;
x->double_buffer[mybuf][x->buf_count[mybuf]++] = bytesread; // store the number of bytes for that message
for(cnt = 0; cnt < bytesread; cnt++) // append the message data into the buffer
{
x->double_buffer[mybuf][x->buf_count[mybuf]++] = buffer[cnt];
}
// post("thread read %i bytes to buffer %i (now %i bytes)",bytesread, mybuf,x->buf_count[mybuf] );
}
}
#ifdef NT
Sleep(1);
#endif
}
}
static void start_thread(t_multio *x)
{
// create the worker thread
if(pthread_attr_init(&x->multio_thread_attr) < 0)
{
post("multio: could not launch receive thread");
return;
}
if(pthread_attr_setdetachstate(&x->multio_thread_attr, PTHREAD_CREATE_DETACHED) < 0)
{
post("multio: could not launch receive thread");
return;
}
if(pthread_create(&x->x_threadid, &x->multio_thread_attr, usb_read_thread, x) < 0)
{
post("multio: could not launch receive thread");
return;
}
else
{
post("multio: thread %d launched", (int)x->x_threadid );
}
}
// methods invoked by the inlets
static void multio_analog_write(t_multio *x, t_symbol *s, int argc, t_atom *argv)
{
int channel;
int value;
unsigned char buffer[8];
int bytesread;
if (argc<2)
{
error("multio: multio_analog_write error: i need minimum 2 values list");
return;
}
if (!(x->d))
{
error("multio: multI/O not initialized");
return;
}
channel = atom_getfloat(argv++);
value = atom_getfloat(argv);
if(channel < 0 || channel > 63)
{
error("multio: inconsistent dac output channel");
return;
}
if (value != x->analog_buffer[channel])
{
x->analog_buffer[channel] = value;
buffer[0] = 97 + channel; // channel is 0 based
buffer[1] = value & 0xff;
buffer[2] = (value & 0xff00) >> 8;
bytesread = usb_interrupt_write(x->d, 1, buffer, 3, TIMEOUT);
}
}
static void multio_digi_write(t_multio *x, t_symbol *s, int argc, t_atom *argv)
{
int channel;
int value;
unsigned char buffer[8];
int bytesread;
char testbit = 0x01;
int count;
int group;
int channel_in_group;
char ctmp;
char bitmask;
if (argc<2)
{
error("multio: multio_digi_write error: i need minimum 2 values list");
return;
}
channel = atom_getfloat(argv++);
value = atom_getfloat(argv);
if(channel < 0 || channel > 63)
{
error("multio: inconsistent digital output channel");
return;
}
group = channel / 8 ;
channel_in_group = channel % 8;
bitmask = 0x01 << channel_in_group;
ctmp = x->digi_outs[group] & ~bitmask;
if (value)
ctmp = ctmp | bitmask;
if(ctmp != x->digi_outs[group])
{
x->digi_outs[group] = ctmp;
buffer[0] = group + 1; // + 1 is the offset for digi outs (1..9)
buffer[1] = ctmp;
bytesread = usb_interrupt_write(x->d, 1, buffer, 3, TIMEOUT);
post("multio: writing %i to group %i", ctmp, group);
}
}
static void multio_system_write(t_multio *x, t_symbol *s, int argc, t_atom *argv)
{
unsigned char cmd, bvalue, smallvalue;
unsigned short int value;
unsigned char buffer[5];
if (argc<3)
{
error("multio: multio_system_write error: i need minimum 3 values list");
return;
}
cmd = atom_getfloat(argv++);
bvalue = atom_getfloat(argv++);
buffer[0] = 161;
buffer[1] = cmd;
buffer[2] = bvalue;
switch(cmd)
{
case 0:
case 1: usb_interrupt_write(x->d, 1, buffer, 3, TIMEOUT); break;
case 2:
case 3:
case 4: value = atom_getfloat(argv);
buffer[3] = value & 0x00ff;
buffer[4] = value >> 8;
usb_interrupt_write(x->d, 1, buffer, 5, TIMEOUT);
break;
case 5:
case 6:
case 7:
case 8: buffer[3] = atom_getfloat(argv);
usb_interrupt_write(x->d, 1, buffer, 4, TIMEOUT);
break;
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17: usb_interrupt_write(x->d, 1, buffer, 3, TIMEOUT); break;
default: error("multio: unknown system command"); break;
}
}
// read & process the buffer
// this will be called each tick in the pd object
static void process_buffer(t_multio *x)
{
int cnt;
if(x->buf_count[x->whichbuf] > 0)
{
// post("process %i bytes buffer\n", x->buf_count[x->whichbuf]);
for(cnt = 0; cnt < x->buf_count[x->whichbuf]; cnt++)
{
if(x->double_buffer[x->whichbuf][cnt] == 2)
{
// post("process buf: %i msglen: %i id: %i val: %i", x->whichbuf, x->double_buffer[x->whichbuf][cnt],x->double_buffer[x->whichbuf][cnt+1],x->double_buffer[x->whichbuf][cnt+2]);
if (x->double_buffer[x->whichbuf][cnt+1]>=1 && x->double_buffer[x->whichbuf][cnt+1] <= 8)
{
// digital input
//send_digi(x, first-1, buffer[1]);
char testbit = 0x01;
t_atom lista[2];
int count;
int group = x->double_buffer[x->whichbuf][cnt+1]-1;
for(count = 0; count < 8; count++)
{
if((x->double_buffer[x->whichbuf][cnt+2] & testbit) != (x->old_digi[group] & testbit))
{
SETFLOAT(lista, (group*8)+count);
if(x->double_buffer[x->whichbuf][cnt+2] & testbit)
SETFLOAT(lista+1, 1);
else
SETFLOAT(lista+1, 0);
outlet_anything(x->d_out, gensym("list") , 2, lista);
}
testbit <<= 1;
}
x->old_digi[group] = x->double_buffer[x->whichbuf][cnt+2];
}
cnt += 2;
}
else if(x->double_buffer[x->whichbuf][cnt] == 3)
{
// post("process buf: %i msglen: %i id: %i val: %i", x->whichbuf, x->double_buffer[x->whichbuf][cnt],x->double_buffer[x->whichbuf][cnt+1],x->double_buffer[x->whichbuf][cnt+2] + (x->double_buffer[x->whichbuf][cnt+3] << 8));
if (x->double_buffer[x->whichbuf][cnt+1]>=9 && x->double_buffer[x->whichbuf][cnt+1] <=96)
{
// analog input
t_atom lista[2];
int result;
int channel = x->double_buffer[x->whichbuf][cnt+1]-9;
result = x->double_buffer[x->whichbuf][cnt+2] + (x->double_buffer[x->whichbuf][cnt+3] << 8);
x->analog_buffer[channel] = result;
SETFLOAT(lista, channel);
SETFLOAT(lista+1, result);
outlet_anything(x->a_out, gensym("list"),2 , lista);
}
cnt += 3;
}
else
cnt += x->double_buffer[x->whichbuf][cnt];
}
x->buf_count[x->whichbuf] = 0;
}
}
/*
// method invoked by the timer
static void multio_read(t_multio *x)
{
unsigned char buffer[8];
int first;
int bytesread;
byte retData[8];
int reads=64;
if (x->d)
{
} else
{
post("error, connection not inizialized");
return;
}
while(usb_interrupt_read(x->d, 0x81, buffer, 8, 2) > 0)
{
// reads--;
//if (usb_interrupt_read(x->d, 0x81, buffer, 8, TIMEOUT) > 0)
//{
first = buffer[0];
if (first>=1 && first <= 8)
{
// digital input
//send_digi(x, first-1, buffer[1]);
char testbit = 0x01;
t_atom lista[2];
int count;
int group = first-1;
for(count = 0; count < 8; count++)
{
if((buffer[1] & testbit) != (x->old_digi[group] & testbit))
{
SETFLOAT(lista, (group*8)+count);
if(buffer[1] & testbit)
SETFLOAT(lista+1, 1);
else
SETFLOAT(lista+1, 0);
outlet_anything(x->d_out, gensym("list") , 2, lista);
}
testbit <<= 1;
}
x->old_digi[group] = buffer[1];
}
if (first>=9 && first <=96)
{
// analog input
t_atom lista[2];
int result;
int channel = first-9;
result = buffer[1] + (buffer[2] << 8);
x->analog_buffer[channel] = result;
SETFLOAT(lista, channel);
SETFLOAT(lista+1, result);
outlet_anything(x->a_out, gensym("list"),2 , lista);
}
if (first==161)
{
t_atom list2[2];
t_atom list3[3];
switch(buffer[1])
{
case 0:
case 1: SETFLOAT(list2, buffer[1]);
SETFLOAT(list2+1, buffer[2]);
outlet_anything(x->s_out, gensym("list"),2 , list2);
break;
case 2:
case 3:
case 4: SETFLOAT(list3, buffer[1]);
SETFLOAT(list3+1, buffer[2]);
SETFLOAT(list3+2, (float)(buffer[3] + (buffer[4]<<8)) );
outlet_anything(x->s_out, gensym("list"),3 , list3);
break;
case 5:
case 6:
case 7:
case 8: SETFLOAT(list3, buffer[1]);
SETFLOAT(list3+1, buffer[2]);
SETFLOAT(list3+2, buffer[3]);
outlet_anything(x->s_out, gensym("list"),3 , list3);
break;
case 9: SETFLOAT(list2, buffer[1] - 9);
outlet_anything(x->a_out, gensym("list"),2 , list2);
break;
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17: SETFLOAT(list3, buffer[1]);
SETFLOAT(list3+1, buffer[2]);
SETFLOAT(list3+2, buffer[3]);
outlet_anything(x->s_out, gensym("list"),3 , list3);
break;
default: error("unknown system command echo"); break;
}
// system input
}
}
}
*/
static void multio_open(t_multio *x)
{
struct usb_device *device;
struct usb_bus* bus;
unsigned char buffer[8];
usb_init();
usb_find_busses();
usb_find_devices();
for (bus=usb_get_busses();bus!=NULL;bus=bus->next)
{
struct usb_device* usb_devices = bus->devices;
for(device=usb_devices;device;device=device->next)
{
if (device->descriptor.idVendor == multio_vendorID
&&device->descriptor.idProduct == multio_productID)
{
post( "multio: Found mamalala multI/O as device '%s' on USB bus %s",
device->filename,
device->bus->dirname);
x->d=usb_open(device);
if (x->d)
{ /* This is our device-- claim it */
if (usb_set_configuration(x->d,multio_configuration)) {
post("multio: Error setting USB configuration.");
usb_close(x->d);
return;
}
else post("multio: Selecting non-HID config");
if (usb_claim_interface(x->d,multio_interface)) {
post("multio: Claim failed-- the mamalala multI/O is in use by another driver.\n"
"multio: Do a `dmesg` to see which kernel driver has claimed it--\n"
"multio: You may need to `rmmod hid` or patch your kernel's hid driver.");
usb_close(x->d);
return;
}
else post("multio: Claimed interface");
while(usb_interrupt_read(x->d, 0x81, buffer, 8, 10) > 0)
{
}
return;
}
}
}
}
// if i am here then i couldn't find mutlIO!
post("multio: unable to find multI/O !");
}
static void multio_tick(t_multio *x)
{
x->x_hit = 0;
// multio_read(x);
process_buffer(x);
if (!x->x_hit) clock_delay(x->x_clock, x->x_deltime);
}
static void multio_float(t_multio *x, t_float f)
{
if (f != 0) multio_tick(x);
else clock_unset(x->x_clock);
x->x_hit = 1;
}
static void multio_start(t_multio *x)
{
multio_float(x, 1);
}
static void multio_stop(t_multio *x)
{
multio_float(x, 0);
}
static void multio_ft1(t_multio *x, t_floatarg g)
{
if (g < 1) g = 1;
x->x_deltime = g;
}
static void multio_free(t_multio *x)
{
if(is_open)
{
clock_free(x->x_clock);
if(x->d)
{
while(pthread_cancel(x->x_threadid) < 0)
post("multio: killing thread\n");
post("multio: thread canceled\n");
usb_close(x->d);
}
is_open = 0;
}
else
post("multio: not active object");
}
static void *multio_new(t_symbol *s, int argc, t_atom *argv)
{
if(!is_open)
{
t_multio *x = (t_multio *)pd_new(multio_class);
x->x_clock = clock_new(x, (t_method)multio_tick);
x->x_deltime = DEFDELTIME;
x->a_out = outlet_new(&x->x_obj, &s_list);
x->d_out = outlet_new(&x->x_obj, &s_list);
x->s_out = outlet_new(&x->x_obj, &s_list);
// look for multIO
multio_open(x);
if(x->d)
start_thread(x);
// inlets for digital and system
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("list"), gensym("digi_write")); // remap to digi_write
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("list"), gensym("system_write"));
is_open = 1;
multio_start(x);
return (x);
}
else
{
post("multio: object already exists");
return(0);
}
}
void multio_setup(void)
{
multio_class = class_new(gensym("multio"), (t_newmethod)multio_new,
(t_method)multio_free, sizeof(t_multio), CLASS_DEFAULT, A_GIMME, 0);
//class_addbang(multio_class, (t_method)multio_bang);
// to set the time between 2 readouts
class_addmethod(multio_class, (t_method)multio_ft1, gensym("readout_time"),
A_FLOAT, 0);
class_addfloat(multio_class, (t_method)multio_float); // start/stop using a toggle
// to stop reading
class_addmethod(multio_class, (t_method)multio_stop, gensym("stop"), 0);
// to start reading
class_addmethod(multio_class, (t_method)multio_start, gensym("start"), 0);
// open the device
class_addmethod(multio_class, (t_method)multio_open, gensym("open"), 0);
// write analog data using leftmost inlet
class_addlist(multio_class, (t_method)multio_analog_write);
class_addmethod(multio_class, (t_method)multio_digi_write, gensym("digi_write"),
A_GIMME, 0);
class_addmethod(multio_class, (t_method)multio_system_write, gensym("system_write"),
A_GIMME, 0);
is_open = 0;
// welcome message
post("\nmultio: a pd driver for the multI/O USB device");
post("multio: www.davidemorelli.it - multio.mamalala.de");
}
--- NEW FILE: Makefile ---
NAME=multio
CSYM=multio
current: pd_linux
# ----------------------- NT -----------------------
pd_nt: $(NAME).dll
.SUFFIXES: .dll
VC="C:\Programmi\Microsoft Visual Studio .NET\Vc7"
PDPATH="H:\PureData\pd-0.38-3.msw\pd"
LIBUSBPATH="H:\PureData\multIO\libusb-win32-device-bin-0.1.10.1"
PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo
PDNTINCLUDE = /I. (PDPATH)\tcl\include /I$(PDPATH)\src /I$(VC)\include /I$(LIBUSBPATH)\include
PDNTLDIR = $(VC)\lib
PDNTLIB = $(PDNTLDIR)\libc.lib \
$(PDNTLDIR)\oldnames.lib \
$(PDNTLDIR)\kernel32.lib \
$(LIBUSBPATH)\lib\msvc\libusb.lib \
$(PDPATH)\bin\pd.lib \
$(PDPATH)\bin\pthreadVC.lib
.c.dll:
cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB)
# ----------------------- LINUX i386 -----------------------
pd_linux: $(NAME).pd_linux
.SUFFIXES: .pd_linux
LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC \
-Wall -W -Wshadow -Wstrict-prototypes \
-Wno-unused -Wno-parentheses -Wno-switch $(CFLAGS)
LINUXINCLUDE = -I../../src
.c.pd_linux:
$(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm -lusb
strip --strip-unneeded $*.pd_linux
rm -f $*.o
# ----------------------- Mac OSX -----------------------
pd_darwin: $(NAME).pd_darwin
.SUFFIXES: .pd_darwin
DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
-Wno-unused -Wno-parentheses -Wno-switch
.c.pd_darwin:
$(CC) $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
$(CC) -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o
rm -f $*.o
# ----------------------------------------------------------
clean:
rm -f *.o *.pd_* so_locations
More information about the Pd-cvs
mailing list