aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Peach <mrpeach@users.sourceforge.net>2007-07-11 17:34:38 +0000
committerMartin Peach <mrpeach@users.sourceforge.net>2007-07-11 17:34:38 +0000
commitede66ad78a3c06557c53b2c0b6ee014aa3418e03 (patch)
tree5e040d57f42f3ec3c4f826cd227885e04998221a
parentb46366d420af97d820fb72a0e7cf34b38ca9edc0 (diff)
unpackOSC now simply outputs (through the right outlet) a delay in milliseconds when it
receives a timetag, as the timetag itself is not useable inside pd. The delay is zero when the timetag is in the past. Help patches have been updated to match. Also corrected a mistake in packOSC.c timetag calculation. svn path=/trunk/externals/mrpeach/; revision=8008
-rwxr-xr-xosc/packOSC-help.pd71
-rwxr-xr-xosc/packOSC.c3
-rwxr-xr-xosc/routeOSC-help.pd52
-rwxr-xr-xosc/unpackOSC.c101
4 files changed, 134 insertions, 93 deletions
diff --git a/osc/packOSC-help.pd b/osc/packOSC-help.pd
index 1747f30..11d9cdb 100755
--- a/osc/packOSC-help.pd
+++ b/osc/packOSC-help.pd
@@ -1,7 +1,7 @@
-#N canvas 0 366 1064 453 12;
+#N canvas 0 430 1064 453 12;
#X obj 72 393 udpsend;
-#X msg 373 359 disconnect;
-#X msg 161 359 connect 127.0.0.1 9997;
+#X msg 102 368 disconnect;
+#X msg 80 345 connect 127.0.0.1 9997;
#X obj 72 296 packOSC;
#X obj 72 428 tgl 15 0 empty empty 1=connected 20 8 0 8 -262144 -1
-1 1 1;
@@ -14,26 +14,24 @@
of floats instead of directly connecting to the network;
#X text 299 2 send a type-guessed message;
#X text 596 201 send a type-forced message;
-#X obj 652 417 routeOSC;
-#X text 573 417 see also:;
-#X msg 121 264 typetags \$1;
-#X obj 121 247 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+#X obj 387 381 routeOSC;
+#X text 308 380 see also:;
+#X msg 242 264 typetags \$1;
+#X obj 242 247 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
1;
-#X text 228 264 typetags are on by default;
-#X text 670 223 Useable types are:;
-#X text 670 241 i: 32 bit integer;
-#X text 670 259 f: 32-bit float;
-#X text 670 277 s: string;
+#X text 349 264 typetags are on by default;
+#X text 722 218 Useable types are:;
+#X text 722 236 i: 32 bit integer;
+#X text 722 254 f: 32-bit float;
+#X text 722 272 s: string;
#X text 539 26 send a type-forced message;
#X msg 164 27 sendtyped /test/one/two/three sis zz 88 T;
#X msg 112 202 sendtyped /left/right TTiTIFNfisf 1.1 2.1 3.1 4.1 5.1
;
-#X text 670 295 T: true (no argument);
-#X text 670 313 F: false (no argument);
-#X text 670 331 I: infinitum (no argument);
-#X obj 72 323 list prepend send;
-#X obj 72 349 list trim;
-#X text 670 348 N: Nil (no argument);
+#X text 722 290 T: true (no argument);
+#X text 722 308 F: false (no argument);
+#X text 722 326 I: infinitum (no argument);
+#X text 722 343 N: Nil (no argument);
#X msg 115 225 bufsize 100;
#X text 221 226 set buffer size (default is 64000 bytes);
#X msg 83 84 prefix /test;
@@ -43,22 +41,29 @@ of floats instead of directly connecting to the network;
#X text 189 156 'send' prefix is not required;
#X msg -37 105 [;
#X msg -95 129 ];
-#X text 270 421 2007/07/05 Martin Peach;
#X text 8 104 open a bundle;
#X text -55 128 close bundle;
#X msg 457 111 timetagoffset 0;
#X msg 464 130 timetagoffset -1;
#X text 602 110 send current time as timetag;
-#X msg 472 149 timetagoffset 1e+07;
#X text 494 169 (timetags are sent in bundle messages only);
-#X text 680 148 current time plus 10 seconds;
#X obj -95 71 t b a b;
#X msg -95 48 /test 5 6 7;
#X text 615 129 immediate time tag (default);
+#X floatatom 130 323 5 0 0 0 - - -;
+#X text 180 323 bundle depth;
+#X obj 294 340 cnv 15 380 30 empty empty empty 20 12 0 14 -24198 -66577
+0;
+#X text 270 421 2007/07/11 Martin Peach;
+#X text 469 380 and http://opensoundcontrol.org/cnmat;
+#X text 653 148 current time plus 1 second;
+#X msg 472 149 timetagoffset 1e+06;
+#X text 298 347 <- First open routeOSC-help \, then connect;
#X connect 0 0 4 0;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
-#X connect 3 0 28 0;
+#X connect 3 0 0 0;
+#X connect 3 1 47 0;
#X connect 5 0 3 0;
#X connect 6 0 3 0;
#X connect 7 0 3 0;
@@ -68,18 +73,16 @@ of floats instead of directly connecting to the network;
#X connect 16 0 15 0;
#X connect 23 0 3 0;
#X connect 24 0 3 0;
-#X connect 28 0 29 0;
-#X connect 29 0 0 0;
+#X connect 29 0 3 0;
#X connect 31 0 3 0;
#X connect 33 0 3 0;
-#X connect 35 0 3 0;
+#X connect 34 0 3 0;
#X connect 36 0 3 0;
-#X connect 38 0 3 0;
-#X connect 39 0 3 0;
-#X connect 43 0 3 0;
-#X connect 44 0 3 0;
-#X connect 46 0 3 0;
-#X connect 49 0 39 0;
-#X connect 49 1 3 0;
-#X connect 49 2 38 0;
-#X connect 50 0 49 0;
+#X connect 37 0 3 0;
+#X connect 40 0 3 0;
+#X connect 41 0 3 0;
+#X connect 44 0 37 0;
+#X connect 44 1 3 0;
+#X connect 44 2 36 0;
+#X connect 45 0 44 0;
+#X connect 53 0 3 0;
diff --git a/osc/packOSC.c b/osc/packOSC.c
index f609d64..ce73277 100755
--- a/osc/packOSC.c
+++ b/osc/packOSC.c
@@ -1281,12 +1281,13 @@ static OSCTimeTag OSCTT_CurrentTimePlusOffset(uint4 offset)
(unsigned) (tz.tz_dsttime ? 3600 : 0)+
(unsigned) offset/onemillion;
/* Now get the fractional part. */
- tt.fraction = ((unsigned) tv.tv_usec + (unsigned)(offset%onemillion)) * (unsigned) TWO_TO_THE_32_OVER_ONE_MILLION;
+ tt.fraction = (unsigned) tv.tv_usec + (unsigned)(offset%onemillion); /* in usec */
if (tt.fraction > onemillion)
{
tt.fraction -= onemillion;
tt.seconds++;
}
+ tt.fraction *= (unsigned) TWO_TO_THE_32_OVER_ONE_MILLION; /* convert usec to 32-bit fraction of 1 sec */
return tt;
}
diff --git a/osc/routeOSC-help.pd b/osc/routeOSC-help.pd
index 53aec8a..2895d49 100755
--- a/osc/routeOSC-help.pd
+++ b/osc/routeOSC-help.pd
@@ -1,28 +1,32 @@
-#N canvas 0 0 623 272 12;
-#X obj 58 69 udpreceive 9997;
-#X obj 188 97 unpack 0 0 0 0;
-#X floatatom 188 128 3 0 0 0 - - -;
-#X floatatom 228 128 3 0 0 0 - - -;
-#X floatatom 268 128 3 0 0 0 - - -;
-#X floatatom 309 128 3 0 0 0 - - -;
-#X text 148 127 from;
-#X obj 58 97 unpackOSC;
-#X obj 58 147 print;
-#X obj 70 206 routeOSC /test /west;
-#X obj 70 241 print a;
-#X obj 157 241 print b;
-#X obj 245 241 print c;
-#X msg 76 175 set /left;
-#X msg 193 175 set /left /right;
+#N canvas 0 0 641 324 12;
+#X obj 25 64 udpreceive 9997;
+#X obj 155 116 unpack 0 0 0 0;
+#X floatatom 155 147 3 0 0 0 - - -;
+#X floatatom 195 147 3 0 0 0 - - -;
+#X floatatom 235 147 3 0 0 0 - - -;
+#X floatatom 276 147 3 0 0 0 - - -;
+#X text 115 146 from;
+#X obj 25 116 unpackOSC;
+#X obj 35 142 print;
+#X obj 25 262 routeOSC /test /west;
+#X obj 25 297 print a;
+#X obj 112 297 print b;
+#X obj 200 297 print c;
+#X msg 31 231 set /left;
+#X msg 148 231 set /left /right;
#X text 10 7 routeOSC;
#X text 10 25 accepts lists of floats that are interpreted as OSC packets
;
#X text 10 43 set message reassigns outputs;
-#X text 258 205 arguments are OSC addresses to route;
-#X obj 134 147 print timetag;
-#X text 329 244 2007/07/05 Martin Peach;
-#X text 423 121 see also:;
-#X obj 502 121 packOSC;
+#X text 213 261 arguments are OSC addresses to route;
+#X text 390 140 see also:;
+#X obj 469 140 packOSC;
+#X text 284 300 2007/07/11 Martin Peach;
+#X obj 43 185 delay 0;
+#X obj 43 206 bng 15 250 50 0 empty empty sync 17 7 0 10 -24198 -258699
+-1;
+#X obj 43 164 b;
+#X floatatom 118 185 10 0 0 1 ms_delay - -;
#X connect 0 0 7 0;
#X connect 0 1 1 0;
#X connect 1 0 2 0;
@@ -31,9 +35,13 @@
#X connect 1 3 5 0;
#X connect 7 0 8 0;
#X connect 7 0 9 0;
-#X connect 7 1 19 0;
+#X connect 7 0 24 0;
+#X connect 7 1 22 1;
+#X connect 7 1 25 0;
#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 22 0 23 0;
+#X connect 24 0 22 0;
diff --git a/osc/unpackOSC.c b/osc/unpackOSC.c
index e84bf97..6a6274d 100755
--- a/osc/unpackOSC.c
+++ b/osc/unpackOSC.c
@@ -33,7 +33,6 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
*/
-
/*
dumpOSC.c
@@ -75,15 +74,13 @@ The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
#include "m_pd.h"
-#ifdef _WIN32
+ #include <stdio.h>
#include <string.h>
#include <stdlib.h>
+ #include <sys/time.h>
+#ifdef _WIN32
#include <winsock2.h>
- #include <stdio.h>
#else
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <ctype.h>
@@ -96,30 +93,39 @@ The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
typedef unsigned long long osc_time_t;
#endif
-#define MAX_MESG 65536 // was 32768 MP: make same as MAX_UDP_PACKET
+#define MAX_MESG 65536
+/* MAX_MESG was 32768 MP: make same as MAX_UDP_PACKET */
/* ----------------------------- was dumpOSC ------------------------- */
-#define MAX_PATH_AT 50 // maximum nuber of elements in OSC path
+#define MAX_PATH_AT 50
+/* MAX_PATH_AT = maximum number of elements in OSC path */
+
+/* You may have to redefine this typedef if ints on your system
+ aren't 4 bytes. */
+typedef unsigned int uint4;
+typedef struct
+{
+ uint4 seconds;
+ uint4 fraction;
+} OSCTimeTag;
static t_class *unpackOSC_class;
typedef struct _unpackOSC
{
- t_object x_obj;
- t_outlet *x_data_out;
- t_outlet *x_timetag_out;
- t_atom x_timetag[4];// timetag as four floats
- t_atom x_data_at[MAX_MESG];// symbols making up the path + payload
- int x_data_atc;// number of symbols to be output
- char x_raw[MAX_MESG];// bytes making up the entire OSC message
- int x_raw_c;// number of bytes in OSC message
+ t_object x_obj;
+ t_outlet *x_data_out;
+ t_outlet *x_delay_out;
+ t_atom x_data_at[MAX_MESG];/* symbols making up the path + payload */
+ int x_data_atc;/* number of symbols to be output */
+ char x_raw[MAX_MESG];/* bytes making up the entire OSC message */
+ int x_raw_c;/* number of bytes in OSC message */
} t_unpackOSC;
void unpackOSC_setup(void);
static void *unpackOSC_new(void);
static void unpackOSC_free(t_unpackOSC *x);
-void unpackOSC_setup(void);
static void unpackOSC_list(t_unpackOSC *x, t_symbol *s, int argc, t_atom *argv);
static int unpackOSC_path(t_unpackOSC *x, char *path);
static void unpackOSC_Smessage(t_unpackOSC *x, void *v, int n);
@@ -127,6 +133,7 @@ static void unpackOSC_PrintTypeTaggedArgs(t_unpackOSC *x, void *v, int n);
static void unpackOSC_PrintHeuristicallyTypeGuessedArgs(t_unpackOSC *x, void *v, int n, int skipComma);
static char *unpackOSC_DataAfterAlignedString(char *string, char *boundary);
static int unpackOSC_IsNiceString(char *string, char *boundary);
+static t_float unpackOSC_DeltaTime(OSCTimeTag tt);
static void *unpackOSC_new(void)
{
@@ -134,7 +141,7 @@ static void *unpackOSC_new(void)
x = (t_unpackOSC *)pd_new(unpackOSC_class);
x->x_data_out = outlet_new(&x->x_obj, &s_list);
- x->x_timetag_out = outlet_new(&x->x_obj, &s_list);
+ x->x_delay_out = outlet_new(&x->x_obj, &s_float);
x->x_raw_c = x->x_data_atc = 0;
return (x);
}
@@ -154,11 +161,9 @@ void unpackOSC_setup(void)
/* unpackOSC_list expects an OSC packet in the form of a list of floats on [0..255] */
static void unpackOSC_list(t_unpackOSC *x, t_symbol *s, int argc, t_atom *argv)
{
- int size, messageLen, i, j;
- char *messageName, *args, *buf;
- unsigned long timetag_s;
- unsigned long timetag_ms;
- unsigned short timetag[4];
+ int size, messageLen, i, j;
+ char *messageName, *args, *buf;
+ OSCTimeTag tt;
if ((argc%4) != 0)
{
@@ -171,9 +176,9 @@ static void unpackOSC_list(t_unpackOSC *x, t_symbol *s, int argc, t_atom *argv)
if (argv[i].a_type == A_FLOAT)
{
j = (int)argv[i].a_w.w_float;
-// if ((j == argv[i].a_w.w_float) && (j >= 0) && (j <= 255))
-// this can miss bytes between 128 and 255 because they are interpreted somewhere as negative
-// , so change to this:
+/* if ((j == argv[i].a_w.w_float) && (j >= 0) && (j <= 255)) */
+/* this can miss bytes between 128 and 255 because they are interpreted somewhere as negative */
+/* , so change to this: */
if ((j == argv[i].a_w.w_float) && (j >= -128) && (j <= 255))
{
x->x_raw[i] = (char)j;
@@ -210,15 +215,11 @@ static void unpackOSC_list(t_unpackOSC *x, t_symbol *s, int argc, t_atom *argv)
printf("unpackOSC: [ %lx%08lx\n", ntohl(*((unsigned long *)(buf+8))),
ntohl(*((unsigned long *)(buf+12))));
#endif
-/* split the timetag into 4 16-bit fragments so we can output them as floats */
- timetag_s = ntohl(*((unsigned long *)(buf+8)));
- timetag_ms = ntohl(*((unsigned long *)(buf+12)));
- timetag[0] = (short)(timetag_s>>8);
- timetag[1] = (short)(timetag_s & 0xFFFF);
- timetag[2] = (short)(timetag_ms>>8);
- timetag[3] = (short)(timetag_ms & 0xFFFF);
- for (i = 0; i < 4; ++i) SETFLOAT(&x->x_timetag[i], (float)timetag[i]);
- outlet_list(x->x_timetag_out, &s_list, 4, x->x_timetag);
+/* convert the timetag into a millisecond delay from now */
+ tt.seconds = ntohl(*((unsigned long *)(buf+8)));
+ tt.fraction = ntohl(*((unsigned long *)(buf+12)));
+ /* pd can use a delay in milliseconds */
+ outlet_float(x->x_delay_out, unpackOSC_DeltaTime(tt));
/* Note: if we wanted to actually use the time tag as a little-endian
64-bit int, we'd have to word-swap the two 32-bit halves of it */
@@ -490,7 +491,7 @@ static void unpackOSC_PrintHeuristicallyTypeGuessedArgs(t_unpackOSC *x, void *v,
}
else
{
- // unhandled .. ;)
+ /* unhandled .. ;) */
#ifdef DEBUG
post("unpackOSC: indeterminate type: 0x%x xx", ints[i]);
#endif
@@ -580,4 +581,32 @@ static int unpackOSC_IsNiceString(char *string, char *boundary)
return 1;
}
+#define SECONDS_FROM_1900_to_1970 2208988800LL /* 17 leap years */
+#define TWO_TO_THE_32_OVER_ONE_MILLION 4295LL
+#define ONE_MILLION_OVER_TWO_TO_THE_32 0.00023283064365386963
+
+/* return the time difference in milliseconds between an OSC timetag and now */
+static t_float unpackOSC_DeltaTime(OSCTimeTag tt)
+{
+ OSCTimeTag ttnow;
+ struct timeval tv;
+ struct timezone tz;
+ static double onemillion = 1000000.0f;
+ double ttusec, nowusec, delta;
+
+ if (tt.fraction == 1 && tt.seconds == 0) return 0.0; /* immediate */
+ gettimeofday(&tv, &tz); /* find now */
+ /* First get the seconds right */
+ ttnow.seconds = (unsigned) SECONDS_FROM_1900_to_1970 +
+ (unsigned) tv.tv_sec -
+ (unsigned) 60 * tz.tz_minuteswest +
+ (unsigned) (tz.tz_dsttime ? 3600 : 0);
+ /* find usec in tt */
+ ttusec = tt.seconds*onemillion + ONE_MILLION_OVER_TWO_TO_THE_32*tt.fraction;
+ nowusec = ttnow.seconds*onemillion + tv.tv_usec;
+ /* subtract now from tt to get delta time */
+ if (ttusec < nowusec) return 0.0;
+ delta = ttusec - nowusec;
+ return (float)(delta*0.001f);
+}
/* end of unpackOSC.c */