aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2003-03-03 19:54:59 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2003-03-03 19:54:59 +0000
commit80929a20e07d36abe421ea4cc3bdad760ccb89fa (patch)
tree080e7838e344858ddfbeefb5b32ca33f1072f4fd /src
parent4f2fc07b69014d9540cca2200d9f55fcbbb08db0 (diff)
added changed from Olaf's version 1.2
svn path=/trunk/externals/maxlib/; revision=450
Diffstat (limited to 'src')
-rw-r--r--src/netclient.c8
-rw-r--r--src/netdist.c6
-rw-r--r--src/netrec.c2
-rw-r--r--src/netserver.c11
-rw-r--r--src/remote.c27
-rw-r--r--src/rewrap.c149
-rw-r--r--src/split.c91
-rw-r--r--src/timebang.c147
-rw-r--r--src/unroute.c170
-rw-r--r--src/urn.c144
-rw-r--r--src/wrap.c136
11 files changed, 874 insertions, 17 deletions
diff --git a/src/netclient.c b/src/netclient.c
index 0503b97..7ad252f 100644
--- a/src/netclient.c
+++ b/src/netclient.c
@@ -29,7 +29,7 @@
#include <sys/types.h>
#include <string.h>
#include <pthread.h>
-#if defined(UNIX) || defined(unix)
+#ifdef UNIX
#include <sys/socket.h>
#include <sys/errno.h>
#include <netinet/in.h>
@@ -71,7 +71,7 @@ static void sys_sockerror(char *s)
int err = WSAGetLastError();
if (err == 10054) return;
#endif
-#if defined(UNIX) || defined(unix)
+#ifdef UNIX
int err = errno;
#endif
post("%s: %s (%d)\n", s, strerror(err), err);
@@ -79,7 +79,7 @@ static void sys_sockerror(char *s)
static void sys_closesocket(int fd) {
-#if defined(UNIX) || defined(unix)
+#ifdef UNIX
close(fd);
#endif
#ifdef NT
@@ -345,4 +345,4 @@ void netclient_setup(void)
class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("receive"), 0);
class_addmethod(netclient_class, (t_method)netclient_rcv, gensym("rcv"), 0);
class_sethelpsymbol(netclient_class, gensym("maxlib/help-netclient.pd"));
-}
+} \ No newline at end of file
diff --git a/src/netdist.c b/src/netdist.c
index 12a2e9d..4f91c2d 100644
--- a/src/netdist.c
+++ b/src/netdist.c
@@ -29,7 +29,7 @@
#include <sys/types.h>
#include <string.h>
#include <pthread.h>
-#if defined(UNIX) || defined(unix)
+#ifdef UNIX
#include <sys/socket.h>
#include <sys/errno.h>
#include <netinet/in.h>
@@ -67,7 +67,7 @@ static void sys_sockerror(char *s)
int err = WSAGetLastError();
if (err == 10054) return;
#endif
-#if defined(UNIX) || defined(unix)
+#ifdef UNIX
int err = errno;
#endif
post("%s: %s (%d)\n", s, strerror(err), err);
@@ -75,7 +75,7 @@ static void sys_sockerror(char *s)
static void sys_closesocket(int fd) {
-#if defined(UNIX) || defined(unix)
+#ifdef UNIX
close(fd);
#endif
#ifdef NT
diff --git a/src/netrec.c b/src/netrec.c
index ca89ccb..0b5d87e 100644
--- a/src/netrec.c
+++ b/src/netrec.c
@@ -31,7 +31,7 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
-#if defined(UNIX) || defined(unix)
+#ifdef UNIX
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
diff --git a/src/netserver.c b/src/netserver.c
index ae0a13a..19cf6d4 100644
--- a/src/netserver.c
+++ b/src/netserver.c
@@ -33,7 +33,7 @@
#include <string.h>
#include <stdio.h>
#include <pthread.h>
-#if defined(UNIX) || defined(unix)
+#ifdef UNIX
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
@@ -52,7 +52,7 @@
#define MAX_CONNECT 32 /* maximum number of connections */
#define INBUFSIZE 4096 /* size of receiving data buffer */
-static char *version = "netserver v0.1 :: bidirectional communication for Pd\n"
+static char *version = "netserver v0.2 :: bidirectional communication for Pd\n"
" written by Olaf Matthes <olaf.matthes@gmx.de>";
/* ----------------------------- netserver ------------------------- */
@@ -542,7 +542,12 @@ static void *netserver_new(t_floatarg fportno)
static void netserver_free(t_netserver *x)
{
- /* LATER make me clean up open connections */
+ int i;
+ for(i = 0; i < x->x_nconnections; i++)
+ {
+ sys_rmpollfn(x->x_fd[i]);
+ sys_closesocket(x->x_fd[i]);
+ }
if (x->x_connectsocket >= 0)
{
sys_rmpollfn(x->x_connectsocket);
diff --git a/src/remote.c b/src/remote.c
index 6697113..6abf4c7 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -2,7 +2,7 @@
/* */
/* Send data to receive obejct <name>. */
/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
-/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* Get source at http://www.akustische-kunst.de/puredata/ */
/* */
/* This program is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
@@ -30,13 +30,15 @@
#define MAX_REC 64 /* maximum number of receive objects */
#define MAX_ARG 32 /* maximum number of arguments to pass on */
-static char *version = "remote v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+static char *version = "remote v0.2, written by Olaf Matthes <olaf.matthes@gmx.de>";
static t_class *remote_class;
typedef struct _remote
{
t_object x_obj;
+ t_symbol *x_prefix;
+ t_int x_prepend;
} t_remote;
/* send 'anything' to receiver */
@@ -45,6 +47,8 @@ static void remote_anything(t_remote *x, t_symbol *s, int argc, t_atom *argv)
int i;
t_atom av[MAX_ARG]; /* the 'new' t_atom without first element */
t_int ac = argc - 1; /* the 'new' number of arguments */
+ char mysym[MAXPDSTRING];
+ t_symbol *target;
if(argc < 1) /* need <name> <data> */
{
@@ -62,13 +66,24 @@ static void remote_anything(t_remote *x, t_symbol *s, int argc, t_atom *argv)
av[i - 1] = argv[i]; /* just copy, don't care about types */
}
/* send only argument-part to receivers */
- if (s->s_thing) pd_forwardmess(s->s_thing, argc, argv);
+ if(x->x_prepend)
+ {
+ sprintf(mysym,"%s%s", x->x_prefix->s_name, s->s_name);
+ target = gensym(mysym);
+ if (target->s_thing) pd_forwardmess(target->s_thing, argc, argv);
+ }
+ else
+ if (s->s_thing) pd_forwardmess(s->s_thing, argc, argv);
}
-static void *remote_new(void)
+static void *remote_new(t_symbol *s)
{
t_remote *x = (t_remote *)pd_new(remote_class);
+ x->x_prefix = s;
+ if(x->x_prefix) x->x_prepend = 1;
+ else x->x_prepend = 0;
+
#ifndef MAXLIB
post(version);
#endif
@@ -78,7 +93,7 @@ static void *remote_new(void)
void remote_setup(void)
{
remote_class = class_new(gensym("remote"), (t_newmethod)remote_new, 0,
- sizeof(t_remote), 0, 0);
+ sizeof(t_remote), 0, A_DEFSYM, 0);
class_addanything(remote_class, remote_anything);
- class_sethelpsymbol(remote_class, gensym("maxlib/help-remote.pd"));
+ class_sethelpsymbol(remote_class, gensym("help-remote.pd"));
}
diff --git a/src/rewrap.c b/src/rewrap.c
new file mode 100644
index 0000000..e825feb
--- /dev/null
+++ b/src/rewrap.c
@@ -0,0 +1,149 @@
+/* ------------------------- rewrap ------------------------------------------ */
+/* */
+/* rewraps input to lie within an output range. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+static char *version = "rewrap v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct rewrap
+{
+ t_object x_ob;
+ t_float x_min; /* low border of input range */
+ t_float x_max; /* high border of input range */
+ t_outlet *x_outlet1; /* path-through outlet */
+ t_outlet *x_outlet2; /* rewrap outlet */
+} t_rewrap;
+
+static void rewrap_float(t_rewrap *x, t_floatarg f)
+{
+ t_float min = x->x_min;
+ t_float max = x->x_max;
+ t_float range = 2.0f * (max - min);
+ t_int i;
+
+ if(range == 0.0f)
+ {
+ f = min;
+ outlet_float(x->x_outlet2, 0);
+ }
+ else if(f < min)
+ {
+ float diff = min - f;
+ float n = ceil(diff / range);
+
+ f += n * range;
+
+ if(f >= max)
+ {
+ f = 2 * max - f;
+ n -= 0.5;
+ }
+
+ outlet_float(x->x_outlet2, (t_int)(-2.0f * n));
+ }
+ else if (f >= max)
+ {
+ float diff = f - max;
+ float n = floor(diff / range) + 1.0f;
+
+ f -= n * range;
+
+ if(f < min)
+ {
+ f = 2 * min - f;
+ n -= 0.5;
+ }
+
+ outlet_float(x->x_outlet2, (t_int)(2.0f * n));
+ }
+ else
+ outlet_float(x->x_outlet2, 0.0f);
+
+
+ outlet_float(x->x_outlet1, f);
+}
+
+static void rewrap_a(t_rewrap *x, t_floatarg a)
+{
+ t_float max = x->x_max;
+
+ if(a <= max)
+ x->x_min = a;
+ else
+ {
+ x->x_min = max;
+ x->x_max = a;
+ }
+}
+
+static void rewrap_b(t_rewrap *x, t_floatarg b)
+{
+ t_float min = x->x_min;
+
+ if(b >= min)
+ x->x_max = b;
+ else
+ {
+ x->x_max = min;
+ x->x_min = b;
+ }
+}
+
+static t_class *rewrap_class;
+
+static void *rewrap_new(t_floatarg fmin, t_floatarg fmax)
+{
+ t_rewrap *x = (t_rewrap *)pd_new(rewrap_class);
+
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("a"));
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("b"));
+
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_min = fmin;
+ rewrap_b(x, fmax);
+
+#ifndef MAXLIB
+ post(version);
+#endif
+ return (void *)x;
+}
+
+void rewrap_setup(void)
+{
+ rewrap_class = class_new(gensym("rewrap"), (t_newmethod)rewrap_new,
+ 0, sizeof(t_rewrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(rewrap_class, rewrap_float);
+ class_addmethod(rewrap_class, (t_method)rewrap_a, gensym("a"), A_FLOAT, 0);
+ class_addmethod(rewrap_class, (t_method)rewrap_b, gensym("b"), A_FLOAT, 0);
+#ifndef MAXLIB
+ class_sethelpsymbol(rewrap_class, gensym("help-rewrap.pd"));
+#else
+ class_sethelpsymbol(rewrap_class, gensym("maxlib/help-rewrap.pd"));
+#endif
+}
+
diff --git a/src/split.c b/src/split.c
new file mode 100644
index 0000000..11a910d
--- /dev/null
+++ b/src/split.c
@@ -0,0 +1,91 @@
+/* ------------------------- split ------------------------------------------ */
+/* */
+/* splits input to lie within an output range. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+static char *version = "split v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct split
+{
+ t_object x_ob;
+ t_float x_min; /* low border of input range */
+ t_float x_max; /* high border of input range */
+ t_int x_revert; /* range is inverted */
+ t_outlet *x_outlet1; /* path-through outlet */
+ t_outlet *x_outlet2; /* split outlet */
+} t_split;
+
+static void split_float(t_split *x, t_floatarg f)
+{
+ if(x->x_max >= x->x_min)
+ {
+ if(f <= x->x_max && f >= x->x_min)
+ outlet_float(x->x_outlet1, f);
+ else
+ outlet_float(x->x_outlet2, f);
+ }
+ else
+ {
+ if(f >= x->x_max && f <= x->x_min)
+ outlet_float(x->x_outlet1, f);
+ else
+ outlet_float(x->x_outlet2, f);
+ }
+}
+
+static t_class *split_class;
+
+static void *split_new(t_floatarg fmin, t_floatarg fmax)
+{
+ t_split *x = (t_split *)pd_new(split_class);
+
+ floatinlet_new(&x->x_ob, &x->x_min);
+ floatinlet_new(&x->x_ob, &x->x_max);
+
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_min = fmin;
+ x->x_max = fmax;
+
+#ifndef MAXLIB
+ post(version);
+#endif
+ return (void *)x;
+}
+
+void split_setup(void)
+{
+ split_class = class_new(gensym("split"), (t_newmethod)split_new,
+ 0, sizeof(t_split), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(split_class, split_float);
+#ifndef MAXLIB
+ class_sethelpsymbol(split_class, gensym("help-split.pd"));
+#else
+ class_sethelpsymbol(split_class, gensym("maxlib/help-split.pd"));
+#endif
+}
+
diff --git a/src/timebang.c b/src/timebang.c
new file mode 100644
index 0000000..0733af9
--- /dev/null
+++ b/src/timebang.c
@@ -0,0 +1,147 @@
+/* ------------------------- timebang --------------------------------------- */
+/* */
+/* Send out bangs at given times (time of day!). */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+#include <time.h>
+
+#define MAX_TIMES 256 /* maximum number of times to process */
+
+static char *version = "timebang v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct timebang
+{
+ t_object x_ob;
+ t_clock *x_clock;
+ t_outlet *x_outlet[MAX_TIMES]; /* the bang outlets */
+ t_int x_sec[MAX_TIMES]; /* seconds (0 - 59) */
+ t_int x_min[MAX_TIMES]; /* minutes (0 - 59) */
+ t_int x_hour[MAX_TIMES]; /* hours (0 - 11) */
+ t_int x_mday[MAX_TIMES]; /* day of month (1 - 31) */
+ t_int x_mon[MAX_TIMES]; /* month (0 - 11) */
+ t_int x_year[MAX_TIMES]; /* year (current year minus 1900) */
+ t_int x_wday[MAX_TIMES]; /* day of week (0 - 6, Sunday = 0, -1 = all days) */
+ t_int x_over[MAX_TIMES]; /* indicate that time is over */
+ t_int x_notimes; /* number of times to bang */
+} t_timebang;
+
+
+static void timebang_tick(t_timebang *x)
+{
+ time_t now = time(NULL);
+ struct tm *newtime;
+ int i;
+
+ newtime = localtime(&now); /* convert to local time. */
+ for(i = 0; i < x->x_notimes; i++)
+ {
+ if(!x->x_over[i])
+ {
+ if(newtime->tm_hour == x->x_hour[i] &&
+ newtime->tm_min == x->x_min[i] &&
+ newtime->tm_sec >= x->x_sec[i])
+ {
+ x->x_over[i] = 1; /* mark as 'time is over' */
+ outlet_bang(x->x_outlet[i]); /* send corresponding bang */
+ }
+ }
+ else if(newtime->tm_hour != x->x_hour[i])
+ x->x_over[i] = 0; /* reactivate time one hour later */
+ }
+
+ clock_delay(x->x_clock, 1000); /* come back in one second */
+}
+
+static void timebang_set(t_timebang *x, t_symbol *s, int ac, t_atom *av)
+{
+}
+
+static void timebang_bang(t_timebang *x)
+{
+ time_t now = time(NULL);
+ struct tm *newtime = localtime(&now); /* convert to local time. */
+ post("timebang: local time is %02d:%02d:%02d", newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
+}
+
+static t_class *timebang_class;
+
+static void *timebang_new(t_symbol *s, int ac, t_atom *av)
+{
+ int i;
+ t_timebang *x = (t_timebang *)pd_new(timebang_class);
+
+ x->x_clock = clock_new(x, (t_method)timebang_tick);
+
+#ifndef MAXLIB
+ post(version);
+#endif
+ if(ac > MAX_TIMES * 3)
+ {
+ post("timebang: too many creation arguments");
+ ac = MAX_TIMES * 3;
+ }
+
+ x->x_notimes = 0;
+ for(i = 0; i < ac; i += 3)
+ {
+ if (av[i].a_type == A_FLOAT) x->x_hour[x->x_notimes] = av[i].a_w.w_float;
+ else { post ("timebang: first argument must be (int) hours"); return 0; }
+ if (av[i+1].a_type == A_FLOAT) x->x_min[x->x_notimes] = av[i+1].a_w.w_float;
+ else { post ("timebang: second argument must be (int) minutes"); return 0; }
+ if (av[i+2].a_type == A_FLOAT) x->x_sec[x->x_notimes] = av[i+2].a_w.w_float;
+ else { post ("timebang: third argument must be (int) seconds"); return 0; }
+ x->x_over[x->x_notimes] = 0;
+ x->x_notimes++;
+ }
+ post("timebang: read in %d times of day:", x->x_notimes);
+ for(i = 0; i < x->x_notimes; i++)
+ {
+ x->x_outlet[i] = outlet_new(&x->x_ob, gensym("bang")); /* create specific bang outlet for time */
+ post(" %02d:%02d:%02d", x->x_hour[i], x->x_min[i], x->x_sec[i]);
+ }
+
+ clock_set(x->x_clock, 0);
+
+ return (void *)x;
+}
+
+static void timebang_free(t_timebang *x)
+{
+ clock_free(x->x_clock);
+}
+
+void timebang_setup(void)
+{
+ timebang_class = class_new(gensym("timebang"), (t_newmethod)timebang_new,
+ (t_method)timebang_free, sizeof(t_timebang), 0, A_GIMME, 0);
+ class_addmethod(timebang_class, (t_method)timebang_set, gensym("set"), A_GIMME, 0);
+ class_addbang(timebang_class, (t_method)timebang_bang);
+#ifndef MAXLIB
+ class_sethelpsymbol(timebang_class, gensym("help-timebang.pd"));
+#else
+ class_sethelpsymbol(timebang_class, gensym("maxlib/help-timebang.pd"));
+#endif
+}
+
diff --git a/src/unroute.c b/src/unroute.c
new file mode 100644
index 0000000..f9507d1
--- /dev/null
+++ b/src/unroute.c
@@ -0,0 +1,170 @@
+/* -------------------------- unroute ------------------------------------- */
+/* */
+/* Opposit to croute. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+
+#define MAX_INLET 256
+
+static char *version = "unroute v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct unroute
+{
+ t_object x_obj;
+ t_outlet *x_outlet;
+ t_int x_ninstance;
+ t_atom x_id;
+} t_unroute;
+
+typedef struct proxy
+{
+ t_object obj;
+ t_int index; /* number of proxy inlet(s) */
+ t_atom id;
+ t_unroute *x; /* we'll put the other struct in here */
+} t_proxy;
+
+static void unroute_any(t_unroute *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_atom at[MAXPDSTRING];
+
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 2] = argv[i];
+ }
+ argc += 2;
+ SETSYMBOL(at+1, s);
+
+ at[0] = x->x_id; /* prepend id of that inlet */
+
+ outlet_list(x->x_outlet, NULL, argc, at);
+}
+
+static void unroute_list(t_unroute *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+ t_atom at[MAXPDSTRING];
+
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 1] = argv[i];
+ }
+ argc++;
+
+ at[0] = x->x_id; /* prepend id of that inlet */
+
+ outlet_list(x->x_outlet, NULL, argc, at);
+}
+
+static void unroute_float(t_unroute *x, t_floatarg f)
+{
+ t_atom list[2];
+
+ list[0] = x->x_id; /* prepend id of that inlet */
+ SETFLOAT(list+1, f);
+ outlet_list(x->x_outlet, NULL, 2, list);
+}
+
+static void unroute_input(t_proxy *p, t_symbol *s, int argc, t_atom *argv)
+{
+ t_unroute *x = (t_unroute *)(p->x);
+ int i;
+ t_atom at[MAXPDSTRING];
+
+ if(s == gensym("list"))
+ {
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 1] = argv[i];
+ }
+ argc++;
+ }
+ else
+ {
+ for(i = 0; i < argc; i++)
+ {
+ at[i + 2] = argv[i];
+ }
+ argc += 2;
+ SETSYMBOL(at+1, s);
+ }
+
+ at[0] = p->id; /* prepend id for that inlet */
+
+ outlet_list(x->x_outlet, NULL, argc, at);
+}
+
+
+static t_class *unroute_class;
+static t_class *proxy_class;
+
+static void *unroute_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int i;
+
+ t_unroute *x = (t_unroute *)pd_new(unroute_class);
+ t_proxy *inlet[MAX_INLET];
+
+ x->x_ninstance = argc;
+ x->x_id = argv[0];
+
+ for(i = 0; i < x->x_ninstance - 1; i++)
+ {
+ inlet[i] = (t_proxy *)pd_new(proxy_class);
+ inlet[i]->x = x; /* make x visible to the proxy inlets */
+ inlet[i]->index = i; /* remember our number */
+ inlet[i]->id = argv[i+1];
+ /* the inlet we're going to create belongs to the object
+ 't_unroute' but the destination is the instance 'i'
+ of the proxy class 't_proxy' */
+ inlet_new(&x->x_obj, &inlet[i]->obj.ob_pd, 0,0);
+ }
+ x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
+
+#ifndef MAXLIB
+ post(version);
+#endif
+ return (void *)x;
+}
+
+void unroute_setup(void)
+{
+ unroute_class = class_new(gensym("unroute"), (t_newmethod)unroute_new,
+ 0, sizeof(t_unroute), 0, A_GIMME, 0);
+
+ /* a class for the proxy inlet: */
+ proxy_class = class_new(gensym("proxy"), NULL, NULL, sizeof(t_proxy),
+ CLASS_PD|CLASS_NOINLET, A_NULL);
+
+ class_addanything(proxy_class, unroute_input);
+
+ class_addfloat(unroute_class, unroute_float);
+ class_addlist(unroute_class, unroute_list);
+ class_addanything(unroute_class, unroute_any);
+#ifndef MAXLIB
+ class_sethelpsymbol(unroute_class, gensym("help-unroute.pd"));
+#else
+ class_sethelpsymbol(unroute_class, gensym("maxlib/help-unroute.pd"));
+#endif
+} \ No newline at end of file
diff --git a/src/urn.c b/src/urn.c
new file mode 100644
index 0000000..bf7d414
--- /dev/null
+++ b/src/urn.c
@@ -0,0 +1,144 @@
+/* ------------------------------- urn -------------------------------------- */
+/* */
+/* urn - urn selection model (random numbers without repetition). */
+/* Written by Olaf Matthes (olaf.matthes@gmx.de) */
+/* Based on code found in Dodge/Jerse "Computer Music" */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdlib.h>
+#include <time.h>
+#include <math.h>
+
+static char *version = "urn v0.1, urn selection model\n"
+ " written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+/* -------------------------- urn ------------------------------ */
+
+static t_class *urn_class;
+
+typedef struct _urn
+{
+ t_object x_obj;
+ t_outlet *x_numberout;
+ t_outlet *x_notify;
+
+ t_float x_f; /* number of numbers in urn */
+ t_int x_numbers; /* numbers left in urn */
+ t_int *x_selected;
+ unsigned int x_state;
+} t_urn;
+
+static int makeseed(void)
+{
+ static unsigned int random_nextseed = 1489853723;
+ random_nextseed = random_nextseed * 435898247 + 938284287;
+ return (random_nextseed & 0x7fffffff);
+}
+
+static void *urn_new(t_floatarg f)
+{
+ t_urn *x = (t_urn *)pd_new(urn_class);
+ srand( (unsigned)time( NULL ) );
+ x->x_numbers = x->x_f = f;
+ if(x->x_f < 0)x->x_f = 0;
+ x->x_selected = getbytes(((t_int)x->x_f+1)*sizeof(t_int));
+
+ x->x_state = makeseed();
+
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("f"));
+
+ x->x_numberout = outlet_new(&x->x_obj, &s_float);
+ x->x_notify = outlet_new(&x->x_obj, &s_bang);
+ return (x);
+}
+
+ /* set new size of urn */
+static void urn_f(t_urn *x, t_floatarg f)
+{
+ int i;
+ if(f < 0)
+ f = 0;
+ freebytes(x->x_selected, ((t_int)x->x_f+1)*sizeof(t_int));
+ x->x_numbers = x->x_f = f;
+ x->x_selected = getbytes(((t_int)x->x_f+1)*sizeof(t_int));
+ for(i = 0; i <= x->x_f; i++)
+ x->x_selected[i] = 0;
+}
+
+ /* clear (refill) urn */
+static void urn_clear(t_urn *x)
+{
+ int i;
+ x->x_numbers = x->x_f;
+ for(i = 0; i <= x->x_f; i++)
+ x->x_selected[i] = 0;
+}
+
+static void urn_seed(t_urn *x, float f, float glob)
+{
+ x->x_state = f;
+}
+
+ /* choose from urn */
+static void urn_bang(t_urn *x)
+{
+ int n = x->x_f, nval;
+ int range = (n < 1 ? 1 : n);
+ unsigned int randval = x->x_state;
+ if(x->x_numbers == 0)
+ goto notify;
+ do
+ {
+ x->x_state = randval = randval * 472940017 + 832416023;
+ nval = ((double)range) * ((double)randval)
+ * (1./4294967296.);
+ if (nval >= range) nval = range-1;
+ }
+ while(x->x_selected[nval]);
+
+ x->x_selected[nval] = 1;
+
+ outlet_float(x->x_numberout, nval);
+
+ if(--x->x_numbers == 0) /* urn is now empty */
+ goto notify;
+ return;
+
+notify:
+ outlet_bang(x->x_notify);
+}
+
+void urn_setup(void)
+{
+ urn_class = class_new(gensym("urn"), (t_newmethod)urn_new, 0,
+ sizeof(t_urn), 0, A_DEFFLOAT, 0);
+ class_addbang(urn_class, urn_bang);
+ class_addmethod(urn_class, (t_method)urn_f, gensym("f"), A_FLOAT, 0);
+ class_addmethod(urn_class, (t_method)urn_clear, gensym("clear"), 0);
+ class_addmethod(urn_class, (t_method)urn_seed, gensym("seed"), A_FLOAT, 0);
+#ifndef MAXLIB
+ post(version);
+ class_sethelpsymbol(urn_class, gensym("help-urn.pd"));
+#else
+ class_sethelpsymbol(urn_class, gensym("maxlib/help-urn.pd"));
+#endif
+} \ No newline at end of file
diff --git a/src/wrap.c b/src/wrap.c
new file mode 100644
index 0000000..0a81d3d
--- /dev/null
+++ b/src/wrap.c
@@ -0,0 +1,136 @@
+/* ------------------------- wrap ------------------------------------------ */
+/* */
+/* wraps input to lie within an output range. */
+/* Written by Olaf Matthes <olaf.matthes@gmx.de> */
+/* Get source at http://www.akustische-kunst.org/puredata/maxlib/ */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* Based on PureData by Miller Puckette and others. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <math.h>
+
+static char *version = "wrap v0.1, written by Olaf Matthes <olaf.matthes@gmx.de>";
+
+typedef struct wrap
+{
+ t_object x_ob;
+ t_float x_min; /* low border of input range */
+ t_float x_max; /* high border of input range */
+ t_outlet *x_outlet1; /* path-through outlet */
+ t_outlet *x_outlet2; /* wrap outlet */
+} t_wrap;
+
+static void wrap_float(t_wrap *x, t_floatarg f)
+{
+ t_float min = x->x_min;
+ t_float max = x->x_max;
+ t_float range = max - min;
+ t_int i;
+
+ if(range == 0.0f)
+ {
+ f = min;
+ outlet_float(x->x_outlet2, 0);
+ }
+ else if(f < min)
+ {
+ t_float diff = min - f;
+ t_float n = ceil(diff / range);
+
+ f += n * range;
+
+ outlet_float(x->x_outlet2, -(t_int)n);
+ }
+ else if (f >= max)
+ {
+ t_float diff = f - max;
+ t_float n = floor(diff / range) + 1.0f;
+
+ f -= n * range;
+
+ outlet_float(x->x_outlet2, (t_int)n);
+ }
+ else
+ outlet_float(x->x_outlet2, 0.0f);
+
+ outlet_float(x->x_outlet1, f);
+}
+
+static void wrap_a(t_wrap *x, t_floatarg a)
+{
+ t_float max = x->x_max;
+
+ if(a <= max)
+ x->x_min = a;
+ else
+ {
+ x->x_min = max;
+ x->x_max = a;
+ }
+}
+
+static void wrap_b(t_wrap *x, t_floatarg b)
+{
+ t_float min = x->x_min;
+
+ if(b >= min)
+ x->x_max = b;
+ else
+ {
+ x->x_max = min;
+ x->x_min = b;
+ }
+}
+
+static t_class *wrap_class;
+
+static void *wrap_new(t_floatarg fmin, t_floatarg fmax)
+{
+ t_wrap *x = (t_wrap *)pd_new(wrap_class);
+
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("a"));
+ inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("b"));
+
+ x->x_outlet1 = outlet_new(&x->x_ob, gensym("float"));
+ x->x_outlet2 = outlet_new(&x->x_ob, gensym("float"));
+
+ x->x_min = fmin;
+ wrap_b(x, fmax);
+
+#ifndef MAXLIB
+ post(version);
+#endif
+ return (void *)x;
+}
+
+void wrap_setup(void)
+{
+ wrap_class = class_new(gensym("wrap"), (t_newmethod)wrap_new,
+ 0, sizeof(t_wrap), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addfloat(wrap_class, wrap_float);
+ class_addmethod(wrap_class, (t_method)wrap_a, gensym("a"), A_FLOAT, 0);
+ class_addmethod(wrap_class, (t_method)wrap_b, gensym("b"), A_FLOAT, 0);
+#ifndef MAXLIB
+ class_sethelpsymbol(wrap_class, gensym("help-wrap.pd"));
+#else
+ class_sethelpsymbol(wrap_class, gensym("maxlib/help-wrap.pd"));
+#endif
+}
+