diff --git a/mixer/src/Controller_Module.C b/mixer/src/Controller_Module.C index 4953fb0..b9ce74f 100644 --- a/mixer/src/Controller_Module.C +++ b/mixer/src/Controller_Module.C @@ -41,7 +41,6 @@ #include "Engine/Engine.H" #include "Chain.H" - #include "OSC/Endpoint.H" // needed for mixer->endpoint @@ -65,7 +64,6 @@ 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 ); @@ -86,69 +84,12 @@ 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; - - // /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. - 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 ); - free( _osc_path_cv ); - - _osc_path = NULL; - _osc_path_cv = NULL; - } - - if ( path ) - { - _osc_path_cv = (char*)malloc( strlen( path ) + 4 ); - _osc_path_cv[0] = 0; - - strcpy( _osc_path_cv, path ); - strcat( _osc_path_cv, "/cv" ); - - mixer->osc_endpoint->add_method( path, "f", &Controller_Module::osc_control_change_exact, this, "value" ); - - mixer->osc_endpoint->add_method( _osc_path_cv, "f", &Controller_Module::osc_control_change_cv, this, "value" ); - - _osc_path = path; - - tooltip( _osc_path ); - } +// change_osc_path( generate_osc_path() ); } @@ -463,8 +404,6 @@ Controller_Module::connect_to ( Port *p ) } // create OSC port - - change_osc_path( generate_osc_path() ); } void @@ -550,7 +489,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 }, }; @@ -587,14 +526,20 @@ Controller_Module::handle ( int m ) } void -Controller_Module::handle_control_changed ( Port * ) +Controller_Module::handle_control_changed ( Port *p ) { /* ignore changes initiated while mouse is over widget */ if ( contains( Fl::pushed() ) ) return; + if ( p ) + control_value = p->control_value(); + if ( control->value() != control_value ) + { redraw(); + DMESSAGE( "handle_control_changed" ); + } if ( type() == SPATIALIZATION ) { @@ -652,64 +597,3 @@ Controller_Module::process ( nframes_t nframes ) control_value = f; } } - -int -Controller_Module::osc_control_change_exact ( 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(); - - const Port *p = c->control_output[0].connected_port(); - - float f = argv[0]->f; - - if ( p->hints.ranged ) - { - if ( f > p->hints.maximum ) - f = p->hints.maximum; - else if ( f < p->hints.minimum ) - f = p->hints.minimum; - } - - c->control_value = f; - - mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" ); - - return 0; -} - -int -Controller_Module::osc_control_change_cv ( 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(); - - const Port *p = c->control_output[0].connected_port(); - - float f = argv[0]->f; - - if (p->hints.ranged ) - { - // scale value to range. - // we assume that CV values are between 0 and 1 - - float scale = p->hints.maximum - p->hints.minimum; - float offset = p->hints.minimum; - - f = ( f * scale ) + offset; - } - - c->control_value = f; - - mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" ); - - return 0; -} diff --git a/mixer/src/Controller_Module.H b/mixer/src/Controller_Module.H index 2e30388..60b2ba1 100644 --- a/mixer/src/Controller_Module.H +++ b/mixer/src/Controller_Module.H @@ -106,9 +106,6 @@ private: char *generate_osc_path ( void ); void change_osc_path ( char *path ); - static int osc_control_change_exact ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); - static int osc_control_change_cv ( 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/Module.C b/mixer/src/Module.C index 920084b..8e49631 100644 --- a/mixer/src/Module.C +++ b/mixer/src/Module.C @@ -37,6 +37,7 @@ #include #include "FL/test_press.H" #include "FL/menu_popup.H" +#include "Mixer.H" @@ -65,7 +66,6 @@ Module::Module ( ) : Fl_Group( 0, 0, 50, 50, "Unnamed" ) { init(); - log_create(); } @@ -83,12 +83,16 @@ Module::~Module ( ) for ( unsigned int i = 0; i < audio_output.size(); ++i ) audio_output[i].disconnect(); for ( unsigned int i = 0; i < control_input.size(); ++i ) + { control_input[i].disconnect(); + control_input[i].destroy_osc_port(); + } for ( unsigned int i = 0; i < control_output.size(); ++i ) control_output[i].disconnect(); audio_input.clear(); audio_output.clear(); + control_input.clear(); control_output.clear(); } @@ -187,6 +191,118 @@ Module::paste_before ( void ) m->copy(); } + +char * +Module::Port::generate_osc_path () +{ + const Port *p = this; + + char *path; + + // /mixer/strip/STRIPNAME/control/MODULENAME/CONTROLNAME + asprintf( &path, "/mixer/strip/%s/control/%s/%s", module()->chain()->name(), p->module()->label(), p->name() ); + +// asprintf( &path, "/mixer/strip/control/%s/%s", 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 +Module::Port::change_osc_path ( char *path ) +{ + if ( _osc_path ) + { + mixer->osc_endpoint->del_method( _osc_path, "f" ); + + free( _osc_path ); + free( _osc_path_cv ); + + _osc_path = NULL; + _osc_path_cv = NULL; + } + + if ( path ) + { + _osc_path_cv = (char*)malloc( strlen( path ) + 4 ); + _osc_path_cv[0] = 0; + + strcpy( _osc_path_cv, path ); + strcat( _osc_path_cv, "/cv" ); + + mixer->osc_endpoint->add_method( path, "f", &Module::Port::osc_control_change_exact, this, "value" ); + + mixer->osc_endpoint->add_method( _osc_path_cv, "f", &Module::Port::osc_control_change_cv, this, "value" ); + + _osc_path = path; + +// tooltip( _osc_path ); + } +} + + +int +Module::Port::osc_control_change_exact ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) +{ + Module::Port *p = (Module::Port*)user_data; + + OSC_DMSG(); + +// const Port *p = c->control_output[0].connected_port(); + + float f = argv[0]->f; + + if ( p->hints.ranged ) + { + if ( f > p->hints.maximum ) + f = p->hints.maximum; + else if ( f < p->hints.minimum ) + f = p->hints.minimum; + } + + p->control_value( f ); + + mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" ); + + return 0; +} + +int +Module::Port::osc_control_change_cv ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) +{ + Module::Port *p = (Module::Port*)user_data; + +// const Port *p = c->control_output[0].connected_port(); + + float f = argv[0]->f; + + if (p->hints.ranged ) + { + // scale value to range. + // we assume that CV values are between 0 and 1 + + float scale = p->hints.maximum - p->hints.minimum; + float offset = p->hints.minimum; + + f = ( f * scale ) + offset; + } + + p->control_value( f ); + +// c->control_value = f; + + mixer->osc_endpoint->send( lo_message_get_source( msg ), "/reply", path, "ok" ); + + return 0; +} + + void Module::set ( Log_Entry &e ) { diff --git a/mixer/src/Module.H b/mixer/src/Module.H index 2d35063..14e8987 100644 --- a/mixer/src/Module.H +++ b/mixer/src/Module.H @@ -30,6 +30,7 @@ #include "Loggable.H" #include "JACK/Port.H" +#include "OSC/Endpoint.H" class Chain; class Module_Parameter_Editor; @@ -97,7 +98,7 @@ public: float maximum; float default_value; int dimensions; - + Hints ( ) { type = LINEAR; @@ -109,6 +110,9 @@ public: } }; + static int osc_control_change_exact ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); + static int osc_control_change_cv ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); + Hints hints; Port ( Module *module, Direction direction, Type type, const char *name = 0 ) @@ -120,6 +124,8 @@ public: _nframes = 0; _connected = 0; _module = module; + _osc_path = 0; + _osc_path_cv = 0; } Port ( const Port& p ) @@ -132,10 +138,13 @@ public: _connected = p._connected; _module = p._module; hints = p.hints; + _osc_path = p._osc_path; + _osc_path_cv = p._osc_path; } virtual ~Port ( ) { + // change_osc_path( NULL ); // disconnect(); } @@ -149,6 +158,17 @@ public: void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; }; void *buffer ( void ) const { return _buf; } + void update_osc_port ( ) + { + if ( INPUT == _direction ) + change_osc_path( generate_osc_path() ); + } + + void destroy_osc_port ( ) + { + change_osc_path( NULL ); + } + void control_value_no_callback ( float f ) { THREAD_ASSERT( UI ); @@ -163,6 +183,8 @@ public: { control_value_no_callback( f ); _module->handle_control_changed( this ); + if ( connected() ) + connected_port()->_module->handle_control_changed( connected_port() ); } float control_value ( ) const @@ -208,6 +230,9 @@ public: private: + char *generate_osc_path ( void ); + void change_osc_path ( char *path ); + Port *_connected; Type _type; Direction _direction; @@ -215,6 +240,9 @@ public: void *_buf; nframes_t _nframes; Module *_module; + + char *_osc_path; + char *_osc_path_cv; }; void bbox ( int &X, int &Y, int &W, int &H ) @@ -317,7 +345,15 @@ public: } Chain *chain ( void ) const { return _chain; } - void chain ( Chain * v ) { _chain = v; } + void chain ( Chain * v ) + { + _chain = v; + + for ( int i = 0; i < ncontrol_inputs(); ++i ) + { + control_input[i].update_osc_port(); + } + } char *get_parameters ( void ) const; void set_parameters ( const char * );