void lo_message_add_blob(lo_message m, lo_blob a) { const int size = lo_blobsize(a); const int32_t dsize = lo_htoo32(lo_blob_datasize(a)); char *nptr = lo_message_add_data(m, size); lo_message_add_typechar(m, LO_BLOB); memset(nptr + size - 4, 0, 4); memcpy(nptr, &dsize, sizeof(dsize)); memcpy(nptr + sizeof(int32_t), lo_blob_dataptr(a), lo_blob_datasize(a)); }
int ppm_handler(const char *path, const char *types, lo_arg ** argv, int argc, void *data, void *user_data) { printf("ppm_handler: path: <%s>\n", path); #ifdef __ANDROID__ __android_log_print(ANDROID_LOG_DEBUG, "osc.c", "path: <%s>\n", path); #endif int track_id = argv[0]->i; lo_blob blob = argv[1]; int size = lo_blob_datasize(blob); unsigned char *bdata = (unsigned char *) lo_blob_dataptr(blob); tracks[track_get_deck(track_id)].length = (unsigned int) argv[2]->i; //printf("track.length: %i\n", tracks[0].length); track_add_ppm_block(track_id, bdata, size); #ifdef __ANDROID__ __android_log_print(ANDROID_LOG_DEBUG, "osc.c", "arg %d '%c' [%d byte blob]\nlength:%d", 0, types[0], size, tracks[track_get_deck(track_id)].length); #endif //printf("\n"); //fflush(stdout); return 1; }
int LEDFrameHandler(const char *path, const char *types, lo_arg **argv, int argc, void *data, void *instancePointer) { MantaOSC::LEDState state; uint8_t rowdata[12]; try { state = getLEDStateFromString(&argv[0]->s); // a state of All means we should be sending two frames, or 12 bytes int framesize = (state == MantaOSC::All ? 12 : 6); /* SetPadLEDFrame doesn't know how long the frame is, so we've got to check here */ int n = lo_blob_datasize(argv[1]); uint8_t *msgdata = (uint8_t *)lo_blob_dataptr(argv[1]); int i; for(i = 0; i < n && i < framesize; ++i) { rowdata[i] = msgdata[i]; } for(; i < framesize; ++i) { rowdata[i] = 0; } static_cast<MantaOSC *>(instancePointer)->SetPadLEDFrame(state, rowdata); return 0; } catch(std::exception e) { std::cout << e.what() << std::endl; return 1; } }
int lo_message_add_blob(lo_message m, lo_blob a) { const uint32_t size = lo_blobsize(a); const uint32_t dsize = lo_blob_datasize(a); char *nptr = lo_message_add_data(m, size); if (!nptr) return -1; if (lo_message_add_typechar(m, LO_BLOB)) return -1; memset(nptr + size - 4, 0, 4); memcpy(nptr, &dsize, sizeof(dsize)); memcpy(nptr + sizeof(int32_t), lo_blob_dataptr(a), lo_blob_datasize(a)); return 0; }
int lots_handler(const char *path, const char *types, lo_arg **argv, int argc, lo_message data, void *user_data) { lo_blob b; unsigned char *d; if (strcmp(path, "/lotsofformats")) { fprintf(stderr, "path != /lotsofformats\n"); exit(1); } printf("path = %s\n", path); TEST(types[0] == 'f' && argv[0]->f == 0.12345678f); TEST(types[1] == 'i' && argv[1]->i == 123); TEST(types[2] == 's' && !strcmp(&argv[2]->s, "123")); b = (lo_blob)argv[3]; d = lo_blob_dataptr(b); TEST(types[3] == 'b' && lo_blob_datasize(b) == 5); TEST(d[0] == 'A' && d[1] == 'B' && d[2] == 'C' && d[3] == 'D' && d[4] == 'E'); d = argv[4]->m; TEST(d[0] == 0xff && d[1] == 0xf7 && d[2] == 0xaa && d[3] == 0x00); TEST(types[5] == 'h' && argv[5]->h == 0x0123456789ABCDEFULL); TEST(types[6] == 't' && argv[6]->t.sec == 1 && \ argv[6]->t.frac == 0x80000000); TEST(types[7] == 'd' && argv[7]->d == 0.9999); TEST(types[8] == 'S' && !strcmp(&argv[8]->S, "sym")); printf("char: %d\n", argv[9]->c); TEST(types[9] == 'c' && argv[9]->c == 'X'); TEST(types[10] == 'c' && argv[10]->c == 'Y'); TEST(types[11] == 'T'); TEST(types[12] == 'F'); TEST(types[13] == 'N'); TEST(types[14] == 'I'); printf("\n"); return 0; }
// /audio //handler for audio messages int audio_handler(const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { if(shutdown_in_progress==1) { return 0; } //init to 0, increment before use msg_received_counter++; gettimeofday(&tv, NULL); //first blob is at data_offset+1 (one-based) int data_offset=4; //ignore first n channels/blobs data_offset+=channel_offset; message_number_prev=message_number; //the messages are numbered sequentially. first msg is numberd 1 message_number=argv[0]->h; if(message_number_prev<message_number-1) { fprintf(stderr,"\ngap in message sequence! possibly lost %" PRId64" message(s) on the way.\n" ,message_number-message_number_prev-1); fflush(stderr); } //total args count minus metadata args and channel offset count = number of blobs input_port_count=argc-data_offset; //only process useful number of channels port_count=fmin(input_port_count,output_port_count); if(port_count < 1) { fprintf(stderr,"\n\nchannel offset %d >= available input channels %d! (nothing to receive). shutting down...\n" ,channel_offset ,(argc-data_offset+channel_offset)); fflush(stderr); shutdown_in_progress=1; return 0; } //need to warn when offset + outchannels limited //check sample rate and period size if sender (re)started or values not yet initialized (=no /offer received) if(message_number_prev>message_number || message_number==1 || remote_sample_rate==0 || remote_period_size==0 ) { lo_address loa; loa = lo_message_get_source(data); strcpy(sender_host,lo_address_get_hostname(loa)); strcpy(sender_port,lo_address_get_port(loa)); remote_sample_rate=argv[3]->i; remote_period_size=lo_blob_datasize((lo_blob)argv[0+data_offset])/bytes_per_sample; fprintf(stderr,"\nsender was (re)started. "); if(remote_period_size!=period_size) { fprintf(stderr,"sender period size: %d samples (%.3f x forward period size)\n\n",remote_period_size,(float)remote_period_size/period_size); } else { fprintf(stderr,"equal sender and receiver period size\n\n"); } }//end if "no-offer init" was needed remote_xrun_counter=argv[1]->h; lo_timetag tt=argv[2]->t; double msg_time=tt.sec+(double)tt.frac/1000000; double msg_time_prev=tt_prev.sec+(double)tt_prev.frac/1000000; double time_now=tv.tv_sec+(double)tv.tv_usec/1000000; time_interval=msg_time-msg_time_prev; time_interval_sum+=time_interval; time_interval_avg=(float)time_interval_sum/msg_received_counter; tt_prev=tt; //reset avg calc, check and reset after use if(msg_received_counter>=avg_calc_interval) { msg_received_counter=0; time_interval_sum=0; } fflush(stderr); // process_enabled=1; int mc_period_bytes=period_size*bytes_per_sample*port_count; //check if a whole mc period can be written to the ringbuffer uint64_t can_write_count=rb_can_write(rb); if(can_write_count < mc_period_bytes) { buffer_overflow_counter++; ///////////////// fprintf(stderr,"\nBUFFER OVERFLOW! this is bad -----%s\n","\033[0J"); return 0; } //======================================== //new: support different period sizes on sender / receiver (still need same SR) //this needs more tests and optimization if(period_size==remote_period_size) { int i; //don't read more channels than we have outputs for(i=0;i < port_count;i++) { //get blob (=one period of one channel) unsigned char *data = lo_blob_dataptr((lo_blob)argv[i+data_offset]); //fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset])); //write to ringbuffer //========================================== int cnt=rb_write(rb, (void *) data, period_size*bytes_per_sample); } } else if(period_size>remote_period_size) { int i; //don't read more channels than we have outputs for(i=0;i < port_count;i++) { //get blob (=one period of one channel) unsigned char *data = lo_blob_dataptr((lo_blob)argv[i+data_offset]); //fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset])); //write to temporary ringbuffer until there is enough data //========================================== int cnt=rb_write(rb_helper, (void *) data, remote_period_size*bytes_per_sample); } //if enough data collected for one larger multichannel period while(rb_can_read(rb_helper) >=mc_period_bytes && rb_can_write(rb) >=mc_period_bytes) { //transfer from helper to main ringbuffer unsigned char* data; data=malloc( mc_period_bytes); //store orig pointer unsigned char* orig_data=data; rb_read(rb_helper,data, mc_period_bytes); for(i=0;i < port_count;i++) { int k; for(k=0;k<(period_size/remote_period_size);k++) { //reset pointer data=orig_data; //position in helper buffer for next sample for main buffer data+= k*remote_period_size*bytes_per_sample*port_count + i*remote_period_size*bytes_per_sample; //write one channel snipped (remote_period_size) to main buffer int w=rb_write(rb,(void *)data,remote_period_size*bytes_per_sample); } } data=orig_data; free(data); } } else if(period_size<remote_period_size) { int k; for(k=0;k<(remote_period_size/period_size);k++) { int i; //don't read more channels than we have outputs for(i=0;i < port_count;i++) { //get blob (=one period of one channel) unsigned char *data = lo_blob_dataptr((lo_blob)argv[i+data_offset]); //fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset])); //write to ringbuffer //========================================== data+=k*period_size*bytes_per_sample; int cnt=rb_write(rb, (void *) data, period_size*bytes_per_sample); } } } return 0; }//end audio_handler
static int OSC_list(CSOUND *csound, OSCLISTEN *p) { OSC_PAT *m; /* quick check for empty queue */ if (p->patterns == NULL) { *p->kans = 0; return OK; } csound->LockMutex(p->port->mutex_); m = p->patterns; /* check again for thread safety */ if (m != NULL) { int i; /* unlink from queue */ p->patterns = m->next; /* copy arguments */ //printf("copying args\n"); for (i = 0; p->saved_types[i] != '\0'; i++) { //printf("%d: type %c\n", i, p->saved_types[i]); if (p->saved_types[i] == 's') { char *src = m->args[i].string.data; char *dst = ((STRINGDAT*) p->args[i])->data; if (src != NULL) { if (((STRINGDAT*) p->args[i])->size <= (int) strlen(src)){ if (dst != NULL) csound->Free(csound, dst); dst = csound->Strdup(csound, src); ((STRINGDAT*) p->args[i])->size = strlen(dst) + 1; ((STRINGDAT*) p->args[i])->data = dst; } else strcpy(dst, src); } } else if (p->saved_types[i]=='b') { char c = p->type->data[i]; int len = lo_blob_datasize(m->args[i].blob); //printf("blob found %p type %c\n", m->args[i].blob, c); //printf("length = %d\n", lo_blob_datasize(m->args[i].blob)); int *idata = lo_blob_dataptr(m->args[i].blob); if (c == 'A') { /* Decode an numeric array */ int j; MYFLT* data = (MYFLT*)(&idata[1+idata[0]]); int size = 1; ARRAYDAT* foo = (ARRAYDAT*)p->args[i]; foo->dimensions = idata[0]; csound->Free(csound, foo->sizes); foo->sizes = (int*)csound->Malloc(csound, sizeof(int)*idata[0]); #ifdef JPFF printf("dimension=%d\n", idata[0]); #endif for (j=0; j<idata[0]; j++) { foo->sizes[j] = idata[j+1]; #ifdef JPFF printf("sizes[%d] = %d\n", j, idata[j+1]); #endif size*=idata[j+1]; } #ifdef JPFF printf("idata = %i %i %i %i %i %i %i ...\n", idata[0], idata[1], idata[2], idata[3], idata[4], idata[5], idata[6]); printf("data = %f, %f, %f...\n", data[0], data[1], data[2]); #endif foo->data = (MYFLT*)csound->Malloc(csound, sizeof(MYFLT)*size); memcpy(foo->data, data, sizeof(MYFLT)*size); //printf("data = %f %f ...\n", foo->data[0], foo->data[1]); } else if (c == 'a') { MYFLT *data= (MYFLT*)idata; unsigned int len = (int)data[0]; if (len>CS_KSMPS) len = CS_KSMPS; memcpy(p->args[i], &data[1], len*sizeof(MYFLT)); } else if (c == 'G') { /* ftable received */ FUNC* data = (FUNC*)idata; int fno = MYFLT2LRND(*p->args[i]); FUNC *ftp; if (UNLIKELY(fno <= 0 /* || fno > csound->maxfnum */)) return csound->PerfError(csound, p->h.insdshead, Str("Invalid ftable no. %d"), fno); ftp = csound->FTFindP(csound, p->args[i]); if (ftp==NULL) // need to allocate ***FIXME*** {} memcpy(ftp, data, sizeof(FUNC)-sizeof(MYFLT*)); ftp->fno = fno; ftp->ftable = (MYFLT*)csound->ReAlloc(csound, ftp->ftable, len-sizeof(FUNC)+sizeof(MYFLT*)); { MYFLT* dst = ftp->ftable; MYFLT* src = (MYFLT*)(&(data->ftable)); #ifdef JPFF //int j; printf("copy data: from %p to %p length %d %d\n", src, dst, len-sizeof(FUNC)+sizeof(MYFLT*), data->flen); printf("was %f %f %f ...\n", dst[0], dst[1], dst[2]); printf("will be %f %f %f ...\n", src[0],src[1], src[2]); memcpy(dst, src, len-sizeof(FUNC)+sizeof(MYFLT*)); #endif //for (j=0; j<data->flen;j++) dst[j]=src[j]; //printf("now %f %f %f ...\n", dst[0], dst[1], dst[2]); } } else if (c == 'S') { } else return csound->PerfError(csound, p->h.insdshead, "Oh dear"); csound->Free(csound, m->args[i].blob); } else *(p->args[i]) = m->args[i].number; } /* push to stack of free message structures */ m->next = p->freePatterns; p->freePatterns = m; *p->kans = 1; } else *p->kans = 0; csound->UnlockMutex(p->port->mutex_); return OK; }
static int OSC_handler(const char *path, const char *types, lo_arg **argv, int argc, void *data, void *p) { OSC_PORT *pp = (OSC_PORT*) p; OSCLISTEN *o; CSOUND *csound = (CSOUND *) pp->csound; int retval = 1; pp->csound->LockMutex(pp->mutex_); o = (OSCLISTEN*) pp->oplst; //printf("opst=%p\n", o); while (o != NULL) { //printf("Looking at %s/%s against %s/%s\n", // o->saved_path, path,o->saved_types, types); if (strcmp(o->saved_path, path) == 0 && strcmp(o->saved_types, types) == 0) { /* Message is for this guy */ int i; OSC_PAT *m; //printf("handler found message\n"); m = get_pattern(o); if (m != NULL) { /* queue message for being read by OSClisten opcode */ m->next = NULL; if (o->patterns == NULL) o->patterns = m; else { OSC_PAT *mm; for (mm = o->patterns; mm->next != NULL; mm = mm->next) ; mm->next = m; } /* copy argument list */ for (i = 0; o->saved_types[i] != '\0'; i++) { switch (types[i]) { default: /* Should not happen */ case 'i': m->args[i].number = (MYFLT) argv[i]->i; break; case 'h': m->args[i].number = (MYFLT) argv[i]->i64; break; case 'c': m->args[i].number= (MYFLT) argv[i]->c; break; case 'f': m->args[i].number = (MYFLT) argv[i]->f; break; case 'd': m->args[i].number= (MYFLT) argv[i]->d; break; case 's': { // ***NO CHECK THAT m->args[i] IS A STRING char *src = (char*) &(argv[i]->s), *dst = m->args[i].string.data; if (m->args[i].string.size <= (int) strlen(src)) { if (dst != NULL) csound->Free(csound, dst); dst = csound->Strdup(csound, src); // who sets m->args[i].string.size ?? m->args[i].string.data = dst; m->args[i].string.size = strlen(dst)+1; } else strcpy(dst, src); break; } case 'b': { int len = lo_blobsize((lo_blob*)argv[i]); m->args[i].blob = csound->Malloc(csound,len); memcpy(m->args[i].blob, argv[i], len); #ifdef JPFF { lo_blob *bb = (lo_blob*)m->args[i].blob; int size = lo_blob_datasize(bb); MYFLT *data = lo_blob_dataptr(bb); int *idata = (int*)data; printf("size=%d data=%.8x %.8x ...\n",size, idata[0], idata[1]); } #endif } } } retval = 0; } break; } o = (OSCLISTEN*) o->nxt; } pp->csound->UnlockMutex(pp->mutex_); return retval; }
//================================================================ // /audio //handler for audio messages int osc_audio_handler(const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { if(shutdown_in_progress==1 || not_yet_ready==1) { return 0; } //init to 0, increment before use msg_received_counter++; gettimeofday(&tv, NULL); //first blob is at data_offset+1 (one-based) int data_offset=4; //ignore first n channels/blobs data_offset+=channel_offset; message_number_prev=message_number; //the messages are numbered sequentially. first msg is numberd 1 message_number=argv[0]->h; if(message_number_prev<message_number-1) { fprintf(stderr,"\ngap in message sequence! possibly lost %" PRId64" message(s) on the way.\n" ,message_number-message_number_prev-1); fflush(stderr); } //total args count minus metadata args count = number of blobs input_port_count=argc-data_offset; //only process useful number of channels port_count=fmin(input_port_count,output_port_count); if(port_count < 1) { fprintf(stderr,"channel offset %d >= available input channels %d! (nothing to receive). shutting down...\n" ,channel_offset ,channel_offset+input_port_count); fflush(stderr); shutdown_in_progress=1; return 0; } //check sample rate and period size if sender (re)started or values not yet initialized (=no /offer received) if(message_number_prev>message_number || message_number==1 || remote_sample_rate==0 || remote_period_size==0 ) { lo_address loa; if(use_tcp==1) { lo_address loa_=lo_message_get_source(data); loa=lo_address_new_with_proto(lo_proto,lo_address_get_hostname(loa_),remote_tcp_server_port); } else { loa=lo_message_get_source(data); } strcpy(sender_host,lo_address_get_hostname(loa)); strcpy(sender_port,lo_address_get_port(loa)); //option --rebuff if(rebuffer_on_restart==1) { uint64_t can_read_count=jack_ringbuffer_read_space(rb); pre_buffer_counter=fmax(0,(float)can_read_count/(float)bytes_per_sample/(float)period_size/(float)port_count); //start buffering process_enabled=0; } else { pre_buffer_counter=0; } remote_sample_rate=argv[3]->i; if(sample_rate!=remote_sample_rate) { if(close_on_incomp==0) { //sending deny will tell sender to stop/quit lo_message msg=lo_message_new(); lo_message_add_float(msg,format_version); lo_message_add_int32(msg,sample_rate); // /deny as reply to /audio should be the same as for /deny as reply to /offer //will need change of /audio (add format, bytes_per_sample) /////// lo_message_add_int32(msg,99); lo_send_message(loa, "/deny", msg); lo_message_free(msg); fprintf(stderr,"\ndenying transmission from %s:%s\n(incompatible JACK settings on sender: SR: %d). telling sender to stop.\n", lo_address_get_hostname(loa),lo_address_get_port(loa),remote_sample_rate ); fflush(stderr); message_number=0; message_number_prev=0; remote_sample_rate=0; remote_period_size=0; //pre_buffer_counter=0; } else { lo_address loa; if(use_tcp==1) { lo_address loa_=lo_message_get_source(data); loa=lo_address_new_with_proto(lo_proto,lo_address_get_hostname(loa_),remote_tcp_server_port); } else { loa=lo_message_get_source(data); } fprintf(stderr,"\ndenying transmission from %s:%s\nincompatible JACK settings on sender: SR: %d.\nshutting down (see option --close)...\n", lo_address_get_hostname(loa),lo_address_get_port(loa),remote_sample_rate ); fflush(stderr); shutdown_in_progress=1; return 0; } } remote_period_size=lo_blob_datasize((lo_blob)argv[0+data_offset])/bytes_per_sample; if(shutup==0 && quiet==0) { fprintf(stderr,"\nsender was (re)started. "); lo_address loa=lo_message_get_source(data); fprintf(stderr,"receiving from %s:%s\n",lo_address_get_hostname(loa),lo_address_get_port(loa)); } io_simple("/sender_restarted"); if(shutup==0 && quiet==0) { if(remote_period_size!=period_size) { fprintf(stderr,"sender period size: %d samples (%.3f x local)\n\n",remote_period_size,(float)remote_period_size/period_size); } else { fprintf(stderr,"equal sender and receiver period size\n\n"); } fflush(stderr); } }//end if "no-offer init" was needed remote_xrun_counter=argv[1]->h; lo_timetag tt=argv[2]->t; double msg_time=tt.sec+(double)tt.frac/1000000; double msg_time_prev=tt_prev.sec+(double)tt_prev.frac/1000000; //unused for now // double time_now=tv.tv_sec+(double)tv.tv_usec/1000000; time_interval=msg_time-msg_time_prev; time_interval_sum+=time_interval; time_interval_avg=(float)time_interval_sum/msg_received_counter; tt_prev=tt; //reset avg calc, check and reset after use if(msg_received_counter>=avg_calc_interval) { msg_received_counter=0; time_interval_sum=0; } if(pre_buffer_counter>=pre_buffer_size && process_enabled==0) { //if buffer filled, start to output audio in process() process_enabled=1; } int mc_period_bytes=period_size*bytes_per_sample*port_count; //check if a whole mc period can be written to the ringbuffer uint64_t can_write_count=jack_ringbuffer_write_space(rb); if(can_write_count < mc_period_bytes) { buffer_overflow_counter++; ///////////////// if(shutup==0 && quiet==0) { fprintf(stderr,"\rBUFFER OVERFLOW! this is bad -----%s","\033[0J"); } return 0; } //======================================== //new: support different period sizes on sender / receiver (still need same SR) //this needs more tests and optimization if(period_size==remote_period_size) { int i; //don't read more channels than we have outputs for(i=0;i < port_count;i++) { //get blob (=one period of one channel) unsigned char *data=lo_blob_dataptr((lo_blob)argv[i+data_offset]); //fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset])); //write to ringbuffer //========================================== //int cnt= jack_ringbuffer_write(rb, (void *) data, period_size*bytes_per_sample); } pre_buffer_counter++; } else if(period_size>remote_period_size) { int i; //don't read more channels than we have outputs for(i=0;i < port_count;i++) { //get blob (=one period of one channel) unsigned char *data=lo_blob_dataptr((lo_blob)argv[i+data_offset]); //fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset])); //write to temporary ringbuffer until there is enough data //========================================== //int cnt= jack_ringbuffer_write(rb_helper, (void *) data, remote_period_size*bytes_per_sample); } //if enough data collected for one larger multichannel period while(jack_ringbuffer_read_space(rb_helper) >=mc_period_bytes && jack_ringbuffer_write_space(rb) >=mc_period_bytes) { //transfer from helper to main ringbuffer unsigned char* data; data=malloc( mc_period_bytes); //store orig pointer unsigned char* orig_data=data; jack_ringbuffer_read(rb_helper,data, mc_period_bytes); for(i=0;i < port_count;i++) { int k; for(k=0;k<(period_size/remote_period_size);k++) { //reset pointer data=orig_data; //position in helper buffer for next sample for main buffer data+= k*remote_period_size*bytes_per_sample*port_count + i*remote_period_size*bytes_per_sample; //write one channel snipped (remote_period_size) to main buffer //int w= jack_ringbuffer_write(rb,(void *)data,remote_period_size*bytes_per_sample); } } data=orig_data; free(data); pre_buffer_counter++; } } else if(period_size<remote_period_size) { int k; for(k=0;k<(remote_period_size/period_size);k++) { int i; //don't read more channels than we have outputs for(i=0;i < port_count;i++) { //get blob (=one period of one channel) unsigned char *data=lo_blob_dataptr((lo_blob)argv[i+data_offset]); //fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset])); //write to ringbuffer //========================================== data+=k*period_size*bytes_per_sample; //int cnt= jack_ringbuffer_write(rb, (void *) data, period_size*bytes_per_sample); } pre_buffer_counter++; } } return 0; }//end osc_audio_handler
void test_deserialise() { char *buf, *buf2, *tmp; const char *types = NULL, *path; lo_arg **argv = NULL; size_t len, size; char data[256]; int result = 0; lo_blob btest = lo_blob_new(sizeof(testdata), testdata); uint8_t midi_data[4] = {0xff, 0xf7, 0xAA, 0x00}; lo_timetag tt = {0x1, 0x80000000}; lo_blob b = NULL; // build a message lo_message msg = lo_message_new(); TEST(0 == lo_message_get_argc(msg)); lo_message_add_float(msg, 0.12345678f); // 0 f lo_message_add_int32(msg, 123); // 1 i lo_message_add_string(msg, "123"); // 2 s lo_message_add_blob(msg, btest); // 3 b lo_message_add_midi(msg, midi_data); // 4 m lo_message_add_int64(msg, 0x0123456789abcdefULL); // 5 h lo_message_add_timetag(msg, tt); // 6 t lo_message_add_double(msg, 0.9999); // 7 d lo_message_add_symbol(msg, "sym"); // 8 S lo_message_add_char(msg, 'X'); // 9 c lo_message_add_char(msg, 'Y'); // 10 c lo_message_add_true(msg); // 11 T lo_message_add_false(msg); // 12 F lo_message_add_nil(msg); // 13 N lo_message_add_infinitum(msg); // 14 I // test types, args TEST(15 == lo_message_get_argc(msg)); types = lo_message_get_types(msg); TEST(NULL != types); argv = lo_message_get_argv(msg); TEST(NULL != argv); TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON); TEST('i' == types[1] && 123 == argv[1]->i); TEST('s' == types[2] && !strcmp(&argv[2]->s, "123")); TEST('b' == types[3]); b = (lo_blob)argv[3]; TEST(lo_blob_datasize(b) == sizeof(testdata)); TEST(12 == lo_blobsize(b)); TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata))); TEST('m' == types[4] && !memcmp(&argv[4]->m, midi_data, 4)); TEST('h' == types[5] && 0x0123456789abcdefULL == argv[5]->h); TEST('t' == types[6] && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac); TEST('d' == types[7] && fabs(argv[7]->d - 0.9999) < FLT_EPSILON); TEST('S' == types[8] && !strcmp(&argv[8]->s, "sym")); TEST('c' == types[9] && 'X' == argv[9]->c); TEST('c' == types[10] && 'Y' == argv[10]->c); TEST('T' == types[11] && NULL == argv[11]); TEST('F' == types[12] && NULL == argv[12]); TEST('N' == types[13] && NULL == argv[13]); TEST('I' == types[14] && NULL == argv[14]); // serialise it len = lo_message_length(msg, "/foo"); printf("serialise message_length=%d\n", (int)len); buf = calloc(len, sizeof(char)); size = 0; tmp = lo_message_serialise(msg, "/foo", buf, &size); TEST(tmp == buf && size == len && 92 == len); lo_message_free(msg); // deserialise it printf("deserialise\n"); path = lo_get_path(buf, len); TEST(NULL != path && !strcmp(path, "/foo")); msg = lo_message_deserialise(buf, size, NULL); TEST(NULL != msg); // repeat same test as above TEST(15 == lo_message_get_argc(msg)); types = lo_message_get_types(msg); TEST(NULL != types); argv = lo_message_get_argv(msg); TEST(NULL != argv); TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON); TEST('i' == types[1] && 123 == argv[1]->i); TEST('s' == types[2] && !strcmp(&argv[2]->s, "123")); TEST('b' == types[3]); b = (lo_blob)argv[3]; TEST(lo_blob_datasize(b) == sizeof(testdata)); TEST(12 == lo_blobsize(b)); TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata))); TEST('m' == types[4] && !memcmp(&argv[4]->m, midi_data, 4)); TEST('h' == types[5] && 0x0123456789abcdefULL == argv[5]->h); TEST('t' == types[6] && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac); TEST('d' == types[7] && fabs(argv[7]->d - 0.9999) < FLT_EPSILON); TEST('S' == types[8] && !strcmp(&argv[8]->s, "sym")); TEST('c' == types[9] && 'X' == argv[9]->c); TEST('c' == types[10] && 'Y' == argv[10]->c); TEST('T' == types[11] && NULL == argv[11]); TEST('F' == types[12] && NULL == argv[12]); TEST('N' == types[13] && NULL == argv[13]); TEST('I' == types[14] && NULL == argv[14]); // serialise it again, compare len = lo_message_length(msg, "/foo"); printf("serialise message_length=%d\n", (int)len); buf2 = calloc(len, sizeof(char)); size = 0; tmp = lo_message_serialise(msg, "/foo", buf2, &size); TEST(tmp == buf2 && size == len && 92 == len); TEST(!memcmp(buf, buf2, len)); lo_message_free(msg); lo_blob_free(btest); free(buf); free(buf2); // deserialise failure tests with invalid message data msg = lo_message_deserialise(data, 0, &result); // 0 size TEST(NULL == msg && LO_ESIZE == result); snprintf(data, 256, "%s", "/foo"); // unterminated path string msg = lo_message_deserialise(data, 4, &result); TEST(NULL == msg && LO_EINVALIDPATH == result); snprintf(data, 256, "%s", "/f_o"); // non-0 in pad area msg = lo_message_deserialise(data, 4, &result); TEST(NULL == msg && LO_EINVALIDPATH == result); snprintf(data, 256, "%s", "/t__"); // types missing replace_char(data, 4, '_', '\0'); msg = lo_message_deserialise(data, 4, &result); TEST(NULL == msg && LO_ENOTYPE == result); snprintf(data, 256, "%s%s", "/t__", "____"); // types empty replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 8, &result); TEST(NULL == msg && LO_EBADTYPE == result); snprintf(data, 256, "%s%s", "/t__", ",f_"); // short message replace_char(data, 7, '_', '\0'); msg = lo_message_deserialise(data, 7, &result); TEST(NULL == msg && LO_EINVALIDTYPE == result); snprintf(data, 256, "%s%s", "/t__", "ifi_"); // types missing comma replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 8, &result); TEST(NULL == msg && LO_EBADTYPE == result); snprintf(data, 256, "%s%s", "/t__", ",ifi"); // types unterminated replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 8, &result); TEST(NULL == msg && LO_EINVALIDTYPE == result); snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 12, &result); TEST(NULL == msg && LO_EINVALIDARG == result); snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data again replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 15, &result); TEST(NULL == msg && LO_EINVALIDARG == result); snprintf(data, 256, "%s%s", "/t__", ",f__"); // too much arg data replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 16, &result); TEST(NULL == msg && LO_ESIZE == result); snprintf(data, 256, "%s%s", "/t__", ",bs_"); // blob longer than msg length replace_char(data, 8, '_', '\0'); *(uint32_t *)(data + 8) = lo_htoo32((uint32_t)99999); msg = lo_message_deserialise(data, 256, &result); TEST(NULL == msg && LO_EINVALIDARG == result); }
int main() { lo_blob btest = lo_blob_new(sizeof(testdata), testdata); lo_server_thread st, sta, stb; lo_server s = lo_server_new(NULL, error); lo_bundle b; lo_message m1, m2; char *server_url, *path, *protocol, *host, *port; const char *host2, *port2; lo_address a; uint8_t midi_data[4] = {0xff, 0xf7, 0xAA, 0x00}; union end_test32 et32; union end_test64 et64; lo_timetag tt = {0x1, 0x80000000}, sched; int count; int proto; char cmd[256]; test_deserialise(); sta = lo_server_thread_new("7591", error); stb = lo_server_thread_new("7591", rep_error); if (stb) { fprintf(stderr, "FAILED: create bad server thread object!\n"); exit(1); } lo_server_thread_free(sta); /* leak check */ st = lo_server_thread_new(NULL, error); lo_server_thread_start(st); #ifdef WIN32 Sleep(4); #else usleep(4000); #endif lo_server_thread_stop(st); lo_server_thread_free(st); st = lo_server_thread_new(NULL, error); lo_server_thread_start(st); lo_server_thread_stop(st); lo_server_thread_free(st); st = lo_server_thread_new(NULL, error); lo_server_thread_free(st); st = lo_server_thread_new(NULL, error); lo_server_thread_free(st); st = lo_server_thread_new(NULL, error); a = lo_address_new_from_url("osc://localhost/"); TEST(a != NULL); lo_address_free(a); a = lo_address_new_from_url("osc.://localhost/"); TEST(a == NULL); atexit(exitcheck); printf("type tests\n"); TEST(sizeof(float) == sizeof(int32_t)); TEST(sizeof(double) == sizeof(int64_t)); et32.i = 0x23242526U; et32.i = lo_htoo32(et32.i); if (et32.c[0] != 0x23 || et32.c[1] != 0x24 || et32.c[2] != 0x25 || et32.c[3] != 0x26) { fprintf(stderr, "failed 32bit endian conversion test\n"); fprintf(stderr, "0x23242526 -> %X\n", et32.i); exit(1); } else { printf("passed 32bit endian conversion test\n"); } et64.i = 0x232425262728292AULL; et64.i = lo_htoo64(et64.i); if (et64.c[0] != 0x23 || et64.c[1] != 0x24 || et64.c[2] != 0x25 || et64.c[3] != 0x26 || et64.c[4] != 0x27 || et64.c[5] != 0x28 || et64.c[6] != 0x29 || et64.c[7] != 0x2A) { fprintf(stderr, "failed 64bit endian conversion\n"); fprintf(stderr, "0x232425262728292A -> %llX\n", (long long unsigned int)et64.i); exit(1); } else { printf("passed 64bit endian conversion\n"); } printf("\n"); /* OSC URL tests */ path = lo_url_get_path("osc.udp://localhost:9999/a/path/is/here"); if (strcmp(path, "/a/path/is/here")) { printf("failed lo_url_get_path() test1\n"); printf("'%s' != '/a/path/is/here'\n", path); exit(1); } else { printf("passed lo_url_get_path() test1\n"); } free(path); protocol = lo_url_get_protocol("osc.udp://localhost:9999/a/path/is/here"); if (strcmp(protocol, "udp")) { printf("failed lo_url_get_protocol() test1\n"); printf("'%s' != 'udp'\n", protocol); exit(1); } else { printf("passed lo_url_get_protocol() test1\n"); } free(protocol); protocol = lo_url_get_protocol("osc.tcp://localhost:9999/a/path/is/here"); if (strcmp(protocol, "tcp")) { printf("failed lo_url_get_protocol() test2\n"); printf("'%s' != 'tcp'\n", protocol); exit(1); } else { printf("passed lo_url_get_protocol() test2\n"); } free(protocol); protocol = lo_url_get_protocol("osc.udp://[::ffff:localhost]:9999/a/path/is/here"); if (strcmp(protocol, "udp")) { printf("failed lo_url_get_protocol() test1 (IPv6)\n"); printf("'%s' != 'udp'\n", protocol); exit(1); } else { printf("passed lo_url_get_protocol() test1 (IPv6)\n"); } free(protocol); proto = lo_url_get_protocol_id("osc.udp://localhost:9999/a/path/is/here"); if (proto != LO_UDP) { printf("failed lo_url_get_protocol_id() test1\n"); printf("'%d' != LO_UDP\n", proto); exit(1); } else { printf("passed lo_url_get_protocol_id() test1\n"); } proto = lo_url_get_protocol_id("osc.tcp://localhost:9999/a/path/is/here"); if (proto != LO_TCP) { printf("failed lo_url_get_protocol_id() test2\n"); printf("'%d' != LO_TCP\n", proto); exit(1); } else { printf("passed lo_url_get_protocol_id() test2\n"); } proto = lo_url_get_protocol_id("osc.invalid://localhost:9999/a/path/is/here"); if (proto != -1) { printf("failed lo_url_get_protocol_id() test3\n"); printf("'%d' != -1\n", proto); exit(1); } else { printf("passed lo_url_get_protocol_id() test3\n"); } proto = lo_url_get_protocol_id("osc.udp://[::ffff:localhost]:9999/a/path/is/here"); if (proto != LO_UDP) { printf("failed lo_url_get_protocol_id() test1 (IPv6)\n"); printf("'%d' != LO_UDP\n", proto); exit(1); } else { printf("passed lo_url_get_protocol_id() test1 (IPv6)\n"); } host = lo_url_get_hostname("osc.udp://foo.example.com:9999/a/path/is/here"); if (strcmp(host, "foo.example.com")) { printf("failed lo_url_get_hostname() test1\n"); printf("'%s' != 'foo.example.com'\n", host); exit(1); } else { printf("passed lo_url_get_hostname() test1\n"); } free(host); host = lo_url_get_hostname("osc.udp://[0000::::0001]:9999/a/path/is/here"); if (strcmp(host, "0000::::0001")) { printf("failed lo_url_get_hostname() test2 (IPv6)\n"); printf("'%s' != '0000::::0001'\n", host); exit(1); } else { printf("passed lo_url_get_hostname() test2 (IPv6)\n"); } free(host); port = lo_url_get_port("osc.udp://localhost:9999/a/path/is/here"); if (strcmp(port, "9999")) { printf("failed lo_url_get_port() test1\n"); printf("'%s' != '9999'\n", port); exit(1); } else { printf("passed lo_url_get_port() test1\n"); } free(port); port = lo_url_get_port("osc.udp://[::ffff:127.0.0.1]:9999/a/path/is/here"); if (strcmp(port, "9999")) { printf("failed lo_url_get_port() test1 (IPv6)\n"); printf("'%s' != '9999'\n", port); exit(1); } else { printf("passed lo_url_get_port() test1 (IPv6)\n"); } free(port); printf("\n"); a = lo_address_new_from_url("osc.tcp://foo.example.com:9999/"); host2 = lo_address_get_hostname(a); if (strcmp(host2, "foo.example.com")) { printf("failed lo_address_get_hostname() test\n"); printf("'%s' != 'foo.example.com'\n", host2); exit(1); } else { printf("passed lo_address_get_hostname() test\n"); } port2 = lo_address_get_port(a); if (strcmp(port2, "9999")) { printf("failed lo_address_get_port() test\n"); printf("'%s' != '9999'\n", port2); exit(1); } else { printf("passed lo_address_get_port() test\n"); } proto = lo_address_get_protocol(a); if (proto != LO_TCP) { printf("failed lo_address_get_protocol() test\n"); printf("'%d' != '%d'\n", proto, LO_TCP); exit(1); } else { printf("passed lo_address_get_protocol() test\n"); } server_url = lo_address_get_url(a); if (strcmp(server_url, "osc.tcp://foo.example.com:9999/")) { printf("failed lo_address_get_url() test\n"); printf("'%s' != '%s'\n", server_url, "osc.tcp://foo.example.com:9999/"); exit(1); } else { printf("passed lo_address_get_url() test\n"); } free(server_url); lo_address_free( a ); printf("\n"); /* Test blod sizes */ if (lo_blob_datasize(btest) != 5 || lo_blobsize(btest) != 12) { printf("blob is %d (%d) bytes long, should be 5 (12)\n", lo_blob_datasize(btest), lo_blobsize(btest)); lo_arg_pp(LO_BLOB, btest); printf(" <- blob\n"); exit(1); } /* Server method handler tests */ server_url = lo_server_thread_get_url(st); a = lo_address_new_from_url(server_url); printf("Server URL: %s\n", server_url); free(server_url); /* add method that will match the path /foo/bar, with two numbers, coerced * to float and int */ lo_server_thread_add_method(st, "/foo/bar", "fi", foo_handler, lo_server_thread_get_server(st)); lo_server_thread_add_method(st, "/reply", "s", reply_handler, NULL); lo_server_thread_add_method(st, "/lotsofformats", "fisbmhtdSccTFNI", lots_handler, NULL); lo_server_thread_add_method(st, "/coerce", "dfhiSs", coerce_handler, NULL); lo_server_thread_add_method(st, "/bundle", NULL, bundle_handler, NULL); lo_server_thread_add_method(st, "/timestamp", NULL, timestamp_handler, NULL); lo_server_thread_add_method(st, "/jitter", "ti", jitter_handler, NULL); lo_server_thread_add_method(st, "/pattern/foo", NULL, pattern_handler, "foo"); lo_server_thread_add_method(st, "/pattern/bar", NULL, pattern_handler, "bar"); lo_server_thread_add_method(st, "/pattern/baz", NULL, pattern_handler, "baz"); lo_server_thread_add_method(st, "/subtest", "i", subtest_handler, st); lo_server_thread_add_method(st, "/subtest-reply", "i", subtest_reply_handler, NULL); /* add method that will match any path and args */ lo_server_thread_add_method(st, NULL, NULL, generic_handler, NULL); /* add method that will match the path /quit with no args */ lo_server_thread_add_method(st, "/quit", "", quit_handler, NULL); /* check that the thread restarts */ lo_server_thread_start(st); lo_server_thread_stop(st); lo_server_thread_start(st); if (lo_send(a, "/foo/bar", "ff", 0.12345678f, 23.0f) == -1) { printf("OSC error A %d: %s\n", lo_address_errno(a), lo_address_errstr(a)); exit(1); } if (lo_send(a, "/foo/bar", "ff", 0.12345678f, 23.0f) == -1) { printf("OSC error B %d: %s\n", lo_address_errno(a), lo_address_errstr(a)); exit(1); } test_validation(a); test_multicast(st); lo_send(a, "/", "i", 242); lo_send(a, "/pattern/", "i", 243); #ifndef _MSC_VER /* MS compiler refuses to compile this case */ lo_send(a, "/bar", "ff", 0.12345678f, 1.0/0.0); #endif lo_send(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X', 'Y'); lo_send(a, "/coerce", "fdihsS", 0.1f, 0.2, 123, 124LL, "aaa", "bbb"); lo_send(a, "/coerce", "ffffss", 0.1f, 0.2f, 123.0, 124.0, "aaa", "bbb"); lo_send(a, "/coerce", "ddddSS", 0.1, 0.2, 123.0, 124.0, "aaa", "bbb"); lo_send(a, "/a/b/c/d", "sfsff", "one", 0.12345678f, "three", -0.00000023001f, 1.0); lo_send(a, "/a/b/c/d", "b", btest); TEST(test_varargs(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X', 'Y', LO_ARGS_END) == 0); #ifdef __GNUC__ // Note: Lack of support for variable-argument macros in non-GCC compilers // does not allow us to test for these conditions. // too many args TEST(test_varargs(a, "/lotsofformats", "f", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X', 'Y', LO_ARGS_END) != 0); // too many types TEST(test_varargs(a, "/lotsofformats", "fisbmhtdSccTFNI", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.5, LO_ARGS_END) != 0); #endif // test lo_message_add m1 = lo_message_new(); TEST(lo_message_add(m1, "fisbmhtdSccTFNI", 0.12345678f, 123, "123", btest, midi_data, 0x0123456789abcdefULL, tt, 0.9999, "sym", 'X', 'Y') == 0); lo_send_message(a, "/lotsofformats", m1); lo_message_free(m1); lo_blob_free(btest); lo_send(a, "/pattern/*", "s", "a"); lo_send(a, "/pattern/ba[rz]", "s", "b"); server_url = lo_server_thread_get_url(st); sprintf(cmd, "." PATHDELIM "subtest %s &", server_url); if (system(cmd) != 0) { fprintf(stderr, "Cannot execute subtest command\n"); exit(1); } system(cmd); free(server_url); #ifdef WIN32 Sleep(2000); #else sleep(2); #endif TEST(reply_count == 3); TEST(pattern_count == 5); TEST(subtest_count == 2); TEST(subtest_reply_count == 22); printf("\n"); { lo_timetag t = {10,0xFFFFFFFC}; b = lo_bundle_new(t); } m1 = lo_message_new(); lo_message_add_string(m1, "abcdefghijklmnopqrstuvwxyz"); lo_message_add_string(m1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); lo_bundle_add_message(b, "/bundle", m1); lo_send_bundle(a, b); /* This should be safe for multiple copies of the same message. */ lo_bundle_free_messages(b); { lo_timetag t = {1,2}; b = lo_bundle_new(t); } m1 = lo_message_new(); lo_message_add_int32(m1, 23); lo_message_add_string(m1, "23"); lo_bundle_add_message(b, "/bundle", m1); m2 = lo_message_new(); lo_message_add_string(m2, "24"); lo_message_add_int32(m2, 24); lo_bundle_add_message(b, "/bundle", m2); lo_bundle_add_message(b, "/bundle", m1); /* lo_send_bundle(a, b); if (a->errnum) { printf("error %d: %s\n", a->errnum, a->errstr); exit(1); } */ TEST(lo_send_bundle(a, b) == 88); /* Test freeing out-of-order copies of messages in a bundle. */ lo_bundle_free_messages(b); { lo_timetag t = {10,0xFFFFFFFE}; b = lo_bundle_new(t); } m1 = lo_message_new(); lo_message_add_string(m1, "abcdefghijklmnopqrstuvwxyz"); lo_message_add_string(m1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); lo_bundle_add_message(b, "/bundle", m1); lo_send_bundle(a, b); lo_message_free(m1); lo_bundle_free(b); lo_timetag_now(&sched); sched.sec += 5; b = lo_bundle_new(sched); m1 = lo_message_new(); lo_message_add_string(m1, "future"); lo_message_add_string(m1, "time"); lo_message_add_string(m1, "test"); lo_bundle_add_message(b, "/bundle", m1); lo_send_bundle(a, b); lo_message_free(m1); lo_bundle_free(b); lo_send_timestamped(a, sched, "/bundle", "s", "lo_send_timestamped() test"); /* test bundle timestamp ends up in message struct (and doesn't end up in unbundled messages) */ lo_timetag_now(&sched); lo_send_timestamped(a, sched, "/timestamp", "it", 1, sched); lo_send(a, "/timestamp", "it", 0, sched); #define JITTER_ITS 25 /* jitter tests */ { lo_timetag stamps[JITTER_ITS]; lo_timetag now; int i; for (i=0; i<JITTER_ITS; i++) { lo_timetag_now(&now); stamps[i] = now; stamps[i].sec += 1; stamps[i].frac = rand(); lo_send_timestamped(a, stamps[i], "/jitter", "ti", stamps[i], i); } } #ifdef WIN32 Sleep(2000); #else sleep(2); #endif lo_address_free(a); TEST(lo_server_thread_events_pending(st)); while (lo_server_thread_events_pending(st)) { printf("pending events, wait...\n"); #ifdef WIN32 fflush(stdout); Sleep(1000); #else sleep(1); #endif } TEST(bundle_count == 7); printf("\n"); printf("bundle timing jitter results:\n" "max jitter = %fs\n" "avg jitter = %fs\n" "min jitter = %fs\n\n", jitter_max, jitter_total/(float)jitter_count, jitter_min); server_url = lo_server_get_url(s); lo_server_add_method(s, NULL, NULL, generic_handler, NULL); a = lo_address_new_from_url(server_url); TEST(lo_server_recv_noblock(s, 0) == 0); printf("Testing noblock API on %s\n", server_url); lo_send(a, "/non-block-test", "f", 23.0); count = 0; while (!lo_server_recv_noblock(s, 10) && count++ < 1000) { } if (count >= 1000) { printf("lo_server_recv_noblock() test failed\n"); exit(1); } /* Delete methods */ lo_server_thread_del_method(st, "/coerce", "dfhiSs"); lo_server_del_method(s, NULL, NULL); lo_address_free(a); lo_server_free(s); free(server_url); #ifndef WIN32 { /* UNIX domain tests */ lo_address ua; lo_server us; char *addr; unlink("/tmp/testlo.osc"); us = lo_server_new_with_proto("/tmp/testlo.osc", LO_UNIX, error); ua = lo_address_new_from_url("osc.unix:///tmp/testlo.osc"); TEST(lo_server_get_protocol(us) == LO_UNIX); TEST(lo_send(ua, "/unix", "f", 23.0) == 16); TEST(lo_server_recv(us) == 16); addr = lo_server_get_url(us); TEST(!strcmp("osc.unix:////tmp/testlo.osc", addr)); free(addr); lo_address_free(ua); ua = lo_address_new_with_proto(LO_UNIX, NULL, "/tmp/testlo.osc"); TEST(lo_send(ua, "/unix", "f", 23.0) == 16); TEST(lo_server_recv(us) == 16); lo_server_free(us); lo_address_free(ua); } #endif { /* TCP tests */ lo_address ta; lo_server ts; char *addr; ts = lo_server_new_with_proto(NULL, LO_TCP, error); addr = lo_server_get_url(ts); ta = lo_address_new_from_url(addr); if (lo_address_errno(ta)) { printf("err: %s\n", lo_address_errstr(ta)); exit(1); } TEST(lo_server_get_protocol(ts) == LO_TCP); TEST(lo_send(ta, "/tcp", "f", 23.0) == 16); TEST(lo_send(ta, "/tcp", "f", 23.0) == 16); TEST(lo_server_recv(ts) == 16); TEST(lo_server_recv(ts) == 16); free(addr); lo_server_free(ts); lo_address_free(ta); } server_url = lo_server_thread_get_url(st); a = lo_address_new_from_url(server_url); /* exit */ lo_send(a, "/quit", NULL); lo_address_free(a); while (!done) { #ifdef WIN32 Sleep(1); #else usleep(1000); #endif } lo_server_thread_free(st); free(server_url); return 0; }