// Constructor. qtractorNsmClient::qtractorNsmClient ( const QString& nsm_url, QObject *pParent ) : QObject(pParent), #ifdef CONFIG_LIBLO m_address(NULL), m_thread(NULL), m_server(NULL), #endif m_active(false) { #ifdef CONFIG_LIBLO m_address = lo_address_new_from_url(nsm_url.toUtf8().constData()); const int proto = lo_address_get_protocol(m_address); m_thread = lo_server_thread_new_with_proto(NULL, proto, NULL); if (m_thread) { m_server = lo_server_thread_get_server(m_thread); lo_server_thread_add_method(m_thread, "/error", "sis", osc_nsm_error, this); lo_server_thread_add_method(m_thread, "/reply", "ssss", osc_nsm_reply, this); lo_server_thread_add_method(m_thread, "/nsm/client/open", "sss", osc_nsm_open, this); lo_server_thread_add_method(m_thread, "/nsm/client/save", "", osc_nsm_save, this); lo_server_thread_add_method(m_thread, "/nsm/client/session_is_loaded", "", osc_nsm_loaded, this); lo_server_thread_add_method(m_thread, "/nsm/client/show_optional_gui", "", osc_nsm_show, this); lo_server_thread_add_method(m_thread, "/nsm/client/hide_optional_gui", "", osc_nsm_hide, this); lo_server_thread_start(m_thread); } #endif }
int subtest_handler(const char *path, const char *types, lo_arg **argv, int argc, lo_message data, void *user_data) { lo_address a = lo_message_get_source(data); subtest_count++; printf("got subtest message %d\n", subtest_count); lo_send_from(a, lo_server_thread_get_server(user_data), LO_TT_IMMEDIATE, "/subtest", "i", subtest_count); return 0; }
int Client::init_thread(const char *nsm_url) { this->nsm_url = nsm_url; lo_address addr = lo_address_new_from_url(nsm_url); int proto = lo_address_get_protocol(addr); lo_address_free(addr); _st = lo_server_thread_new_with_proto(NULL, proto, NULL); _server = lo_server_thread_get_server(_st); if(!_server || !_st) return -1; lo_server_thread_add_method(_st, "/error", "sis", &Client::osc_error, this); lo_server_thread_add_method(_st, "/reply", "ssss", &Client::osc_announce_reply, this); lo_server_thread_add_method(_st, "/nsm/client/open", "sss", &Client::osc_open, this); lo_server_thread_add_method(_st, "/nsm/client/save", "", &Client::osc_save, this); lo_server_thread_add_method(_st, "/nsm/client/session_is_loaded", "", &Client::osc_session_is_loaded, this); lo_server_thread_add_method(_st, NULL, NULL, &Client::osc_broadcast, this); return 0; }
bool announce(const int pid, const char* const executableName) { CARLA_SAFE_ASSERT_RETURN(pid != 0, false); CARLA_SAFE_ASSERT_RETURN(executableName != nullptr && executableName[0] != '\0', false); const char* const NSM_URL(std::getenv("NSM_URL")); if (NSM_URL == nullptr) return false; const lo_address nsmAddress(lo_address_new_from_url(NSM_URL)); CARLA_SAFE_ASSERT_RETURN(nsmAddress != nullptr, false); const int proto = lo_address_get_protocol(nsmAddress); if (fServerThread == nullptr) { // create new OSC server fServerThread = lo_server_thread_new_with_proto(nullptr, proto, _osc_error_handler); CARLA_SAFE_ASSERT_RETURN(fServerThread != nullptr, false); // register message handlers lo_server_thread_add_method(fServerThread, "/error", "sis", _error_handler, this); lo_server_thread_add_method(fServerThread, "/reply", "ssss", _reply_handler, this); lo_server_thread_add_method(fServerThread, "/nsm/client/open", "sss", _open_handler, this); lo_server_thread_add_method(fServerThread, "/nsm/client/save", "", _save_handler, this); lo_server_thread_add_method(fServerThread, "/nsm/client/session_is_loaded", "", _loaded_handler, this); lo_server_thread_add_method(fServerThread, "/nsm/client/show_optional_gui", "", _show_gui_handler, this); lo_server_thread_add_method(fServerThread, "/nsm/client/hide_optional_gui", "", _hide_gui_handler, this); lo_server_thread_add_method(fServerThread, nullptr, nullptr, _broadcast_handler, this); fServer = lo_server_thread_get_server(fServerThread); fServerURL = lo_server_thread_get_url(fServerThread); } const char* appName = std::getenv("CARLA_NSM_NAME"); if (appName == nullptr) appName = "Carla"; lo_send_from(nsmAddress, fServer, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii", appName, NSM_CLIENT_FEATURES, executableName, NSM_API_VERSION_MAJOR, NSM_API_VERSION_MINOR, pid); lo_address_free(nsmAddress); return true; }
int OscReceiver::handleMessages(int timeoutMS) { if(!m_serverThread) { LOG_ERROR << "OscReceiver: Cannot handle messages, address not set" << std::endl; return 0; } if(m_bIsRunning) { LOG_WARN << "OscReceiver: You shouldn't need to handle messages manually " << "when the thread is already running" << std::endl; return 0; } lo_server server = lo_server_thread_get_server(m_serverThread); return lo_server_recv_noblock(server, timeoutMS); }
void test_multicast(lo_server_thread st) { /* test multicast server and sender */ /* message is sent from st otherwise reply doesn't work */ lo_server ms = lo_server_new_multicast("224.0.1.1", "15432", error); lo_address ma = lo_address_new("224.0.1.1", "15432"); lo_address_set_ttl(ma, 1); lo_server_add_method(ms, "/foo/bar", "fi", foo_handler, ms); lo_server_add_method(ms, "/reply", "s", reply_handler, NULL); if (lo_send_from(ma, lo_server_thread_get_server(st), LO_TT_IMMEDIATE, "/foo/bar", "ff", 0.12345678f, 23.0f) == -1) { printf("multicast send error %d: %s\n", lo_address_errno(ma), lo_address_errstr(ma)); exit(1); } TEST(lo_server_recv(ms)==24); lo_server_free(ms); lo_address_free(ma); }
int init_osc( char * ip, char *outport, char * port ){ /* create liblo addres */ t = lo_address_new(ip, outport); // change later to use other host lo_server_thread st = lo_server_thread_new(port, error); lo_server_thread_add_method(st, "/joystick/open", "i", joy_open_handler, NULL); lo_server_thread_add_method(st, "/joystick/info", "i", joy_info_handler, NULL); lo_server_thread_add_method(st, "/joystick/close", "i", joy_close_handler, NULL); lo_server_thread_add_method(st, "/sdl2osc/info", "", info_handler, NULL); lo_server_thread_add_method(st, "/sdl2osc/quit", "", quit_handler, NULL); lo_server_thread_add_method(st, NULL, NULL, generic_handler, NULL); lo_server_thread_start(st); lo_server s = lo_server_thread_get_server( st ); lo_send_from( t, s, LO_TT_IMMEDIATE, "/sdl2osc/started", "" ); }
lo_server_thread init_osc( char *port ) { lo_server_thread st = NULL; lo_server serv = NULL; // Create new server st = lo_server_thread_new( port, osc_error_handler ); if (!st) return NULL; // Add the methods serv = lo_server_thread_get_server( st ); lo_server_thread_add_method( st, "/deck/play", "", play_handler, serv); lo_server_thread_add_method( st, "/deck/pause", "", pause_handler, serv); lo_server_thread_add_method( st, "/deck/stop", "", stop_handler, serv); lo_server_thread_add_method( st, "/deck/cue", "", cue_handler, serv); lo_server_thread_add_method( st, "/deck/cue", "f", cue_handler, serv); lo_server_thread_add_method( st, "/deck/eject", "", eject_handler, serv); lo_server_thread_add_method( st, "/deck/load", "s", load_handler, serv); lo_server_thread_add_method( st, "/deck/get_state", "", state_handler, serv); lo_server_thread_add_method( st, "/deck/get_duration", "", duration_handler, serv); lo_server_thread_add_method( st, "/deck/get_position", "", position_handler, serv); lo_server_thread_add_method( st, "/deck/get_filepath", "", filepath_handler, serv); lo_server_thread_add_method( st, "/get_error", "", get_error_handler, serv); lo_server_thread_add_method( st, "/get_version", "", get_version_handler, serv); lo_server_thread_add_method( st, "/ping", "", ping_handler, serv); // add method that will match any path and args lo_server_thread_add_method(st, NULL, NULL, wildcard_handler, serv); // Start the thread lo_server_thread_start(st); if (!quiet) { char *url = lo_server_thread_get_url( st ); printf( "OSC server URL: %s\n", url ); free(url); } return st; }
unsigned int OscReceiver::getPort() { return m_serverThread ? (unsigned int) lo_server_get_port(lo_server_thread_get_server(m_serverThread)) : 0; }
//================================================================ int main(int argc, char *argv[]) { //jack const char **ports; //jack_options_t options = JackNullOption; jack_status_t status; //options struct was here if(argc-optind<1) { print_header("jack_audio_receive"); fprintf(stderr, "Missing arguments, see --help.\n\n"); exit(1); } int opt; //do until command line options parsed while(1) { /* getopt_long stores the option index here. */ int option_index=0; opt=getopt_long(argc, argv, "", long_options, &option_index); /* Detect the end of the options. */ if(opt==-1) { break; } switch(opt) { case 0: /* If this option set a flag, do nothing else now. */ if(long_options[option_index].flag!=0) { break; } case 'h': print_header("jack_audio_receive"); print_help(); break; case 'v': print_version(); break; case 'x': print_header("jack_audio_receive"); check_lo_props(1); return 1; case 'o': output_port_count=atoi(optarg); if(output_port_count>max_channel_count) { output_port_count=max_channel_count; } port_count=fmin(input_port_count,output_port_count); break; case 'f': channel_offset=atoi(optarg); break; case 'y': bytes_per_sample=2; break; case 'n': client_name=optarg; break; case 's': server_name=optarg; jack_opts |= JackServerName; break; case 'b': pre_buffer_size=fmax(1,(uint64_t)atoll(optarg)); break; case 'm': max_buffer_size=fmax(1,(uint64_t)atoll(optarg)); break; case 'u': update_display_every_nth_cycle=fmax(1,(uint64_t)atoll(optarg)); break; case 'l': receive_max=fmax(1,(uint64_t)atoll(optarg)); test_mode=1; break; case 'a': io_host=optarg; break; case 'c': io_port=optarg; break; case 't': use_tcp=1; remote_tcp_server_port=optarg; break; case '?': //invalid commands /* getopt_long already printed an error message. */ print_header("jack_audio_receive"); fprintf(stderr, "Wrong arguments, see --help.\n\n"); exit(1); break; default: break; } //end switch op }//end while(1) //remaining non optional parameters listening port if(argc-optind!=1) { print_header("jack_audio_receive"); fprintf(stderr, "Wrong arguments, see --help.\n\n"); exit(1); } localPort=argv[optind]; //for commuication with a gui / other controller / visualizer loio=lo_address_new_with_proto(LO_UDP, io_host, io_port); //if was set to use random port if(atoi(localPort)==0) { //for lo_server_thread_new_with_proto localPort=NULL; } //add osc hooks & start osc server early (~right after cmdline parsing) registerOSCMessagePatterns(localPort); lo_server_thread_start(lo_st); //read back port (in case of random) //could use //int lo_server_thread_get_port(lo_server_thread st) const char *osc_server_url=lo_server_get_url(lo_server_thread_get_server(lo_st)); localPort=lo_url_get_port(osc_server_url); //int lport=lo_server_thread_get_port(lo_st); //notify osc gui if(io_()) { lo_message msgio=lo_message_new(); lo_message_add_float(msgio, version); lo_message_add_float(msgio, format_version); lo_send_message(loio, "/startup", msgio); lo_message_free(msgio); } if(check_lo_props(0)>0) { return 1; } if(use_tcp==1) { lo_proto=LO_TCP; } if(shutup==0) { print_header("jack_audio_receive"); if(output_port_count>max_channel_count) { fprintf(stderr,"/!\\ limiting playback ports to %d, sry\n",max_channel_count); } if(test_mode==1) { fprintf(stderr,"/!\\ limiting number of messages: %" PRId64 "\n",receive_max); } } //check for default jack server env var char *evar=getenv("JACK_DEFAULT_SERVER"); if(evar==NULL || strlen(evar)<1) { #ifndef _WIN unsetenv("JACK_DEFAULT_SERVER"); #endif } else if(server_name==NULL) { //use env var if no server was given with --sname server_name=evar; } if(server_name==NULL || strlen(server_name)<=0) { server_name="default"; } if(client_name==NULL) { client_name="receive"; } if(have_libjack()!=0) { fprintf(stderr,"/!\\ libjack not found (JACK not installed?). this is fatal: jack_audio_receive needs JACK to run.\n"); io_quit("nolibjack"); exit(1); } //initialize time gettimeofday(&tv, NULL); tt_prev.sec=tv.tv_sec; tt_prev.frac=tv.tv_usec; //create an array of input ports ioPortArray=(jack_port_t**) malloc(output_port_count * sizeof(jack_port_t*)); //open a client connection to the JACK server client=jack_client_open(client_name, jack_opts, &status, server_name); if(client==NULL) { fprintf(stderr,"jack_client_open() failed, status = 0x%2.0x\n", status); if(status & JackServerFailed) { fprintf(stderr,"Unable to connect to JACK server.\n"); io_quit("nojack"); } exit(1); } if(use_tcp==1) { if(shutup==0) { fprintf(stderr,"receiving on TCP port: %s\n",localPort); } } else { if(shutup==0) { fprintf(stderr,"receiving on UDP port: %s\n",localPort); } } client_name=jack_get_client_name(client); if(shutup==0) { fprintf(stderr,"started JACK client '%s' on server '%s'\n",client_name,server_name); if(status & JackNameNotUnique) { fprintf(stderr, "/!\\ name '%s' was automatically assigned\n", client_name); } } if(status & JackNameNotUnique) { io_simple("/client_name_changed"); } //print startup info read_jack_properties(); if(shutup==0) { print_common_jack_properties(); fprintf(stderr,"channels (playback): %d\n",output_port_count); fprintf(stderr,"channel offset: %d\n",channel_offset); print_bytes_per_sample(); fprintf(stderr,"multi-channel period size: %d bytes\n", output_port_count*period_size*bytes_per_sample ); char *strat="fill with zero (silence)"; if(zero_on_underflow==0) { strat="re-use last available period"; } fprintf(stderr,"underflow strategy: %s\n",strat); if(rebuffer_on_restart==1) { fprintf(stderr,"rebuffer on sender restart: yes\n"); } else { fprintf(stderr,"rebuffer on sender restart: no\n"); } if(rebuffer_on_underflow==1) { fprintf(stderr,"rebuffer on underflow: yes\n"); } else { fprintf(stderr,"rebuffer on underflow: no\n"); } if(allow_remote_buffer_control==1) { fprintf(stderr,"allow external buffer control: yes\n"); } else { fprintf(stderr,"allow external buffer control: no\n"); } if(close_on_incomp==1) { fprintf(stderr,"shutdown receiver when incompatible data received: yes\n"); } else { fprintf(stderr,"shutdown receiver when incompatible data received: no\n"); } }//end cond. print char buf[64]; format_seconds(buf,(float)pre_buffer_size*period_size/(float)sample_rate); uint64_t rb_size_pre=pre_buffer_size*output_port_count*period_size*bytes_per_sample; if(shutup==0) { fprintf(stderr,"initial buffer size: %" PRId64 " mc periods (%s, %" PRId64 " bytes, %.2f MB)\n", pre_buffer_size, buf, rb_size_pre, (float)rb_size_pre/1000/1000 ); } buf[0]='\0'; //ringbuffer size bytes uint64_t rb_size; //ringbuffer mc periods int max_buffer_mc_periods; //max given as param (user knows best. if pre=max, overflows are likely) if(max_buffer_size>0) { max_buffer_mc_periods=fmax(pre_buffer_size,max_buffer_size); rb_size=max_buffer_mc_periods *output_port_count*period_size*bytes_per_sample; } else //"auto" { //make max buffer 0.5 seconds larger than pre buffer max_buffer_mc_periods=pre_buffer_size+ceil(0.5*(float)sample_rate/period_size); rb_size=max_buffer_mc_periods *output_port_count*period_size*bytes_per_sample; } max_buffer_size=max_buffer_mc_periods; format_seconds(buf,(float)max_buffer_mc_periods*period_size/sample_rate); if(shutup==0) { fprintf(stderr,"allocated buffer size: %" PRId64 " mc periods (%s, %" PRId64 " bytes, %.2f MB)\n", max_buffer_size, buf, rb_size, (float)rb_size/1000/1000 ); } buf[0]='\0'; io_dump_config(); //==================================== //main ringbuffer osc blobs -> jack output rb=jack_ringbuffer_create(rb_size); //helper ringbuffer: used when remote period size < local period size rb_helper=jack_ringbuffer_create(rb_size); if(rb==NULL) { fprintf(stderr,"could not create a ringbuffer with that size.\n"); fprintf(stderr,"try --max <smaller size>.\n"); io_quit("ringbuffer_too_large"); exit(1); } //JACK will call process() for every cycle (given by JACK) //NULL could be config/data struct jack_set_process_callback(client, process, NULL); jack_set_xrun_callback(client, xrun_handler, NULL); //register hook to know when JACK shuts down or the connection //was lost (i.e. client zombified) jack_on_shutdown(client, jack_shutdown_handler, 0); // Register each output port int port; for(port=0; port<output_port_count; port ++) { // Create port name char* portName; if(asprintf(&portName, "output_%d", (port+1)) < 0) { fprintf(stderr,"Could not create portname for port %d", port); io_quit("port_error"); exit(1); } // Register the output port ioPortArray[port]=jack_port_register(client, portName, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if(ioPortArray[port]==NULL) { fprintf(stderr,"Could not create output port %d\n", (port+1)); io_quit("port_error"); exit(1); } } /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ if(jack_activate(client)) { fprintf(stderr, "cannot activate client"); io_quit("cannot_activate_client"); exit(1); } /* Connect the ports. You can't do this before the client is * activated, because we can't make connections to clients * that aren't running. Note the confusing (but necessary) * orientation of the driver backend ports: playback ports are * "input" to the backend, and capture ports are "output" from * it. */ //prevent to get physical midi ports const char* pat="audio"; ports=jack_get_ports(client, NULL, pat, JackPortIsPhysical|JackPortIsInput); if(ports==NULL) { if(shutup==0) { fprintf(stderr,"no physical playback ports\n"); } //exit(1); } if(autoconnect==1) { fprintf(stderr, "\n"); int j=0; int i; for(i=0;i<output_port_count;i++) { if(ports[i]!=NULL && ioPortArray[j]!=NULL && jack_port_name(ioPortArray[j])!=NULL) { if(!jack_connect(client, jack_port_name(ioPortArray[j]), ports[i])) { if(shutup==0) { fprintf(stderr, "autoconnect: %s -> %s\n", jack_port_name(ioPortArray[j]),ports[i] ); } io_simple_string_double("/autoconnect",jack_port_name(ioPortArray[j]),ports[i]); j++; } else { if(shutup==0) { fprintf(stderr, "autoconnect: failed: %s -> %s\n", jack_port_name(ioPortArray[j]),ports[i] ); } } } else { //no more playback ports break; } }//end for all output ports if(shutup==0) { fprintf(stderr, "\n"); } } free(ports); fflush(stderr); /* install a signal handler to properly quits jack client */ #ifndef _WIN signal(SIGQUIT, signal_handler); signal(SIGHUP, signal_handler); #endif signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); if(use_tcp==1) { //10 MB max int desired_max_tcp_size=10000000; lo_server s=lo_server_thread_get_server(lo_st); int ret_set_size=lo_server_max_msg_size(s, desired_max_tcp_size); if(shutup==0) { printf("set tcp max size return: %d\n",ret_set_size); io_simple("/tcp_max_size_xxxx"); } } not_yet_ready=0; io_simple("/start_main_loop"); //run possibly forever until not interrupted by any means while(1) { //possibly clean shutdown without any glitches if(shutdown_in_progress==1) { signal_handler(42); } #ifdef WIN_ Sleep(1000); #else sleep(1); #endif } exit(0); }//end main
int main (int argc, char **argv) { lo_server_thread serv = NULL; FILE *file = NULL; int c; while ( (c = getopt (argc, argv, "i:o:")) != -1) switch (c) { case 'i': { int proto = lo_url_get_protocol_id (optarg); if (proto == -1) fprintf (stderr, "protocol not supported\n"); char *port = lo_url_get_port (optarg); serv = lo_server_thread_new_with_proto (port, proto, _error); free (port); break; } case 'o': { if (!strcmp (optarg, "-")) file = stdout; else file = fopen (optarg, "wb"); break; } case '?': if ( (optopt == 'i') || (optopt == 'o') ) fprintf (stderr, "Option `-%c' requires an argument.\n", optopt); else if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return 1; default: return (1); } if (!serv || !file) { fprintf (stderr, "usage: %s -i PROTOCOL://HOST:PORT -o FILE|-\n\n", argv[0]); return (1); } lo_server *_serv = lo_server_thread_get_server (serv); lo_server_add_bundle_handlers (_serv, _bundle_start_handler, _bundle_end_handler, file); lo_server_enable_queue (_serv, 0, 1); lo_server_thread_add_method (serv, NULL, NULL, _msg_handler, file); lo_server_thread_start (serv); signal (SIGHUP, _quit); signal (SIGQUIT, _quit); signal (SIGTERM, _quit); signal (SIGINT, _quit); while (!done) nanosleep (&_10mu, NULL); fprintf (stderr, "cleaning up\n"); lo_server_thread_stop (serv); lo_server_thread_free (serv); if (file != stdout) fclose (file); return 0; }
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; }