diff --git a/pd/doc/5.reference/fudiformat-help.pd b/pd/doc/5.reference/fudiformat-help.pd
new file mode 100644
index 0000000000000000000000000000000000000000..a66f6ba7e31e1e2b31582c98e80089c0edaaadbd
--- /dev/null
+++ b/pd/doc/5.reference/fudiformat-help.pd
@@ -0,0 +1,38 @@
+#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;
diff --git a/pd/doc/5.reference/fudiparse-help.pd b/pd/doc/5.reference/fudiparse-help.pd
new file mode 100644
index 0000000000000000000000000000000000000000..8eb5a713baa2895df7a9c0a653b171bc3304b012
--- /dev/null
+++ b/pd/doc/5.reference/fudiparse-help.pd
@@ -0,0 +1,39 @@
+#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;
diff --git a/pd/src/x_misc.c b/pd/src/x_misc.c
index 27d489e2a9905f231f4dd465e5cfab927bd9143e..e468fe31eba04bb9e9398937f7a037180360858b 100644
--- a/pd/src/x_misc.c
+++ b/pd/src/x_misc.c
@@ -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();
 }