예제 #1
0
// 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
}
예제 #2
0
Server::Server() {
    st = lo_server_thread_new("6340", error);
    if (st) lo_server_thread_start(st);
    else { printf("err: starting Server\n"); while(1);}
    
    st_tcp = lo_server_thread_new_with_proto("6341", LO_TCP, errorTCP);
    if (st_tcp) lo_server_thread_start(st_tcp);
    else { printf("err: starting Server\n"); while(1);}
}
예제 #3
0
void registerOSCMessagePatterns(const char *port)
{
	/* osc server */
	//lo_st = lo_server_thread_new(port, error);
	lo_st = lo_server_thread_new_with_proto(port, lo_proto, error);

/*
	/offer fiiiifh

	1) f: audio rx/tx format version
	2) i: sample rate
	3) i: bytes per sample
	4) i: period size
	5) i: channel count
	6) f: expected network data rate
	7) h: send / request counter
*/

	lo_server_thread_add_method(lo_st, "/offer", "fiiiifh", offer_handler, NULL);

/*
	/audio hhtib*

	1) h: message number
	2) h: xrun counter (sender side, as all the following meta data)
	3) t: timetag (seconds since Jan 1st 1900 in the UTC, fraction 1/2^32nds of a second)
	4) i: sampling rate
	5) b: blob of channel 1 (period size * bytes per sample) bytes long
	...
	...b: up to n channels
*/

	char typetag_string[1024];
	int v=0;
	for(v=0;v<1024;v++)
	{
		typetag_string[v]='\0';
	}

	//char *prefix="hhti";
	typetag_string[0]='h';
	typetag_string[1]='h';
	typetag_string[2]='t';
	typetag_string[3]='i';

	/////////////////
	int data_offset=4;

	v=0;
	for(v=0;v<max_channel_count;v++)
	{
		typetag_string[data_offset+v]='b';
		lo_server_thread_add_method(lo_st, "/audio", typetag_string, audio_handler, NULL);
	}
	//the max possible channel count depends on JACK period size, SR, liblo version (fixmax), 16/32 bit, 100/1000 mbit/s network

}//end registerocsmessages
예제 #4
0
Server::Obj::Obj( int port, Proto proto )
{
	string portStr = boost::lexical_cast< string >( port );
	mThread = lo_server_thread_new_with_proto( ( port == PORT_ANY ) ? NULL : portStr.c_str(), proto, errorHandler );
	if ( port == PORT_ANY )
		mPort = lo_server_thread_get_port( mThread );
	else
		mPort = port;

	lo_server_thread_start( mThread );
}
예제 #5
0
Server::Server( int port, Proto proto /* = PROTO_UDP */ )
{
	string portStr = boost::lexical_cast< string >( port );
	mThread = lo_server_thread_new_with_proto( ( port == PORT_ANY ) ? NULL : portStr.c_str(), proto, errorHandler );
	if ( port == PORT_ANY )
	{
		mPort = lo_server_thread_get_port( mThread );
	}
	else
	{
		mPort = port;
	}

	lo_server_thread_start( mThread );
}
예제 #6
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;
    }
예제 #7
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;
    }
