Mixer: Allow clients to query for available OSC paths.
This commit is contained in:
parent
d959b54f6a
commit
fe4faaca1b
|
@ -106,7 +106,8 @@ Controller_Module::generate_osc_path ()
|
||||||
|
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
asprintf( &path, "/mixer/%s/%s/%s", chain()->name(), p->module()->label(), p->name() );
|
// /mixer/strip/STRIPNAME/control/MODULENAME/CONTROLNAME
|
||||||
|
asprintf( &path, "/mixer/strip/%s/control/%s/%s", chain()->name(), p->module()->label(), p->name() );
|
||||||
|
|
||||||
// Hack to keep spaces out of OSC URL... Probably need to handle other special characters similarly.
|
// Hack to keep spaces out of OSC URL... Probably need to handle other special characters similarly.
|
||||||
for ( int i = strlen( path ); i--; )
|
for ( int i = strlen( path ); i--; )
|
||||||
|
@ -114,7 +115,6 @@ Controller_Module::generate_osc_path ()
|
||||||
if ( path[i] == ' ' )
|
if ( path[i] == ' ' )
|
||||||
path[i] = '_';
|
path[i] = '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ Controller_Module::change_osc_path ( char *path )
|
||||||
|
|
||||||
if ( path )
|
if ( path )
|
||||||
{
|
{
|
||||||
mixer->osc_endpoint->add_method( path, "f", &Controller_Module::osc_control_change, this );
|
mixer->osc_endpoint->add_method( path, "f", &Controller_Module::osc_control_change, this, "value" );
|
||||||
|
|
||||||
_osc_path = path;
|
_osc_path = path;
|
||||||
|
|
||||||
|
|
|
@ -65,12 +65,6 @@ extern char *user_config_dir;
|
||||||
/* OSC Message Handlers */
|
/* OSC Message Handlers */
|
||||||
/************************/
|
/************************/
|
||||||
|
|
||||||
OSC_HANDLER( generic )
|
|
||||||
{
|
|
||||||
OSC_DMSG();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSC_HANDLER( quit )
|
OSC_HANDLER( quit )
|
||||||
{
|
{
|
||||||
|
@ -125,14 +119,9 @@ OSC_HANDLER( new )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSC_HANDLER( root )
|
// OSC_HANDLER( root )
|
||||||
{
|
// {
|
||||||
OSC_DMSG();
|
// }
|
||||||
|
|
||||||
OSC_REPLY( "load\nsave\nquit\nnew\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSC_HANDLER( add_strip )
|
OSC_HANDLER( add_strip )
|
||||||
{
|
{
|
||||||
|
@ -395,15 +384,14 @@ Mixer::init_osc ( const char *osc_port )
|
||||||
|
|
||||||
// if ( 1 >= lo_send_from( src, ((Mixer*)user_data)->osc_endpoint, LO_TT_IMMEDIATE, "/finger-reply", "s", s ) )
|
// if ( 1 >= lo_send_from( src, ((Mixer*)user_data)->osc_endpoint, LO_TT_IMMEDIATE, "/finger-reply", "s", s ) )
|
||||||
|
|
||||||
osc_endpoint->add_method( "/nsm/quit", "", OSC_NAME( quit ), this );
|
osc_endpoint->add_method( "/nsm/quit", "", OSC_NAME( quit ), this, "" );
|
||||||
osc_endpoint->add_method( "/nsm/load", "ss", OSC_NAME( load ), this );
|
osc_endpoint->add_method( "/nsm/load", "ss", OSC_NAME( load ), this, "path,display_name" );
|
||||||
osc_endpoint->add_method( "/nsm/save", "", OSC_NAME( save ), this );
|
osc_endpoint->add_method( "/nsm/save", "", OSC_NAME( save ), this, "" );
|
||||||
osc_endpoint->add_method( "/nsm/new", "ss", OSC_NAME( new ), this );
|
osc_endpoint->add_method( "/nsm/new", "ss", OSC_NAME( new ), this, "path,display_name" );
|
||||||
osc_endpoint->add_method( "/nsm/", "", OSC_NAME( root ), this );
|
// osc_endpoint->add_method( "/nsm/", "", OSC_NAME( root ), this );
|
||||||
osc_endpoint->add_method( "/finger", "", OSC_NAME( finger ), this );
|
osc_endpoint->add_method( "/finger", "", OSC_NAME( finger ), this, "" );
|
||||||
osc_endpoint->add_method( "/mixer/add_strip", "", OSC_NAME( add_strip ), this );
|
osc_endpoint->add_method( "/mixer/add_strip", "", OSC_NAME( add_strip ), this, "" );
|
||||||
// osc_endpoint->add_method( NULL, "", osc_generic, this );
|
|
||||||
|
|
||||||
// osc_endpoint->start();
|
// osc_endpoint->start();
|
||||||
|
|
||||||
/* poll so we can keep OSC handlers running in the GUI thread and avoid extra sync */
|
/* poll so we can keep OSC handlers running in the GUI thread and avoid extra sync */
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "Endpoint.H"
|
#include "Endpoint.H"
|
||||||
|
|
||||||
|
@ -48,6 +49,11 @@ namespace OSC
|
||||||
char *url = lo_server_get_url(_server);
|
char *url = lo_server_get_url(_server);
|
||||||
printf("OSC: %s\n",url);
|
printf("OSC: %s\n",url);
|
||||||
free(url);
|
free(url);
|
||||||
|
|
||||||
|
|
||||||
|
add_method( NULL, "", &Endpoint::osc_generic, this, "" );
|
||||||
|
|
||||||
|
// _path_names = new std::list<const char*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Endpoint::~Endpoint ( )
|
Endpoint::~Endpoint ( )
|
||||||
|
@ -56,12 +62,63 @@ namespace OSC
|
||||||
lo_server_free( _server );
|
lo_server_free( _server );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Endpoint::osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
||||||
|
{
|
||||||
|
OSC_DMSG();
|
||||||
|
|
||||||
|
if ( path[ strlen(path) - 1 ] != '/' )
|
||||||
|
{
|
||||||
|
DMESSAGE( "Unknown OSC signal %s", path );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *paths = ((Endpoint*)user_data)->get_paths( path );
|
||||||
|
|
||||||
|
((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path, paths );
|
||||||
|
|
||||||
|
free(paths);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a malloc()'d string containing path names beginning with /prefix/, newline separated
|
||||||
|
char *
|
||||||
|
Endpoint::get_paths ( const char *prefix )
|
||||||
|
{
|
||||||
|
char *r = (char*)malloc( 1024 );
|
||||||
|
r[0] = 0;
|
||||||
|
|
||||||
|
for ( std::list<char*>::iterator i = _path_names.begin(); i != _path_names.end(); ++i )
|
||||||
|
{
|
||||||
|
if ( ! *i )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (! strncmp( *i, prefix, strlen(prefix) ) )
|
||||||
|
{
|
||||||
|
r = (char*)realloc( r, strlen( r ) + strlen( *i ) + 2 );
|
||||||
|
|
||||||
|
strcat( r, *i );
|
||||||
|
strcat( r, "\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data )
|
Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description )
|
||||||
{
|
{
|
||||||
DMESSAGE( "Added OSC method %s (%s)", path, typespec );
|
DMESSAGE( "Added OSC method %s (%s)", path, typespec );
|
||||||
|
|
||||||
lo_server_add_method( _server, path, typespec, handler, user_data );
|
lo_server_add_method( _server, path, typespec, handler, user_data );
|
||||||
|
|
||||||
|
char *stored_path;
|
||||||
|
|
||||||
|
asprintf( &stored_path, "%s (%s); %s", path, typespec, argument_description );
|
||||||
|
|
||||||
|
_path_names.push_back( stored_path );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -70,6 +127,18 @@ namespace OSC
|
||||||
DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
|
DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
|
||||||
|
|
||||||
lo_server_del_method( _server, path, typespec );
|
lo_server_del_method( _server, path, typespec );
|
||||||
|
|
||||||
|
for ( std::list<char *>::iterator i = _path_names.begin(); i != _path_names.end(); ++i )
|
||||||
|
{
|
||||||
|
if ( ! *i )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( ! strncmp( path, *i, index( *i, ' ' ) - *i ) )
|
||||||
|
{
|
||||||
|
free( *i );
|
||||||
|
i = _path_names.erase( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* void * */
|
/* void * */
|
||||||
|
@ -146,7 +215,6 @@ namespace OSC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Endpoint::send ( lo_address to, const char *path, std::list< OSC_Value > values )
|
Endpoint::send ( lo_address to, const char *path, std::list< OSC_Value > values )
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,18 +109,24 @@ namespace OSC
|
||||||
{
|
{
|
||||||
static void error_handler(int num, const char *msg, const char *path);
|
static void error_handler(int num, const char *msg, const char *path);
|
||||||
|
|
||||||
|
|
||||||
|
static int osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
||||||
|
|
||||||
// Thread _thread;
|
// Thread _thread;
|
||||||
|
|
||||||
// lo_server_thread _st;
|
// lo_server_thread _st;
|
||||||
lo_server _server;
|
lo_server _server;
|
||||||
|
|
||||||
|
std::list<char*> _path_names;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Endpoint ( const char *port = 0 );
|
Endpoint ( const char *port = 0 );
|
||||||
|
|
||||||
~Endpoint ( );
|
~Endpoint ( );
|
||||||
|
|
||||||
void add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data );
|
char *get_paths ( const char *prefix );
|
||||||
|
void add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description );
|
||||||
void del_method ( const char *path, const char *typespec );
|
void del_method ( const char *path, const char *typespec );
|
||||||
void start ( void );
|
void start ( void );
|
||||||
void stop ( void );
|
void stop ( void );
|
||||||
|
|
Loading…
Reference in New Issue