Commit c1c28e5e authored by Jonathan Wilkes's avatar Jonathan Wilkes

Merge branch 'fudiparse'

parents db64cdcc 2ded0cd2
#N canvas 51 189 685 507 10;
#X text 36 21 fudiformat - convert lists to FUDI packets, f 61;
#X msg 72 127 1 2 3;
#X obj 180 312 fudiparse;
#X obj 72 311 print packet;
#X msg 342 389 disconnect;
#X obj 334 416 netsend -u -b;
#X msg 343 365 connect localhost 5000;
#X obj 335 315 list prepend send;
#X obj 335 340 list trim;
#X obj 180 337 print reassembled;
#X text 437 389 don't send;
#X text 530 364 send as UDP;
#X text 54 454 see also:;
#X obj 127 455 fudiparse;
#X obj 72 278 fudiformat;
#X msg 80 154 foo 4 5 weasel 6 7 rat;
#X text 125 128 FUDI messages with numbers and symbols.;
#X text 29 55 fudiformat makes FUDI messages suitable for sending over
the network via netsend (in UDP mode). Incoming messages are output
as FUDI messages \, byte by byte., f 61;
#X obj 439 250 fudiformat -u;
#X obj 127 475 oscformat;
#X text 281 193 The '-u' creation argument switches to "UDP" mode \,
omitting the packet separator. This saves some two bytes \, but only
works when sending single FUDI messages over UDP. It doesn't work with
TCP/IP (however \, you can use the default format even with UDP transport).
;
#X connect 1 0 14 0;
#X connect 2 0 9 0;
#X connect 4 0 5 0;
#X connect 6 0 5 0;
#X connect 7 0 8 0;
#X connect 8 0 5 0;
#X connect 14 0 3 0;
#X connect 14 0 7 0;
#X connect 14 0 2 0;
#X connect 15 0 14 0;
#N canvas 6 49 673 427 10;
#X obj 171 286 fudiparse;
#X text 52 373 see also:;
#X obj 171 309 print parse-output;
#X obj 419 231 netreceive -u -b;
#X msg 419 176 listen 5000;
#X msg 431 204 listen 0;
#X text 520 203 stop listening;
#X msg 57 181 1 2 3 foo 5;
#X text 51 156 numbers and symbols;
#X obj 57 286 print packet;
#X text 416 152 packets from network;
#X text 558 231 UDP packets \, binary output, f 13;
#X text 80 11 fudiparse - parse FUDI packets into Pd messages, f 67
;
#X obj 57 206 fudiformat;
#X obj 222 206 fudiformat -u;
#X text 220 159 without packet separator;
#X msg 222 181 flab -1 1.1;
#X obj 140 373 fudiformat;
#X obj 224 373 oscparse;
#X obj 222 226 t a a;
#X obj 57 226 t a a;
#X text 45 40 fudiparse takes incoming lists of numbers \, interpreting
them as the bytes in a FUDI message (as received when sending Pd-messages
via [netreceive -b]).;
#X text 521 176 listen on port 5000;
#X connect 0 0 2 0;
#X connect 3 0 0 0;
#X connect 4 0 3 0;
#X connect 5 0 3 0;
#X connect 7 0 13 0;
#X connect 13 0 20 0;
#X connect 14 0 19 0;
#X connect 16 0 14 0;
#X connect 19 0 0 0;
#X connect 19 1 9 0;
#X connect 20 0 0 0;
#X connect 20 1 9 0;
......@@ -36,6 +36,14 @@
#define CLOCKHZ sysconf(_SC_CLK_TCK)
#endif
#ifdef _WIN32
# include <malloc.h> /* MSVC or mingw on Windows */
#elif defined(__linux__) || defined(__APPLE__)
# include <alloca.h> /* linux, mac, mingw, cygwin */
#else
# include <stdlib.h> /* BSDs for example */
#endif
/* -------------------------- random ------------------------------ */
/* this is strictly homebrew and untested. */
......@@ -793,6 +801,167 @@ void oscformat_setup(void)
class_addlist(oscformat_class, oscformat_list);
}
/* ---------- fudiparse - parse bytelists to to FUDI messages ----------------- */
static t_class *fudiparse_class;
typedef struct _fudiparse {
t_object x_obj;
t_outlet *x_msgout;
char *x_bytes;
size_t x_numbytes;
} t_fudiparse;
static void fudiparse_binbufout(t_fudiparse *x, t_binbuf *b)
{
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;
/* check for illegal atoms */
for (i = msg; i < emsg; i++)
if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM) {
pd_error(x, "fudiparse: got dollar sign in message");
goto nodice;
}
if (at[msg].a_type == A_FLOAT) {
if (emsg > msg + 1)
outlet_list(x->x_msgout, 0, emsg-msg, at + msg);
else outlet_float(x->x_msgout, at[msg].a_w.w_float);
}
else if (at[msg].a_type == A_SYMBOL) {
outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
emsg-msg-1, at + msg + 1);
}
}
nodice:
msg = emsg + 1;
}
}
static void fudiparse_list(t_fudiparse *x, t_symbol*s, int argc, t_atom*argv) {
size_t len = argc;
t_binbuf* bbuf = binbuf_new();
char*cbuf;
if((size_t)argc > x->x_numbytes) {
freebytes(x->x_bytes, x->x_numbytes);
x->x_numbytes = argc;
x->x_bytes = getbytes(x->x_numbytes);
}
cbuf = x->x_bytes;
while(argc--) {
char b = atom_getfloat(argv++);
*cbuf++ = b;
}
binbuf_text(bbuf, x->x_bytes, len);
fudiparse_binbufout(x, bbuf);
binbuf_free(bbuf);
}
static void fudiparse_free(t_fudiparse *x) {
freebytes(x->x_bytes, x->x_numbytes);
x->x_bytes = NULL;
x->x_numbytes = 0;
}
static void *fudiparse_new(void) {
t_fudiparse *x = (t_fudiparse *)pd_new(fudiparse_class);
x->x_msgout = outlet_new(&x->x_obj, 0);
x->x_numbytes = 1024;
x->x_bytes = getbytes(x->x_numbytes);
return (void *)x;
}
void fudiparse_setup(void) {
fudiparse_class = class_new(gensym("fudiparse"),
(t_newmethod)fudiparse_new,
(t_method)fudiparse_free,
sizeof(t_fudiparse), CLASS_DEFAULT,
0);
class_addlist(fudiparse_class, fudiparse_list);
}
/* --------- fudiformat - format Pd (FUDI) messages to bytelists ------------ */
static t_class *fudiformat_class;
typedef struct _fudiformat {
t_object x_obj;
t_outlet *x_msgout;
t_atom *x_atoms;
size_t x_numatoms;
int x_udp;
} t_fudiformat;
static void fudiformat_any(t_fudiformat *x, t_symbol*s, int argc, t_atom*argv) {
char *buf;
int length;
int i;
t_atom at;
t_binbuf*bbuf = binbuf_new();
SETSYMBOL(&at, s);
binbuf_add(bbuf, 1, &at);
binbuf_add(bbuf, argc, argv);
if(!x->x_udp) {
SETSEMI(&at);
binbuf_add(bbuf, 1, &at);
}
binbuf_gettext(bbuf, &buf, &length);
binbuf_free(bbuf);
if((size_t)length>x->x_numatoms) {
freebytes(x->x_atoms, sizeof(*x->x_atoms) * x->x_numatoms);
x->x_numatoms = length;
x->x_atoms = getbytes(sizeof(*x->x_atoms) * x->x_numatoms);
}
for(i=0; i<length; i++) {
SETFLOAT(x->x_atoms+i, buf[i]);
}
freebytes(buf, length);
outlet_list(x->x_msgout, 0, length, x->x_atoms);
}
static void fudiformat_free(t_fudiformat *x) {
freebytes(x->x_atoms, sizeof(*x->x_atoms) * x->x_numatoms);
x->x_atoms = NULL;
x->x_numatoms = 0;
}
static void *fudiformat_new(t_symbol*s) {
t_fudiformat *x = (t_fudiformat *)pd_new(fudiformat_class);
x->x_msgout = outlet_new(&x->x_obj, 0);
x->x_numatoms = 1024;
x->x_atoms = getbytes(sizeof(*x->x_atoms) * x->x_numatoms);
if (gensym("-u") == s)
x->x_udp = 1;
else if (gensym("-t") == s)
x->x_udp = 0;
else if (gensym("") != s) {
pd_error(x, "fudiformat: unsupported mode '%s'", s->s_name);
}
return (void *)x;
}
static void fudiformat_setup(void) {
fudiformat_class = class_new(gensym("fudiformat"),
(t_newmethod)fudiformat_new,
(t_method)fudiformat_free,
sizeof(t_fudiformat), CLASS_DEFAULT,
A_DEFSYMBOL, 0);
class_addanything(fudiformat_class, fudiformat_any);
}
void x_misc_setup(void)
{
random_setup();
......@@ -805,4 +974,6 @@ void x_misc_setup(void)
realtime_setup();
oscparse_setup();
oscformat_setup();
fudiparse_setup();
fudiformat_setup();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment