From fc3d3c0a4f110a23335398c327ac0a4fc949d5cb Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Mon, 17 Jun 2002 10:13:57 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r12, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/ggee/; revision=13 --- control/Makefile | 53 ++++++ control/constant.c | 61 +++++++ control/inv.c | 74 ++++++++ control/inv.pd | 26 +++ control/osctl | 66 +++++++ control/prepend.c | 74 ++++++++ control/qread.c | 129 ++++++++++++++ control/receivelocal.pd | 18 ++ control/rl.c | 80 +++++++++ control/rtout.c | 41 +++++ control/sendlocal.pd | 18 ++ control/serial_bird.c | 264 +++++++++++++++++++++++++++ control/serial_bird.pd | 35 ++++ control/serial_ms.c | 120 +++++++++++++ control/serial_mt.c | 77 ++++++++ control/serialctl.c | 463 ++++++++++++++++++++++++++++++++++++++++++++++++ control/serialctl.pd | 61 +++++++ control/serialize.c | 58 ++++++ control/serialize.pd | 8 + control/serialmouse.pd | 35 ++++ control/shell.c | 206 +++++++++++++++++++++ control/shell.pd | 21 +++ control/sinh.c | 54 ++++++ control/sl.c | 73 ++++++++ control/stripdir.c | 48 +++++ control/stripdir.pd | 7 + control/unserialize.c | 57 ++++++ control/unwonk.c | 119 +++++++++++++ control/unwonk.pd | 36 ++++ 29 files changed, 2382 insertions(+) create mode 100755 control/Makefile create mode 100755 control/constant.c create mode 100755 control/inv.c create mode 100755 control/inv.pd create mode 100755 control/osctl create mode 100755 control/prepend.c create mode 100755 control/qread.c create mode 100755 control/receivelocal.pd create mode 100755 control/rl.c create mode 100755 control/rtout.c create mode 100755 control/sendlocal.pd create mode 100755 control/serial_bird.c create mode 100755 control/serial_bird.pd create mode 100755 control/serial_ms.c create mode 100755 control/serial_mt.c create mode 100755 control/serialctl.c create mode 100755 control/serialctl.pd create mode 100755 control/serialize.c create mode 100755 control/serialize.pd create mode 100755 control/serialmouse.pd create mode 100755 control/shell.c create mode 100755 control/shell.pd create mode 100755 control/sinh.c create mode 100755 control/sl.c create mode 100755 control/stripdir.c create mode 100755 control/stripdir.pd create mode 100755 control/unserialize.c create mode 100755 control/unwonk.c create mode 100755 control/unwonk.pd (limited to 'control') diff --git a/control/Makefile b/control/Makefile new file mode 100755 index 0000000..abcf9dd --- /dev/null +++ b/control/Makefile @@ -0,0 +1,53 @@ +current: nt + + +# TARGETS += stk + +VERSION = \"0.16\" + +.SUFFIXES: .dll .obj +# ----------------------- NT ---------------------------- + +NTOBJECTS = *.obj +NTDLLS = *.dll + +PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo + +PDNTINCLUDE = /I. /I..\..\pd\src + +ProgramFiles = c:\Program Files +PDNTLDIR = "$(ProgramFiles)\Microsoft Visual Studio\Vc98\lib" + +PDNTLIB = $(PDNTLDIR)\libc.lib \ + $(PDNTLDIR)\oldnames.lib \ + $(PDNTLDIR)\wsock32.lib \ + $(PDNTLDIR)\kernel32.lib \ + $(PDNTLDIR)\uuid.lib \ + ..\..\pd\bin\pd.lib + +nt: $(NTOBJECTS) + -link /dll $(PDNTLIB) constant.obj /export:constant_setup + -link /dll $(PDNTLIB) inv.obj /export:inv_setup + -link /dll $(PDNTLIB) qread.obj /export:qread_setup + -link /dll $(PDNTLIB) rl.obj /export:rl_setup + -link /dll $(PDNTLIB) rtout.obj /export:rtout_setup + -link /dll $(PDNTLIB) unserialize.obj /export:unserialize_setup + -link /dll $(PDNTLIB) serialize.obj /export:serialize_setup + -link /dll $(PDNTLIB) sinh.obj /export:sinh_setup + -link /dll $(PDNTLIB) sl.obj /export:sl_setup + -link /dll $(PDNTLIB) stripdir.obj /export:stripdir_setup + -link /dll $(PDNTLIB) unwonk.obj /export:unwonk_setup + +clean: + del *.obj + del *.dll + + +.c.obj: + -cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c + +.obj.dll: + + + + diff --git a/control/constant.c b/control/constant.c new file mode 100755 index 0000000..7e8ccfa --- /dev/null +++ b/control/constant.c @@ -0,0 +1,61 @@ +/* (C) Guenter Geiger */ + + +#include +#include +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ constant ----------------------------- */ +#ifndef M_PI +#define M_PI 3.141593f +#endif + +static t_class *constant_class; + + +typedef struct _constant +{ + t_object x_obj; + t_float x_constant; +} t_constant; + + +void constant_bang(t_constant *x) +{ + outlet_float(x->x_obj.ob_outlet, x->x_constant); +} + +static void *constant_new(t_symbol* s) +{ + t_constant *x = (t_constant *)pd_new(constant_class); + + if (s == &s_) + x->x_constant = M_PI; + + if (!strcmp(s->s_name,"PI")) + x->x_constant = M_PI; + + if (!strcmp(s->s_name,"TWOPI")) + x->x_constant = 2*M_PI; + + if (!strcmp(s->s_name,"e")) + x->x_constant = exp(1.0); + + + + outlet_new(&x->x_obj, &s_float); + return (x); +} + +void constant_setup(void) +{ + constant_class = class_new(gensym("constant"), (t_newmethod)constant_new, 0, + sizeof(t_constant), 0,0); + class_addbang(constant_class,constant_bang); +} + + diff --git a/control/inv.c b/control/inv.c new file mode 100755 index 0000000..ef9f736 --- /dev/null +++ b/control/inv.c @@ -0,0 +1,74 @@ +/* (C) Guenter Geiger */ + +#include + + +typedef struct inv +{ + t_object x_obj; +} t_inv; + +static t_class *inv_class; + +static void *inv_new(void) +{ + t_inv *x = (t_inv *)pd_new(inv_class); + outlet_new(&x->x_obj, gensym("signal")); + return (x); +} + +static t_int *inv_perform(t_int *w) /* not static; also used in d_fft.c */ +{ + float *in = *(t_float **)(w+1), *out = *(t_float **)(w+2); + t_int n = *(t_int *)(w+3); + while (n--) + { + *out++ = 1/ *in++; + } + return (w + 4); +} + +static void inv_dsp(t_inv *x, t_signal **sp) +{ + dsp_add(inv_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +void inv_setup(void) +{ + inv_class = class_new(gensym("1/x~"), (t_newmethod)inv_new, 0, + sizeof(t_inv), 0, 0); + + class_addmethod(inv_class, nullfn, gensym("signal"), 0); + class_addmethod(inv_class, (t_method)inv_dsp, gensym("dsp"), 0); +} + + + + +typedef struct scalarinv +{ + t_object x_obj; +} t_scalarinv; + +static t_class *scalarinv_class; + +static void *scalarinv_new(void) +{ + t_scalarinv *x = (t_scalarinv *)pd_new(scalarinv_class); + outlet_new(&x->x_obj, gensym("float")); + return (x); +} + +static void scalarinv_float(t_scalarinv *x,t_float val) +{ + outlet_float(x->x_obj.ob_outlet,1.0f/val); + +} + +void scalarinv_setup(void) +{ + scalarinv_class = class_new(gensym("1/x"), (t_newmethod)scalarinv_new, 0, + sizeof(t_scalarinv), 0, 0); + + class_addfloat(scalarinv_class, (t_method)scalarinv_float); +} diff --git a/control/inv.pd b/control/inv.pd new file mode 100755 index 0000000..4724449 --- /dev/null +++ b/control/inv.pd @@ -0,0 +1,26 @@ +#N canvas 201 39 506 289 10; +#X floatatom 32 76; +#X floatatom 32 137; +#X obj 188 93 sig~ 220; +#X floatatom 188 74; +#X obj 188 150 1/x~; +#X obj 188 192 clip~ -1 1; +#X obj 181 222 dac~; +#X text 25 267 (C) Guenter Geiger; +#X obj 188 111 phasor~; +#X obj 188 129 +~ 1; +#X obj 188 173 -~ 0.5; +#X text 184 54 the signal version doesnt look useful to me; +#X text 34 54 To make life easier; +#X text 32 12 1/x takes the inverse of the input; +#X obj 32 107 invert; +#X connect 0 0 14 0; +#X connect 2 0 8 0; +#X connect 3 0 2 0; +#X connect 4 0 10 0; +#X connect 5 0 6 0; +#X connect 5 0 6 1; +#X connect 8 0 9 0; +#X connect 9 0 4 0; +#X connect 10 0 5 0; +#X connect 14 0 1 0; diff --git a/control/osctl b/control/osctl new file mode 100755 index 0000000..a6ab246 --- /dev/null +++ b/control/osctl @@ -0,0 +1,66 @@ +#include +#include +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ osctl ----------------------------- */ +#ifndef M_PI +#define M_PI 3.141593f +#endif + +void InitOSCReceive() { + struct OSCReceiveMemoryTuner rt; + Boolean result; + + rt.InitTimeMemoryAllocator = MyInitTimeMalloc; + rt.RealTimeMemoryAllocator = MyRealTimeMalloc; + rt.receiveBufferSize = 1000; + rt.numReceiveBuffers = 100; + rt.numQueuedObjects = 200; + rt.numCallbackListNodes = 100; + + result = OSCInitReceive(&rt); + + if (result == FALSE) { + fatal_error("OSCInitReceive returned FALSE!\n"); + } +} + + + +static t_class *osctl_class; + + +typedef struct _osctl +{ + t_object x_obj; +} t_osctl; + + +void osctl_bang(t_osctl *x) +{ + outlet_float(x->x_obj.ob_outlet, x->x_osctl); +} + +static void *osctl_new(t_symbol* s) +{ + t_osctl *x = (t_osctl *)pd_new(osctl_class); + + InitOSCReceive(); + + + outlet_new(&x->x_obj, &s_float); + return (x); +} + +void osctl_setup(void) +{ + osctl_class = class_new(gensym("osctl"), (t_newmethod)osctl_new, 0, + sizeof(t_osctl), 0,0); + class_addbang(osctl_class,osctl_bang); +} + + diff --git a/control/prepend.c b/control/prepend.c new file mode 100755 index 0000000..f2fc4af --- /dev/null +++ b/control/prepend.c @@ -0,0 +1,74 @@ +/* (C) Guenter Geiger */ + + +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ prepend ----------------------------- */ + +static t_class *prepend_class; + + +typedef struct _prepend +{ + t_object x_obj; + t_symbol* x_s; +} t_prepend; + + +void prepend_anything(t_prepend *x,t_symbol* s,t_int argc,t_atom* argv) +{ + int i = argc; + t_symbol* cur; + t_atom a_out[256]; + int c_out = 0; + t_atom* a = a_out; + +#if 1 + SETSYMBOL(a,s); + a++; + c_out++; +#endif + while (i--) { + switch( argv->a_type) { + case A_FLOAT: + post("%f",atom_getfloat(argv)); + break; + case A_SYMBOL: + post("%s",atom_getsymbol(argv)->s_name); + SETSYMBOL(a,atom_getsymbol(argv)); + a++; + c_out++; + break; + default: + post("unknown type"); + } + argv++; + } + + outlet_list(x->x_obj.ob_outlet,x->x_s,c_out,(t_atom*)&a_out); + post("done"); +} + +static void *prepend_new(t_symbol* s) +{ + t_prepend *x = (t_prepend *)pd_new(prepend_class); + outlet_new(&x->x_obj, &s_float); + if (s != &s_) + x->x_s = s; + else + x->x_s = gensym("prepend"); + return (x); +} + +void prepend_setup(void) +{ + prepend_class = class_new(gensym("prepend"), (t_newmethod)prepend_new, 0, + sizeof(t_prepend), 0,A_DEFSYM,NULL); + class_addanything(prepend_class,prepend_anything); +} + + diff --git a/control/qread.c b/control/qread.c new file mode 100755 index 0000000..bfad03e --- /dev/null +++ b/control/qread.c @@ -0,0 +1,129 @@ +/* (C) Guenter Geiger */ + + +#include +#include "g_canvas.h" +/* ------------------------ qread ----------------------------- */ + +#include + +static t_class *qread_class; + + +#define MAXLINE 255 + +typedef struct _qread +{ + t_object x_obj; + FILE* x_file; + int x_size; + t_clock* x_clock; + t_glist * x_glist; + int x_num; + t_symbol* x_name; +} t_qread; + + + +static void qread_open(t_qread *x,t_symbol *filename) +{ + char fname[MAXPDSTRING]; + + if (filename == &s_) { + post("sfread: open without filename"); + return; + } + + canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name, + fname, MAXPDSTRING); + + + /* close the old file */ + + if (x->x_file) fclose(x->x_file); + + if (!(x->x_file = fopen(fname,"r"))) + { + error("can't open %s",fname); + return; + } + + +} + +void qread_next(t_qread *x) +{ + int i; + float delay; + char name[MAXLINE]; + t_atom at[20]; + int ac=0; + t_floatarg ff; + + if (!x->x_file) return; + + fscanf(x->x_file,"%f",&delay); + if (feof(x->x_file)) { + clock_unset(x->x_clock); + return; + } + + fscanf(x->x_file,"%s",name); +#ifdef DEBUG + post("next: name = %s delay = %f",name,delay); +#endif + + for (i=0;i<=x->x_num && !feof(x->x_file);i++) { + fscanf(x->x_file,"%f",&ff); + SETFLOAT(at+i,ff); + } + ac = i-1; + fscanf(x->x_file,";"); + + + clock_delay(x->x_clock,delay); + + outlet_list(x->x_obj.ob_outlet, gensym(name), ac, at); +} + +static void qread_bang(t_qread *x) +{ + if (!x->x_file) return; + + fseek(x->x_file,0,SEEK_SET); + clock_delay(x->x_clock,0); + +#ifdef DEBUG + post("bang"); +#endif +} + +static void qread_stop(t_qread *x) +{ + clock_unset(x->x_clock); +} + +static void *qread_new(t_floatarg n) +{ + t_qread *x = (t_qread *)pd_new(qread_class); + outlet_new(&x->x_obj, &s_float); + + x->x_name = gensym("qread"); + x->x_glist = (t_glist*) canvas_getcurrent(); + x->x_clock = clock_new(x, (t_method)qread_next); + x->x_file = NULL; + x->x_num = n; + return (x); +} + +void qread_setup(void) +{ + qread_class = class_new(gensym("qread"), (t_newmethod)qread_new, 0, + sizeof(t_qread), 0,A_DEFFLOAT,A_NULL); + class_addbang(qread_class,qread_bang); + class_addmethod(qread_class,(t_method)qread_next,gensym("next"),A_NULL); + class_addmethod(qread_class,(t_method)qread_open,gensym("open"),A_SYMBOL,A_NULL); + class_addmethod(qread_class,(t_method)qread_stop,gensym("stop"),A_NULL); +} + + diff --git a/control/receivelocal.pd b/control/receivelocal.pd new file mode 100755 index 0000000..5ada9f9 --- /dev/null +++ b/control/receivelocal.pd @@ -0,0 +1,18 @@ +#N canvas 245 35 596 413 10; +#N canvas 296 238 600 380 /SUBPATCH/ 0; +#X obj 104 220 print subpatch; +#X obj 105 160 rl test; +#X connect 1 0 0 0; +#X restore 254 192 pd; +#X obj 39 285 print local; +#X floatatom 38 142; +#X msg 72 138 nope dope; +#X text 38 327 (C) 1999 Guenter Geiger; +#X obj 41 198 sl test1; +#X obj 39 259 rl test1; +#X text 31 38 receive locally sent messages with receivelocal; +#X text 31 20 send messages locally (per canvas) with sendlocal; +#X text 30 56 aliases are "sl" and "rl"; +#X connect 2 0 5 0; +#X connect 3 0 5 0; +#X connect 6 0 1 0; diff --git a/control/rl.c b/control/rl.c new file mode 100755 index 0000000..7a789d5 --- /dev/null +++ b/control/rl.c @@ -0,0 +1,80 @@ +/* (C) Guenter Geiger */ + + +#include +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +/* -------------------- lreceive ------------------------------ */ + +static t_class *lreceive_class; + +typedef struct _lreceive +{ + t_object x_obj; + t_symbol *x_sym; +} t_lreceive; + +static void lreceive_bang(t_lreceive *x) +{ + outlet_bang(x->x_obj.ob_outlet); +} + +static void lreceive_float(t_lreceive *x, t_float f) +{ + outlet_float(x->x_obj.ob_outlet, f); +} + +static void lreceive_symbol(t_lreceive *x, t_symbol *s) +{ + outlet_symbol(x->x_obj.ob_outlet, s); +} + +static void lreceive_pointer(t_lreceive *x, t_gpointer *gp) +{ + outlet_pointer(x->x_obj.ob_outlet, gp); +} + +static void lreceive_list(t_lreceive *x, t_symbol *s, int argc, t_atom *argv) +{ + outlet_list(x->x_obj.ob_outlet, s, argc, argv); +} + +static void lreceive_anything(t_lreceive *x, t_symbol *s, int argc, t_atom *argv) +{ + outlet_anything(x->x_obj.ob_outlet, s, argc, argv); +} + +static void *lreceive_new(t_symbol *s) +{ + t_lreceive *x = (t_lreceive *)pd_new(lreceive_class); + char mysym[MAXPDSTRING]; + + sprintf(mysym,"%s%p",s->s_name,canvas_getcurrent()); + x->x_sym = gensym(mysym); + pd_bind(&x->x_obj.ob_pd, x->x_sym); + outlet_new(&x->x_obj, 0); + return (x); +} + +static void lreceive_free(t_lreceive *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_sym); +} + +void rl_setup(void) +{ + lreceive_class = class_new(gensym("receivelocal"), (t_newmethod)lreceive_new, + (t_method)lreceive_free, sizeof(t_lreceive), CLASS_NOINLET, A_SYMBOL, 0); + class_addcreator((t_newmethod)lreceive_new, gensym("rl"), A_DEFSYM, 0); + class_addbang(lreceive_class, lreceive_bang); + class_addfloat(lreceive_class, (t_method)lreceive_float); + class_addsymbol(lreceive_class, lreceive_symbol); + class_addpointer(lreceive_class, lreceive_pointer); + class_addlist(lreceive_class, lreceive_list); + class_addanything(lreceive_class, lreceive_anything); +} diff --git a/control/rtout.c b/control/rtout.c new file mode 100755 index 0000000..95df28c --- /dev/null +++ b/control/rtout.c @@ -0,0 +1,41 @@ +/* (C) Guenter Geiger */ + + +#include + +/* -------------------------- rtout -------------------------- */ + +void sys_putmidimess(int portno, int a, int b, int c); + +static t_class *rtout_class; + + + +typedef struct _rtout +{ + t_object x_obj; + t_float x_rt; + t_float x_channel; +} t_rtout; + +static void *rtout_new(t_floatarg channel) +{ + t_rtout *x = (t_rtout *)pd_new(rtout_class); + if (channel <= 0) channel = 1; + x->x_channel = channel; + return (x); +} + +static void rtout_float(t_rtout *x, t_float f) +{ + int binchan = (int) x->x_channel - 1; + sys_putmidimess((binchan>>4),(int) f,0,0); +} + +void rtout_setup(void) +{ + rtout_class = class_new(gensym("rtout"), (t_newmethod)rtout_new, 0, + sizeof(t_rtout), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addfloat(rtout_class, rtout_float); +} + diff --git a/control/sendlocal.pd b/control/sendlocal.pd new file mode 100755 index 0000000..5ada9f9 --- /dev/null +++ b/control/sendlocal.pd @@ -0,0 +1,18 @@ +#N canvas 245 35 596 413 10; +#N canvas 296 238 600 380 /SUBPATCH/ 0; +#X obj 104 220 print subpatch; +#X obj 105 160 rl test; +#X connect 1 0 0 0; +#X restore 254 192 pd; +#X obj 39 285 print local; +#X floatatom 38 142; +#X msg 72 138 nope dope; +#X text 38 327 (C) 1999 Guenter Geiger; +#X obj 41 198 sl test1; +#X obj 39 259 rl test1; +#X text 31 38 receive locally sent messages with receivelocal; +#X text 31 20 send messages locally (per canvas) with sendlocal; +#X text 30 56 aliases are "sl" and "rl"; +#X connect 2 0 5 0; +#X connect 3 0 5 0; +#X connect 6 0 1 0; diff --git a/control/serial_bird.c b/control/serial_bird.c new file mode 100755 index 0000000..25a837d --- /dev/null +++ b/control/serial_bird.c @@ -0,0 +1,264 @@ +/* (C) Guenter Geiger */ + + +#include + +#define DEBUG(x) +/*#define DEBUG(x) x*/ + +static t_class *serial_bird_class; + + +#define BIRD_DATA_START 0x80 + +#define BIRDCMD_MODE_POS 86 +#define BIRD_BYTES_POS 6 + +#define BIRDCMD_MODE_POSANG 89 +#define BIRD_BYTES_POSANG 12 + +#define BIRDCMD_MODE_POSMAT 90 +#define BIRD_BYTES_POSMAT 24 + +#define BIRDCMD_MODE_POSQUAT 93 +#define BIRD_BYTES_POSQUAT 14 + +#define BIRDCMD_MODE_QUAT 92 +#define BIRD_BYTES_QUAT 8 + +#define BIRDCMD_STREAM 64 +#define BIRDCMD_POINT 66 + +#define BIRD_GETDATA(x,y) ((float)((short)(y<<9 | x<<2))) + +#define MAXBUFFER 32 + + + +typedef struct _serial_bird +{ + t_object x_obj; + char x_c[MAXBUFFER]; + t_int x_dataformat; + t_int x_maxcount; + t_int x_count; + t_float x_posx; + t_float x_posy; + t_float x_posz; + t_outlet *x_out2; +} t_serial_bird; + + +static void serial_bird_reset( t_serial_bird* x) +{ + x->x_posx=0; + x->x_posy=0; + x->x_count = 0; + outlet_float(x->x_obj.ob_outlet, x->x_posx); + outlet_float(x->x_out2, x->x_posy); +} + +static void serial_bird_float( t_serial_bird* x,t_floatarg f) +{ + unsigned char c = (unsigned char) f; + t_atom at[BIRD_BYTES_POSMAT]; + t_int ac = 0; + + if (c&BIRD_DATA_START) { + x->x_count=0; + x->x_c[x->x_count] = c & 0x7f; + } + else + x->x_c[x->x_count] = c; + + DEBUG(post("data %d in = %x, start = %d",x->x_count,c,c&BIRD_DATA_START);) + + if (x->x_count == x->x_maxcount-1) { + switch (x->x_dataformat) { + case BIRDCMD_MODE_POS: + ac = 3; + SETFLOAT(&at[0], 0.25*BIRD_GETDATA(x->x_c[0],x->x_c[1])); + SETFLOAT(&at[1], 0.25*BIRD_GETDATA(x->x_c[2],x->x_c[3])); + SETFLOAT(&at[2], 0.25*BIRD_GETDATA(x->x_c[4],x->x_c[5])); + break; + case BIRDCMD_MODE_POSANG: + ac = 6; + SETFLOAT(&at[0], 0.25*BIRD_GETDATA(x->x_c[0],x->x_c[1])); + SETFLOAT(&at[1], 0.25*BIRD_GETDATA(x->x_c[2],x->x_c[3])); + SETFLOAT(&at[2], 0.25*BIRD_GETDATA(x->x_c[4],x->x_c[5])); + SETFLOAT(&at[3], BIRD_GETDATA(x->x_c[6],x->x_c[7])); + SETFLOAT(&at[4], BIRD_GETDATA(x->x_c[8],x->x_c[9])); + SETFLOAT(&at[5], BIRD_GETDATA(x->x_c[10],x->x_c[11])); + break; + case BIRDCMD_MODE_POSMAT: + ac = 12; + SETFLOAT(&at[0], BIRD_GETDATA(x->x_c[0],x->x_c[1])); + SETFLOAT(&at[1], BIRD_GETDATA(x->x_c[2],x->x_c[3])); + SETFLOAT(&at[2], BIRD_GETDATA(x->x_c[4],x->x_c[5])); + SETFLOAT(&at[3], BIRD_GETDATA(x->x_c[6],x->x_c[7])); + SETFLOAT(&at[4], BIRD_GETDATA(x->x_c[8],x->x_c[9])); + SETFLOAT(&at[5], BIRD_GETDATA(x->x_c[10],x->x_c[11])); + SETFLOAT(&at[6], BIRD_GETDATA(x->x_c[12],x->x_c[13])); + SETFLOAT(&at[7], BIRD_GETDATA(x->x_c[14],x->x_c[15])); + SETFLOAT(&at[8], BIRD_GETDATA(x->x_c[16],x->x_c[17])); + SETFLOAT(&at[9], BIRD_GETDATA(x->x_c[18],x->x_c[19])); + SETFLOAT(&at[10], BIRD_GETDATA(x->x_c[20],x->x_c[21])); + SETFLOAT(&at[11], BIRD_GETDATA(x->x_c[22],x->x_c[23])); + break; + case BIRDCMD_MODE_POSQUAT: + ac = 7; + SETFLOAT(&at[0], BIRD_GETDATA(x->x_c[0],x->x_c[1])); + SETFLOAT(&at[1], BIRD_GETDATA(x->x_c[2],x->x_c[3])); + SETFLOAT(&at[2], BIRD_GETDATA(x->x_c[4],x->x_c[5])); + SETFLOAT(&at[3], BIRD_GETDATA(x->x_c[6],x->x_c[7])); + SETFLOAT(&at[4], BIRD_GETDATA(x->x_c[8],x->x_c[9])); + SETFLOAT(&at[5], BIRD_GETDATA(x->x_c[10],x->x_c[11])); + SETFLOAT(&at[6], BIRD_GETDATA(x->x_c[12],x->x_c[13])); + break; + case BIRDCMD_MODE_QUAT: + ac = 4; + SETFLOAT(&at[0], BIRD_GETDATA(x->x_c[0],x->x_c[1])); + SETFLOAT(&at[1], BIRD_GETDATA(x->x_c[2],x->x_c[3])); + SETFLOAT(&at[2], BIRD_GETDATA(x->x_c[4],x->x_c[5])); + SETFLOAT(&at[3], BIRD_GETDATA(x->x_c[6],x->x_c[7])); + break; + } + +/* post("posx %d, posy %d",x->x_posx,x->x_posy);*/ + outlet_list(x->x_obj.ob_outlet,&s_list, ac, at); + } + + x->x_count = (++x->x_count)%(x->x_maxcount); +} + +static void serial_bird_poll( t_serial_bird* x) +{ + post("poll"); + /* outlet_float(x->x_out2,(float)x->x_dataformat);*/ + outlet_float(x->x_out2,(float)BIRDCMD_POINT); +} + +static void serial_bird_mode( t_serial_bird* x,t_symbol* s) +{ + post("mode"); + /* outlet_float(x->x_out2,(float)x->x_dataformat);*/ + + + if (!strcmp(s->s_name,"position")) { + x->x_dataformat = BIRDCMD_MODE_POS; + x->x_maxcount = BIRD_BYTES_POS; + } + + if (!strcmp(s->s_name,"positionangle")) { + x->x_dataformat = BIRDCMD_MODE_POSANG; + x->x_maxcount = BIRD_BYTES_POSANG; + } + + if (!strcmp(s->s_name,"positionmatrix")) { + x->x_dataformat = BIRDCMD_MODE_POSMAT; + x->x_maxcount = BIRD_BYTES_POSMAT; + } + + if (!strcmp(s->s_name,"positionquat")) { + x->x_dataformat = BIRDCMD_MODE_POSQUAT; + x->x_maxcount = BIRD_BYTES_POSQUAT; + } + + if (!strcmp(s->s_name,"quaternion")) { + x->x_dataformat = BIRDCMD_MODE_QUAT; + x->x_maxcount = BIRD_BYTES_QUAT; + } + + outlet_float(x->x_out2,(float)x->x_dataformat); +} + +static void serial_bird_init( t_serial_bird* x) +{ + t_atom cmd[8]; + + SETFLOAT(cmd,14400.); + outlet_anything(x->x_out2,gensym("speed"),1,cmd); + + + SETFLOAT(cmd,0.); + SETSYMBOL(cmd+1,gensym("CLOCAL")); + SETSYMBOL(cmd+2,gensym("CREAD")); + SETSYMBOL(cmd+3,gensym("CS8")); + outlet_anything(x->x_out2,gensym("setcontrol"),4,cmd); + + SETFLOAT(cmd,0.); + SETSYMBOL(cmd+1,gensym("IXOFF")); + outlet_anything(x->x_out2,gensym("setinput"),2,cmd); + + SETFLOAT(cmd,0.); + outlet_anything(x->x_out2,gensym("setlocal"),1,cmd); + + SETFLOAT(cmd,0.); + SETFLOAT(cmd+1,20.); + outlet_anything(x->x_out2,gensym("vtime"),2,cmd); + + + SETSYMBOL(cmd,gensym("RTS")); + SETFLOAT(cmd+1,0.); + outlet_anything(x->x_out2,gensym("setlines"),2,cmd); + + SETSYMBOL(cmd,gensym("DTR")); + SETFLOAT(cmd+1,1.); + outlet_anything(x->x_out2,gensym("setlines"),2,cmd); + + + /* start the polling on the serial device immediately */ + + outlet_anything(x->x_out2,gensym("start"),0,cmd); + +} + +static void serial_bird_start( t_serial_bird* x) +{ + post("start"); + /* outlet_float(x->x_out2,(float)x->x_dataformat);*/ + outlet_float(x->x_out2,(float)BIRDCMD_STREAM); +} + + +static void serial_bird_stop( t_serial_bird* x) +{ + post("stop"); + outlet_float(x->x_out2,(float)BIRDCMD_POINT); +} + +static void *serial_bird_new(t_symbol *s) +{ + t_serial_bird *x = (t_serial_bird *)pd_new(serial_bird_class); + + x->x_count = 0; + x->x_posx = 0; + x->x_posy = 0; + x->x_dataformat = BIRDCMD_MODE_POSANG; + x->x_maxcount = BIRD_BYTES_POSANG; + + + outlet_new(&x->x_obj, &s_float); + x->x_out2 = outlet_new(&x->x_obj, &s_float); + + return x; +} + + +void serial_bird_setup(void) +{ + serial_bird_class = class_new(gensym("serial_bird"), (t_newmethod)serial_bird_new, + NULL, + sizeof(t_serial_bird), 0,A_DEFSYM,0); + class_addfloat(serial_bird_class,serial_bird_float); + class_addmethod(serial_bird_class,(t_method) serial_bird_reset,gensym("reset"),0); + class_addmethod(serial_bird_class,(t_method) serial_bird_init,gensym("init"),0); + + + class_addmethod(serial_bird_class,(t_method) serial_bird_start,gensym("start"),0); + class_addmethod(serial_bird_class,(t_method) serial_bird_stop,gensym("stop"),0); + class_addmethod(serial_bird_class,(t_method) serial_bird_poll,gensym("poll"),0); + class_addmethod(serial_bird_class,(t_method) serial_bird_mode,gensym("mode"),A_SYMBOL,NULL); +} + + diff --git a/control/serial_bird.pd b/control/serial_bird.pd new file mode 100755 index 0000000..bec40d9 --- /dev/null +++ b/control/serial_bird.pd @@ -0,0 +1,35 @@ +#N canvas 48 227 891 382 10; +#X obj 77 254 serial_bird; +#X msg 98 89 start; +#X msg 90 55 poll; +#X msg 414 97 mode position; +#X msg 77 26 init; +#X msg 414 80 mode positionangle; +#X obj 77 277 unpack 1 2 3 4 5 6; +#X floatatom 180 310; +#X floatatom 159 331; +#X floatatom 138 355; +#X floatatom 97 323; +#X floatatom 76 344; +#X floatatom 55 368; +#X text 415 23 The serial_bird object interprets the acsension Flock of Birds device.; +#X text 414 51 The mode command sets the output mode (see FOB description for further information; +#X text 114 24 Init initializes the serial device; +#X text 125 50 poll stops streaming mode and outputs; +#X text 125 60 one data set; +#X text 136 89 start streaming mode with start; +#X obj 180 254 serialctl /dev/ttyS0; +#X connect 0 0 6 0; +#X connect 0 1 19 0; +#X connect 1 0 0 0; +#X connect 2 0 0 0; +#X connect 3 0 0 0; +#X connect 4 0 0 0; +#X connect 5 0 0 0; +#X connect 6 0 12 0; +#X connect 6 1 11 0; +#X connect 6 2 10 0; +#X connect 6 3 9 0; +#X connect 6 4 8 0; +#X connect 6 5 7 0; +#X connect 19 0 0 0; diff --git a/control/serial_ms.c b/control/serial_ms.c new file mode 100755 index 0000000..723b8bf --- /dev/null +++ b/control/serial_ms.c @@ -0,0 +1,120 @@ +/* (C) Guenter Geiger */ + + +#include + + +static t_class *serial_ms_class; + + +typedef struct _serial_ms +{ + t_object x_obj; + char x_c[4]; + t_int x_count; + t_int x_posx; + t_int x_posy; + t_outlet *x_out2; +} t_serial_ms; + + +static void serial_ms_reset( t_serial_ms* x) +{ + x->x_posx=0; + x->x_posy=0; + x->x_count = 0; + outlet_float(x->x_obj.ob_outlet, x->x_posx); + outlet_float(x->x_out2, x->x_posy); +} + +static void serial_ms_init( t_serial_ms* x) +{ + t_atom cmd[8]; + + SETFLOAT(cmd,0.); + SETSYMBOL(cmd+1,gensym("CLOCAL")); + SETSYMBOL(cmd+2,gensym("CREAD")); + SETSYMBOL(cmd+3,gensym("CS7")); +/* SETSYMBOL(cmd+4,gensym("HUPCL")); */ + outlet_anything(x->x_out2,gensym("setcontrol"),4,cmd); + + SETFLOAT(cmd,0.); + SETSYMBOL(cmd+1,gensym("IGNBRK")); + SETSYMBOL(cmd+2,gensym("IGNPAR")); + outlet_anything(x->x_out2,gensym("setinput"),3,cmd); + + SETFLOAT(cmd,0.); + SETFLOAT(cmd+1,1.); + outlet_anything(x->x_out2,gensym("vtime"),2,cmd); + + SETFLOAT(cmd,1200.); + outlet_anything(x->x_out2,gensym("speed"),1,cmd); + + SETSYMBOL(cmd,gensym("*n")); + outlet_anything(x->x_out2,gensym("send"),1,cmd); + + + SETSYMBOL(cmd,gensym("N")); + outlet_anything(x->x_out2,gensym("send"),1,cmd); + + +} + + + +static void serial_ms_float( t_serial_ms* x,t_floatarg f) +{ + int dx,dy; + t_atom at[2]; + + x->x_c[x->x_count] = (char) f; + + x->x_count = (++x->x_count)%3; + + if (x->x_count==2) { + dx= (signed char)(((x->x_c[0] & 0x03) << 6) | + (x->x_c[1] & 0x3F)); + dy= (signed char)(((x->x_c[0] & 0x0C) << 4) | + (x->x_c[2] & 0x3F)); + x->x_posx += dx; + x->x_posy += dy; +/* post("posx %d, posy %d",x->x_posx,x->x_posy);*/ + + SETFLOAT(at,x->x_posx); + SETFLOAT(at+1,x->x_posy); + outlet_list(x->x_obj.ob_outlet,&s_list, 2, at); + } + + +} + + +static void *serial_ms_new(t_symbol *s) +{ + t_serial_ms *x = (t_serial_ms *)pd_new(serial_ms_class); + + x->x_count = 0; + x->x_posx = 0; + x->x_posy = 0; + + + outlet_new(&x->x_obj, &s_float); + x->x_out2 = outlet_new(&x->x_obj, &s_float); + + return x; +} + + +void serial_ms_setup(void) +{ + serial_ms_class = class_new(gensym("serial_ms"), (t_newmethod)serial_ms_new, + NULL, + sizeof(t_serial_ms), 0,A_DEFSYM,0); + class_addfloat(serial_ms_class,serial_ms_float); + class_addmethod(serial_ms_class,(t_method) serial_ms_reset,gensym("reset"),0); + class_addmethod(serial_ms_class, (t_method)serial_ms_init, gensym("init"),0); + + +} + + diff --git a/control/serial_mt.c b/control/serial_mt.c new file mode 100755 index 0000000..ed8a0ed --- /dev/null +++ b/control/serial_mt.c @@ -0,0 +1,77 @@ +/* (C) Guenter Geiger */ + + +#include + + +static t_class *serial_mt_class; + + +typedef struct _serial_mt +{ + t_object x_obj; + char x_c[4]; + t_int x_count; + t_int x_posx; + t_int x_posy; + t_outlet *x_out2; +} t_serial_mt; + + +static void serial_mt_reset( t_serial_mt* x) +{ + x->x_posx=0; + x->x_posy=0; + x->x_count = 0; +} + +static void serial_mt_float( t_serial_mt* x,t_floatarg f) +{ + int dx,dy; + + x->x_c[x->x_count] = (char) f; + + x->x_count = (++x->x_count)%3; + + if (x->x_count==2) { + dx= (signed char)(((x->x_c[0] & 0x03) << 6) | + (x->x_c[1] & 0x3F)); + dy= (signed char)(((x->x_c[0] & 0x0C) << 4) | + (x->x_c[2] & 0x3F)); + x->x_posx += dx; + x->x_posy += dy; +/* post("posx %d, posy %d",x->x_posx,x->x_posy); */ + outlet_float(x->x_obj.ob_outlet, x->x_posx); + outlet_float(x->x_out2, x->x_posy); + } + + +} + + +static void *serial_mt_new(t_symbol *s) +{ + t_serial_mt *x = (t_serial_mt *)pd_new(serial_mt_class); + + x->x_count = 0; + x->x_posx = 0; + x->x_posy = 0; + + + outlet_new(&x->x_obj, &s_float); + x->x_out2 = outlet_new(&x->x_obj, &s_float); + + return x; +} + + +void serial_mt_setup(void) +{ + serial_mt_class = class_new(gensym("serial_mt"), (t_newmethod)serial_mt_new, + NULL, + sizeof(t_serial_mt), 0,A_DEFSYM,0); + class_addfloat(serial_mt_class,serial_mt_float); + class_addmethod(serial_mt_class,(t_method) serial_mt_reset,gensym("reset"),0); +} + + diff --git a/control/serialctl.c b/control/serialctl.c new file mode 100755 index 0000000..4a80bbb --- /dev/null +++ b/control/serialctl.c @@ -0,0 +1,463 @@ +/* (C) Guenter Geiger */ + + +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include +#include +#include +#include +#include +#include +#include + + +#ifndef __linux__ +#define CRTSCTS 0 +#endif + +#define DEBUG(x) +/*#define DEBUG(x) x*/ + + +#define SETBIT(yy,ww,xx) \ +if (!strcmp(yy->s_name,#xx)) \ + valid=1,ww |= ##xx;\ +if (!strcmp(yy->s_name,"~"#xx))\ + valid=1,ww &= ~##xx;\ +if (!strcmp(yy->s_name,"list"))\ + valid=1,post(#xx); + + +/* ------------------------ serialctl ----------------------------- */ + +static t_class *serialctl_class; + + +typedef struct _serialctl +{ + t_object x_obj; + t_int x_fd; + t_symbol* x_devname; + int read_ok; + int started; + int numbytes; + struct termios x_termios; + struct termios x_oldtermios; +} t_serialctl; + + + +static int serialctl_close(t_serialctl *x) +{ + if (x->x_fd <0) return 0; + + close(x->x_fd); + return 1; +} + +static int serialctl_open(t_serialctl *x,t_symbol* s) +{ + serialctl_close(x); + + if (s != &s_) + x->x_devname = s; + + if (x->x_devname) { + post("opening ..."); + x->x_fd = open(x->x_devname->s_name,O_RDWR | O_NOCTTY); + if (x->x_fd >= 0 ) post("done"); + else post("failed"); + } + else { + return 1; + } + + if (x->x_fd >= 0) + post("%s opened",x->x_devname->s_name); + else { + post("unable to open %s",x->x_devname->s_name); + x->x_fd = -1; + return 0; + } + + return 1; +} + + + +static int serialctl_read(t_serialctl *x,int fd) +{ + unsigned char c; + if (x->x_fd < 0) return 0; + if (x->read_ok) { + DEBUG(post("reading %d",x->numbytes);) + if (read(x->x_fd,&c,1) < 0) { + post("serialctl: read failed"); + x->read_ok = 0; + return 0; + } + x->numbytes++; + } + outlet_float(x->x_obj.ob_outlet,(float)c); + + return 1; + +} + + +/* + * Configuration Options + */ + +static void serialctl_setlines(t_serialctl *x,t_symbol* s,t_floatarg f) +{ + int lines; + + ioctl(x->x_fd,TIOCMGET,&lines); + if (!strcmp(s->s_name,"RTS")) { + if (f) + lines |= TIOCM_RTS; + else + lines &= ~TIOCM_RTS; + } + if (!strcmp(s->s_name,"DTR")) { + if (f) + lines |= TIOCM_DTR; + else + lines &= ~TIOCM_DTR; + } + + + + ioctl(x->x_fd,TIOCMSET,&lines); + +} + + +static void serialctl_getlines(t_serialctl *x) +{ + int lines; + /* check hardware signals */ + + ioctl(x->x_fd,TIOCMGET,&lines); + post("serialctl: CD %s",lines&TIOCM_CD ? "on":"off"); + post("serialctl: DTR %s",lines&TIOCM_DTR ? "on":"off"); + post("serialctl: DSR %s",lines&TIOCM_DSR ? "on":"off"); + post("serialctl: RTS %s",lines&TIOCM_RTS ? "on":"off"); + post("serialctl: CTS %s",lines&TIOCM_CTS ? "on":"off"); + +} + + +static void serialctl_setlocal(t_serialctl *x,t_symbol* s,t_int ac, t_atom* at) +{ + int valid =0; + int i; + + + for (i=0;i< ac;i++) { + valid = 0; + + if (at[i].a_type == A_FLOAT) { + x->x_termios.c_lflag = (int)atom_getfloat(at+i); + DEBUG(post("localflags set to %d",(int)atom_getfloat(at+i));) + valid = 1; + } + + if (at[i].a_type == A_SYMBOL) { + DEBUG(post("symbol %s",atom_getsymbolarg(i,ac,at)->s_name);) + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ISIG); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ICANON); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ECHO); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ECHOE); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ECHOK); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, ECHONL); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, NOFLSH); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, TOSTOP); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_lflag, IEXTEN); + + if (!valid) post("serialctl: invalide flag %s",atom_getsymbolarg(i,ac,at)->s_name); + } + } + + if (x->x_fd < 0) return; + + if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0) + post("serialctl: set attributes failed"); + +} + +static void serialctl_setcontrol(t_serialctl *x,t_symbol* s,t_int ac,t_atom* at) +{ + int valid =0; + int i; + + + for (i=0;i< ac;i++) { + valid = 0; + + if (at[i].a_type == A_FLOAT) { + x->x_termios.c_cflag = (int) atom_getfloat(at+i); + DEBUG(post("controlflags set to %d",(int)atom_getfloat(at+i))); + valid = 1; + } + + if (at[i].a_type == A_SYMBOL) { + DEBUG(post("symbol %s",atom_getsymbolarg(i,ac,at)->s_name);) + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,PARENB); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,PARODD); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CS5); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CS6); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CS7); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CS8); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CLOCAL); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CREAD); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CSTOPB); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_cflag,CRTSCTS); + if (!valid) post("serialctl: invalide flag %s",atom_getsymbolarg(i,ac,at)->s_name); + } + } + + if (x->x_fd < 0) return; + + + if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0) + post("serialctl: set attributes failed"); + +} + + +static void serialctl_setinput(t_serialctl *x,t_symbol* s,t_int ac,t_atom* at) +{ + int valid =0; + int i; + + + for (i=0;i< ac;i++) { + valid = 0; + + if (at[i].a_type == A_FLOAT) { + x->x_termios.c_iflag = (int)atom_getfloat(at+i); + DEBUG(post("inputflags set to %d",(int)atom_getfloat(at+i))); + valid = 1; + } + + if (at[i].a_type == A_SYMBOL) { + DEBUG(post("symbol %s",atom_getsymbolarg(i,ac,at)->s_name);) + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IGNBRK); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, BRKINT); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IGNPAR); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, PARMRK); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, INPCK); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, ISTRIP); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, INLCR); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IGNCR); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, ICRNL); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IUCLC); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IXON); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IXANY); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IXOFF); + SETBIT(atom_getsymbolarg(i,ac,at),x->x_termios.c_iflag, IMAXBEL); + + if (!valid) post("serialctl: invalide flag %s",atom_getsymbolarg(i,ac,at)->s_name); + } + } + + if (x->x_fd < 0) return; + + + if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0) + post("serialctl: set attributes failed"); + +} + +static void serialctl_makeraw(t_serialctl *x,t_floatarg f) +{ + cfmakeraw(&x->x_termios); + if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0) + post("serialctl: set attributes failed"); +} + + +static void serialctl_vmintime(t_serialctl *x,t_floatarg f,t_floatarg ft) +{ + + post("vmin = %f, vtime = %f",f,ft); + x->x_termios.c_cc[VMIN] = (int) f; + x->x_termios.c_cc[VTIME] = (int) ft; + if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0) + post("serialctl: set attributes failed"); + +} + + +static void serialctl_canonical(t_serialctl *x,t_floatarg f) +{ + post("setting canonical"); + x->x_termios.c_iflag |= IGNBRK | IGNPAR; + x->x_termios.c_cflag |= CS8 | CREAD | PARENB| CLOCAL | CRTSCTS; + x->x_termios.c_lflag = 0; +} + + +static void serialctl_speed(t_serialctl *x,t_floatarg f) +{ + + int speed = f; + post("setting speed %f",f); + + cfsetospeed (&x->x_termios,speed); + cfsetispeed (&x->x_termios,speed); + if (x->x_fd < 0) return; + + if (tcsetattr(x->x_fd, TCSANOW,&x->x_termios) < 0) + post("serialctl: set attributes failed"); +} + + +/* Actions */ +static void serialctl_bang(t_serialctl* x) +{ + +} + +static void serialctl_float(t_serialctl* x,t_float f) +{ + int ret = -1; + unsigned char c = (unsigned char) f; + DEBUG(post("serialctl: sending %d",c)); + if (f < 256.) { + ret = write(x->x_fd,&c,1); + DEBUG(post("done")); + if (ret != 1) + post("serialctl: send %f %s",f,((ret < 0) ? strerror(ret) : "ok")); + ioctl(x->x_fd,TCFLSH,TCIOFLUSH); + return; + } + post("unable to send char < 256"); + +} + +static void serialctl_send(t_serialctl* x,t_symbol* s) +{ + int ret; + if (s == &s_) return; + ret = write(x->x_fd,s->s_name,sizeof(s->s_name)); + post("serialctl: send %s %s",s->s_name,((ret < 0) ? "not ok" : "ok")); +} + + + + +void serialctl_start(t_serialctl* x) +{ + if (x->x_fd >= 0 && !x->started) { + sys_addpollfn(x->x_fd, (t_fdpollfn)serialctl_read, x); + post("serialctl: start"); + x->started = 1; + } +} + + +void serialctl_stop(t_serialctl* x) +{ + if (x->x_fd >= 0 && x->started) { + sys_rmpollfn(x->x_fd); + post("serialctl: stop"); + x->started = 0; + } +} + + +/* Misc setup functions */ + + +static void serialctl_free(t_serialctl* x) +{ + if (x->x_fd < 0) return; + + serialctl_stop(x); + + if (tcsetattr(x->x_fd, TCSANOW,&x->x_oldtermios) < 0) + post("serialctl: set attributes failed"); + + + close(x->x_fd); +} + + + +static void *serialctl_new(t_symbol *s) +{ + t_serialctl *x = (t_serialctl *)pd_new(serialctl_class); + + x->x_fd = -1; + x->read_ok = 1; + x->numbytes = 0; + x->started = 0; + outlet_new(&x->x_obj, &s_float); + if (s != &s_) + x->x_devname = s; + + /* Open the device and save settings */ + + if (!serialctl_open(x,s)) return x; + + if (tcgetattr(x->x_fd,&x->x_oldtermios) < 0) + post("serialctl: get attributes failed"); + + if (tcgetattr(x->x_fd,&x->x_termios) < 0) + post("serialctl: get attributes failed"); + + + tcflush(x->x_fd, TCIOFLUSH); + return (x); +} + + +void serialctl_setup(void) +{ + serialctl_class = class_new(gensym("serialctl"), (t_newmethod)serialctl_new, + (t_method)serialctl_free, + sizeof(t_serialctl), 0,A_DEFSYM,0); + + class_addmethod(serialctl_class,(t_method) serialctl_start,gensym("start"),0); + class_addmethod(serialctl_class,(t_method) serialctl_stop,gensym("stop"),0); + class_addmethod(serialctl_class, (t_method) serialctl_open,gensym("open"),A_DEFSYM); + class_addmethod(serialctl_class,(t_method) serialctl_close,gensym("close"),0); + + /* used to configure the device via symbols or with bytes */ + + class_addmethod(serialctl_class, (t_method) serialctl_send, gensym("send"), A_DEFSYM,A_NULL); + + + class_addfloat(serialctl_class,(t_method) serialctl_float); + + class_addmethod(serialctl_class,(t_method) serialctl_getlines,gensym("getlines"),0); + class_addmethod(serialctl_class,(t_method) serialctl_setlines,gensym("setlines"),A_DEFSYM,A_DEFFLOAT,NULL); + + + + /* general controlling */ + + class_addmethod(serialctl_class,(t_method) serialctl_setcontrol,gensym("setcontrol"),A_GIMME,NULL); + class_addmethod(serialctl_class,(t_method) serialctl_setlocal,gensym("setlocal"),A_GIMME,NULL); + class_addmethod(serialctl_class,(t_method) serialctl_setinput,gensym("setinput"),A_GIMME,NULL); + + + /* specifics */ + + class_addmethod(serialctl_class,(t_method) serialctl_canonical,gensym("canonical"),A_DEFFLOAT); + class_addmethod(serialctl_class,(t_method) serialctl_speed,gensym("speed"),A_DEFFLOAT); + class_addmethod(serialctl_class,(t_method) serialctl_makeraw,gensym("makeraw"),0); + class_addmethod(serialctl_class,(t_method) serialctl_vmintime,gensym("vtime"),A_DEFFLOAT,A_DEFFLOAT,NULL); + +} + + + diff --git a/control/serialctl.pd b/control/serialctl.pd new file mode 100755 index 0000000..34fd023 --- /dev/null +++ b/control/serialctl.pd @@ -0,0 +1,61 @@ +#N canvas 91 60 907 514 10; +#X msg 202 243 getlines; +#X msg 201 169 setlines RTS 0; +#X msg 201 187 setlines RTS 1; +#X msg 24 213 start; +#X msg 24 195 stop; +#X msg 515 231 vtime 0 20; +#X msg 515 212 setlocal 0; +#X msg 515 193 setcontrol 0 CS8 CLOCAL CREAD; +#X msg 201 224 setlines DTR 1; +#X msg 201 206 setlines DTR 0; +#X text 12 489 (C) 2000 Guenter Geiger; +#X text 32 22 serialin reads from a Unix serial device. There are several ways how serial devices can be setup \, and serialin provides access to these serial device settings. This makes it possible to interpret the data stream from a serial device either within pd itself \, or via a specially written external for the device attached to the serial port (see serial_bird and serial_ms).; +#X msg 516 431 79 \, 75 \, 13; +#X msg 517 451 OK \, 13; +#X text 201 138 setlines set the serial port; +#X text 199 151 lines (only acces to RTS and DTR is provided; +#X text 23 153 start/stop; +#X text 23 165 reading characters; +#X text 23 177 from the device; +#X text 510 69 setinput \, setcontrol \, setlocal \, vtime provide access to the termios status bits of the serial device. This is lowlevel configuration and is sometimes necessary.; +#X text 512 296 set the baudrate; +#X msg 514 348 makeraw; +#X text 513 330 configure the device as "raw"; +#X text 511 110 If a 0 is prepended to the flags \, the flags are reset before any bits are switched. All other commands set the corresponding bits to either 1 (e.g. CLOCAL) or 0 (!CLOCAL).; +#X msg 516 250 listflags; +#X msg 716 210 setinput list; +#X text 511 151 the "list flag" lists all available flags.; +#X text 514 412 data can be sent as symbols or as ASCII character code; +#X msg 716 230 setcontrol list; +#X msg 717 191 setlocal list; +#X msg 514 175 setinput 0 IXOFF; +#X floatatom 590 314; +#X msg 513 313 speed \$1; +#X obj 24 455 print; +#X floatatom 62 243; +#X msg 73 277 send c; +#X obj 24 429 serialctl /dev/ttyS0; +#X connect 0 0 36 0; +#X connect 1 0 36 0; +#X connect 2 0 36 0; +#X connect 3 0 36 0; +#X connect 4 0 36 0; +#X connect 5 0 36 0; +#X connect 6 0 36 0; +#X connect 7 0 36 0; +#X connect 8 0 36 0; +#X connect 9 0 36 0; +#X connect 12 0 36 0; +#X connect 13 0 36 0; +#X connect 21 0 36 0; +#X connect 24 0 36 0; +#X connect 25 0 36 0; +#X connect 28 0 36 0; +#X connect 29 0 36 0; +#X connect 30 0 36 0; +#X connect 31 0 32 0; +#X connect 32 0 36 0; +#X connect 34 0 36 0; +#X connect 35 0 36 0; +#X connect 36 0 33 0; diff --git a/control/serialize.c b/control/serialize.c new file mode 100755 index 0000000..d288ec4 --- /dev/null +++ b/control/serialize.c @@ -0,0 +1,58 @@ +/* (C) Guenter Geiger */ + + +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ serialize ----------------------------- */ + +#define MAX_ELEMENTS 256 + +static t_class *serialize_class; + + +typedef struct _serialize +{ + t_object x_obj; + t_atom x_abuf[MAX_ELEMENTS]; + t_int x_count; + t_float x_elements; +} t_serialize; + + +void serialize_float(t_serialize *x,t_floatarg f) +{ + SETFLOAT(&x->x_abuf[x->x_count],f); + x->x_count++; + + if (x->x_count == x->x_elements) { + outlet_list(x->x_obj.ob_outlet,0,x->x_count,x->x_abuf); + x->x_count = 0; + } +} + + +static void *serialize_new(t_floatarg f) +{ + t_serialize *x = (t_serialize *)pd_new(serialize_class); + outlet_new(&x->x_obj,&s_float); + x->x_elements = f; + x->x_count=0; + if ((f <= 0) || (f > MAX_ELEMENTS)) x->x_elements = 1; + floatinlet_new(&x->x_obj, &x->x_elements); + return (x); +} + + + +void serialize_setup(void) +{ + serialize_class = class_new(gensym("serialize"), (t_newmethod)serialize_new, 0, + sizeof(t_serialize),0, A_DEFFLOAT,0); + class_addfloat(serialize_class,serialize_float); +} + + diff --git a/control/serialize.pd b/control/serialize.pd new file mode 100755 index 0000000..0fbacf6 --- /dev/null +++ b/control/serialize.pd @@ -0,0 +1,8 @@ +#N canvas 246 82 551 292 10; +#X obj 34 106 serialize 4; +#X obj 34 141 print; +#X floatatom 34 69; +#X text 30 195 (C) 2000 Guenter Geiger; +#X text 30 39 serialize ... turn a stream of floats into a list; +#X connect 0 0 1 0; +#X connect 2 0 0 0; diff --git a/control/serialmouse.pd b/control/serialmouse.pd new file mode 100755 index 0000000..4591119 --- /dev/null +++ b/control/serialmouse.pd @@ -0,0 +1,35 @@ +#N canvas 515 351 462 262 10; +#X obj 251 170 print reading; +#X msg 154 72 start; +#X msg 155 90 stop; +#X obj 59 147 serial_ms; +#X text 35 9 decodes serial mice attached to the 1 serial port; +#X text 35 258 (C) Guenter Geiger; +#X msg 37 43 init; +#X msg 245 88 setcontrol 0 CREAD CLOCAL CS7; +#X msg 247 67 getlines; +#X obj 59 170 unpack; +#X floatatom 59 192; +#X floatatom 90 192; +#X msg 344 46 setlines RTS 1; +#X msg 247 27 setlines DTR 0; +#X msg 247 45 setlines RTS 0; +#X msg 342 27 setlines DTR 1; +#X msg 304 123 setlocal 0; +#X obj 155 113 serialctl /dev/ttyS0; +#X connect 1 0 17 0; +#X connect 2 0 17 0; +#X connect 3 0 9 0; +#X connect 3 1 17 0; +#X connect 6 0 3 0; +#X connect 7 0 17 0; +#X connect 8 0 17 0; +#X connect 9 0 10 0; +#X connect 9 1 11 0; +#X connect 12 0 17 0; +#X connect 13 0 17 0; +#X connect 14 0 17 0; +#X connect 15 0 17 0; +#X connect 16 0 17 0; +#X connect 17 0 0 0; +#X connect 17 0 3 0; diff --git a/control/shell.c b/control/shell.c new file mode 100755 index 0000000..b60744c --- /dev/null +++ b/control/shell.c @@ -0,0 +1,206 @@ +/* (C) Guenter Geiger */ + + +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include +#include +#include +#include +#include + +/* ------------------------ shell ----------------------------- */ + +#define INBUFSIZE 1024 + +static t_class *shell_class; + + +typedef struct _shell +{ + t_object x_obj; + int x_echo; + char *sr_inbuf; + int sr_inhead; + int sr_intail; + void* x_binbuf; + int fdpipe[2]; + int pid; +} t_shell; + +static int shell_pid; + +void child_handler(int n) +{ + int ret; + waitpid(-1,&ret,WNOHANG); +} + +void shell_bang(t_shell *x) +{ + post("bang"); +} + +#if 1 +static void shell_doit(void *z, t_binbuf *b) +{ + t_atom messbuf[1024]; + t_shell *x = (t_shell *)z; + int msg, natom = binbuf_getnatom(b); + t_atom *at = binbuf_getvec(b); + + for (msg = 0; msg < natom;) + { + int emsg; + for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA + && at[emsg].a_type != A_SEMI; emsg++) + ; + if (emsg > msg) + { + int i; + for (i = msg; i < emsg; i++) + if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM) + { + pd_error(x, "netreceive: got dollar sign in message"); + goto nodice; + } + if (at[msg].a_type == A_FLOAT) + { + if (emsg > msg + 1) + outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg); + else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float); + } + else if (at[msg].a_type == A_SYMBOL) + outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol, + emsg-msg-1, at + msg + 1); + } + nodice: + msg = emsg + 1; + } +} + + +void shell_read(t_shell *x, int fd) +{ + char buf[INBUFSIZE]; + t_binbuf* bbuf = binbuf_new(); + int i; + int readto = + (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); + int ret; + + ret = read(fd, buf,INBUFSIZE); + buf[ret] = '\0'; + + for (i=0;ifdpipe[0] = -1; + close(fd); + return; + } + else if (ret == 0) + { + post("EOF on socket %d\n", fd); + sys_rmpollfn(fd); + x->fdpipe[0] = -1; + close(fd); + return; + } + else + { + int natom; + t_atom *at; + binbuf_text(bbuf, buf, strlen(buf)); + + natom = binbuf_getnatom(bbuf); + at = binbuf_getvec(bbuf); + shell_doit(x,bbuf); + + } + binbuf_free(bbuf); +} + +#endif + +static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at) +{ + int i; + char* argv[20]; + + argv[0] = s->s_name; + + if (x->fdpipe[0] != -1) { + close(x->fdpipe[0]); + close(x->fdpipe[1]); + sys_rmpollfn(x->fdpipe[0]); + x->fdpipe[0] = -1; + x->fdpipe[1] = -1; + kill(x->pid,SIGKILL); + } + + + + for (i=1;i<=ac;i++) { + argv[i] = atom_getsymbolarg(i-1,ac,at)->s_name; + /* post("argument %s",argv[i]);*/ + } + argv[i] = 0; + + if (pipe(x->fdpipe) < 0) + error("unable to create pipe"); + + sys_addpollfn(x->fdpipe[0],shell_read,x); + + if (!(x->pid = fork())) { + /* reassign stdout */ + dup2(x->fdpipe[1],1); + execvp(s->s_name,argv); + exit(0); + } + + if (x->x_echo) + outlet_anything(x->x_obj.ob_outlet, s, ac, at); +} + + + +void shell_free(t_shell* x) +{ + binbuf_free(x->x_binbuf); +} + +static void *shell_new() +{ + t_shell *x = (t_shell *)pd_new(shell_class); + + x->x_echo = 0; + x->fdpipe[0] = -1; + x->fdpipe[1] = -1; + + x->sr_inhead = x->sr_intail = 0; + if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");; + + x->x_binbuf = binbuf_new(); + + outlet_new(&x->x_obj, &s_list); + return (x); +} + +void shell_setup(void) +{ + shell_class = class_new(gensym("shell"), (t_newmethod)shell_new, + (t_method)shell_free,sizeof(t_shell), 0,0); + class_addbang(shell_class,shell_bang); + class_addanything(shell_class, shell_anything); + signal(SIGCHLD, child_handler); +} + + diff --git a/control/shell.pd b/control/shell.pd new file mode 100755 index 0000000..a3b1735 --- /dev/null +++ b/control/shell.pd @@ -0,0 +1,21 @@ +#N canvas 338 239 450 300 10; +#X obj 137 98 shell; +#X msg 36 39 ls; +#X obj 121 165 print; +#X msg 64 40 ls makefile; +#X msg 287 159 date +%k%M; +#X floatatom 287 195 4 0 0; +#X obj 287 177 shell; +#X text 287 141 Getting the date; +#X msg 118 17 bang; +#X msg 140 42 ./startwrapper; +#X obj 60 17 metro 10; +#X floatatom 271 89 4 0 0; +#X connect 0 0 2 0; +#X connect 1 0 0 0; +#X connect 3 0 0 0; +#X connect 4 0 6 0; +#X connect 6 0 5 0; +#X connect 8 0 10 0; +#X connect 9 0 0 0; +#X connect 10 0 3 0; diff --git a/control/sinh.c b/control/sinh.c new file mode 100755 index 0000000..609ef3f --- /dev/null +++ b/control/sinh.c @@ -0,0 +1,54 @@ +/* (C) Guenter Geiger */ + + +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include + + + +/* ------------------------ sinh ----------------------------- */ + +static t_class *sinh_class; + + +typedef struct _sinh +{ + t_object x_obj; +} t_sinh; + + +void sinh_bang(t_sinh *x) +{ + post("bang"); +} + + +void sinh_float(t_sinh *x,t_floatarg f) +{ + + outlet_float(x->x_obj.ob_outlet,sinh(f)); +} + + +static void *sinh_new() +{ + t_sinh *x = (t_sinh *)pd_new(sinh_class); + + outlet_new(&x->x_obj,&s_float); + return (x); +} + +void sinh_setup(void) +{ + sinh_class = class_new(gensym("sinh"), (t_newmethod)sinh_new, 0, + sizeof(t_sinh), 0,0); + class_addbang(sinh_class,sinh_bang); + class_addfloat(sinh_class,sinh_float); +} + + diff --git a/control/sl.c b/control/sl.c new file mode 100755 index 0000000..2c94cb5 --- /dev/null +++ b/control/sl.c @@ -0,0 +1,73 @@ +/* (C) Guenter Geiger */ + + +#include +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + + +/* -------------------- lsend ------------------------------ */ + +static t_class *lsend_class; + +typedef struct _lsend +{ + t_object x_obj; + t_symbol *x_sym; +} t_lsend; + +static void lsend_bang(t_lsend *x) +{ + if (x->x_sym->s_thing) pd_bang(x->x_sym->s_thing); +} + +static void lsend_float(t_lsend *x, t_float f) +{ + if (x->x_sym->s_thing) pd_float(x->x_sym->s_thing, f); +} + +static void lsend_symbol(t_lsend *x, t_symbol *s) +{ + if (x->x_sym->s_thing) pd_symbol(x->x_sym->s_thing, s); +} + +static void lsend_pointer(t_lsend *x, t_gpointer *gp) +{ + if (x->x_sym->s_thing) pd_pointer(x->x_sym->s_thing, gp); +} + +static void lsend_list(t_lsend *x, t_symbol *s, int argc, t_atom *argv) +{ + if (x->x_sym->s_thing) pd_list(x->x_sym->s_thing, s, argc, argv); +} + +static void lsend_anything(t_lsend *x, t_symbol *s, int argc, t_atom *argv) +{ + if (x->x_sym->s_thing) typedmess(x->x_sym->s_thing, s, argc, argv); +} + +static void *lsend_new(t_symbol *s) +{ + t_lsend *x = (t_lsend *)pd_new(lsend_class); + char mysym[MAXPDSTRING]; + + sprintf(mysym,"%s%p",s->s_name,canvas_getcurrent()); + x->x_sym = gensym(mysym); + return (x); +} + +void sl_setup(void) +{ + lsend_class = class_new(gensym("sendlocal"), (t_newmethod)lsend_new, 0, + sizeof(t_lsend), 0, A_DEFSYM, 0); + class_addcreator((t_newmethod)lsend_new, gensym("sl"), A_DEFSYM, 0); + class_addbang(lsend_class, lsend_bang); + class_addfloat(lsend_class, lsend_float); + class_addsymbol(lsend_class, lsend_symbol); + class_addpointer(lsend_class, lsend_pointer); + class_addlist(lsend_class, lsend_list); + class_addanything(lsend_class, lsend_anything); +} diff --git a/control/stripdir.c b/control/stripdir.c new file mode 100755 index 0000000..10ba19b --- /dev/null +++ b/control/stripdir.c @@ -0,0 +1,48 @@ +/* (C) Guenter Geiger */ + + +#include +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ stripdir ----------------------------- */ + +static t_class *stripdir_class; + + +typedef struct _stripdir +{ + t_object x_obj; +} t_stripdir; + + +void stripdir_symbol(t_stripdir *x,t_symbol* s) +{ + int len = strlen(s->s_name); + + while (len--) + if (*(s->s_name + len) == '/') { + outlet_symbol(x->x_obj.ob_outlet,gensym(s->s_name + len + 1)); + break; + } + +} + +static void *stripdir_new() +{ + t_stripdir *x = (t_stripdir *)pd_new(stripdir_class); + outlet_new(&x->x_obj, &s_float); + return (x); +} + +void stripdir_setup(void) +{ + stripdir_class = class_new(gensym("stripdir"), (t_newmethod)stripdir_new, 0, + sizeof(t_stripdir), 0,0); + class_addsymbol(stripdir_class,stripdir_symbol); +} + + diff --git a/control/stripdir.pd b/control/stripdir.pd new file mode 100755 index 0000000..1d200a8 --- /dev/null +++ b/control/stripdir.pd @@ -0,0 +1,7 @@ +#N canvas 231 207 452 294 10; +#X obj 22 78 stripdir; +#X symbolatom 22 48 0 0 0; +#X obj 22 105 print; +#X text 20 22 strips all leading directories from a path; +#X connect 0 0 2 0; +#X connect 1 0 0 0; diff --git a/control/unserialize.c b/control/unserialize.c new file mode 100755 index 0000000..6133ead --- /dev/null +++ b/control/unserialize.c @@ -0,0 +1,57 @@ +/* (C) Guenter Geiger */ + + +#include +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +/* ------------------------ unserialize ----------------------------- */ + +#define MAX_ELEMENTS 256 + +static t_class *unserialize_class; + + +typedef struct _unserialize +{ + t_object x_obj; + t_atom x_abuf[MAX_ELEMENTS]; + t_int x_count; + t_int x_elements; +} t_unserialize; + + +void unserialize_float(t_unserialize *x,t_floatarg f) +{ + SETFLOAT(&x->x_abuf[x->x_count],f); + x->x_count++; + + if (x->x_count == x->x_elements) { + outlet_list(x->x_obj.ob_outlet,0,x->x_count,x->x_abuf); + x->x_count = 0; + } +} + + +static void *unserialize_new(t_floatarg f) +{ + t_unserialize *x = (t_unserialize *)pd_new(unserialize_class); + outlet_new(&x->x_obj,&s_float); + x->x_elements = f; + x->x_count=0; + if ((f <= 0) || (f > MAX_ELEMENTS)) x->x_elements = 1; + return (x); +} + + + +void unserialize_setup(void) +{ + unserialize_class = class_new(gensym("unserialize"), (t_newmethod)unserialize_new, + 0,sizeof(t_unserialize),0, A_DEFFLOAT,0); + class_addfloat(unserialize_class,unserialize_float); +} + + diff --git a/control/unwonk.c b/control/unwonk.c new file mode 100755 index 0000000..e44ef10 --- /dev/null +++ b/control/unwonk.c @@ -0,0 +1,119 @@ +/* (C) Guenter Geiger */ + + +#include + + +/* -------------------------- unwonk ------------------------------ */ + +static t_class *unwonk_class; + +typedef struct unwonkout +{ + t_atomtype u_type; + t_outlet *u_outlet; +} t_unwonkout; + +typedef struct _unwonk +{ + t_object x_obj; + t_int x_n; + t_unwonkout *x_vec; +} t_unwonk; + +static void *unwonk_new(t_symbol *s, int argc, t_atom *argv) +{ + t_unwonk *x = (t_unwonk *)pd_new(unwonk_class); + t_atom defarg[2], *ap; + t_unwonkout *u; + int i; + if (!argc) + { + argv = defarg; + argc = 2; + SETFLOAT(&defarg[0], 0); + SETFLOAT(&defarg[1], 0); + } + + x->x_n = argc + 1; + x->x_vec = (t_unwonkout *)getbytes(x->x_n * sizeof(*x->x_vec)); + + for (i = 0, ap = argv, u = x->x_vec; i < argc; u++, ap++, i++) + { + t_atomtype type = ap->a_type; + if (type == A_SYMBOL) + { + char c = *ap->a_w.w_symbol->s_name; + if (c == 's') + { + u->u_type = A_SYMBOL; + u->u_outlet = outlet_new(&x->x_obj, &s_symbol); + } + else if (c == 'p') + { + u->u_type = A_POINTER; + u->u_outlet = outlet_new(&x->x_obj, &s_pointer); + } + else + { + if (c != 'f') error("unwonk: %s: bad type", + ap->a_w.w_symbol->s_name); + u->u_type = A_FLOAT; + u->u_outlet = outlet_new(&x->x_obj, &s_float); + } + } + else + { + u->u_type = A_FLOAT; + u->u_outlet = outlet_new(&x->x_obj, &s_float); + } + } + + u->u_type = A_GIMME; + u->u_outlet = outlet_new(&x->x_obj, &s_list); + + return (x); +} + +static void unwonk_list(t_unwonk *x, t_symbol *s, int argc, t_atom *argv) +{ + t_atom *ap; + t_unwonkout *u; + int i; + int margc = argc; + + + if (argc > x->x_n - 1) margc = x->x_n - 1; + + if (argc - margc > 0) { + ap = argv + margc; + u = x->x_vec + margc; + outlet_list(u->u_outlet,0,argc - margc, ap); + } + + for (i = margc, u = x->x_vec + i, ap = argv + i; u--, ap--, i--;) + { + t_atomtype type = u->u_type; + if (type != ap->a_type) + error("unwonk: type mismatch"); + else if (type == A_FLOAT) + outlet_float(u->u_outlet, ap->a_w.w_float); + else if (type == A_SYMBOL) + outlet_symbol(u->u_outlet, ap->a_w.w_symbol); + else outlet_pointer(u->u_outlet, ap->a_w.w_gpointer); + } + + +} + +static void unwonk_free(t_unwonk *x) +{ + freebytes(x->x_vec, x->x_n * sizeof(*x->x_vec)); +} + +void unwonk_setup(void) +{ + unwonk_class = class_new(gensym("unwonk"), (t_newmethod)unwonk_new, + (t_method)unwonk_free, sizeof(t_unwonk), 0, A_GIMME, 0); + class_addlist(unwonk_class, unwonk_list); +} diff --git a/control/unwonk.pd b/control/unwonk.pd new file mode 100755 index 0000000..2769a1e --- /dev/null +++ b/control/unwonk.pd @@ -0,0 +1,36 @@ +#N canvas 273 9 542 405 10; +#X obj 53 134 unwonk; +#X obj 211 246 print; +#X floatatom 39 175; +#X floatatom 65 175; +#X obj 144 179 unwonk 1 2 3; +#X floatatom 119 223; +#X floatatom 145 223; +#X floatatom 171 223; +#X msg 30 100 1 2 3 4 5 6 7 8; +#X obj 30 267 unwonk 1 2 3 4 5 6 7 8 9; +#X floatatom 27 310; +#X floatatom 53 310; +#X floatatom 79 310; +#X floatatom 105 311; +#X floatatom 131 311; +#X floatatom 157 311; +#X text 25 364 (C) 1999 Guenter Geiger; +#X text 27 24 unwonk is an unpack which sends; +#X text 27 41 unused symbols to the last outlet; +#X text 25 59 instead of discarding them; +#X connect 0 0 2 0; +#X connect 0 1 3 0; +#X connect 0 2 4 0; +#X connect 4 0 5 0; +#X connect 4 1 6 0; +#X connect 4 2 7 0; +#X connect 4 3 1 0; +#X connect 8 0 0 0; +#X connect 8 0 9 0; +#X connect 9 0 10 0; +#X connect 9 1 11 0; +#X connect 9 2 12 0; +#X connect 9 3 13 0; +#X connect 9 4 14 0; +#X connect 9 5 15 0; -- cgit v1.2.1