예제 #8
0
lo_server_thread lo_server_thread_new(const char *port, lo_err_handler err_h)
{
    return lo_server_thread_new_with_proto(port, LO_DEFAULT, err_h);
}
예제 #9
0
int
main (int argc, char *argv[])
{

//////////////////////////////////////////////
//will be removed
//	sample_rate=44100;
	sample_rate=48000;
//	period_size=2048;
	period_size=4096;
//	period_size=256;
	//period_size=128;
	bytes_per_sample=4;

	//osc
	const char *listenPort;

	//command line options parsing
	//http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html
	static struct option long_options[] =
	{
		{"help",	no_argument,		0, 'h'},
		{"version",     no_argument,            0, 'v'},
		{"loinfo",      no_argument,            0, 'x'},
		{"out",		required_argument, 	0, 'o'},
		{"offset",	required_argument, 	0, 'f'},
		{"16",          no_argument,            0, 'y'},
		{"max",		required_argument,	0, 'm'},//max (allocate) buffer
		{"update",	required_argument,	0, 'u'},//screen info update every nth cycle
		{"limit",	required_argument,	0, 'l'},//test, stop after n processed
		{0, 0, 0, 0}
	};

	//print program header
	if(argc>1 && strcmp(argv[1],"--version"))
	{
		print_header("audio_post_send");
	}

	if (argc - optind < 1)
	{
		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_help();
				break;

			case 'v':
				print_version();
				break;

			case 'x':
				check_lo_props(1);
				return 1;

			case 'o':
				output_port_count=atoi(optarg);

				if(output_port_count>max_channel_count)
				{
					fprintf(stderr,"*** limiting playback ports to %d, sry\n",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 'm':
				//min 1 MB
				max_buffer_size=fmax(1,(uint64_t)atoll(optarg)*1000*1000);
				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;
				fprintf(stderr,"*** limiting number of messages: %" PRId64 "\n",receive_max);

				break;

			case '?': //invalid commands
				/* getopt_long already printed an error message. */
				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, remote host, remote port
	if(argc-optind != 3)
	{
		fprintf (stderr, "Wrong arguments, see --help.\n\n");
		exit(1);
	}

	if(check_lo_props(0)>0)
	{
		return 1;
	}

	if(have_libjack()!=0)
	{
		fprintf(stderr,"/!\\ libjack not found (JACK not installed?). this is fatal: audio_post_send needs JACK to run.\n");
		//io_quit("nolibjack");
		exit(1);
	}

	listenPort=argv[optind];

	//tcp target
	remote_tcp_host=argv[optind+1];
	remote_tcp_port=argv[optind+2];

	loa_tcp = lo_address_new_with_proto(LO_TCP, remote_tcp_host, remote_tcp_port);

	//initialize time
	gettimeofday(&tv, NULL);
	tt_prev.sec=tv.tv_sec;
	tt_prev.frac=tv.tv_usec;

	//print startup info

	fprintf(stderr,"listening on UDP port: %s\n",listenPort);
	//udp/tcp use the same port for now
	fprintf(stderr,"started TCP server on port: %s\n",listenPort);

	fprintf(stderr,"channels (forward): %d\n",output_port_count);
	fprintf(stderr,"channel offset: %d\n",channel_offset);

	fprintf(stderr, "TCP target: %s:%s\n",remote_tcp_host,remote_tcp_port);

	fprintf(stderr, "period size (TCP forward): %d samples\n",period_size);

	fprintf(stderr, "delay between TCP sends: %d ms\n",delay_between_tcp_sends);
	fprintf(stderr, "delay between TCP retries on broken connection: %d ms\n",delay_between_tcp_retries);

	//ringbuffer size bytes
	uint64_t rb_size;

	//use as given via param --max or:
	if(max_buffer_size==0)
	{
		//default
		//10 MB           .  .  
		max_buffer_size=10000000;
	}

	//
	rb_size=max_buffer_size;

	fprintf(stderr,"allocated buffer size: %" PRId64 " bytes (%.2f MB)\n",max_buffer_size,(float)max_buffer_size/1000/1000);

	//====================================
	//main ringbuffer osc blobs -> jack output
	rb = rb_new (rb_size);
	//helper ringbuffer: used when remote period size < local period size
	rb_helper = rb_new (rb_size);

	if(rb==NULL)
	{
		fprintf(stderr,"could not create a ringbuffer with that size.\n");
		fprintf(stderr,"try --max <smaller size>.\n");
		exit(1);
	}

	/* 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);

	//add osc hooks & start UDP server
	registerOSCMessagePatterns(listenPort);
	lo_server_thread_start(lo_st);

	//start TCP server, for forwarding to final receiver
	lo_st_tcp = lo_server_thread_new_with_proto(listenPort, LO_TCP, error);
	lo_server_thread_start(lo_st_tcp);

	fflush(stderr);

	/* keep running until the Ctrl+C */
	while(1) 
	{
		//possibly clean shutdown without any glitches
		if(shutdown_in_progress==1)
		{
			signal_handler(42);
		}

		//if tcp message could not be sent
		if(process()<0)
		{
			//wait x and update info
			int i;
			for(i=0;i<delay_between_tcp_retries;i++)
			{
				usleep(1000);
				print_info();
			}
		}
		else
		{
			//wait y and update info
			int i;
			for(i=0;i<delay_between_tcp_sends;i++)
			{
				usleep(1000);
				print_info();
			}
		}
	}
	exit (0);
}
예제 #10
0
//================================================================
void registerOSCMessagePatterns(const char *port)
{
	/* osc server */
	//lo_st=lo_server_thread_new(port, error);
	lo_st=lo_server_thread_new_with_proto(port, lo_proto, osc_error_handler);

//AUDIO RELATED=========================================

/*
	/offer fiiiifh

	1) f: audio rx/tx format version
	2) i: sample rate
	3) i: bytes per sample
	4) i: period size
	5) i: channel count
	6) f: expected network data rate
	7) h: send / request counter
*/

	lo_server_thread_add_method(lo_st, "/offer", "fiiiifh", osc_offer_handler, NULL);

/*
	experimental

	/buffer ii

	1) i: target fill value for available periods in ringbuffer (multi channel)
	2) i: max. target buffer size in mc periods
	drop or add periods
	this will introduce a hearable click on drops
	or pause playback for rebuffering depending on the current buffer fill
*/

	lo_server_thread_add_method(lo_st, "/buffer", "ii", osc_buffer_handler, NULL);

/*
	/audio hhtib*

	1) h: message number
	2) h: xrun counter (sender side, as all the following meta data)
	3) t: timetag (seconds since Jan 1st 1900 in the UTC, fraction 1/2^32nds of a second)
	4) i: sampling rate
	5) b: blob of channel 1 (period size * bytes per sample) bytes long
	...
	...b: up to n channels
*/

	char typetag_string[1024];
	int v=0;
	for(v=0;v<1024;v++)
	{
		typetag_string[v]='\0';
	}

	//char *prefix="hhti";
	typetag_string[0]='h';
	typetag_string[1]='h';
	typetag_string[2]='t';
	typetag_string[3]='i';

	/////////////////
	int data_offset=4;

//the max possible channel count depends on JACK period size, SR, liblo version (fixmax), 16/32 bit, 100/1000 mbit/s network
/*
	//support 1-n blobs / channels per message
	lo_server_thread_add_method(lo_st, "/audio", "hhtib", audio_handler, NULL);
	lo_server_thread_add_method(lo_st, "/audio", "hhtibb", audio_handler, NULL);
..
*/
	v=0;
	for(v=0;v<max_channel_count;v++)
	{
		typetag_string[data_offset+v]='b';
		lo_server_thread_add_method(lo_st, "/audio", typetag_string, osc_audio_handler, NULL);
	}

//GUI I/O, CONTROL RELATED==============================

/*
	/quit
	close / release resources and shutdown program
*/
	lo_server_thread_add_method(lo_st, "/quit", "", osc_quit_handler, NULL);


}//end registerocsmessages
예제 #11
0
파일: oscrec.c 프로젝트: ViktorNova/oscfile
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;
}