diff --git a/mixer/src/Chain.C b/mixer/src/Chain.C index 55956d9..15adc29 100644 --- a/mixer/src/Chain.C +++ b/mixer/src/Chain.C @@ -446,7 +446,9 @@ Chain::name ( const char *name ) _name = name; for ( int i = 0; i < modules(); ++i ) + { module( i )->handle_chain_name_changed(); + } } bool diff --git a/mixer/src/Controller_Module.C b/mixer/src/Controller_Module.C index e105d4c..7b91d08 100644 --- a/mixer/src/Controller_Module.C +++ b/mixer/src/Controller_Module.C @@ -42,6 +42,11 @@ #include "Engine/Engine.H" #include "Chain.H" +#include "OSC/Endpoint.H" + +// needed for mixer->endpoint +#include "Mixer.H" + const float CONTROL_UPDATE_FREQ = 0.1f; @@ -60,6 +65,7 @@ Controller_Module::Controller_Module ( bool is_default ) : Module( is_default, 5 add_port( Port( this, Port::OUTPUT, Port::CONTROL ) ); _mode = GUI; + _osc_path = NULL; // mode( GUI ); // mode( CV ); @@ -70,7 +76,6 @@ Controller_Module::Controller_Module ( bool is_default ) : Module( is_default, 5 Fl::add_timeout( CONTROL_UPDATE_FREQ, update_cb, this ); log_create(); - } Controller_Module::~Controller_Module ( ) @@ -81,6 +86,59 @@ Controller_Module::~Controller_Module ( ) /* shutdown JACK port, if we have one */ mode( GUI ); + + change_osc_path( NULL ); +} + +void +Controller_Module::handle_chain_name_changed() +{ + change_osc_path( generate_osc_path() ); +} + +char * +Controller_Module::generate_osc_path () +{ + const Port *p = control_output[0].connected_port(); + + if ( !p ) + return NULL; + + char *path; + + asprintf( &path, "/mixer/%s/%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. + for ( int i = strlen( path ); i--; ) + { + if ( path[i] == ' ' ) + path[i] = '_'; + } + + + return path; +} + +void +Controller_Module::change_osc_path ( char *path ) +{ + if ( _osc_path ) + { + mixer->osc_endpoint->del_method( _osc_path, "f" ); + + free( _osc_path ); + + _osc_path = NULL; + } + + if ( path ) + { + mixer->osc_endpoint->add_method( path, "f", &Controller_Module::osc_control_change, this ); + + _osc_path = path; + + tooltip( _osc_path ); + } } @@ -180,7 +238,7 @@ Controller_Module::mode ( Mode m ) chain()->engine()->unlock(); } } - else if ( mode() == CV && m == GUI ) + else if ( mode() == CV && m != CV ) { chain()->engine()->lock(); @@ -391,6 +449,10 @@ Controller_Module::connect_to ( Port *p ) resizable( w ); /* init_sizes(); */ } + + // create OSC port + + change_osc_path( generate_osc_path() ); } void @@ -461,6 +523,8 @@ Controller_Module::menu_cb ( const Fl_Menu_ *m ) mode( GUI ); else if ( ! strcmp( picked, "Mode/Control Voltage" ) ) mode( CV ); + else if ( ! strcmp( picked, "Mode/Open Sound Control (OSC)" ) ) + mode( OSC ); } /** build the context menu for this control */ @@ -474,7 +538,7 @@ Controller_Module::menu ( void ) { "Mode", 0, 0, 0, FL_SUBMENU }, { "Manual", 0, 0, 0, FL_MENU_RADIO | ( mode() == GUI ? FL_MENU_VALUE : 0 ) }, { "Control Voltage", 0, 0, 0, FL_MENU_RADIO | ( mode() == CV ? FL_MENU_VALUE : 0 ) }, -// { "Open Sound Control (OSC)", 0, 0, 0, FL_MENU_RADIO | ( mode() == OSC ? FL_MENU_VALUE : 0 ) }, + { "Open Sound Control (OSC)", 0, 0, 0, FL_MENU_RADIO | ( mode() == OSC ? FL_MENU_VALUE : 0 ) }, { 0 }, { 0 }, }; @@ -575,3 +639,22 @@ Controller_Module::process ( nframes_t nframes ) control_value = f; } } + +int +Controller_Module::osc_control_change ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) +{ + Controller_Module *c = (Controller_Module*)user_data; + + if ( c->mode() != OSC ) + return 0; + + OSC_DMSG(); + + c->control_value = argv[0]->f; + + mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" ); + +// OSC_REPLY_OK(); + + return 0; +} diff --git a/mixer/src/Controller_Module.H b/mixer/src/Controller_Module.H index a452442..b76042b 100644 --- a/mixer/src/Controller_Module.H +++ b/mixer/src/Controller_Module.H @@ -22,6 +22,7 @@ #include "Module.H" #include #include "JACK/Port.H" +#include "OSC/Endpoint.H" class Fl_Menu_Button; class Fl_Menu_; @@ -42,6 +43,8 @@ class Controller_Module : public Module static void menu_cb ( Fl_Widget *w, void *v ); void menu_cb ( const Fl_Menu_ *m ); + char *_osc_path; + public: enum Mode { GUI, CV, OSC, MIDI }; @@ -76,6 +79,7 @@ public: bool connect_spatializer_to ( Module *m ); void handle_control_changed ( Port *p ); + void handle_chain_name_changed ( void ); LOG_CREATE_FUNC( Controller_Module ); @@ -89,6 +93,8 @@ public: int handle ( int m ); +// void set_control_value ( float f ) { control_value = f; } + protected: void get ( Log_Entry &e ) const; @@ -96,6 +102,12 @@ protected: private: + char *generate_osc_path ( void ); + void change_osc_path ( char *path ); + + static int osc_control_change ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); + + std::vector jack_input; Mode _mode; Type _type; diff --git a/mixer/src/Mixer.C b/mixer/src/Mixer.C index ce15e68..7327037 100644 --- a/mixer/src/Mixer.C +++ b/mixer/src/Mixer.C @@ -78,6 +78,8 @@ OSC_HANDLER( quit ) ((Mixer*)user_data)->command_quit(); + OSC_REPLY_OK(); + return 0; } diff --git a/mixer/src/Module.C b/mixer/src/Module.C index 696ce86..920084b 100644 --- a/mixer/src/Module.C +++ b/mixer/src/Module.C @@ -548,6 +548,17 @@ Module::menu ( void ) const return m; } +void +Module::handle_chain_name_changed ( ) +{ + // pass it along to our connected Controller_Modules, if any. + for ( int i = 0; i < ncontrol_inputs(); ++i ) + { + if ( control_input[i].connected() ) + control_input[i].connected_port()->module()->handle_chain_name_changed(); + } +} + int Module::handle ( int m ) { diff --git a/mixer/src/Module.H b/mixer/src/Module.H index 939410c..2d35063 100644 --- a/mixer/src/Module.H +++ b/mixer/src/Module.H @@ -341,7 +341,7 @@ public: /* called whenever the name of the chain changes (usually because * the name of the mixer strip changed). */ - virtual void handle_chain_name_changed () {} + virtual void handle_chain_name_changed (); virtual void handle_port_connection_change () {} diff --git a/nonlib/OSC/Endpoint.C b/nonlib/OSC/Endpoint.C index 346877f..3408a8f 100644 --- a/nonlib/OSC/Endpoint.C +++ b/nonlib/OSC/Endpoint.C @@ -59,12 +59,16 @@ namespace OSC void Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data ) { + DMESSAGE( "Added OSC method %s (%s)", path, typespec ); + lo_server_add_method( _server, path, typespec, handler, user_data ); } void Endpoint::del_method ( const char *path, const char *typespec ) { + DMESSAGE( "Deleted OSC method %s (%s)", path, typespec ); + lo_server_del_method( _server, path, typespec ); }