1ZOSC(3) CZMQ Manual ZOSC(3)
2
3
4
6 zosc - Class for work with Open Sound Control messages
7
9 // This is a draft class, and may change without notice. It is disabled in
10 // stable builds by default. If you use this in applications, please ask
11 // for it to be pushed to stable state. Use --enable-drafts to enable.
12 #ifdef CZMQ_BUILD_DRAFT_API
13 // *** Draft method, for development use, may change without warning ***
14 // Create a new empty OSC message with the specified address string.
15 CZMQ_EXPORT zosc_t *
16 zosc_new (const char *address);
17
18 // *** Draft method, for development use, may change without warning ***
19 // Create a new OSC message from the specified zframe. Takes ownership of
20 // the zframe.
21 CZMQ_EXPORT zosc_t *
22 zosc_fromframe (zframe_t *frame);
23
24 // *** Draft method, for development use, may change without warning ***
25 // Create a new zosc message from memory. Take ownership of the memory
26 // and calling free on the data after construction.
27 CZMQ_EXPORT zosc_t *
28 zosc_frommem (char *data, size_t size);
29
30 // *** Draft method, for development use, may change without warning ***
31 // Create a new zosc message from the given format and arguments.
32 // The format type tags are as follows:
33 // i - 32bit integer
34 // h - 64bit integer
35 // f - 32bit floating point number (IEEE)
36 // d - 64bit (double) floating point number
37 // s - string (NULL terminated)
38 // t = timetag: an OSC timetag in NTP format (uint64_t)
39 // S - symbol
40 // c - char
41 // m - 4 byte midi packet (8 digits hexadecimal)
42 // T - TRUE (no value required)
43 // F - FALSE (no value required)
44 // N - NIL (no value required)
45 // I - Impulse (for triggers) or INFINITUM (no value required)
46 // b - binary blob
47 CZMQ_EXPORT zosc_t *
48 zosc_create (const char *address, const char *format, ...);
49
50 // *** Draft method, for development use, may change without warning ***
51 // Destroy an OSC message
52 CZMQ_EXPORT void
53 zosc_destroy (zosc_t **self_p);
54
55 // *** Draft method, for development use, may change without warning ***
56 // Return chunk data size
57 CZMQ_EXPORT size_t
58 zosc_size (zosc_t *self);
59
60 // *** Draft method, for development use, may change without warning ***
61 // Return OSC chunk data. Caller does not own the data!
62 CZMQ_EXPORT byte *
63 zosc_data (zosc_t *self);
64
65 // *** Draft method, for development use, may change without warning ***
66 // Return the OSC address string
67 CZMQ_EXPORT const char *
68 zosc_address (zosc_t *self);
69
70 // *** Draft method, for development use, may change without warning ***
71 // Return the OSC format of the message.
72 // i - 32bit integer
73 // h - 64bit integer
74 // f - 32bit floating point number (IEEE)
75 // d - 64bit (double) floating point number
76 // s - string (NULL terminated)
77 // t = timetag: an OSC timetag in NTP format (uint64_t)
78 // S - symbol
79 // c - char
80 // m - 4 byte midi packet (8 digits hexadecimal)
81 // T - TRUE (no value required)
82 // F - FALSE (no value required)
83 // N - NIL (no value required)
84 // I - Impulse (for triggers) or INFINITUM (no value required)
85 // b - binary blob
86 CZMQ_EXPORT const char *
87 zosc_format (zosc_t *self);
88
89 // *** Draft method, for development use, may change without warning ***
90 // Append data to the osc message. The format describes the data that
91 // needs to be appended in the message. This essentially relocates all
92 // data!
93 // The format type tags are as follows:
94 // i - 32bit integer
95 // h - 64bit integer
96 // f - 32bit floating point number (IEEE)
97 // d - 64bit (double) floating point number
98 // s - string (NULL terminated)
99 // t = timetag: an OSC timetag in NTP format (uint64_t)
100 // S - symbol
101 // c - char
102 // m - 4 byte midi packet (8 digits hexadecimal)
103 // T - TRUE (no value required)
104 // F - FALSE (no value required)
105 // N - NIL (no value required)
106 // I - Impulse (for triggers) or INFINITUM (no value required)
107 // b - binary blob
108 CZMQ_EXPORT int
109 zosc_append (zosc_t *self, const char *format, ...);
110
111 // *** Draft method, for development use, may change without warning ***
112 // Retrieve the values provided by the given format. Note that zosc_retr
113 // creates the objects and the caller must destroy them when finished.
114 // The supplied pointers do not need to be initialized. Returns 0 if
115 // successful, or -1 if it failed to retrieve a value in which case the
116 // pointers are not modified. If an argument pointer is NULL is skips the
117 // value. See the format method for a detailed list op type tags for the
118 // format string.
119 CZMQ_EXPORT int
120 zosc_retr (zosc_t *self, const char *format, ...);
121
122 // *** Draft method, for development use, may change without warning ***
123 // Create copy of the message, as new chunk object. Returns a fresh zosc_t
124 // object, or null if there was not enough heap memory. If chunk is null,
125 // returns null.
126 // Caller owns return value and must destroy it when done.
127 CZMQ_EXPORT zosc_t *
128 zosc_dup (zosc_t *self);
129
130 // *** Draft method, for development use, may change without warning ***
131 // Transform zosc into a zframe that can be sent in a message.
132 // Caller owns return value and must destroy it when done.
133 CZMQ_EXPORT zframe_t *
134 zosc_pack (zosc_t *self);
135
136 // *** Draft method, for development use, may change without warning ***
137 // Transform zosc into a zframe that can be sent in a message.
138 // Take ownership of the chunk.
139 // Caller owns return value and must destroy it when done.
140 CZMQ_EXPORT zframe_t *
141 zosc_packx (zosc_t **self_p);
142
143 // *** Draft method, for development use, may change without warning ***
144 // Transform a zframe into a zosc.
145 // Caller owns return value and must destroy it when done.
146 CZMQ_EXPORT zosc_t *
147 zosc_unpack (zframe_t *frame);
148
149 // *** Draft method, for development use, may change without warning ***
150 // Dump OSC message to stdout, for debugging and tracing.
151 CZMQ_EXPORT void
152 zosc_print (zosc_t *self);
153
154 // *** Draft method, for development use, may change without warning ***
155 // Probe the supplied object, and report if it looks like a zosc_t.
156 CZMQ_EXPORT bool
157 zosc_is (void *self);
158
159 // *** Draft method, for development use, may change without warning ***
160 // Return a pointer to the item at the head of the OSC data.
161 // Sets the given char argument to the type tag of the data.
162 // If the message is empty, returns NULL and the sets the
163 // given char to NULL.
164 CZMQ_EXPORT const void *
165 zosc_first (zosc_t *self, char *type);
166
167 // *** Draft method, for development use, may change without warning ***
168 // Return the next item of the OSC message. If the list is empty, returns
169 // NULL. To move to the start of the OSC message call zosc_first ().
170 CZMQ_EXPORT const void *
171 zosc_next (zosc_t *self, char *type);
172
173 // *** Draft method, for development use, may change without warning ***
174 // Return a pointer to the item at the tail of the OSC message.
175 // Sets the given char argument to the type tag of the data. If
176 // the message is empty, returns NULL.
177 CZMQ_EXPORT const void *
178 zosc_last (zosc_t *self, char *type);
179
180 // *** Draft method, for development use, may change without warning ***
181 // Set the provided 32 bit integer from value at the current cursor position in the message.
182 // If the type tag at the current position does not correspond it will fail and
183 // return -1. Returns 0 on success.
184 CZMQ_EXPORT int
185 zosc_pop_int32 (zosc_t *self, int *val);
186
187 // *** Draft method, for development use, may change without warning ***
188 // Set the provided 64 bit integer from the value at the current cursor position in the message.
189 // If the type tag at the current position does not correspond it will fail and
190 // return -1. Returns 0 on success.
191 CZMQ_EXPORT int
192 zosc_pop_int64 (zosc_t *self, int64_t *val);
193
194 // *** Draft method, for development use, may change without warning ***
195 // Set the provided float from the value at the current cursor position in the message.
196 // If the type tag at the current position does not correspond it will fail and
197 // return -1. Returns 0 on success.
198 CZMQ_EXPORT int
199 zosc_pop_float (zosc_t *self, float *val);
200
201 // *** Draft method, for development use, may change without warning ***
202 // Set the provided double from the value at the current cursor position in the message.
203 // If the type tag at the current position does not correspond it will fail and
204 // return -1. Returns 0 on success.
205 CZMQ_EXPORT int
206 zosc_pop_double (zosc_t *self, double *val);
207
208 // *** Draft method, for development use, may change without warning ***
209 // Set the provided string from the value at the current cursor position in the message.
210 // If the type tag at the current position does not correspond it will fail and
211 // return -1. Returns 0 on success. Caller owns the string!
212 CZMQ_EXPORT int
213 zosc_pop_string (zosc_t *self, char **val);
214
215 // *** Draft method, for development use, may change without warning ***
216 // Set the provided char from the value at the current cursor position in the message.
217 // If the type tag at the current position does not correspond it will fail and
218 // return -1. Returns 0 on success.
219 CZMQ_EXPORT int
220 zosc_pop_char (zosc_t *self, char *val);
221
222 // *** Draft method, for development use, may change without warning ***
223 // Set the provided boolean from the type tag in the message. Booleans are not represented
224 // in the data in the message, only in the type tag. If the type tag at the current
225 // position does not correspond it will fail and return -1. Returns 0 on success.
226 CZMQ_EXPORT int
227 zosc_pop_bool (zosc_t *self, bool *val);
228
229 // *** Draft method, for development use, may change without warning ***
230 // Set the provided 4 bytes (unsigned 32bit int) from the value at the current
231 // cursor position in the message. If the type tag at the current position does
232 // not correspond it will fail and return -1. Returns 0 on success.
233 CZMQ_EXPORT int
234 zosc_pop_midi (zosc_t *self, uint32_t *val);
235
236 // *** Draft method, for development use, may change without warning ***
237 // Self test of this class.
238 CZMQ_EXPORT void
239 zosc_test (bool verbose);
240
241 #endif // CZMQ_BUILD_DRAFT_API
242 Please add '@interface' section in './../src/zosc.c'.
243
245 zosc - work with Open Sound Control messages
246
247 Please add @discuss section in ./../src/zosc.c.
248
250 From zosc_test method.
251
252 // we need to have packets on the heap
253 char *p1 = (char *)malloc(40);
254 memcpy(p1, oscpacket, 40);
255 zosc_t *self = zosc_frommem(p1, 40);
256 assert (self);
257 assert ( zosc_is( self ));
258 assert(streq ( zosc_address(self), "/sample/address"));
259 assert(streq ( zosc_format(self), "iTfs"));
260 // check value
261 uint32_t test = 0;
262 bool b = false;
263 float f = 0.f;
264 char *s = "BLA";
265 zosc_retr(self, "iTfs", &test, &b, &f, &s);
266 assert(test == 1);
267 assert(b);
268 assert(fabsf(f - 3.14f) < FLT_EPSILON); // float equal
269 assert(streq(s, "hello"));
270 zstr_free(&s);
271
272 zosc_destroy (&self);
273
274 zframe_t *frame = zframe_new(oscpacket, 40);
275 assert(frame);
276 assert(zframe_size(frame) == 40);
277 zosc_t *fosc = zosc_fromframe(frame);
278 assert (fosc);
279 assert(streq ( zosc_address(fosc), "/sample/address"));
280 assert(streq ( zosc_format(fosc), "iTfs"));
281 // test skipping retrieving values
282 zosc_retr(fosc, "iTfs", NULL, NULL, NULL, NULL);
283 char *fstr = "";
284 zosc_retr(fosc, "iTfs", NULL, NULL, NULL, &fstr);
285 assert( streq(fstr, "hello") );
286 zstr_free(&fstr);
287 zosc_destroy (&fosc);
288
289 // to the heap, otherwise we can't destroy
290 char *p2 = (char *)malloc(48);
291 memcpy(p2, testpack, 48);
292 zosc_t *testmsg = zosc_frommem(p2, 48);
293 assert( testmsg );
294 assert(streq ( zosc_address(testmsg), "/test"));
295 assert(streq ( zosc_format(testmsg), "ihTfds" ) );
296 // test duplicate
297 zosc_t *testmsgdup = zosc_dup(NULL);
298 assert( testmsgdup == NULL );
299 testmsgdup = zosc_dup(testmsg);
300 assert( testmsgdup );
301 assert(streq ( zosc_address(testmsgdup), "/test"));
302 assert(streq ( zosc_format(testmsgdup), "ihTfds" ) );
303 zosc_destroy(&testmsgdup);
304 // check value
305 int itest = -1;
306 int64_t ltest = -1;
307 bool btest = false;
308 float ftest = -1.f;
309 double dtest = -1.;
310 char *stest;
311 const char *format = zosc_format(testmsg);
312 zosc_retr(testmsg, format, &itest, <est, &btest, &ftest, &dtest, &stest);
313 assert( itest == 2 );
314 assert( ltest == 1844674407370 );
315 assert( btest );
316 assert( fabsf(ftest - 3.14f) < FLT_EPSILON ); // float equal
317 assert( fabs(dtest - 3.1415926535897932) < DBL_EPSILON );
318 assert( streq(stest, "hello") );
319 zstr_free(&stest);
320 zosc_destroy(&testmsg);
321
322 // test constructing messages
323 int64_t prez = 3;
324 zosc_t* conm = zosc_create("/construct", "iihfdscF", -2,2, prez, 3.14,6.283185307179586, "greetings", 'q');
325 assert(conm);
326 assert(streq(zosc_address(conm), "/construct"));
327 assert(streq(zosc_format(conm), "iihfdscF"));
328 if (verbose) zosc_print(conm);
329 int x,y;
330 int64_t z;
331 float zz;
332 double zzz;
333 char *ss = "aliens";
334 char q = 'z';
335 bool Ftest = true;
336 zosc_retr(conm, "iihfdscF", &x, &y, &z, &zz, &zzz, &ss, &q, &Ftest);
337 assert( x==-2 );
338 assert( y==2 );
339 assert( z==3 );
340 assert( fabsf(zz-3.14f) < FLT_EPSILON );
341 assert( fabs(zzz-6.283185307179586) < DBL_EPSILON );
342 assert( streq( ss, "greetings") );
343 assert( q == 'q');
344 assert( !Ftest );
345 zstr_free(&ss);
346
347 // test iterating
348 char type = '0';
349 const void *data = zosc_first(conm, &type);
350 while ( data )
351 {
352 if (verbose)
353 zsys_info("type tag is %c", type);
354
355 switch (type)
356 {
357 case('i'):
358 {
359 int32_t test = 9;
360 int rc = zosc_pop_int32(conm, &test);
361 assert(rc == 0);
362 assert( test == -2 || test == 2);
363 break;
364 }
365 case('h'):
366 {
367 int32_t fail = 9;
368 int rc = zosc_pop_int32(conm, &fail); // this will fail
369 assert(rc == -1);
370 int64_t test = 9;
371 rc = zosc_pop_int64(conm, &test);
372 assert(rc == 0);
373 assert( test == 3 );
374 break;
375 }
376 case('f'):
377 {
378 float flt_v = 0.f;
379 int rc = zosc_pop_float(conm, &flt_v);
380 assert(rc == 0);
381 assert( fabsf(flt_v-3.14f) < FLT_EPSILON );
382 break;
383 }
384 case 'd':
385 {
386 double dbl_v = 0.;
387 int rc = zosc_pop_double(conm, &dbl_v);
388 assert(rc == 0);
389 assert( fabs(dbl_v-6.283185307179586) < DBL_EPSILON );
390 break;
391 }
392 case 's':
393 {
394 char *str;
395 int rc = zosc_pop_string(conm, &str);
396 assert(rc == 0);
397 assert(streq(str, "greetings"));
398 zstr_free(&str);
399 break;
400 }
401 case 'c':
402 {
403 char chr;
404 int rc = zosc_pop_char(conm, &chr);
405 assert(rc == 0);
406 assert(chr == 'q');
407 break;
408 }
409 case 'F':
410 {
411 bool bl;
412 int rc = zosc_pop_bool(conm, &bl);
413 assert(rc == 0);
414 assert( !bl );
415 break;
416 }
417 default:
418 assert(0);
419 }
420 data = zosc_next(conm, &type);
421 }
422
423 // test append
424 int64_t preal = -80000;
425 zosc_append(conm, "ih", -200, preal);
426 int ax,ay;
427 int64_t az;
428 float azz;
429 double azzz;
430 char *ass = "aliens";
431 char aq = 'z';
432 bool aFtest = true;
433 int ai = 0;
434 int64_t al = 0;
435 zosc_retr(conm, "iihfdscFih", &ax, &ay, &az, &azz, &azzz, &ass, &aq, &aFtest, &ai, &al);
436 assert( ax==-2 );
437 assert( ay==2 );
438 assert( az==3 );
439 assert( fabsf(azz-3.14f) < FLT_EPSILON );
440 assert( fabs(azzz-6.283185307179586) < DBL_EPSILON );
441 assert( streq( ass, "greetings") );
442 assert( aq == 'q');
443 assert( !aFtest );
444 assert( ai==-200 );
445 assert( al==-80000 );
446 zstr_free(&ass);
447
448
449 #ifdef ZMQ_DGRAM
450 zsock_t *dgrams = zsock_new_dgram("udp://*:*");
451 assert (dgrams);
452 zframe_t *t = zosc_pack(conm);
453 zstr_sendm( dgrams, "127.0.0.1:7777" );
454 zframe_send( &t, dgrams, 0);
455 zclock_sleep(10); // slow down, otherwise we've cleaned up before async send
456 zsock_destroy( &dgrams );
457 #else
458 int sockfd;
459 struct sockaddr_in servaddr;
460
461 // Creating socket file descriptor
462 if ( (sockfd = (int)socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
463 zsys_error("socket creation failed");
464 }
465
466 memset(&servaddr, 0, sizeof(servaddr));
467 // Filling server information
468 servaddr.sin_family = AF_INET;
469 servaddr.sin_port = htons(7777);
470 servaddr.sin_addr.s_addr = INADDR_ANY;
471 #ifdef __WINDOWS__
472 sendto(sockfd, (const char *)zosc_data(conm), (int)zosc_size(conm),
473 0, (const struct sockaddr *) &servaddr,
474 sizeof(servaddr));
475 #else
476 sendto(sockfd, zosc_data(conm), zosc_size(conm),
477 0, (const struct sockaddr *) &servaddr,
478 sizeof(servaddr));
479 #endif
480 #endif
481 zosc_destroy(&conm);
482 #ifdef __WINDOWS__
483 zsys_shutdown();
484 #endif
485
486
488 The czmq manual was written by the authors in the AUTHORS file.
489
491 Main web site:
492
493 Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
494
496 Copyright (c) the Contributors as noted in the AUTHORS file. This file
497 is part of CZMQ, the high-level C binding for 0MQ:
498 http://czmq.zeromq.org. This Source Code Form is subject to the terms
499 of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
500 distributed with this file, You can obtain one at
501 http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
502 distribution.
503
505 1. zeromq-dev@lists.zeromq.org
506 mailto:zeromq-dev@lists.zeromq.org
507
508
509
510CZMQ 4.2.1 07/19/2023 ZOSC(3)