int osc_controller::_add_cb(const char* path, const char* types,
                            lo_arg** argv, int argc, lo_message msg)
{
    if (!m_restricted || is_target(lo_message_get_source(msg))) {
	pair<int,int> net_id(argv[0]->i, argv[1]->i);

	m_skip++;
	world_node obj = m_world->add_node(std::string(&argv[2]->s));
	m_skip--;

	if (!obj.is_null()) {
	    int local_id = obj.get_id ();
	    m_net_id[local_id] = net_id;
	    m_local_id[net_id] = local_id;

	    if (m_broadcast) {
		lo_message newmsg = lo_message_new();
		lo_message_add_int32(newmsg, argv[0]->i);
		lo_message_add_int32(newmsg, argv[1]->i);
		lo_message_add_string(newmsg, &argv[2]->s);
		broadcast_message_from(PSYNTH_OSC_MSG_ADD, newmsg, lo_message_get_source(msg));
		lo_message_free(newmsg);
	    }
	}
    }

    return 0;
}
int osc_controller::_deactivate_cb(const char* path, const char* types,
                                   lo_arg** argv, int argc, lo_message msg)
{
    if (!m_restricted || is_target (lo_message_get_source(msg))) {
	pair<int,int> net_id(argv[0]->i, argv[1]->i);

	map<pair<int,int>, int>::iterator it = m_local_id.find(net_id);
	world_node obj;

	if (it != m_local_id.end() &&
	    !(obj = m_world->find_node(it->second)).is_null()) {

	    m_skip++;
	    m_world->deactivate_node(obj);
	    m_skip--;

	    if (m_broadcast) {
		lo_message newmsg = lo_message_new();
		lo_message_add_int32(newmsg, argv[0]->i);
		lo_message_add_int32(newmsg, argv[1]->i);
		broadcast_message_from(PSYNTH_OSC_MSG_DEACTIVATE, newmsg, lo_message_get_source(msg));
		lo_message_free(newmsg);
	    }
	}
    }

    return 0;
}
Beispiel #3
0
int OscReceiver::messageCB(const char* path, const char* types, lo_arg** argv,
						   int argc, lo_message msg, void* user_data)
{
	OscReceiver* receiver = (OscReceiver*) user_data;
	return receiver->processMessage(ReceivedMessage((std::string) path, (std::string) types, argv, argc, msg),
									MessageSource(lo_message_get_source(msg)));
}
Beispiel #4
0
int StreamMulticaster::onStreamPingI(const char *path, const char *types, lo_arg **argv,
                                     int argc, lo_message msg)
{
    // send pong reply:
    lowrappers::Address replyTo(lo_message_get_source(msg), false);
    replyTo.sendFrom(streamIn_, streamPath_ + "pong" , "i", argv[0]->i);
    
    return 1; // returning 1 ensures that the call will also be passed to forwardMessage
}
Beispiel #5
0
int reply_handler(const char *path, const char *types, lo_arg **argv, int argc,
		 lo_message data, void *user_data)
{
    lo_address src = lo_message_get_source(data);
    char *url = lo_address_get_url(src);
    printf("Reply received from %s\n", url);
    free(url);
    reply_count++;

    return 0;
}
Beispiel #6
0
int
osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
{
    lo_address to = lo_address_new_from_url( lo_address_get_url( lo_message_get_source( msg ) ));

    nsm_proxy->update( to );

    gui_addr = to;

    return 0;
}
Beispiel #7
0
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;
}
Beispiel #8
0
int StreamMulticaster::onUnknownConnectIn(const char *path, const char *types, lo_arg **argv,
                                          int argc, lo_message msg)
{
    // create a reply adress from msg:
    WonderOscSender replyTo(lo_message_get_source(msg), false);
    
    // send reply:
    const std::string pathStr(path);
    replyTo.sendReply(pathStr, 1, "Unknown command: " + pathStr);
    
    return 0;
}
Beispiel #9
0
int VSReceiver::onStreamVisualPingI(const char *path, const char *types,lo_arg **argv,
                                        int argc, lo_message msg)
{
    if(pingHandler_ == nullptr){
        return 0;
    } else {
        // the lo_address returned from lo_message_get_source will be free'd along
        // with msg, so we need to set ownership to false:
        WonderOscServerSender replyAddress(lo_message_get_source(msg),  *this, false);
        return pingHandler_->onStreamVisualPing(argv[0]->i, &replyAddress);
    }
}
Beispiel #10
0
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;
}
Beispiel #11
0
int
osc_announce_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
{
    if ( strcmp( "/nsm/server/announce", &argv[0]->s ) )
         return -1;

    printf( "Successfully registered. NSM says: %s", &argv[1]->s );
    
    nsm_is_active = 1;
    nsm_addr = lo_address_new_from_url( lo_address_get_url( lo_message_get_source( msg ) ) );
    
    return 0;
}
static int osc_message ( const char *path, const char * /*types*/,
	lo_arg **argv, int /*argc*/, void *data, void * /*user_data*/ )
{
	QMutexLocker locker(&g_oscMutex);

#ifdef CONFIG_DEBUG_0
	printf("osc_message: path \"%s\"", path);
	for (int i = 0; i < argc; ++i) {
		printf(", arg %d '%c' ", i, types[i]);
		lo_arg_pp(lo_type(types[i]), argv[i]);
	}
	printf(", data %p, user_data %p\n", data, user_data);
#endif

	if (::strncmp(path, "/dssi", 5))
		return 1;

	const QString sPath = path;
	const QString& sLabel = sPath.section('/', 2, 2);
	DssiEditor *pDssiEditor = osc_find_editor(sLabel);
	if (pDssiEditor == NULL)
		return 1;

	if (pDssiEditor->busy > 0)
		return 1;

	lo_message message = lo_message(data);
	lo_address source  = lo_message_get_source(message);
	
	const QString& sMethod = sPath.section('/', 3, 3);

	if (sMethod == "update")
		return osc_update(pDssiEditor, argv, source);
	else
	if (sMethod == "configure")
		return osc_configure(pDssiEditor, argv);
	else
	if (sMethod == "control")
		return osc_control(pDssiEditor, argv);
	else
	if (sMethod == "program")
		return osc_program(pDssiEditor, argv);
	else
	if (sMethod == "midi")
		return osc_midi(pDssiEditor, argv);
	else
	if (sMethod == "exiting")
		return osc_exiting(pDssiEditor);

	return 1;
}
Beispiel #13
0
static
int get_version_handler(const char *path, const char *types, lo_arg **argv, int argc,
		 lo_message msg, void *user_data)
{
	lo_address src = lo_message_get_source( msg );
	lo_server serv = (lo_server)user_data;
	int result;
	
	// Send back reply
	result = lo_send_from( src, serv, LO_TT_IMMEDIATE, "/version", "ss", PACKAGE_NAME, PACKAGE_VERSION );
	if (result<1) fprintf(stderr, "Error: sending reply failed: %s\n", lo_address_errstr(src));

    return 0;
}
Beispiel #14
0
static
int position_handler(const char *path, const char *types, lo_arg **argv, int argc,
		 lo_message msg, void *user_data)
{
	lo_address src = lo_message_get_source( msg );
	lo_server serv = (lo_server)user_data;
	int result;
	
	// Send back reply
	result = lo_send_from( src, serv, LO_TT_IMMEDIATE,
	              "/deck/position", "f", input_file->position );
	if (result<1) fprintf(stderr, "Error: sending reply failed: %s\n", lo_address_errstr(src));

    return 0;
}
Beispiel #15
0
static
int filepath_handler(const char *path, const char *types, lo_arg **argv, int argc,
		 lo_message msg, void *user_data)
{
	lo_address src = lo_message_get_source( msg );
	lo_server serv = (lo_server)user_data;
	int result;

	// Send back reply
	if (input_file->filepath) {
		result = lo_send_from( src, serv, LO_TT_IMMEDIATE,
					  "/deck/filepath", "s", input_file->filepath );
	} else {
		// Empty filepath
		result = lo_send_from( src, serv, LO_TT_IMMEDIATE, "/deck/filepath", "s", "" );
	}
	if (result<1) fprintf(stderr, "Error: sending reply failed: %s\n", lo_address_errstr(src));

    return 0;
}
Beispiel #16
0
int foo_handler(const char *path, const char *types, lo_arg **argv, int argc,
		 lo_message data, void *user_data)
{
    lo_server serv = (lo_server)user_data;
    lo_address src = lo_message_get_source(data);
    char *url = lo_address_get_url(src);
    char *server_url = lo_server_get_url(serv);
    printf("Address of us: %s\n", server_url);
    printf("%s <- f:%f, i:%d\n", path, argv[0]->f, argv[1]->i);
    if (lo_send_from(src, serv, LO_TT_IMMEDIATE, "/reply", "s", "a reply") == -1) {
	printf("OSC reply error %d: %s\nSending to %s\n", lo_address_errno(src), lo_address_errstr(src), url);
	exit(1);
    } else {
	printf("Reply sent to %s\n\n", url);
    }
    free(server_url);
    free(url);

    return 0;
}
Beispiel #17
0
static
int ping_handler(const char *path, const char *types, lo_arg **argv, int argc,
		 lo_message msg, void *user_data)
{
	lo_address src = lo_message_get_source( msg );
	lo_server serv = (lo_server)user_data;
	int result;
	
	// Display the address the ping came from
	if (verbose) {
		char *url = lo_address_get_url(src);
		printf( "Got ping from: %s\n", url);
		free(url);
	}

	// Send back reply
	result = lo_send_from( src, serv, LO_TT_IMMEDIATE, "/pong", "" );
	if (result<1) fprintf(stderr, "Error: sending reply failed: %s\n", lo_address_errstr(src));

    return 0;
}
Beispiel #18
0
int subtest_handler(const char *path, const char *types, lo_arg **argv,
                    int argc, lo_message data, void *user_data)
{
    int i;
    lo_address a = lo_message_get_source(data);
    static char *uri = NULL;

    printf("subtest: got reply (%s)\n", path);
    if (!uri) {
	uri = lo_address_get_url(a);
    } else {
	char *new_uri = lo_address_get_url(a);

	if (strcmp(uri, new_uri)) {
	    printf("ERROR: %s != %s\n", uri, new_uri);

	    exit(1);
	}
	free(new_uri);
    }
    lo_send(a, "/subtest-reply", "i", 0xbaa);
    if (lo_address_errno(a)) {
	fprintf(stderr, "subtest error %d: %s\n", lo_address_errno(a),
		lo_address_errstr(a));

	exit(1);
    }

    for (i=0; i<10; i++) {
#ifdef WIN32
        /* TODO: Wait time of 2.233 not easily doable in Windows */
        Sleep(2);
#else
        usleep(2233);
#endif
	lo_send(a, "/subtest-reply", "i", 0xbaa+i);
    }

    return 0;
}
Beispiel #19
0
int get_status_handler(const char *path, const char *types, lo_arg ** argv,
                int argc, void *data, void *user_data)
{
    /* example showing pulling the argument values out of the argv array */
    printf("%s <- deck:%i\n", path, argv[0]->i);
    fflush(stdout);
    
    int d = argv[0]->i;
    
    lo_address a = lo_message_get_source(data);
    
    char* url = lo_address_get_url(a);
    
    printf("%s\n", url);
    
    //url[strlen(url)-2] = 1;
    
    //printf("%s\n", url);
    
    osc_send_status(a, d);
    
}
Beispiel #20
0
int connect_handler(const char *path, const char *types, lo_arg ** argv,
                int argc, void *data, void *user_data)
{
    /* example showing pulling the argument values out of the argv array */
    printf("%s\n", path);
    fflush(stdout);
    
    lo_address a = lo_message_get_source(data);
    
    if(strcmp(lo_address_get_url(address[0]), lo_address_get_url(a)) == 0 || 
        strcmp(lo_address_get_url(address[1]), lo_address_get_url(a)) == 0) {
        // already stored as a client
    } else {
        address[osc_nconnection%2] = lo_address_new_from_url(lo_address_get_url(a));
        printf("OSC client %i address changed to:%s\n", osc_nconnection%2, lo_address_get_url(address[osc_nconnection%2]));
        
        
        ++osc_nconnection;
        if(osc_nclient < 2)
            ++osc_nclient;
    }

    struct deck *de;
    struct player *pl;

    fprintf(stderr, "osc_nclient %i osc_ndeck: %i\n", osc_nclient, osc_ndeck);
    int d;
    for(d = 0; d < osc_ndeck; ++d) {
        de = &osc_deck[d];
        pl = &de->player;
        osc_send_track_load(de);
        osc_send_ppm_block(pl->track);
    }
        
    
    return 0;
}
Beispiel #21
0
void InterfaceSim::on_add_receiver(const char *type)
{
    SimulationType t = str_type(type);
    if (t == ST_UNKNOWN) return;

    lo_address a = lo_message_get_source(m_msg);
    if (!a) return;

    char *url = lo_address_get_url(a);
    if (!url) return;

    // Physics can change object positions in any of the other
    // simulations
    if (t & ST_HAPTICS || t & ST_VISUAL)
        sendtotype(ST_PHYSICS, 0, "/world/add_receiver_url",
                   "ss", type, url);

    // Haptics can add force to objects in the physics simulation.
    if (t & ST_PHYSICS || t & ST_VISUAL)
        sendtotype(ST_HAPTICS, 0, "/world/add_receiver_url",
                   "ss", type, url);

    // Visual can send a message to haptics due to keyboard
    // shortcuts. (e.g. reset_workspace.)
    if (t & ST_HAPTICS)
        sendtotype(ST_VISUAL, 0, "/world/add_receiver_url",
                   "ss", type, url);

    // Interface can modify anything in any other simulation.
    add_receiver(0, url, t, false);

#ifdef DEBUG
    printf("[%s] add_receiver(): %s, source = %s\n", type_str(), type, url);
#endif
    free(url);
}
Beispiel #22
0
    int
    Client::osc_announce_reply(const char *path,
                               const char *types,
                               lo_arg **argv,
                               int argc,
                               lo_message msg,
                               void *user_data)
    {
        if(strcmp(&argv[0]->s, "/nsm/server/announce"))
            return -1;

        NSM::Client *nsm = (NSM::Client *)user_data;

//        MESSAGE( "Successfully registered. NSM says: %s", &argv[1]->s );
        nsm->nsm_is_active = true;
        nsm->_session_manager_name = strdup(&argv[2]->s);
        nsm->nsm_addr =
            lo_address_new_from_url(lo_address_get_url(lo_message_get_source(
                                                           msg)));

        nsm->command_active(nsm->nsm_is_active);

        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
int OSCServer::genericHandler(
        const char *path, const char *types,
        lo_arg **argv, int argc, void *data)
{
    UNUSED(argc); UNUSED(types);

    if(!contacted) {
        firstContact(lo_message_get_source((lo_message)data));
        contacted = true;
    }

    //find out what this message is for (track bus or master)

    std::string pathStr(path);

    pathStr = pathStr.substr(1);
    pathStr = pathStr.substr(pathStr.find("/") + 1);

    std::string object = pathStr.substr(0,pathStr.find("/"));

    pathStr = pathStr.substr(pathStr.find("/") + 1);
    std::string controllable = pathStr.substr(0,pathStr.find("/"));

    if(object == "track") {
        if(controllable == "fader") {
            //get the track number
            pathStr= pathStr.substr(pathStr.find("/") + 1);
            //build a midi event from the fader value and track number
            char data[3];
            if(pthread_mutex_lock(&idMutex) == 0) {
                data[0] = (char) CC_MASK;
                data[1] = trackIds[atoi(pathStr.c_str()) - 1];
                data[2] = (char) ((int) argv[0]->f);

                pthread_mutex_unlock(&idMutex);
            }
            MidiEvent midiEvent(data,true);
            //Send it to the jack client to handle send to Ardour
            if(!((unsigned char)data[1] == 0xFF)){
                jack_ringbuffer_write(controllerBuffer, (char *) &midiEvent,sizeof(MidiEvent));
            }
        }

        if(controllable == "bank") {
            if (argv[0]->f > 0.5){
                pathStr= pathStr.substr(pathStr.find("/") + 1);
                if(pathStr == "up"){
                    int tb = getTrackBank();
                    if((tb+1) < numTrackBanks) {
                        sendTrackBank(tb+1);
                        setTrackBank(tb+1);
                    }
                }
                else if(pathStr == "down"){
                    int tb = getTrackBank();
                    if(tb > 0) {
                        sendTrackBank(tb-1);
                        setTrackBank(tb-1);
                    }
                }

            }
        }


    } else if (object == "bus") {

        if(controllable == "fader") {
            //get the bus number(void *)this
            pathStr= pathStr.substr(pathStr.find("/") + 1);
            char data[3];
            if(pthread_mutex_lock(&idMutex) == 0) {
                data[0] = (char) CC_MASK;
                data[1] = busIds[atoi(pathStr.c_str()) - 1];
                data[2] = (char) ((int) argv[0]->f);

                pthread_mutex_unlock(&idMutex);
            }
            MidiEvent midiEvent(data,true);
            //Send it to the jack client to handle send to Ardour
            //Send it to the jack client to handle send to Ardour
            if(!((unsigned char)data[1] == 0xFF)){
                jack_ringbuffer_write(controllerBuffer, (char *) &midiEvent,sizeof(MidiEvent));
            }
        }

        if(controllable == "bank") {
            if (argv[0]->f > 0.5){
                pathStr= pathStr.substr(pathStr.find("/") + 1);
                if(pathStr == "up"){
                    int bb = getBusBank();
                    if((bb+1) < numBusBanks) {
                        setBusBank(bb+1);
                        sendBusBank(bb+1);
                    }
                }
                else if(pathStr == "down"){
                    int bb = getBusBank();
                    if(bb > 0) {
                        setBusBank(bb-1);
                        sendBusBank(bb-1);
                    }
                }

            }
        }


    }
    else if (object == "master") {
        if(controllable == "fader") {
            //build a midi event from the fader value and track number
            char data[3] = {(char) CC_MASK,MASTER_CC,(char)((int) argv[0]->f)};
            MidiEvent midiEvent(data,true);
            //Send it to the jack client to handle send to Ardour
            jack_ringbuffer_write(controllerBuffer, (char *) &midiEvent,sizeof(MidiEvent));
        }

    }

    else if (object == "scene") {
    }

    return 0;
}
Beispiel #25
0
// /audio
//handler for audio messages
int audio_handler(const char *path, const char *types, lo_arg **argv, int argc,
	void *data, void *user_data)
{
	if(shutdown_in_progress==1)
	{
		return 0;
	}

	//init to 0, increment before use
	msg_received_counter++;

	gettimeofday(&tv, NULL);

	//first blob is at data_offset+1 (one-based)
	int data_offset=4;

	//ignore first n channels/blobs
	data_offset+=channel_offset;

	message_number_prev=message_number;

	//the messages are numbered sequentially. first msg is numberd 1
	message_number=argv[0]->h;

	if(message_number_prev<message_number-1)
	{
		fprintf(stderr,"\ngap in message sequence! possibly lost %" PRId64" message(s) on the way.\n"
			,message_number-message_number_prev-1);
		fflush(stderr);
	}

	//total args count minus metadata args and channel offset count = number of blobs
	input_port_count=argc-data_offset;

	//only process useful number of channels
	port_count=fmin(input_port_count,output_port_count);

	if(port_count < 1)
	{
		fprintf(stderr,"\n\nchannel offset %d >= available input channels %d! (nothing to receive). shutting down...\n"
			,channel_offset
			,(argc-data_offset+channel_offset));
		fflush(stderr);
		shutdown_in_progress=1;
		return 0;
	}

	//need to warn when offset + outchannels limited

	//check sample rate and period size if sender (re)started or values not yet initialized (=no /offer received)
	if(message_number_prev>message_number || message_number==1 || remote_sample_rate==0 || remote_period_size==0 )
	{
		lo_address loa;

		loa = lo_message_get_source(data);

		strcpy(sender_host,lo_address_get_hostname(loa));
		strcpy(sender_port,lo_address_get_port(loa));

		remote_sample_rate=argv[3]->i;

		remote_period_size=lo_blob_datasize((lo_blob)argv[0+data_offset])/bytes_per_sample;
		fprintf(stderr,"\nsender was (re)started. ");

		if(remote_period_size!=period_size)
		{
			fprintf(stderr,"sender period size: %d samples (%.3f x forward period size)\n\n",remote_period_size,(float)remote_period_size/period_size);
		}
		else
		{
			fprintf(stderr,"equal sender and receiver period size\n\n");
		}

	}//end if "no-offer init" was needed

	remote_xrun_counter=argv[1]->h;

	lo_timetag tt=argv[2]->t;

	double msg_time=tt.sec+(double)tt.frac/1000000;
	double msg_time_prev=tt_prev.sec+(double)tt_prev.frac/1000000;
	double time_now=tv.tv_sec+(double)tv.tv_usec/1000000;

	time_interval=msg_time-msg_time_prev;

	time_interval_sum+=time_interval;
	time_interval_avg=(float)time_interval_sum/msg_received_counter;

	tt_prev=tt;

	//reset avg calc, check and reset after use
	if(msg_received_counter>=avg_calc_interval)
	{
		msg_received_counter=0;
		time_interval_sum=0;
	}

	fflush(stderr);

	//
	process_enabled=1;

	int mc_period_bytes=period_size*bytes_per_sample*port_count;

	//check if a whole mc period can be written to the ringbuffer
	uint64_t can_write_count=rb_can_write(rb);
	if(can_write_count < mc_period_bytes)
	{
			buffer_overflow_counter++;
			/////////////////
			fprintf(stderr,"\nBUFFER OVERFLOW! this is bad -----%s\n","\033[0J");
			return 0;
	}

	//========================================
	//new: support different period sizes on sender / receiver (still need same SR)
	//this needs more tests and optimization
	if(period_size==remote_period_size)
	{
		int i;
		//don't read more channels than we have outputs
		for(i=0;i < port_count;i++)
		{
			//get blob (=one period of one channel)
			unsigned char *data = lo_blob_dataptr((lo_blob)argv[i+data_offset]);
			//fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset]));

			//write to ringbuffer
			//==========================================
			int cnt=rb_write(rb, (void *) data, 
				period_size*bytes_per_sample);
		}
	}
	else if(period_size>remote_period_size)
	{
		int i;
		//don't read more channels than we have outputs
		for(i=0;i < port_count;i++)
		{
			//get blob (=one period of one channel)
			unsigned char *data = lo_blob_dataptr((lo_blob)argv[i+data_offset]);
			//fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset]));

			//write to temporary ringbuffer until there is enough data
			//==========================================
			int cnt=rb_write(rb_helper, (void *) data, 
				remote_period_size*bytes_per_sample);
		}

		//if enough data collected for one larger multichannel period

		while(rb_can_read(rb_helper)	>=mc_period_bytes
		&& rb_can_write(rb)		>=mc_period_bytes)
		{
			//transfer from helper to main ringbuffer
			unsigned char* data;
			data=malloc(				mc_period_bytes);
			//store orig pointer
			unsigned char* orig_data=data;
			rb_read(rb_helper,data,	mc_period_bytes);

			for(i=0;i < port_count;i++)
			{
				int k;
				for(k=0;k<(period_size/remote_period_size);k++)
				{
					//reset pointer
					data=orig_data;
					//position in helper buffer for next sample for main buffer
					data+=	k*remote_period_size*bytes_per_sample*port_count
							+ i*remote_period_size*bytes_per_sample;

					//write one channel snipped (remote_period_size) to main buffer
					int w=rb_write(rb,(void *)data,remote_period_size*bytes_per_sample);
				}
			}
			data=orig_data;
			free(data);
		}
	}
	else if(period_size<remote_period_size)
	{
		int k;
		for(k=0;k<(remote_period_size/period_size);k++)
		{

			int i;
			//don't read more channels than we have outputs
			for(i=0;i < port_count;i++)
			{
				//get blob (=one period of one channel)
				unsigned char *data = lo_blob_dataptr((lo_blob)argv[i+data_offset]);
				//fprintf(stderr,"size %d\n",lo_blob_datasize((lo_blob)argv[i+data_offset]));

				//write to ringbuffer
				//==========================================
				data+=k*period_size*bytes_per_sample;

				int cnt=rb_write(rb, (void *) data, 
					period_size*bytes_per_sample);
			}
		}
	}

	return 0;
}//end audio_handler
Beispiel #26
0
// /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
char	*osc_get_uri(void *data)
{
	lo_address a = lo_message_get_source(data);
	char *uri = lo_address_get_url(a);
	return uri;
}
int osc_controller::_param_cb(const char* path, const char* types,
                              lo_arg** argv, int argc, lo_message msg)
{
    if (argc < 4)
        return 0;

    if (!m_restricted || is_target(lo_message_get_source(msg))) {
	pair<int,int> net_id(argv[0]->i, argv[1]->i);

	map<pair<int,int>, int>::iterator it = m_local_id.find(net_id);
	world_node obj;

	if (it != m_local_id.end() &&
	    !(obj = m_world->find_node(it->second)).is_null()) {



	    m_skip++;
            int param_type = 0;

            // TODO: CLEAN this shit!
            switch (types[2])
            {
            case 'i':
            {
                int param_id = argv[2]->i;
                switch(param_type = obj.get_param_type(param_id)) {
                case graph::node_param::FLOAT:
                    m_world->set_param_node(obj, param_id, argv[3]->f);
                    break;
                case graph::node_param::INT:
                    m_world->set_param_node(obj, param_id, argv[3]->i);
                    break;
                case graph::node_param::STRING:
                    m_world->set_param_node(obj, param_id, string(&argv[3]->s));
                    break;
                case graph::node_param::VECTOR2F:
                    if (argc < 5)
                        return 0;
                    m_world->set_param_node(
                        obj, param_id, base::vector_2f(argv[3]->f, argv[4]->f));
                    break;
                default:
                    return 0;
                }
                break;
            }

            case 's':
            {
                std::string param_id = &argv[2]->s;
                switch(param_type = obj.get_param_type(param_id)) {
                case graph::node_param::FLOAT:
                    m_world->set_param_node(obj, param_id, argv[3]->f);
                    break;
                case graph::node_param::INT:
                    m_world->set_param_node(obj, param_id, argv[3]->i);
                    break;
                case graph::node_param::STRING:
                    m_world->set_param_node(obj, param_id, string(&argv[3]->s));
                    break;
                case graph::node_param::VECTOR2F:
                    if (argc < 5)
                        return 0;
                    m_world->set_param_node(
                        obj, param_id, base::vector_2f(argv[3]->f, argv[4]->f));
                    break;
                default:
                    return 0;
                }
                break;
            }

            default:
                return 0;
            }


	    m_skip--;

	    if (m_broadcast) {
		lo_message newmsg = lo_message_new();
		lo_message_add_int32(newmsg, argv[0]->i);
		lo_message_add_int32(newmsg, argv[1]->i);
		lo_message_add_int32(newmsg, argv[2]->i);

		switch(param_type) {
		case graph::node_param::FLOAT:
		    lo_message_add_float(newmsg, argv[3]->f);
		    break;
		case graph::node_param::INT:
		    lo_message_add_int32(newmsg, argv[3]->i);
		    break;
		case graph::node_param::STRING:
		    lo_message_add_string(newmsg, &argv[3]->s);
		    break;
		case graph::node_param::VECTOR2F:
		    lo_message_add_float(newmsg, argv[3]->f);
		    lo_message_add_float(newmsg, argv[4]->f);
		    break;
		default:
		    break;
		}

		broadcast_message_from(PSYNTH_OSC_MSG_PARAM, newmsg, lo_message_get_source(msg));
		lo_message_free(newmsg);
	    }
	}
    }

    return 0;
}
Beispiel #29
0
int all_callback(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data) {
	printf("got %s from %s\n",path,lo_address_get_url(lo_message_get_source(msg)));
	return 1;
}
// *********************************************************
// -(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;
}