static void sendOSC_closebundle(t_sendOSC *x) { if (OSC_closeBundle(x->x_oscbuf)) { error("Problem closing bundle: %s\n", OSC_errorMessage); return; } outlet_float(x->x_bdpthout, (float)x->x_oscbuf->bundleDepth); // in bundle mode we send when bundle is closed? if(!OSC_isBufferEmpty(x->x_oscbuf) > 0 && OSC_isBufferDone(x->x_oscbuf)) { // post("x_oscbuf: something inside me?"); if (x->x_htmsocket) { SendBuffer(x->x_htmsocket, x->x_oscbuf); } else { post("sendOSC: not connected"); } OSC_initBuffer(x->x_oscbuf, SC_BUFFER_SIZE, bufferForOSCbuf); x->x_bundle = 0; return; } // post("x_oscbuf: something went wrong"); }
void InteractiveMode(void *htmsocket) { char mesg[MAXMESG]; OSCbuf buf[1]; int bundleDepth = 0; /* At first, we haven't seen "[". */ OSC_initBuffer(buf, SC_BUFFER_SIZE, bufferForOSCbuf); while (fgets(mesg, MAXMESG, stdin) != NULL) { if (mesg[0] == '\n') { if (bundleDepth > 0) { /* Ignore blank lines inside a group. */ } else { /* blank line => repeat previous send */ SendBuffer(htmsocket, buf); } continue; } if (bundleDepth == 0) { OSC_resetBuffer(buf); } if (mesg[0] == '[') { OSCTimeTag tt = ParseTimeTag(mesg+1); if (OSC_openBundle(buf, tt)) { complain("Problem opening bundle: %s\n", OSC_errorMessage); OSC_resetBuffer(buf); bundleDepth = 0; continue; } bundleDepth++; } else if (mesg[0] == ']' && mesg[1] == '\n' && mesg[2] == '\0') { if (bundleDepth == 0) { complain("Unexpected ']': not currently in a bundle.\n"); } else { if (OSC_closeBundle(buf)) { complain("Problem closing bundle: %s\n", OSC_errorMessage); OSC_resetBuffer(buf); bundleDepth = 0; continue; } bundleDepth--; if (bundleDepth == 0) { SendBuffer(htmsocket, buf); } } } else { ParseInteractiveLine(buf, mesg); if (bundleDepth != 0) { /* Don't send anything until we close all bundles */ } else { SendBuffer(htmsocket, buf); } } } }
static void packOSC_openbundle(t_packOSC *x) { int result; if (x->x_timeTagOffset == -1) result = OSC_openBundle(x->x_oscbuf, OSCTT_Immediately()); else result = OSC_openBundle(x->x_oscbuf, OSCTT_CurrentTimePlusOffset((uint4)x->x_timeTagOffset)); if (result != 0) { /* reset the buffer */ OSC_initBuffer(x->x_oscbuf, x->x_buflength, x->x_bufferForOSCbuf); x->x_bundle = 0; } else x->x_bundle = 1; outlet_float(x->x_bdpthout, (float)x->x_oscbuf->bundleDepth); }
static void packOSC_setbufsize(t_packOSC *x, t_floatarg f) { if (x->x_bufferForOSCbuf != NULL) freebytes((void *)x->x_bufferForOSCbuf, sizeof(char)*x->x_buflength); if (x->x_bufferForOSClist != NULL) freebytes((void *)x->x_bufferForOSClist, sizeof(t_atom)*x->x_buflength); post("packOSC: bufsize arg is %f (%lu)", f, (long)f); x->x_buflength = (long)f; x->x_bufferForOSCbuf = (char *)getbytes(sizeof(char)*x->x_buflength); if(x->x_bufferForOSCbuf == NULL) error("packOSC unable to allocate %lu bytes for x_bufferForOSCbuf", (long)(sizeof(char)*x->x_buflength)); x->x_bufferForOSClist = (t_atom *)getbytes(sizeof(t_atom)*x->x_buflength); if(x->x_bufferForOSClist == NULL) error("packOSC unable to allocate %lu bytes for x_bufferForOSClist", (long)(sizeof(t_atom)*x->x_buflength)); OSC_initBuffer(x->x_oscbuf, x->x_buflength, x->x_bufferForOSCbuf); post("packOSC: bufsize is now %d",x->x_buflength); }
static void *sendOSC_new(t_floatarg udpflag) { t_sendOSC *x = (t_sendOSC *)pd_new(sendOSC_class); outlet_new(&x->x_obj, &s_float); x->x_htmsocket = 0; // {{raf}} // set udp x->x_protocol = SOCK_DGRAM; ////MP20060308// not SOCK_STREAM but we don't use it anyway... // set typetags to 1 by default x->x_typetags = 1; // bundle is closed x->x_bundle = 0; OSC_initBuffer(x->x_oscbuf, SC_BUFFER_SIZE, bufferForOSCbuf); x->x_bdpthout = outlet_new(&x->x_obj, 0); // outlet_float(); //x->x_oscbuf = return (x); }
void CommandLineMode(int argc, char *argv[], void *htmsocket) { char *messageName; char *token; typedArg args[MAX_ARGS]; int i,j, numArgs; OSCbuf buf[1]; OSC_initBuffer(buf, SC_BUFFER_SIZE, bufferForOSCbuf); if (argc > 1) { if (OSC_openBundle(buf, OSCTT_Immediately())) { complain("Problem opening bundle: %s\n", OSC_errorMessage); return; } } for (i = 0; i < argc; i++) { messageName = strtok(argv[i], ","); if (messageName == NULL) { break; } j = 0; while ((token = strtok(NULL, ",")) != NULL) { args[j] = ParseToken(token); j++; if (j >= MAX_ARGS) { complain("Sorry; your message has more than MAX_ARGS (%d) arguments; ignoring the rest.\n", MAX_ARGS); break; } } numArgs = j; WriteMessage(buf, messageName, numArgs, args); } if (argc > 1) { if (OSC_closeBundle(buf)) { complain("Problem closing bundle: %s\n", OSC_errorMessage); return; } } SendBuffer(htmsocket, buf); }
static void packOSC_closebundle(t_packOSC *x) { if (OSC_closeBundle(x->x_oscbuf)) { error("packOSC: Problem closing bundle."); return; } outlet_float(x->x_bdpthout, (float)x->x_oscbuf->bundleDepth); /* in bundle mode we send when bundle is closed */ if(!OSC_isBufferEmpty(x->x_oscbuf) > 0 && OSC_isBufferDone(x->x_oscbuf)) { packOSC_sendbuffer(x); OSC_initBuffer(x->x_oscbuf, x->x_buflength, x->x_bufferForOSCbuf); x->x_bundle = 0; return; } }
static void *packOSC_new(void) { t_packOSC *x = (t_packOSC *)pd_new(packOSC_class); x->x_typetags = 1; /* set typetags to 1 by default */ x->x_bundle = 0; /* bundle is closed */ x->x_buflength = SC_BUFFER_SIZE; x->x_bufferForOSCbuf = (char *)getbytes(sizeof(char)*x->x_buflength); if(x->x_bufferForOSCbuf == NULL) error("packOSC: unable to allocate %lu bytes for x_bufferForOSCbuf", (long)(sizeof(char)*x->x_buflength)); x->x_bufferForOSClist = (t_atom *)getbytes(sizeof(t_atom)*x->x_buflength); if(x->x_bufferForOSClist == NULL) error("packOSC: unable to allocate %lu bytes for x_bufferForOSClist", (long)(sizeof(t_atom)*x->x_buflength)); if (x->x_oscbuf != NULL) OSC_initBuffer(x->x_oscbuf, x->x_buflength, x->x_bufferForOSCbuf); x->x_listout = outlet_new(&x->x_obj, &s_list); x->x_bdpthout = outlet_new(&x->x_obj, &s_float); x->x_timeTagOffset = -1; /* immediately */ return (x); }
static inline int Osc_BuildFloatMessage(OSCbuf *buf, const char *address, float value) { Uint32 size = Osc_StrPad32(strlen(address)) + 4 + sizeof(float); char *data; if (!(data = malloc(size))) return 1; OSC_initBuffer(buf, size, data); if (OSC_writeAddressAndTypes(buf, (char*)address, ",f") || OSC_writeFloatArg(buf, value)) { free(data); return 1; } return 0; }
static void sendOSC_sendtyped(t_sendOSC *x, t_symbol *s, int argc, t_atom *argv) { char messageName[MAXPDSTRING]; // char *token; typedArg args[MAX_ARGS]; int i; messageName[0] = '\0'; // empty if(argc>MAX_ARGS) { post ("sendOSC: too many arguments! (max: %d)", MAX_ARGS); return; } // this sock needs to be larger than 0, not >= .. if (x->x_htmsocket > 0) { #ifdef DEBUG post ("sendOSC: type tags? %d", useTypeTags); #endif atom_string(&argv[0], messageName, MAXPDSTRING); // messageName = strtok(targv[0], ","); for (i = 0; i < argc-1; i++) { // token = strtok(targv[i],","); args[i] = ParseAtom(&argv[i+1]); #ifdef DEBUG switch (args[i].type) { case INT_osc: printf("cell-cont: %d\n", args[i].datum.i); break; case FLOAT_osc: printf("cell-cont: %f\n", args[i].datum.f); break; case STRING_osc: printf("cell-cont: %s\n", args[i].datum.s); break; case NOTYPE_osc: printf("unknown type\n"); break; } printf(" type-id: %d\n", args[i].type); #endif } if(WriteMessage(x->x_oscbuf, messageName, i, args)) { post("sendOSC: usage error, write-msg failed: %s", OSC_errorMessage); return; } if(!x->x_bundle) { SendBuffer(x->x_htmsocket, x->x_oscbuf); OSC_initBuffer(x->x_oscbuf, SC_BUFFER_SIZE, bufferForOSCbuf); } } else post("sendOSC: not connected"); }
static void packOSC_sendtyped(t_packOSC *x, t_symbol *s, int argc, t_atom *argv) { char messageName[MAXPDSTRING]; unsigned int nTypeTags = 0, typeStrTotalSize = 0; unsigned int argsSize = sizeof(typedArg)*argc; char* typeStr = NULL; /* might not be used */ typedArg* args = (typedArg*)getbytes(argsSize); unsigned int i, nTagsWithData, nArgs, blobCount; unsigned int m, j, k; char c; if (args == NULL) { error("packOSC: unable to allocate %lu bytes for args", (long)argsSize); return; } messageName[0] = '\0'; /* empty */ if(x->x_prefix) /* if there is a prefix, prefix it to the path */ { size_t len = strlen(x->x_prefix); if(len >= MAXPDSTRING) len = MAXPDSTRING-1; strncpy(messageName, x->x_prefix, MAXPDSTRING); atom_string(&argv[0], messageName+len, (unsigned)(MAXPDSTRING-len)); } else atom_string(&argv[0], messageName, MAXPDSTRING); /* the OSC address string */ if (x->x_typetags & 2) { /* second arg is typestring */ /* we need to find out how long the type string is before we copy it*/ nTypeTags = (unsigned int)strlen(atom_getsymbol(&argv[1])->s_name); typeStrTotalSize = nTypeTags + 2; typeStr = (char*)getzbytes(typeStrTotalSize); if (typeStr == NULL) { error("packOSC: unable to allocate %u bytes for typeStr", nTypeTags); return; } typeStr[0] = ','; atom_string(&argv[1], &typeStr[1], typeStrTotalSize); #ifdef DEBUG post("typeStr: %s, nTypeTags %lu", typeStr, nTypeTags); #endif nArgs = argc-2; for (m = nTagsWithData = blobCount = 0; m < nTypeTags; ++m) { #ifdef DEBUG post("typeStr[%d] %c", m+1, typeStr[m+1]); #endif if ((c = typeStr[m+1]) == 0) break; if (!(c == 'T' || c == 'F' || c == 'N' || c == 'I')) { ++nTagsWithData; /* anything other than these tags have at least one data byte */ /* OSC-blob An int32 size count, followed by that many 8-bit bytes of arbitrary binary data, followed by 0-3 additional zero bytes to make the total number of bits a multiple of 32. */ if (c == 'b') blobCount++; /* b probably has more than one byte, so set a flag */ } } if (((blobCount == 0)&&(nTagsWithData != nArgs)) || ((blobCount != 0)&&(nTagsWithData > nArgs))) { error("packOSC: Tags count %d doesn't match argument count %d", nTagsWithData, nArgs); goto cleanup; } if (blobCount > 1) { error("packOSC: Only one blob per packet at the moment..."); goto cleanup; } for (j = k = 0; j < m; ++j) /* m is the number of tags */ { c = typeStr[j+1]; if (c == 'b') { /* A blob has to be the last item, until we get more elaborate. */ if (j != m-1) { error("packOSC: Since I don't know how big the blob is, Blob must be the last item in the list"); goto cleanup; } /* Pack all the remaining arguments as a blob */ for (; k < nArgs; ++k) { args[k] = packOSC_blob(&argv[k+2]); } } else if (!(c == 'T' || c == 'F' || c == 'N' || c == 'I')) /* not no data */ { args[k] = packOSC_forceatom(&argv[k+2], c); ++k; } } if(packOSC_writetypedmessage(x, x->x_oscbuf, messageName, nArgs, args, typeStr)) { error("packOSC: usage error, write-msg failed."); goto cleanup; } } else { for (i = 0; i < (unsigned)(argc-1); i++) { args[i] = packOSC_parseatom(&argv[i+1]); #ifdef DEBUG switch (args[i].type) { case INT_osc: post("packOSC: cell-cont: %d\n", args[i].datum.i); break; case FLOAT_osc: post("packOSC: cell-cont: %f\n", args[i].datum.f); break; case STRING_osc: post("packOSC: cell-cont: %s\n", args[i].datum.s); break; case NOTYPE_osc: post("packOSC: unknown type\n"); break; } post("packOSC: type-id: %d\n", args[i].type); #endif } if(packOSC_writemessage(x, x->x_oscbuf, messageName, i, args)) { error("packOSC: usage error, write-msg failed."); goto cleanup; } } if(!x->x_bundle) { packOSC_sendbuffer(x); OSC_initBuffer(x->x_oscbuf, x->x_buflength, x->x_bufferForOSCbuf); } cleanup: if (typeStr != NULL) freebytes(typeStr, typeStrTotalSize); if (args != NULL) freebytes(args, argsSize); }
main() { OSCbuf myBuf; OSCbuf *b = &myBuf; char bytes[SIZE]; OSCTimeTag tt; printf("OSC_initBuffer\n"); OSC_initBuffer(b, SIZE, bytes); PrintBuf(b); printf("Testing one-message packet\n"); if (OSC_writeAddress(b, "/blah/bleh/singlemessage")) { printf("** ERROR: %s\n", OSC_errorMessage); } if (OSC_writeFloatArg(b, 1.23456f)) { printf("** ERROR: %s\n", OSC_errorMessage); } { float floatarray[10]; int i; for (i = 0; i < 10; ++i) { floatarray[i] = i * 10.0f; } if (OSC_writeFloatArgs(b, 10, floatarray)) { printf("** ERROR: %s\n", OSC_errorMessage); } } if (OSC_writeIntArg(b, 123456)) { printf("** ERROR: %s\n", OSC_errorMessage); } if (OSC_writeStringArg(b, "This is a cool string, dude.")) { printf("** ERROR: %s\n", OSC_errorMessage); } PrintBuf(b); PrintPacket(b); printf("Resetting\n"); OSC_resetBuffer(b); printf("Testing time tags\n"); tt = OSCTT_CurrentTime(); printf("Time now is %llx\n", tt); printf("Testing bundles\n"); if (OSC_openBundle(b, tt)) { printf("** ERROR: %s\n", OSC_errorMessage); } if (OSC_writeAddress(b, "/a/hello")) { printf("** ERROR: %s\n", OSC_errorMessage); } if (OSC_writeIntArg(b, 16)) { printf("** ERROR: %s\n", OSC_errorMessage); } if (OSC_writeIntArg(b, 32)) { printf("** ERROR: %s\n", OSC_errorMessage); } if (OSC_openBundle(b, OSCTT_PlusSeconds(tt, 1.0f))) { printf("** ERROR: %s\n", OSC_errorMessage); } if (OSC_writeAddress(b, "/b/hello")) { printf("** ERROR: %s\n", OSC_errorMessage); } if (OSC_writeAddress(b, "/c/hello")) { printf("** ERROR: %s\n", OSC_errorMessage); } OSC_closeAllBundles(b); PrintBuf(b); PrintPacket(b); }
int Osc_BuildMessage(OSCbuf *buf, const char *address, const char *types, ...) { va_list args; Uint32 size = Osc_StrPad32(strlen(address)) + Osc_StrPad32(strlen(types)); char *data = NULL; va_start(args, types); for (const char *p = types + 1; *p; p++) switch (*p) { case 'f': case 'i': va_arg(args, Uint32); size += sizeof(Uint32); break; case 's': size += Osc_StrPad32(strlen(va_arg(args, char*))); break; default: goto err; } va_end(args); va_start(args, types); if (!(data = malloc(size))) goto err; OSC_initBuffer(buf, size, data); if (OSC_writeAddressAndTypes(buf, (char*)address, (char*)types)) goto err; for (const char *p = types + 1; *p; p++) switch (*p) { case 'f': if (OSC_writeFloatArg(buf, va_arg(args, float))) goto err; break; case 'i': if (OSC_writeIntArg(buf, va_arg(args, int))) goto err; break; case 's': if (OSC_writeStringArg(buf, va_arg(args, char*))) goto err; break; } va_end(args); return 0; err: va_end(args); free(data); return 1; }