diff --git a/mixer/src/Controller_Module.C b/mixer/src/Controller_Module.C index da2cb63..aeb7cab 100644 --- a/mixer/src/Controller_Module.C +++ b/mixer/src/Controller_Module.C @@ -485,12 +485,10 @@ Controller_Module::menu_cb ( const Fl_Menu_ *m ) Logger log( this ); - if ( ! strcmp( picked, "Mode/Manual" ) ) + if ( ! strcmp( picked, "Mode/GUI + OSC" ) ) mode( GUI ); - else if ( ! strcmp( picked, "Mode/Control Voltage" ) ) + else if ( ! strcmp( picked, "Mode/Control Voltage (JACK)" ) ) mode( CV ); - else if ( ! strcmp( picked, "Mode/Open Sound Control (OSC)" ) ) - mode( OSC ); } /** build the context menu for this control */ @@ -502,9 +500,8 @@ Controller_Module::menu ( void ) Fl_Menu_Item items[] = { { "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 ) }, + { "GUI + OSC", 0, 0, 0, FL_MENU_RADIO | ( mode() == GUI ? FL_MENU_VALUE : 0 ) }, + { "Control Voltage (JACK)", 0, 0, 0, FL_MENU_RADIO | ( mode() == CV ? FL_MENU_VALUE : 0 ) }, { 0 }, { 0 }, }; diff --git a/nonlib/OSC/Endpoint.C b/nonlib/OSC/Endpoint.C index 6d49e22..f686dff 100644 --- a/nonlib/OSC/Endpoint.C +++ b/nonlib/OSC/Endpoint.C @@ -75,6 +75,16 @@ namespace OSC } } + void + Signal::get_connected_peer_name_and_path ( char **peer_name, char **path ) + { + Target *t = _outgoing.back(); + + Signal *s = get_peer_signal_by_id( t->peer, t->signal_id ); + + *peer_name = strdup( t->peer->name ); + *path = strdup( s->path() ); + } void Endpoint::error_handler(int num, const char *msg, const char *path) @@ -141,6 +151,22 @@ namespace OSC if ( (*i)->id() == id ) return *i; } + + return NULL; + } + + OSC::Signal * + Endpoint::find_peer_signal_by_path ( Peer *p, const char *path ) + { + for ( std::list::iterator i = p->_signals.begin(); + i != p->_signals.end(); + ++i ) + { + if ( !strcmp( (*i)->path(), path ) ) + return *i; + } + + return NULL; } int @@ -213,7 +239,7 @@ namespace OSC { // OSC_DMSG(); - if ( path[ strlen(path) - 1 ] != '/' ) + if ( argc || path[ strlen(path) - 1 ] != '/' ) return -1; Endpoint *ep = (Endpoint*)user_data; @@ -363,13 +389,52 @@ namespace OSC return NULL; } - /* First part of 'to' is a peer name */ + bool + Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path ) + { + if ( s->_direction == Signal::Output ) + { + Peer *p = find_peer_by_name( peer_name ); + + if ( ! p ) + return false; + + Signal *ps = find_peer_signal_by_path( p, signal_path ); + + if ( ! ps ) + return false; + + MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, s->_id ); + + if ( p ) + { + Target *t = new Target(); + + t->peer = p; + t->signal_id = ps->_id; + + s->_outgoing.push_back( t ); + + send( p->addr, "/signal/connect", + s->_id, /* our signal id */ + t->signal_id /* their signal id */ ); + + return true; + } + } + + return false; + } + bool Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, int signal_id ) { if ( s->_direction == Signal::Output ) { Peer *p = find_peer_by_name( peer_name ); + + if ( !p ) + return false; MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, signal_id ); @@ -383,8 +448,8 @@ namespace OSC s->_outgoing.push_back( t ); send( p->addr, "/signal/connect", - 0, /* FIXME: our signal id */ - 0 /* FIXME: their signal id */ ); + s->_id, /* our signal id */ + t->signal_id /* their signal id */ ); return true; } @@ -393,6 +458,19 @@ namespace OSC return false; } + Signal * + Signal::get_peer_signal_by_id ( Peer *p, int signal_id ) + { + for ( std::list::iterator i = p->_signals.begin(); + i != p->_signals.end(); + ++i ) + { + if ( (*i)->_id == signal_id ) + return *i; + } + + return NULL; + } int Endpoint::osc_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) diff --git a/nonlib/OSC/Endpoint.H b/nonlib/OSC/Endpoint.H index 3881158..540ba3d 100644 --- a/nonlib/OSC/Endpoint.H +++ b/nonlib/OSC/Endpoint.H @@ -117,7 +117,6 @@ namespace OSC class Signal; struct Peer { - bool _scanning; char *name; @@ -129,7 +128,6 @@ namespace OSC struct Target { Peer *peer; -// char *path; int signal_id; float value; }; @@ -190,8 +188,10 @@ namespace OSC free( _path ); } + static Signal *get_peer_signal_by_id ( Peer *p, int signal_id ); bool connected ( void ) { return _outgoing.size() + _incoming.size(); } - + void get_connected_peer_name_and_path ( char **peer_name, char **path ); + int id ( void ) { return _id; } Direction direction ( void ) { return _direction; } @@ -260,6 +260,8 @@ namespace OSC OSC::Signal *find_signal_by_id ( int id ); + OSC::Signal *find_peer_signal_by_path ( Peer *p, const char *path ); + Peer *find_peer_by_name ( const char *name ); Peer *find_peer_by_address ( lo_address addr ); static bool address_matches ( lo_address addr1, lo_address addr2 ); @@ -275,6 +277,8 @@ namespace OSC ~Endpoint ( ); + + bool connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path ); bool connect_signal( OSC::Signal *s, const char *peer_name, int signal_id ); diff --git a/session/src/session-manager.C b/session/src/session-manager.C index 04834d1..e720107 100644 --- a/session/src/session-manager.C +++ b/session/src/session-manager.C @@ -916,8 +916,8 @@ main (int argc, char **argv ) Daemon *d = new Daemon; - d->url = optarg; - d->addr = lo_address_new_from_url( optarg ); + d->url = nsm_url; + d->addr = lo_address_new_from_url( nsm_url ); daemon_list.push_back( d ); } diff --git a/timeline/src/Control_Sequence.C b/timeline/src/Control_Sequence.C index 171eaca..e56f1c8 100644 --- a/timeline/src/Control_Sequence.C +++ b/timeline/src/Control_Sequence.C @@ -40,12 +40,12 @@ bool Control_Sequence::draw_with_grid = true; -const double OSC_INTERVAL = 1.0f / 20.0f; - Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0 ) { init(); + _osc_connected_peer = _osc_connected_path = 0; + _track = track; _output = new JACK::Port( engine, JACK::Port::Output, track->name(), track->ncontrols(), "cv" ); @@ -55,20 +55,20 @@ Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0 ) FATAL( "could not create JACK port" ); } - { - char *path; - asprintf( &path, "/non/daw/%s/control/%i", track->name(), track->ncontrols() ); + /* { */ + /* char *path; */ + /* asprintf( &path, "/non/daw/%s/control/%i", track->name(), track->ncontrols() ); */ - _osc_output = timeline->osc->add_signal( path, OSC::Signal::Output, NULL, NULL ); + /* _osc_output = timeline->osc->add_signal( path, OSC::Signal::Output, NULL, NULL ); */ - free( path ); - } + /* free( path ); */ + /* } */ + + _osc_output = 0; if ( track ) track->add( this ); - interpolation( Linear ); - log_create(); } @@ -108,7 +108,10 @@ Control_Sequence::init ( void ) _osc_output = NULL; color( fl_darker( FL_YELLOW ) ); - Fl::add_timeout( OSC_INTERVAL, &Control_Sequence::process_osc, this ); + interpolation( Linear ); + frequency( 10 ); + + Fl::add_timeout( _interval, &Control_Sequence::process_osc, this ); } @@ -124,6 +127,20 @@ void Control_Sequence::get_unjournaled ( Log_Entry &e ) const { e.add( ":interpolation", _interpolation ); + if ( _osc_output->connected() ) + { + char *path; + char *peer; + + _osc_output->get_connected_peer_name_and_path( &peer, &path ); + + e.add( ":osc_peer", peer ); + e.add( ":osc_path", path ); + + free( path ); + free( peer ); + } + e.add( ":frequency", frequency() ); } void @@ -156,7 +173,16 @@ Control_Sequence::set ( Log_Entry &e ) name( v ); else if ( ! strcmp( ":interpolation", s ) ) interpolation( (curve_type_e)atoi( v ) ); - + else if ( ! strcmp( ":frequency", s ) ) + frequency( atoi( v ) ); + else if ( ! strcmp( ":osc_peer", s ) ) + { + _osc_connected_peer = strdup( v ); + } + else if ( !strcmp( ":osc_path", s ) ) + { + _osc_connected_path = strdup( v ); + } } } @@ -354,6 +380,19 @@ Control_Sequence::menu_cb ( const Fl_Menu_ *m ) interpolation( Linear ); else if ( ! strcmp( picked, "Interpolation/None" ) ) interpolation( None ); + else if ( ! strcmp( picked, "Frequency/1Hz" ) ) + frequency( 1 ); + else if ( ! strcmp( picked, "Frequency/5Hz" ) ) + frequency( 5 ); + else if ( ! strcmp( picked, "Frequency/10Hz" ) ) + frequency( 10 ); + else if ( ! strcmp( picked, "Frequency/20Hz" ) ) + frequency( 20 ); + else if ( ! strcmp( picked, "Frequency/30Hz" ) ) + frequency( 30 ); + else if ( ! strcmp( picked, "Frequency/60Hz" ) ) + frequency( 60 ); + else if ( ! strcmp( picked, "/Rename" ) ) { const char *s = fl_input( "Input new name for control sequence:", name() ); @@ -369,6 +408,23 @@ Control_Sequence::menu_cb ( const Fl_Menu_ *m ) } } +void +Control_Sequence::connect_osc ( void ) + +{ + if ( ! _osc_output ) + { + char *path; + asprintf( &path, "/non/daw/%s/control/%i", track()->name(), track()->ncontrols() ); + + _osc_output = timeline->osc->add_signal( path, OSC::Signal::Output, NULL, NULL ); + + free( path ); + } + + if ( _osc_connected_peer && _osc_connected_path ) + timeline->osc->connect_signal( _osc_output, _osc_connected_peer, _osc_connected_path ); +} void Control_Sequence::process_osc ( void *v ) @@ -379,7 +435,7 @@ Control_Sequence::process_osc ( void *v ) void Control_Sequence::process_osc ( void ) { - Fl::add_timeout( OSC_INTERVAL, &Control_Sequence::process_osc, this ); + Fl::repeat_timeout( _interval, &Control_Sequence::process_osc, this ); if ( _osc_output && _osc_output->connected() ) { @@ -443,6 +499,15 @@ Control_Sequence::handle ( int m ) /* menu.add( "Connect To", 0, 0, const_cast< Fl_Menu_Item *>( con->menu() ), FL_SUBMENU_POINTER ); */ menu.add( "Interpolation/None", 0, 0, 0, FL_MENU_RADIO | ( interpolation() == None ? FL_MENU_VALUE : 0 ) ); menu.add( "Interpolation/Linear", 0, 0, 0, FL_MENU_RADIO | ( interpolation() == Linear ? FL_MENU_VALUE : 0 ) ); + + menu.add( "Frequency/1Hz", 0, 0, 0, FL_MENU_RADIO | ( frequency() == 1 ? FL_MENU_VALUE : 0 ) ); + menu.add( "Frequency/5Hz", 0, 0, 0, FL_MENU_RADIO | ( frequency() == 5 ? FL_MENU_VALUE : 0 ) ); + menu.add( "Frequency/10Hz", 0, 0, 0, FL_MENU_RADIO | ( frequency() == 10 ? FL_MENU_VALUE : 0 ) ); + menu.add( "Frequency/20Hz", 0, 0, 0, FL_MENU_RADIO | ( frequency() == 20 ? FL_MENU_VALUE : 0 ) ); + menu.add( "Frequency/30Hz", 0, 0, 0, FL_MENU_RADIO | ( frequency() == 30 ? FL_MENU_VALUE : 0 ) ); + menu.add( "Frequency/60Hz", 0, 0, 0, FL_MENU_RADIO | ( frequency() == 60 ? FL_MENU_VALUE : 0 ) ); + + menu.add( "Rename", 0, 0, 0 ); menu.add( "Remove", 0, 0, 0 ); diff --git a/timeline/src/Control_Sequence.H b/timeline/src/Control_Sequence.H index cbaa9e8..5880788 100644 --- a/timeline/src/Control_Sequence.H +++ b/timeline/src/Control_Sequence.H @@ -42,11 +42,18 @@ private: JACK::Port *_output; + /* these are used to cache the saved osc connection until the + * session is loaded, at which time we will reconnect */ + char *_osc_connected_peer; + char *_osc_connected_path; + /* osc output port */ OSC::Signal *_osc_output; bool _highlighted; curve_type_e _interpolation; + int _frequency; + float _interval; void init ( void ); @@ -78,6 +85,8 @@ protected: public: + void connect_osc ( void ); + static bool draw_with_gradient; static bool draw_with_polygon; static bool draw_with_grid; @@ -91,6 +100,8 @@ public: curve_type_e interpolation ( void ) const { return _interpolation; } void interpolation ( curve_type_e v ) { _interpolation = v; } + int frequency ( void ) const { return _frequency; } + void frequency ( int v ) { _frequency = v; _interval = ( 1.0f / (float)v ) / 2; } /* Engine */ void output ( JACK::Port *p ) { _output = p; } diff --git a/timeline/src/Timeline.C b/timeline/src/Timeline.C index 87da2d0..c4ca99c 100644 --- a/timeline/src/Timeline.C +++ b/timeline/src/Timeline.C @@ -1644,6 +1644,26 @@ Timeline::discover_peers ( void ) nsm->broadcast( m ); lo_message_free( m ); + + /* wait for responses and then autoconnect outputs */ + + MESSAGE( "Waiting for OSC peers..." ); + + osc->wait( 1000 ); + + MESSAGE( "Reconnecting signals." ); + + /* reconnect OSC signals */ + for ( int i = tracks->children(); i-- ; ) + { + Track *t = (Track*)tracks->child( i ); + + for ( int j = t->control->children(); j--; ) + { + Control_Sequence *c = (Control_Sequence*)t->control->child( j ); + c->connect_osc(); + } + } } void