aboutsummaryrefslogtreecommitdiff
path: root/slipdec/slipdec.c
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2010-05-03 23:24:54 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2010-05-03 23:24:54 +0000
commitdb67a6922b9c20c4be792f06772780f6ae30eb2d (patch)
treeadd9da6c3d155ecd8fa5d6b557a494c58bf02016 /slipdec/slipdec.c
parentd12a97f73664e552caec2010a3405b3a381076a1 (diff)
[slipdec] decodes an input list of bytes-as-floats assuming they were encoded using SLIP. Useful for OSC over serial links.
svn path=/trunk/externals/mrpeach/; revision=13488
Diffstat (limited to 'slipdec/slipdec.c')
-rw-r--r--slipdec/slipdec.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/slipdec/slipdec.c b/slipdec/slipdec.c
new file mode 100644
index 0000000..c38cd20
--- /dev/null
+++ b/slipdec/slipdec.c
@@ -0,0 +1,106 @@
+/* slipdec.c 20070711 Martin Peach */
+/* decode a list of SLIP-encoded bytes */
+#include "m_pd.h"
+
+/* -------------------------- slipdec -------------------------- */
+#ifndef _SLIPCODES
+/* SLIP special character codes */
+#define SLIP_END 0300 /* indicates end of packet */
+#define SLIP_ESC 0333 /* indicates byte stuffing */
+#define SLIP_ESC_END 0334 /* SLIP_ESC SLIP_ESC_END means SLIP_END data byte */
+#define SLIP_ESC_ESC 0335 /* SLIP_ESC SLIP_ESC_ESC means SLIP_ESC data byte */
+#define MAX_SLIP 1006 /* maximum SLIP packet size */
+#define _SLIPCODES
+#endif // _SLIPCODES
+
+static t_class *slipdec_class;
+
+typedef struct _slipdec
+{
+ t_object x_obj;
+ t_outlet *x_slipdec_out;
+ t_atom *x_slip_buf;
+ t_int x_slip_length;
+} t_slipdec;
+
+static void *slipdec_new(t_symbol *s, int argc, t_atom *argv);
+static void slipdec_list(t_slipdec *x, t_symbol *s, int ac, t_atom *av);
+static void slipdec_free(t_slipdec *x);
+void slipdec_setup(void);
+
+static void *slipdec_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_slipdec *x = (t_slipdec *)pd_new(slipdec_class);
+
+ x->x_slip_buf = (t_atom *)getbytes(sizeof(t_atom)*MAX_SLIP);
+ if(x->x_slip_buf == NULL)
+ {
+ error("slipdec: unable to allocate %lu bytes for x_slip_buf", (long)sizeof(t_atom)*MAX_SLIP);
+ return NULL;
+ }
+ else post("slipdec: allocated %lu bytes for x_slip_buf", (long)sizeof(t_atom)*MAX_SLIP);
+ /* init the slip buf atoms to float type */
+ for (i = 0; i < MAX_SLIP; ++i) x->x_slip_buf[i].a_type = A_FLOAT;
+ x->x_slipdec_out = outlet_new(&x->x_obj, &s_list);
+ return (x);
+}
+
+static void slipdec_list(t_slipdec *x, t_symbol *s, int ac, t_atom *av)
+{
+ /* SLIP decode a list of bytes */
+ float f;
+ int i, c, esced = 0;
+
+ /* for each byte in the packet, send the appropriate character sequence */
+ for(i = x->x_slip_length = 0; ((i < ac) && (x->x_slip_length < MAX_SLIP)); ++i)
+ {
+ /* check each atom for byteness */
+ f = atom_getfloat(&av[i]);
+ c = (((int)f) & 0x0FF);
+ if (c != f)
+ {
+ /* abort, bad input character */
+ pd_error (x, "slipdec: input %d out of range [0..255]", f);
+ return;
+ }
+ if(SLIP_END == c)
+ {
+ /* If it's the beginning of a packet, ignore it */
+ if (0 == i) continue;
+ /* send the packet */
+ else break;
+ }
+ if (SLIP_ESC == c)
+ {
+ esced = 1;
+ continue;
+ }
+ if (0 != esced)
+ {
+ if (SLIP_ESC_END == c) c = SLIP_END;
+ else if (SLIP_ESC_ESC == c) c = SLIP_ESC;
+ esced = 0;
+ }
+ /* Add the character to the list */
+ x->x_slip_buf[x->x_slip_length++].a_w.w_float = c;
+ }
+ if (0 != x->x_slip_length)
+ outlet_list(x->x_slipdec_out, &s_list, x->x_slip_length, x->x_slip_buf);
+}
+
+static void slipdec_free(t_slipdec *x)
+{
+ if (x->x_slip_buf != NULL) freebytes((void *)x->x_slip_buf, sizeof(t_atom)*MAX_SLIP);
+}
+
+void slipdec_setup(void)
+{
+ slipdec_class = class_new(gensym("slipdec"),
+ (t_newmethod)slipdec_new, (t_method)slipdec_free,
+ sizeof(t_slipdec), 0, A_GIMME, 0);
+ class_addlist(slipdec_class, slipdec_list);
+ class_sethelpsymbol(slipdec_class, gensym("slipenc")); /* use slipenc-help.pd */
+}
+
+/* fin slipdec.c*/