@@ -242,14 +242,6 @@ Module::Port::generate_osc_path () | |||
void | |||
Module::Port::change_osc_path ( char *path ) | |||
{ | |||
if ( _scaled_signal && _unscaled_signal ) | |||
{ | |||
mixer->osc_endpoint->del_signal( _scaled_signal ); | |||
mixer->osc_endpoint->del_signal( _unscaled_signal ); | |||
_scaled_signal = _unscaled_signal = NULL; | |||
} | |||
if ( path ) | |||
{ | |||
char *scaled_path = path; | |||
@@ -257,13 +249,25 @@ Module::Port::change_osc_path ( char *path ) | |||
asprintf( &unscaled_path, "%s/unscaled", path ); | |||
_scaled_signal = mixer->osc_endpoint->add_signal( scaled_path, OSC::Signal::Input, &Module::Port::osc_control_change_cv, this ); | |||
_unscaled_signal = mixer->osc_endpoint->add_signal( unscaled_path, OSC::Signal::Input, &Module::Port::osc_control_change_exact, this ); | |||
if ( ! ( _scaled_signal && _unscaled_signal ) ) | |||
{ | |||
_scaled_signal = | |||
mixer->osc_endpoint->add_signal( scaled_path, | |||
OSC::Signal::Input, &Module::Port::osc_control_change_cv, this ); | |||
_unscaled_signal = | |||
mixer->osc_endpoint->add_signal( unscaled_path, | |||
OSC::Signal::Input, &Module::Port::osc_control_change_exact, this ); | |||
} | |||
else | |||
{ | |||
_scaled_signal->rename( scaled_path ); | |||
_unscaled_signal->rename( unscaled_path ); | |||
} | |||
free( unscaled_path ); | |||
free( scaled_path ); | |||
if ( hints.ranged ) | |||
{ | |||
_unscaled_signal->parameter_limits( | |||
@@ -171,7 +171,11 @@ public: | |||
void destroy_osc_port ( ) | |||
{ | |||
change_osc_path( NULL ); | |||
delete _unscaled_signal; | |||
delete _scaled_signal; | |||
_unscaled_signal = _scaled_signal = NULL; | |||
} | |||
void control_value_no_callback ( float f ) | |||
@@ -53,6 +53,37 @@ namespace OSC | |||
/**********/ | |||
int Signal::next_id = 0; | |||
Signal::~Signal ( ) | |||
{ | |||
if ( _endpoint ) | |||
{ | |||
_endpoint->del_signal( this ); | |||
} | |||
free( _path ); | |||
_path = NULL; | |||
_endpoint = NULL; | |||
} | |||
void | |||
Signal::rename ( const char *path ) | |||
{ | |||
for ( std::list<Target*>::const_iterator i = _incoming.begin(); | |||
i != _incoming.end(); | |||
++i ) | |||
{ | |||
_endpoint->send( (*i)->peer->addr, | |||
"/signal/renamed", | |||
(*i)->signal_id, | |||
path ); | |||
} | |||
free( _path ); | |||
_path = strdup( path ); | |||
} | |||
void | |||
Signal::value ( float f ) | |||
@@ -109,6 +140,7 @@ namespace OSC | |||
return -1; | |||
} | |||
add_method( "/signal/renamed", "is", &Endpoint::osc_sig_renamed, this, "" ); | |||
add_method( "/signal/change", "if", &Endpoint::osc_sig_handler, this, "" ); | |||
add_method( NULL, "", &Endpoint::osc_generic, this, "" ); | |||
add_method( NULL, NULL, &Endpoint::osc_signal_lister, this, "" ); | |||
@@ -169,6 +201,53 @@ namespace OSC | |||
return NULL; | |||
} | |||
OSC::Signal * | |||
Endpoint::find_peer_signal_by_id ( Peer *p, int id ) | |||
{ | |||
for ( std::list<Signal*>::iterator i = p->_signals.begin(); | |||
i != p->_signals.end(); | |||
++i ) | |||
{ | |||
if ( id == (*i)->id() ) | |||
return *i; | |||
} | |||
return NULL; | |||
} | |||
int | |||
Endpoint::osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) | |||
{ | |||
int id = argv[0]->i; | |||
char *new_name = &argv[1]->s; | |||
Endpoint *ep = (Endpoint*)user_data; | |||
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) ); | |||
if ( ! p ) | |||
{ | |||
WARNING( "Got signal rename notification from unknown peer." ); | |||
return 0; | |||
} | |||
Signal *o = ep->find_peer_signal_by_id( p, id ); | |||
if ( ! o ) | |||
{ | |||
WARNING( "Unknown signal id %i", id ); | |||
return 0; | |||
} | |||
DMESSAGE( "Signal %s was renamed to %s" ); | |||
free( o->_path ); | |||
o->_path = strdup( new_name ); | |||
return 0; | |||
} | |||
int | |||
Endpoint::osc_sig_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) | |||
{ | |||
@@ -330,7 +409,7 @@ namespace OSC | |||
void | |||
Endpoint::list_peers ( void (*callback) (const char *, const char *, int, void * ), void *v ) | |||
Endpoint::list_peers ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v ) | |||
{ | |||
for ( std::list<Peer*>::iterator i = _peers.begin(); | |||
i != _peers.end(); | |||
@@ -341,7 +420,7 @@ namespace OSC | |||
++j ) | |||
{ | |||
// DMESSAGE( "Running callback" ); | |||
callback( (*i)->name, (*j)->path(), (*j)->id(), v ); | |||
callback( (*i)->name, *j, v ); | |||
} | |||
} | |||
} | |||
@@ -601,7 +680,7 @@ namespace OSC | |||
lo_server_del_method( _server, o->path(), "f" ); | |||
delete o; | |||
// delete o; | |||
_signals.remove( o ); | |||
} | |||
@@ -181,18 +181,16 @@ namespace OSC | |||
_path = strdup( path ); | |||
_id = ++next_id; | |||
_value = 0.0f; | |||
_endpoint = NULL; | |||
} | |||
~Signal ( ) | |||
{ | |||
free( _path ); | |||
} | |||
~Signal ( ); | |||
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; } | |||
int id ( void ) const { return _id; } | |||
Direction direction ( void ) { return _direction; } | |||
@@ -206,12 +204,14 @@ namespace OSC | |||
Parameter_Limits& parameter_limits ( void ) { return _parameter_limits; } | |||
const char *path ( void ) { return _path; } | |||
const char *path ( void ) const { return _path; } | |||
void rename ( const char *name ); | |||
/* publishes value to targets */ | |||
void value ( float v ); | |||
/* get current value */ | |||
float value ( void ) { return _value; } | |||
float value ( void ) const { return _value; } | |||
friend class Endpoint; | |||
}; | |||
@@ -245,6 +245,7 @@ namespace OSC | |||
static int osc_signal_lister ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
static int osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
static int osc_sig_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
static int osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); | |||
Thread _thread; | |||
@@ -259,8 +260,8 @@ namespace OSC | |||
void osc_thread ( void ); | |||
OSC::Signal *find_signal_by_id ( int id ); | |||
OSC::Signal *find_peer_signal_by_path ( Peer *p, const char *path ); | |||
OSC::Signal *find_peer_signal_by_id ( Peer *p, int id ); | |||
Peer *find_peer_by_name ( const char *name ); | |||
Peer *find_peer_by_address ( lo_address addr ); | |||
@@ -270,7 +271,7 @@ namespace OSC | |||
public: | |||
void list_peers ( void (*callback) (const char *, const char *, int, void * ), void *v ); | |||
void list_peers ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v ); | |||
int init ( int proto, const char *port = 0 ); | |||
Endpoint ( ); | |||
@@ -734,7 +734,7 @@ private: | |||
static int osc_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) | |||
{ | |||
OSC_DMSG(); | |||
// OSC_DMSG(); | |||
NSM_Controller *controller = (NSM_Controller*)((OSC::Endpoint*)user_data)->owner; | |||
@@ -96,6 +96,20 @@ Control_Sequence::~Control_Sequence ( ) | |||
_output = NULL; | |||
delete _osc_output; | |||
_osc_output = NULL; | |||
if ( _osc_connected_peer ) | |||
free( _osc_connected_peer ); | |||
_osc_connected_peer = NULL; | |||
if ( _osc_connected_path ) | |||
free( _osc_connected_path ); | |||
_osc_connected_path = NULL; | |||
Loggable::block_end(); | |||
} | |||
@@ -365,8 +379,7 @@ Control_Sequence::menu_cb ( const Fl_Menu_ *m ) | |||
free( path ); | |||
} | |||
/* FIXME: somebody has to free these unsigned longs */ | |||
unsigned long id = *(unsigned long*)m->mvalue()->user_data(); | |||
int id = ((OSC::Signal*)m->mvalue()->user_data())->id(); | |||
char *peer_name = index( picked, '/' ) + 1; | |||
@@ -421,7 +434,12 @@ Control_Sequence::connect_osc ( void ) | |||
} | |||
if ( _osc_connected_peer && _osc_connected_path ) | |||
timeline->osc->connect_signal( _osc_output, _osc_connected_peer, _osc_connected_path ); | |||
{ | |||
if ( ! timeline->osc->connect_signal( _osc_output, _osc_connected_peer, _osc_connected_path ) ) | |||
{ | |||
/* failed to connect */ | |||
} | |||
} | |||
} | |||
void | |||
@@ -481,6 +499,8 @@ Control_Sequence::handle ( int m ) | |||
{ | |||
timeline->discover_peers(); | |||
timeline->osc->wait( 500 ); | |||
Fl_Menu_Button menu( 0, 0, 0, 0, "Control Sequence" ); | |||
/* Fl_Menu_Button *con = new Fl_Menu_Button( 0, 0, 0, 0 ); */ | |||
@@ -1553,7 +1553,7 @@ Timeline::command_new ( const char *name, const char *display_name ) | |||
/* tle->main_window->redraw(); */ | |||
// discover_peers(); | |||
discover_peers(); | |||
return b; | |||
} | |||
@@ -1652,6 +1652,22 @@ Timeline::reply_to_finger ( lo_message msg ) | |||
lo_address_free( reply ); | |||
} | |||
void | |||
Timeline::connect_osc ( void ) | |||
{ | |||
/* try to (re)connect 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 | |||
Timeline::discover_peers ( void ) | |||
{ | |||
@@ -1668,44 +1684,34 @@ Timeline::discover_peers ( void ) | |||
MESSAGE( "Waiting for OSC peers..." ); | |||
osc->wait( 1000 ); | |||
// 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(); | |||
} | |||
} | |||
connect_osc(); | |||
} | |||
void | |||
Timeline::peer_callback( const char *name, const char *path, int id, void *v ) | |||
Timeline::peer_callback( const char *name, const OSC::Signal *sig, void *v ) | |||
{ | |||
((Timeline*)v)->peer_callback2( name, path, id ); | |||
((Timeline*)v)->peer_callback( name, sig ); | |||
} | |||
static Fl_Menu_Button *peer_menu; | |||
static const char *peer_prefix; | |||
void | |||
Timeline::peer_callback2( const char *name, const char *path, int id ) | |||
Timeline::peer_callback( const char *name, const OSC::Signal *sig ) | |||
{ | |||
char *s; | |||
asprintf( &s, "%s/%s/%s", peer_prefix, name, path ); | |||
asprintf( &s, "%s/%s%s", peer_prefix, name, sig->path() ); | |||
/* FIXME: Somebody has to free these unsigned longs! */ | |||
peer_menu->add( s, 0, NULL, new unsigned long( id ) ); | |||
peer_menu->add( s, 0, NULL, (void*)( sig ) ); | |||
free( s ); | |||
connect_osc(); | |||
} | |||
void | |||
@@ -236,10 +236,11 @@ public: | |||
/* OSC */ | |||
static void peer_callback( const char *name, const char *path, int id, void *v ); | |||
void peer_callback2( const char *name, const char *path, int id ); | |||
static void peer_callback( const char *name, const OSC::Signal *sig, void *v ); | |||
void peer_callback( const char *name, const OSC::Signal *sig ); | |||
void connect_osc ( void ); | |||
void add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix ); | |||
void discover_peers ( void ); | |||