inline int lo_address_cmp(lo_address a, lo_address b) { int res; res = strcmp(lo_address_get_hostname(a), lo_address_get_hostname(b)); if (!res) { res = strcmp(lo_address_get_port(a), lo_address_get_port(b)); } return res; }
mapper_receiver mapper_receiver_find_by_src_address(mapper_receiver r, lo_address src_addr) { const char *host_to_match = lo_address_get_hostname(src_addr); const char *port_to_match = lo_address_get_port(src_addr); while (r) { const char *host = lo_address_get_hostname(r->props.src_addr); const char *port = lo_address_get_port(r->props.src_addr); if ((strcmp(host, host_to_match)==0) && (strcmp(port, port_to_match)==0)) return r; r = r->next; } return 0; }
void *veejay_new_osc_sender_uri( const char *uri ) { oscclient_t *osc = (oscclient_t*) vj_malloc(sizeof(oscclient_t)); memset(osc,0,sizeof(oscclient_t)); osc->addr = lo_address_new_from_url( uri ); osc->addr_str = strdup(lo_address_get_hostname( osc->addr )); osc->port_str = strdup(lo_address_get_port ( osc->addr )); veejay_msg(0,"New OSC sender from uri '%s', Host %s, Port %s", uri, osc->addr_str, osc->port_str ); return (void*) osc; }
int addr_write(IOSTREAM *s, atom_t a, int flags) { PL_blob_t *type; size_t len; lo_address *p=(lo_address *)PL_blob_data(a,&len,&type); if (p) { const char *host = lo_address_get_hostname(*p); const char *port = lo_address_get_port(*p); if (host!=NULL && port!=NULL) { Sfprintf(s,"osc_address<%s:%s>",host,port); } else { Sfprintf(s,"osc_address<invalid>"); } } return TRUE; }
int lo_address_resolve(lo_address a) { int ret; if (a->protocol == LO_UDP || a->protocol == LO_TCP) { struct addrinfo *ai; struct addrinfo hints; const char* host = lo_address_get_hostname(a); #ifdef ENABLE_IPV6 char hosttmp[7+16+1]; // room for ipv6 prefix + a dotted quad #endif memset(&hints, 0, sizeof(hints)); #ifdef ENABLE_IPV6 hints.ai_family = PF_UNSPEC; if (is_dotted_ipv4_address(host)) { host = hosttmp; strcpy(hosttmp, "::FFFF:"); strncpy(hosttmp + 7, lo_address_get_hostname(a), 16); } #else hints.ai_family = PF_INET; #endif hints.ai_socktype = a->protocol == LO_UDP ? SOCK_DGRAM : SOCK_STREAM; if ((ret = getaddrinfo(host, lo_address_get_port(a), &hints, &ai))) { a->errnum = ret; a->errstr = gai_strerror(ret); a->ai = NULL; a->ai_first = NULL; return -1; } a->ai = ai; a->ai_first = ai; } return 0; }
void port_checker::server::init(const char* target_url) { target = lo_address_new_from_url(target_url); if(!target || !lo_address_get_url(target) || !lo_address_get_port(target) || lo_address_get_protocol(target) != LO_UDP) throw std::runtime_error("invalid address"); srv = lo_server_new_with_proto(nullptr, LO_UDP, liblo_error_cb); if(srv == nullptr) throw std::runtime_error("Could not create lo server"); lo_server_add_method(srv, nullptr, nullptr, handle_st, this); rtosc_arg_val_t hi[2]; hi[0].type = hi[1].type = 's'; hi[0].val.s = hi[1].val.s = ""; send_msg("/path-search", 2, hi); std::vector<rtosc_arg_val_t> reply; std::vector<char> buf; wait_for_reply(&buf, &reply, "/paths"); }
inline int lo_generic_handler(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) { int i; printf("--- OSC Message ---\n"); printf("from host: %s\n", lo_address_get_hostname(lo_message_get_source(msg))); printf("from port: %s\n", lo_address_get_port(lo_message_get_source(msg))); printf("path: <%s>\n", path); for (i=0; i<argc; i++) { printf("arg %d '%c' ", i, types[i]); lo_arg_pp((lo_type)types[i], argv[i]); printf("\n"); } printf("\n"); fflush(stdout); return 1; }
static int osc_update ( DssiEditor *pDssiEditor, lo_arg **argv, lo_address source ) { const char *url = (const char *) &argv[0]->s; const char *host, *port; #ifdef CONFIG_DEBUG qDebug("osc_update: path \"%s\"", url); #endif qtractorDssiPlugin *pDssiPlugin = pDssiEditor->plugin; if (pDssiPlugin == NULL) return 1; ++(pDssiEditor->busy); if (pDssiEditor->target) lo_address_free(pDssiEditor->target); host = lo_url_get_hostname(url); port = lo_url_get_port(url); pDssiEditor->target = lo_address_new(host, port); ::free((void *) host); ::free((void *) port); if (pDssiEditor->source) lo_address_free(pDssiEditor->source); host = lo_address_get_hostname(source); port = lo_address_get_port(source); pDssiEditor->source = lo_address_new(host, port); if (pDssiEditor->path) ::free(pDssiEditor->path); pDssiEditor->path = lo_url_get_path(url); --(pDssiEditor->busy); // Update plugin configuration... const qtractorPlugin::Configs& configs = pDssiPlugin->configs(); qtractorPlugin::Configs::ConstIterator iter = configs.constBegin(); const qtractorPlugin::Configs::ConstIterator& iter_end = configs.constEnd(); for (; iter != iter_end; ++iter) { osc_send_configure(pDssiEditor, iter.key().toUtf8().constData(), iter.value().toUtf8().constData()); } // Update program selection... qtractorMidiManager *pMidiManager = (pDssiPlugin->list())->midiManager(); if (pMidiManager && pMidiManager->currentBank() >= 0 && pMidiManager->currentProg() >= 0) { osc_send_program(pDssiEditor, pMidiManager->currentBank(), pMidiManager->currentProg()); } // Update control params... const qtractorPlugin::Params& params = pDssiPlugin->params(); qtractorPlugin::Params::ConstIterator param = params.constBegin(); const qtractorPlugin::Params::ConstIterator& param_end = params.constEnd(); for ( ; param != param_end; ++param) { qtractorPluginParam *pParam = param.value(); osc_send_control(pDssiEditor, pParam->index(), pParam->value()); } // Update all control output ports... pDssiPlugin->updateControlOuts(true); return osc_send_show(pDssiEditor); }
OSC_HANDLER_FUNC(sys_info_##prop##_handler) {\ return info_prop_handler(argv, argc, user_data, info_reply_##prop);\ }\ OSC_HANDLER_FUNC(sys_info_##prop##_handler_default) {\ return info_prop_handler_default(user_data, info_reply_##prop);\ } #define DECLARE_INFO_PROP(prop, typetag, ...)\ DECLARE_INFO_REPLY_FUNC(prop, typetag, __VA_ARGS__)\ DECLARE_INFO_HANDLERS(prop) DECLARE_INFO_PROP(id, "s", monome_get_serial(state->monome)) DECLARE_INFO_PROP(size, "ii", monome_get_cols(state->monome), monome_get_rows(state->monome)) DECLARE_INFO_PROP(host, "s", lo_address_get_hostname(state->outgoing)) DECLARE_INFO_PROP(port, "i", atoi(lo_address_get_port(state->outgoing))) DECLARE_INFO_PROP(prefix, "s", state->config.app.osc_prefix) static void info_reply_rotation(lo_address *to, sosc_state_t *state) { if (monome_get_cols(state->monome) != monome_get_rows(state->monome)) info_reply_size(to, state); lo_send_from(to, state->server, LO_TT_IMMEDIATE, "/sys/rotation", "i", monome_get_rotation(state->monome) * 90); } DECLARE_INFO_HANDLERS(rotation); static void
// /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
// /offer //sender offers audio int offer_handler(const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { if(shutdown_in_progress==1) { return 0; } float offered_format_version=argv[0]->f; int offered_sample_rate=argv[1]->i; int offered_bytes_per_sample=argv[2]->i; int offered_period_size=argv[3]->i; int offered_channel_count=argv[4]->i; float offered_data_rate=argv[5]->f; uint64_t request_counter=argv[6]->h; lo_message msg=lo_message_new(); lo_address loa= lo_message_get_source(data); fprintf(stderr,"\nsender sample rate: %d\n",offered_sample_rate); fprintf(stderr,"sender bytes per sample: %d\n",offered_bytes_per_sample); //re-use for forwarding sample_rate=offered_sample_rate; bytes_per_sample=offered_bytes_per_sample; //check if compatible with sender //could check more stuff (channel count, data rate, sender host/port, ...) if( offered_sample_rate==sample_rate && offered_bytes_per_sample==bytes_per_sample && offered_format_version==format_version //new: support non-matching period sizes //&& offered_period_size==period_size ) { remote_sample_rate=sample_rate; remote_period_size=offered_period_size; strcpy(sender_host,lo_address_get_hostname(loa)); strcpy(sender_port,lo_address_get_port(loa)); //sending accept will tell the sender to start transmission lo_send_message (loa, "/accept", msg); /* fprintf(stderr,"\nreceiving from %s:%s", lo_address_get_hostname(loa),lo_address_get_port(loa)); */ starting_transmission=1; } //data is incompatible, handle depending on --close else if(close_on_incomp==0) { //sending deny will tell sender to stop/quit lo_message_add_float(msg,format_version); lo_message_add_int32(msg,sample_rate); lo_message_add_int32(msg,bytes_per_sample); lo_send_message (loa, "/deny", msg); fprintf(stderr,"\ndenying transmission from %s:%s\nincompatible JACK settings or format version on sender:\nformat version: %.2f\nSR: %d\nbytes per sample: %d\ntelling sender to stop.\n", lo_address_get_hostname(loa),lo_address_get_port(loa),offered_format_version,offered_sample_rate,offered_bytes_per_sample ); fflush(stderr); //shutting down is not a good strategy for the receiver in this case //shutdown_in_progress=1; } lo_message_free(msg); return 0; } //end offer_handler
OscAddress(lo_address address): port( std::atoi(lo_address_get_port(address)) ), host( lo_address_get_hostname(address) ) {}
// ********************************************************* // -(OSC handler)------------------------------------------- int oscmulticast_handler(const char *path, const char *types, lo_arg ** argv, int argc, lo_message msg, void *user_data) { t_oscmulticast *x = (t_oscmulticast *)user_data; int i, j; char my_string[2]; j=0; if (!x->buffer) { post("Error receiving message!"); return 0; } lo_address address = lo_message_get_source(msg); if (address) { maxpd_atom_set_int(x->buffer, atoi(lo_address_get_port(address))); outlet_anything(x->outlet3, gensym("int"), 1, x->buffer); maxpd_atom_set_string(x->buffer, lo_address_get_hostname(address)); outlet_anything(x->outlet2, gensym("symbol"), 1, x->buffer); } if (argc > MAXSIZE) { post("Truncating received message to 256 elements!"); argc = MAXSIZE; } for (i=0; i<argc; i++) { switch (types[i]) { case 'i': maxpd_atom_set_int(x->buffer+j, argv[i]->i); j++; break; case 'h': maxpd_atom_set_int(x->buffer+j, argv[i]->h); j++; break; case 'f': maxpd_atom_set_float(x->buffer+j, argv[i]->f); j++; break; case 'd': maxpd_atom_set_float(x->buffer+j, (float)argv[i]->d); j++; break; case 's': maxpd_atom_set_string(x->buffer+j, (const char *)&argv[i]->s); j++; break; case 'S': maxpd_atom_set_string(x->buffer+j, (const char *)&argv[i]->s); j++; break; case 'c': snprintf(my_string, 2, "%c", argv[i]->c); maxpd_atom_set_string(x->buffer+j, (const char *)my_string); j++; break; case 't': //output timetag from a second outlet? break; } } outlet_anything(x->outlet1, gensym((char *)path), j, x->buffer); return 0; }
//================================================================ // /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
inline bool lo_address_equals(lo_address a, lo_address b) { return strcmp(lo_address_get_hostname(a), lo_address_get_hostname(b)) == 0 && strcmp(lo_address_get_port(a), lo_address_get_port(b)) == 0; // FIXME: && lo_address_get_protocol(a) == lo_address_get_protocol(b); }
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; }