aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2011-01-17 20:30:55 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2011-01-17 20:30:55 +0000
commitddef561c60dac4e9f268e8c43336184fc91ecc27 (patch)
treed4c38796ac01d0a1fba3367305c1c8fd8c96356a
parentfd8385bf03804c1aa375db8418e1732d601dd9ef (diff)
[routeOSC] can now route addresses deeper than 1 (like /testing/one/two/three). Added a [verbosity( message to print some debug info.
Added a [paths( message to print out the currently active addresses to Pd console. Updated the help patch to match. svn path=/trunk/externals/mrpeach/; revision=14748
-rw-r--r--osc/routeOSC-help.pd120
-rw-r--r--osc/routeOSC.c146
2 files changed, 196 insertions, 70 deletions
diff --git a/osc/routeOSC-help.pd b/osc/routeOSC-help.pd
index 934c667..a1dc13f 100644
--- a/osc/routeOSC-help.pd
+++ b/osc/routeOSC-help.pd
@@ -1,49 +1,71 @@
-#N canvas 482 458 615 420 12;
-#X obj -39 219 cnv 15 200 40 empty empty empty 20 12 0 14 -4034 -66577
-0;
-#X obj -96 64 udpreceive 9997;
-#X obj 271 84 unpack 0 0 0 0;
-#X floatatom 271 115 3 0 0 0 - - -;
-#X floatatom 302 115 3 0 0 0 - - -;
-#X floatatom 334 115 3 0 0 0 - - -;
-#X floatatom 366 115 3 0 0 0 - - -;
-#X text 231 114 from;
-#X obj -96 94 unpackOSC;
-#X obj -8 229 routeOSC /test /west;
-#X obj -8 264 print a;
-#X obj 60 264 print b;
-#X obj 129 264 print c;
-#X msg -24 193 set /left;
-#X msg -47 170 set /left /right;
-#X text -108 16 routeOSC;
-#X text -108 34 accepts lists of floats that are interpreted as OSC
-packets;
-#X text 84 176 set message reassigns outputs;
-#X text -106 303 see also:;
-#X obj -27 303 packOSC;
-#X floatatom -12 114 10 0 0 1 millisecond_delay - -;
-#X obj -96 121 pipelist;
-#X text 163 228 arguments are OSC addresses to be routed;
-#X text 269 294 2008/09/17 Martin Peach;
-#X text -108 347 see:;
-#X text 39 348 for a way to send OSC over TCP or serial connections.
-;
-#X obj -73 348 unpackOSCstream;
-#X text 104 196 (but new outlets can't be created);
-#X obj -130 148 print unpacked;
-#X connect 1 0 8 0;
-#X connect 1 1 2 0;
-#X connect 2 0 3 0;
-#X connect 2 1 4 0;
-#X connect 2 2 5 0;
-#X connect 2 3 6 0;
-#X connect 8 0 21 0;
-#X connect 8 0 28 0;
-#X connect 8 1 20 0;
-#X connect 8 1 21 1;
-#X connect 9 0 10 0;
-#X connect 9 1 11 0;
-#X connect 9 2 12 0;
-#X connect 13 0 9 0;
-#X connect 14 0 9 0;
-#X connect 21 0 9 0;
+#N canvas 334 350 923 562 12;
+#X obj 81 389 cnv 15 200 40 empty empty empty 20 12 0 14 -4034 -66577
+0;
+#X obj -76 40 udpreceive 9997;
+#X floatatom 91 111 3 0 0 0 - - -;
+#X floatatom 118 111 3 0 0 0 - - -;
+#X floatatom 145 111 3 0 0 0 - - -;
+#X floatatom 172 111 3 0 0 0 - - -;
+#X text 51 110 from;
+#X obj -76 164 unpackOSC;
+#X obj 112 399 routeOSC /test /west;
+#X msg 76 343 set /left;
+#X msg 53 320 set /left /right;
+#X text 324 108 see also:;
+#X obj 396 109 packOSC;
+#X floatatom 483 184 10 0 0 1 millisecond_delay - -;
+#X obj -76 191 pipelist;
+#X text 283 398 arguments are OSC addresses to be routed;
+#X text -117 517 see:;
+#X text 30 518 for a way to send OSC over TCP or serial connections.
+;
+#X obj -82 518 unpackOSCstream;
+#X text 231 341 (but new outlets can't be created);
+#X obj -110 218 print unpacked;
+#X text 503 476 2011/01/17 Martin Peach;
+#X obj 91 87 unpack 0 0 0 0 0;
+#X floatatom 200 111 8 0 0 0 - - -;
+#X obj 26 64 route received from;
+#X floatatom 26 132 5 0 0 0 - - -;
+#X text 66 132 bytes;
+#X msg 99 366 set /test/one/two/three;
+#X msg 27 294 paths;
+#X msg 4 271 verbosity \$1;
+#X obj 4 253 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
+;
+#X text 22 249 set to 1 for debugging;
+#X text 275 365 routeOSC will match deep paths;
+#X text 245 40 [routeOSC] parses lists of floats (only integers on
+[0..255]) as OSC packets.;
+#X text 246 77 Open [packOSC-help] to send packets to this patch.;
+#X text -6 186 If the OSC packet has a timetag \, [pipelist] will delay
+it until the time occurs;
+#X obj 112 480 print match_1;
+#X obj 180 457 print match_2;
+#X obj 249 434 print no_match;
+#X text 177 319 [set( reassigns outputs from left to right;
+#X text 81 294 [paths( will print the current OSC addresses to Pd console
+;
+#X connect 1 0 7 0;
+#X connect 1 1 24 0;
+#X connect 7 0 14 0;
+#X connect 7 0 20 0;
+#X connect 7 1 13 0;
+#X connect 7 1 14 1;
+#X connect 8 0 36 0;
+#X connect 8 1 37 0;
+#X connect 8 2 38 0;
+#X connect 9 0 8 0;
+#X connect 10 0 8 0;
+#X connect 14 0 8 0;
+#X connect 22 0 2 0;
+#X connect 22 1 3 0;
+#X connect 22 2 4 0;
+#X connect 22 3 5 0;
+#X connect 22 4 23 0;
+#X connect 24 0 25 0;
+#X connect 24 1 22 0;
+#X connect 27 0 8 0;
+#X connect 28 0 8 0;
+#X connect 29 0 8 0;
+#X connect 30 0 29 0;
diff --git a/osc/routeOSC.c b/osc/routeOSC.c
index 5f48e4f..7dea8f6 100644
--- a/osc/routeOSC.c
+++ b/osc/routeOSC.c
@@ -87,22 +87,33 @@ The OpenSound Control WWW page is
typedef struct _routeOSC
{
- t_object x_obj; // required header
- t_int x_num; // Number of prefixes we store
- char *x_prefixes[MAX_NUM];
- void *x_outlets[MAX_NUM+1]; // one for each prefix plus one for everything else
+ t_object x_obj; /* required header */
+ t_int x_num; /* Number of prefixes we store */
+ t_int x_verbosity; /* level of debug output required */
+// char *x_prefixes[MAX_NUM]; /* the OSC addresses to be matched */
+// int x_prefix_depth[MAX_NUM]; /* the number of slashes in each prefix */
+// void *x_outlets[MAX_NUM+1]; /* one for each prefix plus one for everything else */
+ char **x_prefixes; /* the OSC addresses to be matched */
+ int *x_prefix_depth; /* the number of slashes in each prefix */
+ void **x_outlets; /* one for each prefix plus one for everything else */
} t_routeOSC;
/* prototypes */
void routeOSC_setup(void);
+static void routeOSC_free(t_routeOSC *x);
static int MyPatternMatch (const char *pattern, const char *test);
static void routeOSC_doanything(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv);
static void routeOSC_list(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv);
static void *routeOSC_new(t_symbol *s, int argc, t_atom *argv);
static void routeOSC_set(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv);
+static void routeOSC_paths(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv);
+static void routeOSC_verbosity(t_routeOSC *x, t_floatarg v);
+static int routeOSC_count_slashes(char *prefix);
static char *NextSlashOrNull(char *p);
+static char *NthSlashOrNull(char *p, int n);
static void StrCopyUntilSlash(char *target, const char *source);
+static void StrCopyUntilNthSlash(char *target, const char *source, int n);
/* from
OSC-pattern-match.c
@@ -127,6 +138,9 @@ static int MyPatternMatch (const char *pattern, const char *test)
static void routeOSC_free(t_routeOSC *x)
{
+ freebytes(x->x_prefixes, x->x_num*sizeof(char)); /* the OSC addresses to be matched */
+ freebytes(x->x_prefix_depth, x->x_num*sizeof(int)); /* the number of slashes in each prefix */
+ freebytes(x->x_outlets, x->x_num*sizeof(void *)); /* one for each prefix plus one for everything else */
}
/* initialization routine */
@@ -134,10 +148,12 @@ static void routeOSC_free(t_routeOSC *x)
void routeOSC_setup(void)
{
routeOSC_class = class_new(gensym("routeOSC"), (t_newmethod)routeOSC_new,
- (t_method)routeOSC_free,sizeof(t_routeOSC), 0, A_GIMME, 0);
+ (t_method)routeOSC_free, sizeof(t_routeOSC), 0, A_GIMME, 0);
class_addlist(routeOSC_class, routeOSC_list);
class_addanything(routeOSC_class, routeOSC_doanything);
class_addmethod(routeOSC_class, (t_method)routeOSC_set, gensym("set"), A_GIMME, 0);
+ class_addmethod(routeOSC_class, (t_method)routeOSC_paths, gensym("paths"), A_GIMME, 0);
+ class_addmethod(routeOSC_class, (t_method)routeOSC_verbosity, gensym("verbosity"), A_DEFFLOAT, 0);
ps_emptySymbol = gensym("");
@@ -158,6 +174,11 @@ static void *routeOSC_new(t_symbol *s, int argc, t_atom *argv)
return 0;
}
x->x_num = 0;
+
+ x->x_prefixes = (char **)getzbytes(argc*sizeof(char)); /* the OSC addresses to be matched */
+ x->x_prefix_depth = (int *)getzbytes(argc*sizeof(int)); /* the number of slashes in each prefix */
+ x->x_outlets = (void **)getzbytes(argc*sizeof(void *)); /* one for each prefix plus one for everything else */
+
for (i = 0; i < argc; ++i)
{
if (argv[i].a_type == A_SYMBOL)
@@ -165,6 +186,7 @@ static void *routeOSC_new(t_symbol *s, int argc, t_atom *argv)
if (argv[i].a_w.w_symbol->s_name[0] == '/')
{ /* Now that's a nice prefix */
x->x_prefixes[i] = argv[i].a_w.w_symbol->s_name;
+ x->x_prefix_depth[i] = routeOSC_count_slashes(x->x_prefixes[i]);
++(x->x_num);
}
}
@@ -185,6 +207,7 @@ static void *routeOSC_new(t_symbol *s, int argc, t_atom *argv)
{
x->x_outlets[i] = outlet_new(&x->x_obj, &s_list);
}
+ x->x_verbosity = 0; /* quiet by default */
return (x);
}
@@ -215,16 +238,39 @@ static void routeOSC_set(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv)
if (argv[i].a_w.w_symbol->s_name[0] == '/')
{ /* Now that's a nice prefix */
x->x_prefixes[i] = argv[i].a_w.w_symbol->s_name;
+ x->x_prefix_depth[i] = routeOSC_count_slashes(x->x_prefixes[i]);
}
}
}
+static void routeOSC_paths(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv)
+{ /* print out the paths we are matching */
+ int i;
+
+ for (i = 0; i < x->x_num; ++i) post("path[%d]: %s (depth %d)", i, x->x_prefixes[i], x->x_prefix_depth[i]);
+}
+
+static void routeOSC_verbosity(t_routeOSC *x, t_floatarg v)
+{
+ x->x_verbosity = (v == 0)? 0: 1;
+ if (x->x_verbosity) post("routeOSC_verbosity is %d", x->x_verbosity);
+}
+
+static int routeOSC_count_slashes(char *prefix)
+{ /* find the path depth of the prefix by counting the numberof slashes */
+ int i = 0;
+ char *p = prefix;
+
+ while (*p != '\0') if (*p++ == '/') i++;
+ return i;
+}
+
static void routeOSC_list(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv)
{
if(argc < 1)
{
- pd_error(x, "* routeOSC: ignoring empty list...");
- return;
+ pd_error(x, "* routeOSC: ignoring empty list...");
+ return;
}
if (argv[0].a_type == A_SYMBOL)
{
@@ -237,39 +283,44 @@ static void routeOSC_list(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv)
// output on unmatched outlet jdl 20020908
if (argv[0].a_type == A_FLOAT)
{
- outlet_float(x->x_outlets[x->x_num], atom_getfloat(argv));
+ outlet_float(x->x_outlets[x->x_num], atom_getfloat(argv));
}
else
{
- pd_error(x, "* routeOSC: unrecognized atom type!");
+ pd_error(x, "* routeOSC: unrecognized atom type!");
}
}
}
static void routeOSC_doanything(t_routeOSC *x, t_symbol *s, int argc, t_atom *argv)
{
- char *pattern, *nextSlash;
- int i;
- int matchedAnything;
+ char *pattern, *nextSlash;
+ int i, pattern_depth = 0, matchedAnything = 0;
// post("*** routeOSC_anything(s %s, argc %ld)", s->s_name, (long) argc);
pattern = s->s_name;
+ if (x->x_verbosity) post("routeOSC_doanything: pattern is %s", pattern);
if (pattern[0] != '/')
{
pd_error(x, "* routeOSC: invalid message pattern %s does not begin with /", s->s_name);
outlet_anything(x->x_outlets[x->x_num], s, argc, argv);
return;
}
- matchedAnything = 0;
+ pattern_depth = routeOSC_count_slashes(pattern);
+ if (x->x_verbosity) post("routeOSC_doanything: pattern_depth is %i", pattern_depth);
nextSlash = NextSlashOrNull(pattern+1);
if (*nextSlash == '\0')
- {
+ { /* pattern_depth == 1 */
/* last level of the address, so we'll output the argument list */
for (i = 0; i < x->x_num; ++i)
{
- if (MyPatternMatch(pattern+1, x->x_prefixes[i]+1))
+ if
+ (
+ (x->x_prefix_depth[i] <= pattern_depth)
+ && (MyPatternMatch(pattern+1, x->x_prefixes[i]+1))
+ )
{
++matchedAnything;
// I hate stupid Max lists with a special first element
@@ -312,16 +363,27 @@ static void routeOSC_doanything(t_routeOSC *x, t_symbol *s, int argc, t_atom *ar
t_symbol *restOfPattern = 0; /* avoid the gensym unless we have to output */
char patternBegin[1000];
- /* Get the first level of the incoming pattern to match against all our prefixes */
- StrCopyUntilSlash(patternBegin, pattern+1);
+ /* Get the incoming pattern to match against all our prefixes */
for (i = 0; i < x->x_num; ++i)
{
- if (MyPatternMatch(patternBegin, x->x_prefixes[i]+1))
+ restOfPattern = 0;
+ if (x->x_prefix_depth[i] <= pattern_depth)
{
- ++matchedAnything;
- if (restOfPattern == 0) restOfPattern = gensym(nextSlash);
- outlet_anything(x->x_outlets[i], restOfPattern, argc, argv);
+ StrCopyUntilNthSlash(patternBegin, pattern+1, x->x_prefix_depth[i]);
+ if (x->x_verbosity)
+ post("routeOSC_doanything: (%d) patternBegin is %s", i, patternBegin);
+ if (MyPatternMatch(patternBegin, x->x_prefixes[i]+1))
+ {
+ if (x->x_verbosity)
+ post("routeOSC_doanything: (%d) matched %s depth %d", i, x->x_prefixes[i], x->x_prefix_depth[i]);
+ ++matchedAnything;
+ nextSlash = NthSlashOrNull(pattern+1, x->x_prefix_depth[i]);
+ if (x->x_verbosity)
+ post("routeOSC_doanything: (%d) nextSlash %s", i, nextSlash);
+ if (restOfPattern == 0) restOfPattern = gensym(nextSlash);
+ outlet_anything(x->x_outlets[i], restOfPattern, argc, argv);
+ }
}
}
}
@@ -339,6 +401,22 @@ static char *NextSlashOrNull(char *p)
return p;
}
+static char *NthSlashOrNull(char *p, int n)
+{
+ int i;
+ for (i = 0; i < n; ++i)
+ {
+ while (*p != '/')
+ {
+ if (*p == '\0') return p;
+ p++;
+ }
+ if (i < n-1) p++; /* skip the slash unless it's the nth slash */
+ }
+ return p;
+}
+
+
static void StrCopyUntilSlash(char *target, const char *source)
{
while (*source != '/' && *source != '\0')
@@ -350,6 +428,32 @@ static void StrCopyUntilSlash(char *target, const char *source)
*target = 0;
}
+static void StrCopyUntilNthSlash(char *target, const char *source, int n)
+{ /* copy the path up but not including the nth slash */
+ int i = n;
+
+ while (i > 0)
+ {
+ while (*source != '/')
+ {
+ *target = *source;
+ if (*source == '\0') return;
+ ++target;
+ ++source;
+ }
+ i--;
+ /* got a slash. If it's the nth, don't include it */
+ if (i == 0)
+ {
+ *target = 0;
+ return;
+ }
+ *target = *source;
+ ++source;
+ ++target;
+ }
+}
+
/* from
OSC-pattern-match.c
Matt Wright, 3/16/98