summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/extra/dumpOSC.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/extra/dumpOSC.c')
-rw-r--r--apps/plugins/pdbox/PDa/extra/dumpOSC.c1998
1 files changed, 999 insertions, 999 deletions
diff --git a/apps/plugins/pdbox/PDa/extra/dumpOSC.c b/apps/plugins/pdbox/PDa/extra/dumpOSC.c
index 28b0d8223e..4e80de18a0 100644
--- a/apps/plugins/pdbox/PDa/extra/dumpOSC.c
+++ b/apps/plugins/pdbox/PDa/extra/dumpOSC.c
@@ -1,1000 +1,1000 @@
1/* 1/*
2Written by Matt Wright and Adrian Freed, The Center for New Music and 2Written by Matt Wright and Adrian Freed, The Center for New Music and
3Audio Technologies, University of California, Berkeley. Copyright (c) 3Audio Technologies, University of California, Berkeley. Copyright (c)
41992,93,94,95,96,97,98,99,2000,01,02,03,04 The Regents of the University of 41992,93,94,95,96,97,98,99,2000,01,02,03,04 The Regents of the University of
5California (Regents). 5California (Regents).
6 6
7Permission to use, copy, modify, distribute, and distribute modified versions 7Permission to use, copy, modify, distribute, and distribute modified versions
8of this software and its documentation without fee and without a signed 8of this software and its documentation without fee and without a signed
9licensing agreement, is hereby granted, provided that the above copyright 9licensing agreement, is hereby granted, provided that the above copyright
10notice, this paragraph and the following two paragraphs appear in all copies, 10notice, this paragraph and the following two paragraphs appear in all copies,
11modifications, and distributions. 11modifications, and distributions.
12 12
13IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 13IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
14SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 14SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
15OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 15OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
16BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17 17
18REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 20PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
21HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 21HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
22MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 22MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 23
24 24
25The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl 25The OSC webpage is http://cnmat.cnmat.berkeley.edu/OpenSoundControl
26*/ 26*/
27 27
28 28
29 /* 29 /*
30 30
31 dumpOSC.c 31 dumpOSC.c
32 server that displays OpenSoundControl messages sent to it 32 server that displays OpenSoundControl messages sent to it
33 for debugging client udp and UNIX protocol 33 for debugging client udp and UNIX protocol
34 34
35 by Matt Wright, 6/3/97 35 by Matt Wright, 6/3/97
36 modified from dumpSC.c, by Matt Wright and Adrian Freed 36 modified from dumpSC.c, by Matt Wright and Adrian Freed
37 37
38 version 0.2: Added "-silent" option a.k.a. "-quiet" 38 version 0.2: Added "-silent" option a.k.a. "-quiet"
39 39
40 version 0.3: Incorporated patches from Nicola Bernardini to make 40 version 0.3: Incorporated patches from Nicola Bernardini to make
41 things Linux-friendly. Also added ntohl() in the right places 41 things Linux-friendly. Also added ntohl() in the right places
42 to support little-endian architectures. 42 to support little-endian architectures.
43 43
44 44
45 45
46 compile: 46 compile:
47 cc -o dumpOSC dumpOSC.c 47 cc -o dumpOSC dumpOSC.c
48 48
49 to-do: 49 to-do:
50 50
51 More robustness in saying exactly what's wrong with ill-formed 51 More robustness in saying exactly what's wrong with ill-formed
52 messages. (If they don't make sense, show exactly what was 52 messages. (If they don't make sense, show exactly what was
53 received.) 53 received.)
54 54
55 Time-based features: print time-received for each packet 55 Time-based features: print time-received for each packet
56 56
57 Clean up to separate OSC parsing code from socket/select stuff 57 Clean up to separate OSC parsing code from socket/select stuff
58 58
59 pd: branched from http://www.cnmat.berkeley.edu/OpenSoundControl/src/dumpOSC/dumpOSC.c 59 pd: branched from http://www.cnmat.berkeley.edu/OpenSoundControl/src/dumpOSC/dumpOSC.c
60 ------------- 60 -------------
61 -- added pd functions 61 -- added pd functions
62 -- socket is made differently than original via pd mechanisms 62 -- socket is made differently than original via pd mechanisms
63 -- tweaks for Win32 www.zeggz.com/raf 13-April-2002 63 -- tweaks for Win32 www.zeggz.com/raf 13-April-2002
64 -- the OSX changes from cnmat didnt make it here yet but this compiles 64 -- the OSX changes from cnmat didnt make it here yet but this compiles
65 on OSX anyway. 65 on OSX anyway.
66 66
67*/ 67*/
68 68
69#if HAVE_CONFIG_H 69#if HAVE_CONFIG_H
70#include <config.h> 70#include <config.h>
71#endif 71#endif
72 72
73#include "m_pd.h" 73#include "m_pd.h"
74//#include "m_imp.h" 74//#include "m_imp.h"
75#include "s_stuff.h" 75#include "s_stuff.h"
76 76
77/* declarations */ 77/* declarations */
78 78
79// typedef void (*t_fdpollfn)(void *ptr, int fd); 79// typedef void (*t_fdpollfn)(void *ptr, int fd);
80void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr); 80void sys_addpollfn(int fd, t_fdpollfn fn, void *ptr);
81 81
82 82
83#if defined(__sgi) || defined(__linux) || defined(WIN32) || defined(__APPLE__) 83#if defined(__sgi) || defined(__linux) || defined(WIN32) || defined(__APPLE__)
84 84
85#ifdef WIN32 85#ifdef WIN32
86 #include "OSC-common.h" 86 #include "OSC-common.h"
87 #include <winsock2.h> 87 #include <winsock2.h>
88 #include <string.h> 88 #include <string.h>
89 #include <stdlib.h> 89 #include <stdlib.h>
90 #include <fcntl.h> 90 #include <fcntl.h>
91 #include <sys/types.h> 91 #include <sys/types.h>
92 #include <sys/stat.h> 92 #include <sys/stat.h>
93 #include <ctype.h> 93 #include <ctype.h>
94 #include <signal.h> 94 #include <signal.h>
95#else 95#else
96 #include <stdio.h> 96 #include <stdio.h>
97 #include <string.h> 97 #include <string.h>
98 #include <stdlib.h> 98 #include <stdlib.h>
99 #include <unistd.h> 99 #include <unistd.h>
100 #include <fcntl.h> 100 #include <fcntl.h>
101 #include <sys/types.h> 101 #include <sys/types.h>
102 #include <sys/stat.h> 102 #include <sys/stat.h>
103 #include <netinet/in.h> 103 #include <netinet/in.h>
104 #include <rpc/rpc.h> 104 #include <rpc/rpc.h>
105 #include <sys/socket.h> 105 #include <sys/socket.h>
106 #include <sys/un.h> 106 #include <sys/un.h>
107 #include <sys/times.h> 107 #include <sys/times.h>
108 #include <sys/param.h> 108 #include <sys/param.h>
109 #include <sys/time.h> 109 #include <sys/time.h>
110 #include <sys/ioctl.h> 110 #include <sys/ioctl.h>
111 #include <ctype.h> 111 #include <ctype.h>
112 #include <arpa/inet.h> 112 #include <arpa/inet.h>
113 #include <netdb.h> 113 #include <netdb.h>
114 #include <pwd.h> 114 #include <pwd.h>
115 #include <signal.h> 115 #include <signal.h>
116 #include <grp.h> 116 #include <grp.h>
117 #include <sys/file.h> 117 #include <sys/file.h>
118 //#include <sys/prctl.h> 118 //#include <sys/prctl.h>
119 119
120 #ifdef NEED_SCHEDCTL_AND_LOCK 120 #ifdef NEED_SCHEDCTL_AND_LOCK
121 #include <sys/schedctl.h> 121 #include <sys/schedctl.h>
122 #include <sys/lock.h> 122 #include <sys/lock.h>
123 #endif 123 #endif
124#endif 124#endif
125 125
126 126
127char *htm_error_string; 127char *htm_error_string;
128typedef int Boolean; 128typedef int Boolean;
129typedef void *OBJ; 129typedef void *OBJ;
130 130
131typedef struct ClientAddressStruct { 131typedef struct ClientAddressStruct {
132 struct sockaddr_in cl_addr; 132 struct sockaddr_in cl_addr;
133 int clilen; 133 int clilen;
134 int sockfd; 134 int sockfd;
135} *ClientAddr; 135} *ClientAddr;
136 136
137typedef unsigned long long osc_time_t; 137typedef unsigned long long osc_time_t;
138 138
139Boolean ShowBytes = FALSE; 139Boolean ShowBytes = FALSE;
140Boolean Silent = FALSE; 140Boolean Silent = FALSE;
141 141
142/* Declarations */ 142/* Declarations */
143#ifndef WIN32 143#ifndef WIN32
144static int unixinitudp(int chan); 144static int unixinitudp(int chan);
145#endif 145#endif
146 146
147static int initudp(int chan); 147static int initudp(int chan);
148static void closeudp(int sockfd); 148static void closeudp(int sockfd);
149Boolean ClientReply(int packetsize, void *packet, int socketfd, 149Boolean ClientReply(int packetsize, void *packet, int socketfd,
150 void *clientaddresspointer, int clientaddressbufferlength); 150 void *clientaddresspointer, int clientaddressbufferlength);
151void sgi_CleanExit(void); 151void sgi_CleanExit(void);
152Boolean sgi_HaveToQuit(void); 152Boolean sgi_HaveToQuit(void);
153int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy); 153int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy);
154static void catch_sigint(); 154static void catch_sigint();
155static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) ; 155static int Synthmessage(char *m, int n, void *clientdesc, int clientdesclength, int fd) ;
156char *DataAfterAlignedString(char *string, char *boundary) ; 156char *DataAfterAlignedString(char *string, char *boundary) ;
157Boolean IsNiceString(char *string, char *boundary) ; 157Boolean IsNiceString(char *string, char *boundary) ;
158void complain(char *s, ...); 158void complain(char *s, ...);
159 159
160#define MAXMESG 32768 160#define MAXMESG 32768
161static char mbuf[MAXMESG]; 161static char mbuf[MAXMESG];
162 162
163/* ----------------------------- dumpOSC ------------------------- */ 163/* ----------------------------- dumpOSC ------------------------- */
164 164
165#define MAXOUTAT 50 165#define MAXOUTAT 50
166 166
167static t_class *dumpOSC_class; 167static t_class *dumpOSC_class;
168 168
169typedef struct _dumpOSC 169typedef struct _dumpOSC
170{ 170{
171 t_object x_obj; 171 t_object x_obj;
172 t_outlet *x_msgout; 172 t_outlet *x_msgout;
173 t_outlet *x_connectout; 173 t_outlet *x_connectout;
174 t_atom x_outat[MAXOUTAT]; 174 t_atom x_outat[MAXOUTAT];
175 int x_outatc; 175 int x_outatc;
176 t_binbuf *x_b; 176 t_binbuf *x_b;
177 int x_connectsocket; 177 int x_connectsocket;
178 int x_nconnections; 178 int x_nconnections;
179 int x_udp; 179 int x_udp;
180 struct sockaddr_in x_server; 180 struct sockaddr_in x_server;
181 int x_clilen; 181 int x_clilen;
182} t_dumpOSC; 182} t_dumpOSC;
183 183
184void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr); 184void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr);
185Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd); 185Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd);
186static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr); 186static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr);
187static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n); 187static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n);
188static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma); 188static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma);
189 189
190static void dumpOSC_read(t_dumpOSC *x, int sockfd) { 190static void dumpOSC_read(t_dumpOSC *x, int sockfd) {
191 int clilen = x->x_clilen; 191 int clilen = x->x_clilen;
192 int n; 192 int n;
193 struct ClientAddressStruct ras; 193 struct ClientAddressStruct ras;
194 ClientAddr ra = &ras; 194 ClientAddr ra = &ras;
195 195
196 //catchupflag= FALSE; 196 //catchupflag= FALSE;
197 197
198/* if (ShowBytes) { */ 198/* if (ShowBytes) { */
199/* int i; */ 199/* int i; */
200/* printf("%d byte message:\n", n); */ 200/* printf("%d byte message:\n", n); */
201/* for (i = 0; i < n; ++i) { */ 201/* for (i = 0; i < n; ++i) { */
202/* printf(" %x (%c)\t", m[i], m[i]); */ 202/* printf(" %x (%c)\t", m[i], m[i]); */
203/* if (i%4 == 3) printf("\n"); */ 203/* if (i%4 == 3) printf("\n"); */
204/* } */ 204/* } */
205/* printf("\n"); */ 205/* printf("\n"); */
206/* } */ 206/* } */
207 207
208 // return catchupflag; 208 // return catchupflag;
209 //struct sockaddr_in x->x_server; 209 //struct sockaddr_in x->x_server;
210 //while( (n = recvfrom(sockfd, mbuf, MAXMESG, 0, &cl_addr, &clilen)) >0) 210 //while( (n = recvfrom(sockfd, mbuf, MAXMESG, 0, &cl_addr, &clilen)) >0)
211 // while(( 211 // while((
212 212
213 #ifdef WIN32 213 #ifdef WIN32
214 if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (SOCKADDR*)&x->x_server, &clilen)) >0) 214 if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (SOCKADDR*)&x->x_server, &clilen)) >0)
215 #else 215 #else
216 if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (struct sockaddr *)&x->x_server, &clilen)) >0) 216 if ((n = recvfrom(sockfd, mbuf, MAXMESG, 0, (struct sockaddr *)&x->x_server, &clilen)) >0)
217 #endif 217 #endif
218 { 218 {
219 //int r; 219 //int r;
220 ras.cl_addr = *((struct sockaddr_in *) &x->x_server); 220 ras.cl_addr = *((struct sockaddr_in *) &x->x_server);
221 ras.clilen = x->x_clilen; 221 ras.clilen = x->x_clilen;
222 ras.sockfd = x->x_connectsocket; 222 ras.sockfd = x->x_connectsocket;
223 223
224 #ifdef DEBUG 224 #ifdef DEBUG
225 printf("dumpOSC_read: received UDP packet of length %d\n", n); 225 printf("dumpOSC_read: received UDP packet of length %d\n", n);
226 #endif 226 #endif
227 227
228 if(!dumpOSC_SendReply(mbuf, n, &x->x_server, clilen, sockfd)) 228 if(!dumpOSC_SendReply(mbuf, n, &x->x_server, clilen, sockfd))
229 { 229 {
230 dumpOSC_ParsePacket(x, mbuf, n, ra); 230 dumpOSC_ParsePacket(x, mbuf, n, ra);
231 } 231 }
232 //r = Synthmessage(mbuf, n, &x->x_server, clilen, sockfd); 232 //r = Synthmessage(mbuf, n, &x->x_server, clilen, sockfd);
233 //post ("%d", r); 233 //post ("%d", r);
234 //outlet_anything(x->x_msgout, at[msg].a_w.w_symbol, 234 //outlet_anything(x->x_msgout, at[msg].a_w.w_symbol,
235 // emsg-msg-1, at + msg + 1); 235 // emsg-msg-1, at + msg + 1);
236 // outlet_list(x->x_msgout, 0, n, mbuf); 236 // outlet_list(x->x_msgout, 0, n, mbuf);
237 //if( sgi_HaveToQuit()) goto out; 237 //if( sgi_HaveToQuit()) goto out;
238 //if(r>0) goto back; 238 //if(r>0) goto back;
239 //clilen = maxclilen; 239 //clilen = maxclilen;
240 } 240 }
241} 241}
242 242
243static void *dumpOSC_new(t_symbol *compatflag, 243static void *dumpOSC_new(t_symbol *compatflag,
244 t_floatarg fportno) { 244 t_floatarg fportno) {
245 t_dumpOSC *x; 245 t_dumpOSC *x;
246 struct sockaddr_in server; 246 struct sockaddr_in server;
247 int clilen=sizeof(server); 247 int clilen=sizeof(server);
248 int sockfd; 248 int sockfd;
249 int portno=fportno; 249 int portno=fportno;
250 int udp = 1; 250 int udp = 1;
251 251
252 //x->x_b = binbuf_new(); 252 //x->x_b = binbuf_new();
253 //x->x_outat = binbuf_getvec(x->x_b); 253 //x->x_outat = binbuf_getvec(x->x_b);
254 254
255 //{{raf}} pointer not valid yet...moving this down 255 //{{raf}} pointer not valid yet...moving this down
256 //x->x_outatc = 0; {{raf}} 256 //x->x_outatc = 0; {{raf}}
257 257
258 /* create a socket */ 258 /* create a socket */
259 if ((sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0)) == -1) 259 if ((sockfd = socket(AF_INET, (udp ? SOCK_DGRAM : SOCK_STREAM), 0)) == -1)
260 { 260 {
261 sys_sockerror("socket"); 261 sys_sockerror("socket");
262 return (0); 262 return (0);
263 } 263 }
264 264
265 server.sin_family = AF_INET; 265 server.sin_family = AF_INET;
266 server.sin_addr.s_addr = INADDR_ANY; 266 server.sin_addr.s_addr = INADDR_ANY;
267 /* assign server port number */ 267 /* assign server port number */
268 server.sin_port = htons((u_short)portno); 268 server.sin_port = htons((u_short)portno);
269 /* name the socket */ 269 /* name the socket */
270 if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) 270 if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
271 { 271 {
272 sys_sockerror("bind"); 272 sys_sockerror("bind");
273 sys_closesocket(sockfd); 273 sys_closesocket(sockfd);
274 return (0); 274 return (0);
275 } 275 }
276 276
277 x = (t_dumpOSC *)pd_new(dumpOSC_class); 277 x = (t_dumpOSC *)pd_new(dumpOSC_class);
278 x->x_outatc = 0; // {{raf}} now pointer is valid (less invalid) 278 x->x_outatc = 0; // {{raf}} now pointer is valid (less invalid)
279 279
280 x->x_msgout = outlet_new(&x->x_obj, &s_anything); 280 x->x_msgout = outlet_new(&x->x_obj, &s_anything);
281 281
282 // if (udp) /* datagram protocol */ 282 // if (udp) /* datagram protocol */
283 { 283 {
284 284
285 sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_read, x); 285 sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_read, x);
286 x->x_connectout = 0; 286 x->x_connectout = 0;
287 } 287 }
288 // else /* streaming protocol */ 288 // else /* streaming protocol */
289 /* { */ 289 /* { */
290 /* if (listen(sockfd, 5) < 0) */ 290 /* if (listen(sockfd, 5) < 0) */
291 /* { */ 291 /* { */
292 /* sys_sockerror("listen"); */ 292 /* sys_sockerror("listen"); */
293 /* sys_closesocket(sockfd); */ 293 /* sys_closesocket(sockfd); */
294 /* sockfd = -1; */ 294 /* sockfd = -1; */
295 /* } */ 295 /* } */
296 /* else */ 296 /* else */
297 /* { */ 297 /* { */
298 /* sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_connectpoll, x); */ 298 /* sys_addpollfn(sockfd, (t_fdpollfn)dumpOSC_connectpoll, x); */
299 /* x->x_connectout = outlet_new(&x->x_obj, &s_float); */ 299 /* x->x_connectout = outlet_new(&x->x_obj, &s_float); */
300 /* } */ 300 /* } */
301 /* } */ 301 /* } */
302 302
303 x->x_connectsocket = sockfd; 303 x->x_connectsocket = sockfd;
304 x->x_server = server; 304 x->x_server = server;
305 x->x_clilen = clilen; 305 x->x_clilen = clilen;
306 x->x_nconnections = 0; 306 x->x_nconnections = 0;
307 x->x_udp = udp; 307 x->x_udp = udp;
308 308
309 return (x); 309 return (x);
310} 310}
311 311
312static void dumpOSC_free(t_dumpOSC *x) 312static void dumpOSC_free(t_dumpOSC *x)
313{ 313{
314 /* LATER make me clean up open connections */ 314 /* LATER make me clean up open connections */
315 if (x->x_connectsocket >= 0) 315 if (x->x_connectsocket >= 0)
316 { 316 {
317 sys_rmpollfn(x->x_connectsocket); 317 sys_rmpollfn(x->x_connectsocket);
318 sys_closesocket(x->x_connectsocket); 318 sys_closesocket(x->x_connectsocket);
319 } 319 }
320} 320}
321 321
322#ifdef WIN32 322#ifdef WIN32
323OSC_API void dumpOSC_setup(void) 323OSC_API void dumpOSC_setup(void)
324#else 324#else
325void dumpOSC_setup(void) 325void dumpOSC_setup(void)
326#endif 326#endif
327{ 327{
328 dumpOSC_class = class_new(gensym("dumpOSC"), 328 dumpOSC_class = class_new(gensym("dumpOSC"),
329 (t_newmethod)dumpOSC_new, (t_method)dumpOSC_free, 329 (t_newmethod)dumpOSC_new, (t_method)dumpOSC_free,
330 sizeof(t_dumpOSC), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT, 330 sizeof(t_dumpOSC), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT,
331 A_DEFSYM, 0); 331 A_DEFSYM, 0);
332 class_sethelpsymbol(dumpOSC_class, gensym("dumpOSC-help.pd")); 332 class_sethelpsymbol(dumpOSC_class, gensym("dumpOSC-help.pd"));
333} 333}
334 334
335 335
336#ifndef WIN32 336#ifndef WIN32
337 #define UNIXDG_PATH "/tmp/htm" 337 #define UNIXDG_PATH "/tmp/htm"
338 #define UNIXDG_TMP "/tmp/htm.XXXXXX" 338 #define UNIXDG_TMP "/tmp/htm.XXXXXX"
339 static int unixinitudp(int chan) 339 static int unixinitudp(int chan)
340 { 340 {
341 struct sockaddr_un serv_addr; 341 struct sockaddr_un serv_addr;
342 int sockfd; 342 int sockfd;
343 343
344 if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) 344 if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
345 return sockfd; 345 return sockfd;
346 346
347 bzero((char *)&serv_addr, sizeof(serv_addr)); 347 bzero((char *)&serv_addr, sizeof(serv_addr));
348 serv_addr.sun_family = AF_UNIX; 348 serv_addr.sun_family = AF_UNIX;
349 strcpy(serv_addr.sun_path, UNIXDG_PATH); 349 strcpy(serv_addr.sun_path, UNIXDG_PATH);
350 sprintf(serv_addr.sun_path+strlen(serv_addr.sun_path), "%d", chan); 350 sprintf(serv_addr.sun_path+strlen(serv_addr.sun_path), "%d", chan);
351 unlink(serv_addr.sun_path); 351 unlink(serv_addr.sun_path);
352 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr.sun_family)+strlen(serv_addr.sun_path)) < 0) 352 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr.sun_family)+strlen(serv_addr.sun_path)) < 0)
353 { 353 {
354 perror("unable to bind\n"); 354 perror("unable to bind\n");
355 return -1; 355 return -1;
356 } 356 }
357 357
358 fcntl(sockfd, F_SETFL, FNDELAY); 358 fcntl(sockfd, F_SETFL, FNDELAY);
359 return sockfd; 359 return sockfd;
360 } 360 }
361#endif // #ifndef WIN32 361#endif // #ifndef WIN32
362 362
363 363
364 364
365static int initudp(int chan) 365static int initudp(int chan)
366{ 366{
367 367
368#ifdef WIN32 368#ifdef WIN32
369 struct sockaddr_in serv_addr; 369 struct sockaddr_in serv_addr;
370 unsigned int sockfd; 370 unsigned int sockfd;
371 ULONG nonBlocking = (ULONG) TRUE; 371 ULONG nonBlocking = (ULONG) TRUE;
372 372
373 if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET ) { 373 if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET ) {
374 ZeroMemory((char *)&serv_addr, sizeof(serv_addr)); 374 ZeroMemory((char *)&serv_addr, sizeof(serv_addr));
375 serv_addr.sin_family = AF_INET; 375 serv_addr.sin_family = AF_INET;
376 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 376 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
377 serv_addr.sin_port = htons(chan); 377 serv_addr.sin_port = htons(chan);
378 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) { 378 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0) {
379 // set for non-blocking mode 379 // set for non-blocking mode
380 if(ioctlsocket(sockfd, FIONBIO, &nonBlocking) == SOCKET_ERROR) { 380 if(ioctlsocket(sockfd, FIONBIO, &nonBlocking) == SOCKET_ERROR) {
381 perror("unable to set non-blocking\n"); 381 perror("unable to set non-blocking\n");
382 return -1; 382 return -1;
383 } 383 }
384 } 384 }
385 else { perror("unable to bind\n"); return -1; } 385 else { perror("unable to bind\n"); return -1; }
386 } 386 }
387 return (sockfd == INVALID_SOCKET ? -1 : (int)sockfd); 387 return (sockfd == INVALID_SOCKET ? -1 : (int)sockfd);
388#else 388#else
389 struct sockaddr_in serv_addr; 389 struct sockaddr_in serv_addr;
390 int sockfd; 390 int sockfd;
391 391
392 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 392 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
393 return sockfd; 393 return sockfd;
394 394
395 bzero((char *)&serv_addr, sizeof(serv_addr)); 395 bzero((char *)&serv_addr, sizeof(serv_addr));
396 serv_addr.sin_family = AF_INET; 396 serv_addr.sin_family = AF_INET;
397 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 397 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
398 serv_addr.sin_port = htons(chan); 398 serv_addr.sin_port = htons(chan);
399 399
400 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 400 if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
401 { 401 {
402 perror("unable to bind\n"); 402 perror("unable to bind\n");
403 return -1; 403 return -1;
404 } 404 }
405 405
406 fcntl(sockfd, F_SETFL, FNDELAY); 406 fcntl(sockfd, F_SETFL, FNDELAY);
407 return sockfd; 407 return sockfd;
408#endif 408#endif
409} 409}
410 410
411 411
412 412
413 413
414 414
415 415
416 416
417 417
418static void closeudp(int sockfd) { 418static void closeudp(int sockfd) {
419 #ifdef WIN32 419 #ifdef WIN32
420 closesocket(sockfd); 420 closesocket(sockfd);
421 #else 421 #else
422 close(sockfd); 422 close(sockfd);
423 #endif 423 #endif
424} 424}
425 425
426static Boolean catchupflag=FALSE; 426static Boolean catchupflag=FALSE;
427Boolean ClientReply(int packetsize, void *packet, int socketfd, 427Boolean ClientReply(int packetsize, void *packet, int socketfd,
428 void *clientaddresspointer, int clientaddressbufferlength) 428 void *clientaddresspointer, int clientaddressbufferlength)
429{ 429{
430 if(!clientaddresspointer) return FALSE; 430 if(!clientaddresspointer) return FALSE;
431 catchupflag= TRUE; 431 catchupflag= TRUE;
432 return packetsize==sendto(socketfd, packet, packetsize, 0, clientaddresspointer, clientaddressbufferlength); 432 return packetsize==sendto(socketfd, packet, packetsize, 0, clientaddresspointer, clientaddressbufferlength);
433} 433}
434 434
435static Boolean exitflag= FALSE; 435static Boolean exitflag= FALSE;
436void sgi_CleanExit(void) { 436void sgi_CleanExit(void) {
437 exitflag = TRUE; 437 exitflag = TRUE;
438} 438}
439 439
440Boolean sgi_HaveToQuit(void) { 440Boolean sgi_HaveToQuit(void) {
441 return exitflag; 441 return exitflag;
442} 442}
443 443
444 444
445/* file descriptor poll table */ 445/* file descriptor poll table */
446static int npolldevs =0; 446static int npolldevs =0;
447typedef struct polldev 447typedef struct polldev
448{ 448{
449 int fd; 449 int fd;
450 void (*callbackfunction)(int , void *); 450 void (*callbackfunction)(int , void *);
451 void *dummy; 451 void *dummy;
452} polldev; 452} polldev;
453#define TABMAX 8 453#define TABMAX 8
454static polldev polldevs[TABMAX]; 454static polldev polldevs[TABMAX];
455 455
456 456
457/* Register a device (referred to by a file descriptor that the caller 457/* Register a device (referred to by a file descriptor that the caller
458 should have already successfully obtained from a system call) to be 458 should have already successfully obtained from a system call) to be
459 polled as real-time constraints allowed. 459 polled as real-time constraints allowed.
460 460
461 When a select(2) call indicates activity on the file descriptor, the 461 When a select(2) call indicates activity on the file descriptor, the
462 callback function is called with the file descripter as first 462 callback function is called with the file descripter as first
463 argument and the given dummy argument (presumably a pointer to the 463 argument and the given dummy argument (presumably a pointer to the
464 instance variables associated with the device). 464 instance variables associated with the device).
465*/ 465*/
466int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy) 466int RegisterPollingDevice(int fd, void (*callbackfunction)(int , void *), void *dummy)
467{ 467{
468 if(npolldevs<TABMAX) 468 if(npolldevs<TABMAX)
469 { 469 {
470 polldevs[npolldevs].fd = fd; 470 polldevs[npolldevs].fd = fd;
471 polldevs[npolldevs].callbackfunction = callbackfunction; 471 polldevs[npolldevs].callbackfunction = callbackfunction;
472 polldevs[npolldevs].dummy = dummy; 472 polldevs[npolldevs].dummy = dummy;
473 } 473 }
474 else return -1; 474 else return -1;
475 return npolldevs++; 475 return npolldevs++;
476} 476}
477 477
478static int caught_sigint; 478static int caught_sigint;
479 479
480static void catch_sigint() { 480static void catch_sigint() {
481 caught_sigint = 1; 481 caught_sigint = 1;
482} 482}
483static int sockfd, usockfd; 483static int sockfd, usockfd;
484 484
485 485
486void PrintClientAddr(ClientAddr CA) { 486void PrintClientAddr(ClientAddr CA) {
487 unsigned long addr = CA->cl_addr.sin_addr.s_addr; 487 unsigned long addr = CA->cl_addr.sin_addr.s_addr;
488 printf("Client address %p:\n", CA); 488 printf("Client address %p:\n", CA);
489 printf(" clilen %d, sockfd %d\n", CA->clilen, CA->sockfd); 489 printf(" clilen %d, sockfd %d\n", CA->clilen, CA->sockfd);
490 printf(" sin_family %d, sin_port %d\n", CA->cl_addr.sin_family, 490 printf(" sin_family %d, sin_port %d\n", CA->cl_addr.sin_family,
491 CA->cl_addr.sin_port); 491 CA->cl_addr.sin_port);
492 printf(" address: (%x) %s\n", addr, inet_ntoa(CA->cl_addr.sin_addr)); 492 printf(" address: (%x) %s\n", addr, inet_ntoa(CA->cl_addr.sin_addr));
493 493
494 printf(" sin_zero = \"%c%c%c%c%c%c%c%c\"\n", 494 printf(" sin_zero = \"%c%c%c%c%c%c%c%c\"\n",
495 CA->cl_addr.sin_zero[0], 495 CA->cl_addr.sin_zero[0],
496 CA->cl_addr.sin_zero[1], 496 CA->cl_addr.sin_zero[1],
497 CA->cl_addr.sin_zero[2], 497 CA->cl_addr.sin_zero[2],
498 CA->cl_addr.sin_zero[3], 498 CA->cl_addr.sin_zero[3],
499 CA->cl_addr.sin_zero[4], 499 CA->cl_addr.sin_zero[4],
500 CA->cl_addr.sin_zero[5], 500 CA->cl_addr.sin_zero[5],
501 CA->cl_addr.sin_zero[6], 501 CA->cl_addr.sin_zero[6],
502 CA->cl_addr.sin_zero[7]); 502 CA->cl_addr.sin_zero[7]);
503 503
504 printf("\n"); 504 printf("\n");
505} 505}
506 506
507//******************* 507//*******************
508 508
509void WriteTime(char* dst, osc_time_t osctime) 509void WriteTime(char* dst, osc_time_t osctime)
510{ 510{
511 *(int32_t*)dst = htonl((int32_t)(osctime >> 32)); 511 *(int32_t*)dst = htonl((int32_t)(osctime >> 32));
512 *(int32_t*)(dst+4) = htonl((int32_t)osctime); 512 *(int32_t*)(dst+4) = htonl((int32_t)osctime);
513} 513}
514 514
515void WriteMode(char* dst) 515void WriteMode(char* dst)
516{ 516{
517 *(int32_t*)dst = htonl(0); 517 *(int32_t*)dst = htonl(0);
518} 518}
519 519
520osc_time_t ReadTime(const char* src) 520osc_time_t ReadTime(const char* src)
521{ 521{
522 osc_time_t osctime = ntohl(*(int32_t*)src); 522 osc_time_t osctime = ntohl(*(int32_t*)src);
523 return (osctime << 32) + ntohl(*(int32_t*)(src+4)); 523 return (osctime << 32) + ntohl(*(int32_t*)(src+4));
524} 524}
525 525
526double TimeToSeconds(osc_time_t osctime) 526double TimeToSeconds(osc_time_t osctime)
527{ 527{
528 return (double)osctime * 2.3283064365386962890625e-10 /* 1/2^32 */; 528 return (double)osctime * 2.3283064365386962890625e-10 /* 1/2^32 */;
529} 529}
530 530
531int timeRound(double x) 531int timeRound(double x)
532{ 532{
533 return x >= 0.0 ? x+0.5 : x-0.5; 533 return x >= 0.0 ? x+0.5 : x-0.5;
534} 534}
535/* 535/*
536void WriteLogicalTime(char* dst) 536void WriteLogicalTime(char* dst)
537{ 537{
538 static double startTime = -1.0; 538 static double startTime = -1.0;
539 double sTime; 539 double sTime;
540 540
541 // Initialisierung der Startzeit. 541 // Initialisierung der Startzeit.
542 // Knnte effizienter (ohne 'if') auch irgendwo vorher passieren. 542 // Knnte effizienter (ohne 'if') auch irgendwo vorher passieren.
543 // Knnte wahrscheinlich auch 0.0 sein. 543 // Knnte wahrscheinlich auch 0.0 sein.
544 if (startTime < 0.0) { 544 if (startTime < 0.0) {
545 startTime = clock_getlogicaltime(); 545 startTime = clock_getlogicaltime();
546 } 546 }
547 547
548 sTime = clock_gettimesince(startTime) * 0.001; 548 sTime = clock_gettimesince(startTime) * 0.001;
549 *(int32_t*)dst = hton'K l((int32_t)sTime); 549 *(int32_t*)dst = hton'K l((int32_t)sTime);
550 *(int32_t*)(dst+4) = htonl((int32_t)(4294967296.0 * sTime)); 550 *(int32_t*)(dst+4) = htonl((int32_t)(4294967296.0 * sTime));
551} 551}
552*/ 552*/
553 553
554void WriteLogicalTime(char* dst) 554void WriteLogicalTime(char* dst)
555{ 555{
556 double sTime = clock_gettimesince(19230720) / 1000.0; 556 double sTime = clock_gettimesince(19230720) / 1000.0;
557 double tau = sTime - timeRound(sTime); 557 double tau = sTime - timeRound(sTime);
558 558
559 //fprintf(stderr, "sSec = %f tau = %f\n", sTime, tau); 559 //fprintf(stderr, "sSec = %f tau = %f\n", sTime, tau);
560 560
561 *(int32_t*)dst = htonl((int32_t)(sTime)); 561 *(int32_t*)dst = htonl((int32_t)(sTime));
562 *(int32_t*)(dst+4) = htonl((int32_t)(4294967296 * tau)); 562 *(int32_t*)(dst+4) = htonl((int32_t)(4294967296 * tau));
563} 563}
564 564
565Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd) 565Boolean dumpOSC_SendReply(char *buf, int n, void *clientDesc, int clientDescLenght, int fd)
566{ 566{
567 if((n == 24) && (strcmp(buf, "#time") == 0)) 567 if((n == 24) && (strcmp(buf, "#time") == 0))
568 { 568 {
569 osc_time_t t0, t1, t2; 569 osc_time_t t0, t1, t2;
570 double dt0, dt1, dt2; 570 double dt0, dt1, dt2;
571 571
572 WriteMode(buf+6); 572 WriteMode(buf+6);
573 573
574 t0 = ReadTime(buf+8); 574 t0 = ReadTime(buf+8);
575 575
576 WriteLogicalTime(buf+16); 576 WriteLogicalTime(buf+16);
577 t1 = ReadTime(buf+16); // reverse 577 t1 = ReadTime(buf+16); // reverse
578 dt0 = TimeToSeconds(t0); // client time 578 dt0 = TimeToSeconds(t0); // client time
579 dt1 = TimeToSeconds(t1); // server time 579 dt1 = TimeToSeconds(t1); // server time
580 580
581 // fprintf(stderr, "%f\t%f\t%f\n", dt0, dt1, dt0 - dt1); 581 // fprintf(stderr, "%f\t%f\t%f\n", dt0, dt1, dt0 - dt1);
582 582
583 sendto(fd, buf, n, 0, (struct sockaddr *)clientDesc, clientDescLenght); 583 sendto(fd, buf, n, 0, (struct sockaddr *)clientDesc, clientDescLenght);
584 return TRUE; 584 return TRUE;
585 } 585 }
586 else 586 else
587 { 587 {
588 return FALSE; 588 return FALSE;
589 } 589 }
590} 590}
591 591
592//********************** 592//**********************
593 593
594void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr) { 594void dumpOSC_ParsePacket(t_dumpOSC *x, char *buf, int n, ClientAddr returnAddr) {
595 // t_dumpOSC *x; 595 // t_dumpOSC *x;
596 int size, messageLen, i; 596 int size, messageLen, i;
597 char *messageName; 597 char *messageName;
598 char *args; 598 char *args;
599 599
600 //#ifdef PRINTADDRS 600 //#ifdef PRINTADDRS
601 #ifdef DEBUG 601 #ifdef DEBUG
602 //PrintClientAddr(returnAddr); 602 //PrintClientAddr(returnAddr);
603 #endif 603 #endif
604 604
605 605
606 if ((n%4) != 0) { 606 if ((n%4) != 0) {
607 complain("SynthControl packet size (%d) not a multiple of 4 bytes: dropping", n); 607 complain("SynthControl packet size (%d) not a multiple of 4 bytes: dropping", n);
608 return; 608 return;
609 } 609 }
610 610
611 if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) { 611 if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) {
612 /* This is a bundle message. */ 612 /* This is a bundle message. */
613 #ifdef DEBUG 613 #ifdef DEBUG
614 printf("dumpOSC_ParsePacket: bundle msg: bundles not yet supported\n"); 614 printf("dumpOSC_ParsePacket: bundle msg: bundles not yet supported\n");
615 #endif 615 #endif
616 616
617 if (n < 16) { 617 if (n < 16) {
618 complain("Bundle message too small (%d bytes) for time tag", n); 618 complain("Bundle message too small (%d bytes) for time tag", n);
619 return; 619 return;
620 } 620 }
621 621
622 /* Print the time tag */ 622 /* Print the time tag */
623 #ifdef DEBUG 623 #ifdef DEBUG
624 printf("[ %lx%08lx\n", ntohl(*((unsigned long *)(buf+8))), ntohl(*((unsigned long *)(buf+12)))); 624 printf("[ %lx%08lx\n", ntohl(*((unsigned long *)(buf+8))), ntohl(*((unsigned long *)(buf+12))));
625 #endif 625 #endif
626 626
627 /* Note: if we wanted to actually use the time tag as a little-endian 627 /* Note: if we wanted to actually use the time tag as a little-endian
628 64-bit int, we'd have to word-swap the two 32-bit halves of it */ 628 64-bit int, we'd have to word-swap the two 32-bit halves of it */
629 629
630 i = 16; /* Skip "#group\0" and time tag */ 630 i = 16; /* Skip "#group\0" and time tag */
631 631
632 while(i<n) { 632 while(i<n) {
633 size = ntohl(*((int *) (buf + i))); 633 size = ntohl(*((int *) (buf + i)));
634 if ((size % 4) != 0) { 634 if ((size % 4) != 0) {
635 complain("Bad size count %d in bundle (not a multiple of 4)", size); 635 complain("Bad size count %d in bundle (not a multiple of 4)", size);
636 return; 636 return;
637 } 637 }
638 if ((size + i + 4) > n) { 638 if ((size + i + 4) > n) {
639 complain("Bad size count %d in bundle (only %d bytes left in entire bundle)", 639 complain("Bad size count %d in bundle (only %d bytes left in entire bundle)",
640 size, n-i-4); 640 size, n-i-4);
641 return; 641 return;
642 } 642 }
643 643
644 /* Recursively handle element of bundle */ 644 /* Recursively handle element of bundle */
645 dumpOSC_ParsePacket(x, buf+i+4, size, returnAddr); 645 dumpOSC_ParsePacket(x, buf+i+4, size, returnAddr);
646 i += 4 + size; 646 i += 4 + size;
647 } 647 }
648 648
649 if (i != n) { 649 if (i != n) {
650 complain("This can't happen"); 650 complain("This can't happen");
651 } 651 }
652 #ifdef DEBUG 652 #ifdef DEBUG
653 printf("]\n"); 653 printf("]\n");
654 #endif 654 #endif
655 655
656 } 656 }
657 else if ((n == 24) && (strcmp(buf, "#time") == 0)) 657 else if ((n == 24) && (strcmp(buf, "#time") == 0))
658 { 658 {
659 complain("Time message: %s\n :).\n", htm_error_string); 659 complain("Time message: %s\n :).\n", htm_error_string);
660 return; 660 return;
661 661
662 } 662 }
663 else 663 else
664 { 664 {
665 /* This is not a bundle message */ 665 /* This is not a bundle message */
666 666
667 messageName = buf; 667 messageName = buf;
668 args = DataAfterAlignedString(messageName, buf+n); 668 args = DataAfterAlignedString(messageName, buf+n);
669 if (args == 0) { 669 if (args == 0) {
670 complain("Bad message name string: %s\nDropping entire message.\n", 670 complain("Bad message name string: %s\nDropping entire message.\n",
671 htm_error_string); 671 htm_error_string);
672 return; 672 return;
673 } 673 }
674 messageLen = args-messageName; 674 messageLen = args-messageName;
675 dumpOSC_Smessage(x, messageName, (void *)args, n-messageLen, returnAddr); 675 dumpOSC_Smessage(x, messageName, (void *)args, n-messageLen, returnAddr);
676 } 676 }
677} 677}
678 678
679#define SMALLEST_POSITIVE_FLOAT 0.000001f 679#define SMALLEST_POSITIVE_FLOAT 0.000001f
680 680
681static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr) { 681static void dumpOSC_Smessage(t_dumpOSC *x, char *address, void *v, int n, ClientAddr returnAddr) {
682 char *chars = v; 682 char *chars = v;
683 t_atom at; 683 t_atom at;
684 //t_atom myargv[50]; 684 //t_atom myargv[50];
685 685
686 int myargc = x->x_outatc; 686 int myargc = x->x_outatc;
687 t_atom* mya = x->x_outat; 687 t_atom* mya = x->x_outat;
688 int myi; 688 int myi;
689 689
690#ifdef DEBUG 690#ifdef DEBUG
691 printf("%s ", address); 691 printf("%s ", address);
692#endif 692#endif
693 693
694 // ztoln+cvt from envgen.c, ggee-0.18 .. 694 // ztoln+cvt from envgen.c, ggee-0.18 ..
695 // outlet_anything's 'symbol' gets set to address 695 // outlet_anything's 'symbol' gets set to address
696 // so we dont need to append address to the atomlist 696 // so we dont need to append address to the atomlist
697 /* 697 /*
698 SETSYMBOL(mya,gensym(address));myargc++; 698 SETSYMBOL(mya,gensym(address));myargc++;
699 x->x_outatc = myargc; 699 x->x_outatc = myargc;
700 */ 700 */
701 701
702 if (n != 0) { 702 if (n != 0) {
703 if (chars[0] == ',') { 703 if (chars[0] == ',') {
704 if (chars[1] != ',') { 704 if (chars[1] != ',') {
705 /* This message begins with a type-tag string */ 705 /* This message begins with a type-tag string */
706 dumpOSC_PrintTypeTaggedArgs(x, v, n); 706 dumpOSC_PrintTypeTaggedArgs(x, v, n);
707 } else { 707 } else {
708 /* Double comma means an escaped real comma, not a type string */ 708 /* Double comma means an escaped real comma, not a type string */
709 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 1); 709 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 1);
710 } 710 }
711 } else { 711 } else {
712 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0); 712 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0);
713 } 713 }
714 } 714 }
715 715
716 outlet_anything(x->x_msgout,gensym(address),x->x_outatc,(t_atom*)&x->x_outat); 716 outlet_anything(x->x_msgout,gensym(address),x->x_outatc,(t_atom*)&x->x_outat);
717 x->x_outatc = 0; 717 x->x_outatc = 0;
718#ifdef DEBUG 718#ifdef DEBUG
719 printf("\n"); 719 printf("\n");
720#endif 720#endif
721 fflush(stdout); /* Added for Sami 5/21/98 */ 721 fflush(stdout); /* Added for Sami 5/21/98 */
722} 722}
723 723
724static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n) { 724static void dumpOSC_PrintTypeTaggedArgs(t_dumpOSC *x, void *v, int n) {
725 char *typeTags, *thisType; 725 char *typeTags, *thisType;
726 char *p; 726 char *p;
727 727
728 int myargc = x->x_outatc; 728 int myargc = x->x_outatc;
729 t_atom* mya = x->x_outat; 729 t_atom* mya = x->x_outat;
730 int myi; 730 int myi;
731 731
732 typeTags = v; 732 typeTags = v;
733 733
734 if (!IsNiceString(typeTags, typeTags+n)) { 734 if (!IsNiceString(typeTags, typeTags+n)) {
735 /* No null-termination, so maybe it wasn't a type tag 735 /* No null-termination, so maybe it wasn't a type tag
736 string after all */ 736 string after all */
737 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0); 737 dumpOSC_PrintHeuristicallyTypeGuessedArgs(x, v, n, 0);
738 return; 738 return;
739 } 739 }
740 740
741 p = DataAfterAlignedString(typeTags, typeTags+n); 741 p = DataAfterAlignedString(typeTags, typeTags+n);
742 742
743 743
744 for (thisType = typeTags + 1; *thisType != 0; ++thisType) { 744 for (thisType = typeTags + 1; *thisType != 0; ++thisType) {
745 switch (*thisType) { 745 switch (*thisType) {
746 case 'i': case 'r': case 'm': case 'c': 746 case 'i': case 'r': case 'm': case 'c':
747#ifdef DEBUG 747#ifdef DEBUG
748 //post("integer: %d", ntohl(*((int *) p))); 748 //post("integer: %d", ntohl(*((int *) p)));
749#endif 749#endif
750 /* Martin Peach fix for negative floats: 750 /* Martin Peach fix for negative floats:
751 * was: SETFLOAT(mya+myargc,ntohl(*((int *) p))); 751 * was: SETFLOAT(mya+myargc,ntohl(*((int *) p)));
752 * now is: 752 * now is:
753 */ 753 */
754 SETFLOAT(mya+myargc,(signed)ntohl(*((int *) p))); 754 SETFLOAT(mya+myargc,(signed)ntohl(*((int *) p)));
755 myargc++; 755 myargc++;
756 756
757 p += 4; 757 p += 4;
758 break; 758 break;
759 759
760 case 'f': { 760 case 'f': {
761 int i = ntohl(*((int *) p)); 761 int i = ntohl(*((int *) p));
762 float *floatp = ((float *) (&i)); 762 float *floatp = ((float *) (&i));
763#ifdef DEBUG 763#ifdef DEBUG
764 post("float: %f", *floatp); 764 post("float: %f", *floatp);
765#endif 765#endif
766 SETFLOAT(mya+myargc,*floatp); 766 SETFLOAT(mya+myargc,*floatp);
767 myargc++; 767 myargc++;
768 768
769 p += 4; 769 p += 4;
770 } 770 }
771 break; 771 break;
772 772
773 case 'h': case 't': 773 case 'h': case 't':
774#ifdef DEBUG 774#ifdef DEBUG
775 printf("[A 64-bit int] "); 775 printf("[A 64-bit int] ");
776#endif 776#endif
777 post("[A 64-bit int] not implemented"); 777 post("[A 64-bit int] not implemented");
778 778
779 p += 8; 779 p += 8;
780 break; 780 break;
781 781
782 case 'd': 782 case 'd':
783#ifdef DEBUG 783#ifdef DEBUG
784 printf("[A 64-bit float] "); 784 printf("[A 64-bit float] ");
785#endif 785#endif
786 post("[A 64-bit float] not implemented"); 786 post("[A 64-bit float] not implemented");
787 787
788 p += 8; 788 p += 8;
789 break; 789 break;
790 790
791 case 's': case 'S': 791 case 's': case 'S':
792 if (!IsNiceString(p, typeTags+n)) { 792 if (!IsNiceString(p, typeTags+n)) {
793 post("Type tag said this arg is a string but it's not!\n"); 793 post("Type tag said this arg is a string but it's not!\n");
794 return; 794 return;
795 } else { 795 } else {
796#ifdef DEBUG 796#ifdef DEBUG
797 post("string: \"%s\"", p); 797 post("string: \"%s\"", p);
798#endif 798#endif
799 SETSYMBOL(mya+myargc,gensym(p)); 799 SETSYMBOL(mya+myargc,gensym(p));
800 myargc++; 800 myargc++;
801 //outlet_list(x->x_msgout, 0,sizeof(p), p); 801 //outlet_list(x->x_msgout, 0,sizeof(p), p);
802 //outlet_anything(x->x_msgout, 0, sizeof(p), p); 802 //outlet_anything(x->x_msgout, 0, sizeof(p), p);
803 p = DataAfterAlignedString(p, typeTags+n); 803 p = DataAfterAlignedString(p, typeTags+n);
804 // append to output vector .. 804 // append to output vector ..
805 } 805 }
806 break; 806 break;
807 807
808 case 'T': 808 case 'T':
809#ifdef DEBUG 809#ifdef DEBUG
810 printf("[True] "); 810 printf("[True] ");
811#endif 811#endif
812 SETFLOAT(mya+myargc,1.); 812 SETFLOAT(mya+myargc,1.);
813 myargc++; 813 myargc++;
814 break; 814 break;
815 case 'F': 815 case 'F':
816#ifdef DEBUG 816#ifdef DEBUG
817 printf("[False] "); 817 printf("[False] ");
818#endif 818#endif
819 SETFLOAT(mya+myargc,0.); 819 SETFLOAT(mya+myargc,0.);
820 myargc++; 820 myargc++;
821 break; 821 break;
822 case 'N': 822 case 'N':
823#ifdef DEBUG 823#ifdef DEBUG
824 printf("[Nil]"); 824 printf("[Nil]");
825#endif 825#endif
826 post("sendOSC: [Nil] not implemented"); 826 post("sendOSC: [Nil] not implemented");
827 break; 827 break;
828 case 'I': 828 case 'I':
829#ifdef DEBUG 829#ifdef DEBUG
830 printf("[Infinitum]"); 830 printf("[Infinitum]");
831#endif 831#endif
832 post("sendOSC: [Infinitum] not implemented"); 832 post("sendOSC: [Infinitum] not implemented");
833 break; 833 break;
834 834
835 default: 835 default:
836 post("sendOSC: [Unrecognized type tag %c]", *thisType); 836 post("sendOSC: [Unrecognized type tag %c]", *thisType);
837 // return; 837 // return;
838 } 838 }
839 } 839 }
840 x->x_outatc = myargc; 840 x->x_outatc = myargc;
841} 841}
842 842
843static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma) { 843static void dumpOSC_PrintHeuristicallyTypeGuessedArgs(t_dumpOSC *x, void *v, int n, int skipComma) {
844 int i, thisi; 844 int i, thisi;
845 float thisf; 845 float thisf;
846 int *ints; 846 int *ints;
847 char *chars; 847 char *chars;
848 char *string, *nextString; 848 char *string, *nextString;
849 849
850 int myargc= x->x_outatc; 850 int myargc= x->x_outatc;
851 t_atom* mya = x->x_outat; 851 t_atom* mya = x->x_outat;
852 int myi; 852 int myi;
853 853
854 854
855 /* Go through the arguments 32 bits at a time */ 855 /* Go through the arguments 32 bits at a time */
856 ints = v; 856 ints = v;
857 chars = v; 857 chars = v;
858 858
859 for (i = 0; i<n/4; ) { 859 for (i = 0; i<n/4; ) {
860 string = &chars[i*4]; 860 string = &chars[i*4];
861 thisi = ntohl(ints[i]); 861 thisi = ntohl(ints[i]);
862 /* Reinterpret the (potentially byte-reversed) thisi as a float */ 862 /* Reinterpret the (potentially byte-reversed) thisi as a float */
863 thisf = *(((float *) (&thisi))); 863 thisf = *(((float *) (&thisi)));
864 864
865 if (thisi >= -1000 && thisi <= 1000000) { 865 if (thisi >= -1000 && thisi <= 1000000) {
866#ifdef DEBUG 866#ifdef DEBUG
867 printf("%d ", thisi); 867 printf("%d ", thisi);
868#endif 868#endif
869 // append to output vector .. 869 // append to output vector ..
870 SETFLOAT(mya+myargc,(t_float) (thisi)); 870 SETFLOAT(mya+myargc,(t_float) (thisi));
871 myargc++; 871 myargc++;
872 // outlet_float(x->x_msgout, thisi); 872 // outlet_float(x->x_msgout, thisi);
873 i++; 873 i++;
874 } else if (thisf >= -1000.f && thisf <= 1000000.f && 874 } else if (thisf >= -1000.f && thisf <= 1000000.f &&
875 (thisf <=0.0f || thisf >= SMALLEST_POSITIVE_FLOAT)) { 875 (thisf <=0.0f || thisf >= SMALLEST_POSITIVE_FLOAT)) {
876#ifdef DEBUG 876#ifdef DEBUG
877 printf("%f ", thisf); 877 printf("%f ", thisf);
878#endif 878#endif
879 // append to output vector .. 879 // append to output vector ..
880 SETFLOAT(mya+myargc,thisf); 880 SETFLOAT(mya+myargc,thisf);
881 myargc++; 881 myargc++;
882 //outlet_float(x->x_msgout, thisf); 882 //outlet_float(x->x_msgout, thisf);
883 i++; 883 i++;
884 } else if (IsNiceString(string, chars+n)) { 884 } else if (IsNiceString(string, chars+n)) {
885 nextString = DataAfterAlignedString(string, chars+n); 885 nextString = DataAfterAlignedString(string, chars+n);
886#ifdef DEBUG 886#ifdef DEBUG
887 printf("\"%s\" ", (i == 0 && skipComma) ? string +1 : string); 887 printf("\"%s\" ", (i == 0 && skipComma) ? string +1 : string);
888#endif 888#endif
889 // append to output vector .. 889 // append to output vector ..
890 SETSYMBOL(mya+myargc,gensym(string)); 890 SETSYMBOL(mya+myargc,gensym(string));
891 myargc++; 891 myargc++;
892 //outlet_symbol(x->x_msgout, gensym((i == 0 && skipComma) ? string +1 : string)); 892 //outlet_symbol(x->x_msgout, gensym((i == 0 && skipComma) ? string +1 : string));
893 i += (nextString-string) / 4; 893 i += (nextString-string) / 4;
894 } else { 894 } else {
895 // unhandled .. ;) 895 // unhandled .. ;)
896#ifdef DEBUG 896#ifdef DEBUG
897 printf("0x%x xx", ints[i]); 897 printf("0x%x xx", ints[i]);
898#endif 898#endif
899 i++; 899 i++;
900 } 900 }
901 x->x_outatc = myargc; 901 x->x_outatc = myargc;
902 } 902 }
903} 903}
904 904
905 905
906#define STRING_ALIGN_PAD 4 906#define STRING_ALIGN_PAD 4
907 907
908char *DataAfterAlignedString(char *string, char *boundary) 908char *DataAfterAlignedString(char *string, char *boundary)
909{ 909{
910 /* The argument is a block of data beginning with a string. The 910 /* The argument is a block of data beginning with a string. The
911 string has (presumably) been padded with extra null characters 911 string has (presumably) been padded with extra null characters
912 so that the overall length is a multiple of STRING_ALIGN_PAD 912 so that the overall length is a multiple of STRING_ALIGN_PAD
913 bytes. Return a pointer to the next byte after the null 913 bytes. Return a pointer to the next byte after the null
914 byte(s). The boundary argument points to the character after 914 byte(s). The boundary argument points to the character after
915 the last valid character in the buffer---if the string hasn't 915 the last valid character in the buffer---if the string hasn't
916 ended by there, something's wrong. 916 ended by there, something's wrong.
917 917
918 If the data looks wrong, return 0, and set htm_error_string */ 918 If the data looks wrong, return 0, and set htm_error_string */
919 919
920 int i; 920 int i;
921 921
922 if ((boundary - string) %4 != 0) { 922 if ((boundary - string) %4 != 0) {
923 fprintf(stderr, "Internal error: DataAfterAlignedString: bad boundary\n"); 923 fprintf(stderr, "Internal error: DataAfterAlignedString: bad boundary\n");
924 return 0; 924 return 0;
925 } 925 }
926 926
927 for (i = 0; string[i] != '\0'; i++) { 927 for (i = 0; string[i] != '\0'; i++) {
928 if (string + i >= boundary) { 928 if (string + i >= boundary) {
929 htm_error_string = "DataAfterAlignedString: Unreasonably long string"; 929 htm_error_string = "DataAfterAlignedString: Unreasonably long string";
930 return 0; 930 return 0;
931 } 931 }
932 } 932 }
933 933
934 /* Now string[i] is the first null character */ 934 /* Now string[i] is the first null character */
935 i++; 935 i++;
936 936
937 for (; (i % STRING_ALIGN_PAD) != 0; i++) { 937 for (; (i % STRING_ALIGN_PAD) != 0; i++) {
938 if (string + i >= boundary) { 938 if (string + i >= boundary) {
939 htm_error_string = "DataAfterAlignedString: Unreasonably long string"; 939 htm_error_string = "DataAfterAlignedString: Unreasonably long string";
940 return 0; 940 return 0;
941 } 941 }
942 if (string[i] != '\0') { 942 if (string[i] != '\0') {
943 htm_error_string = "DataAfterAlignedString: Incorrectly padded string."; 943 htm_error_string = "DataAfterAlignedString: Incorrectly padded string.";
944 return 0; 944 return 0;
945 } 945 }
946 } 946 }
947 947
948 return string+i; 948 return string+i;
949} 949}
950 950
951Boolean IsNiceString(char *string, char *boundary) 951Boolean IsNiceString(char *string, char *boundary)
952{ 952{
953 /* Arguments same as DataAfterAlignedString(). Is the given "string" 953 /* Arguments same as DataAfterAlignedString(). Is the given "string"
954 really a string? I.e., is it a sequence of isprint() characters 954 really a string? I.e., is it a sequence of isprint() characters
955 terminated with 1-4 null characters to align on a 4-byte boundary? */ 955 terminated with 1-4 null characters to align on a 4-byte boundary? */
956 956
957 int i; 957 int i;
958 958
959 if ((boundary - string) %4 != 0) { 959 if ((boundary - string) %4 != 0) {
960 fprintf(stderr, "Internal error: IsNiceString: bad boundary\n"); 960 fprintf(stderr, "Internal error: IsNiceString: bad boundary\n");
961 return 0; 961 return 0;
962 } 962 }
963 963
964 for (i = 0; string[i] != '\0'; i++) { 964 for (i = 0; string[i] != '\0'; i++) {
965 if (!isprint(string[i])) return FALSE; 965 if (!isprint(string[i])) return FALSE;
966 if (string + i >= boundary) return FALSE; 966 if (string + i >= boundary) return FALSE;
967 } 967 }
968 968
969 /* If we made it this far, it's a null-terminated sequence of printing characters 969 /* If we made it this far, it's a null-terminated sequence of printing characters
970 in the given boundary. Now we just make sure it's null padded... */ 970 in the given boundary. Now we just make sure it's null padded... */
971 971
972 /* Now string[i] is the first null character */ 972 /* Now string[i] is the first null character */
973 i++; 973 i++;
974 for (; (i % STRING_ALIGN_PAD) != 0; i++) { 974 for (; (i % STRING_ALIGN_PAD) != 0; i++) {
975 if (string[i] != '\0') return FALSE; 975 if (string[i] != '\0') return FALSE;
976 } 976 }
977 977
978 return TRUE; 978 return TRUE;
979} 979}
980 980
981 981
982 982
983 983
984 984
985 985
986 986
987 987
988 988
989#include <stdarg.h> 989#include <stdarg.h>
990void complain(char *s, ...) { 990void complain(char *s, ...) {
991 va_list ap; 991 va_list ap;
992 va_start(ap, s); 992 va_start(ap, s);
993 fprintf(stderr, "*** ERROR: "); 993 fprintf(stderr, "*** ERROR: ");
994 vfprintf(stderr, s, ap); 994 vfprintf(stderr, s, ap);
995 fprintf(stderr, "\n"); 995 fprintf(stderr, "\n");
996 va_end(ap); 996 va_end(ap);
997} 997}
998 998
999#endif /* __sgi or LINUX or WIN32 */ 999#endif /* __sgi or LINUX or WIN32 */
1000 1000