OSC: Improvements to signal routing.
This commit is contained in:
parent
edefd1126f
commit
a48a739db2
|
@ -36,6 +36,7 @@ public:
|
||||||
JACK_Module ( );
|
JACK_Module ( );
|
||||||
virtual ~JACK_Module ( );
|
virtual ~JACK_Module ( );
|
||||||
|
|
||||||
|
bool allows_external_control ( void ) const { return false; }
|
||||||
const char *name ( void ) const { return "JACK"; }
|
const char *name ( void ) const { return "JACK"; }
|
||||||
|
|
||||||
bool initialize ( void );
|
bool initialize ( void );
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
Meter_Indicator_Module ( bool is_default = false );
|
Meter_Indicator_Module ( bool is_default = false );
|
||||||
virtual ~Meter_Indicator_Module ( );
|
virtual ~Meter_Indicator_Module ( );
|
||||||
|
|
||||||
|
bool allows_external_control ( void ) const { return false; }
|
||||||
const char *name ( void ) const { return "Meter Indicator"; }
|
const char *name ( void ) const { return "Meter Indicator"; }
|
||||||
|
|
||||||
int can_support_inputs ( int ) { return 0; }
|
int can_support_inputs ( int ) { return 0; }
|
||||||
|
|
|
@ -213,6 +213,12 @@ Module::handle_control_changed ( Port *p )
|
||||||
_editor->handle_control_changed ( p );
|
_editor->handle_control_changed ( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Module::Port::connected_osc ( void ) const
|
||||||
|
{
|
||||||
|
return _scaled_signal->connected();
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
Module::Port::generate_osc_path ()
|
Module::Port::generate_osc_path ()
|
||||||
{
|
{
|
||||||
|
@ -222,6 +228,12 @@ Module::Port::generate_osc_path ()
|
||||||
|
|
||||||
// /mixer/STRIPNAME/MODULENAME/CONTROLNAME
|
// /mixer/STRIPNAME/MODULENAME/CONTROLNAME
|
||||||
|
|
||||||
|
if ( ! module()->allows_external_control() )
|
||||||
|
{
|
||||||
|
/* Don't create signals for the default modules other than Gain */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int n = module()->chain()->get_module_instance_number( module() );
|
int n = module()->chain()->get_module_instance_number( module() );
|
||||||
|
|
||||||
if ( n > 0 )
|
if ( n > 0 )
|
||||||
|
@ -290,6 +302,7 @@ Module::Port::change_osc_path ( char *path )
|
||||||
0.0f,
|
0.0f,
|
||||||
1.0f,
|
1.0f,
|
||||||
scaled_default );
|
scaled_default );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +513,12 @@ Module::draw_box ( void )
|
||||||
{
|
{
|
||||||
/* maybe draw control indicators */
|
/* maybe draw control indicators */
|
||||||
if ( control_input.size() )
|
if ( control_input.size() )
|
||||||
|
{
|
||||||
fl_draw_box( FL_ROUNDED_BOX, tx + 4, ty + 4, 5, 5, is_being_controlled() ? FL_YELLOW : fl_inactive( FL_YELLOW ) );
|
fl_draw_box( FL_ROUNDED_BOX, tx + 4, ty + 4, 5, 5, is_being_controlled() ? FL_YELLOW : fl_inactive( FL_YELLOW ) );
|
||||||
|
|
||||||
|
fl_draw_box( FL_ROUNDED_BOX, tx + 4, ty + 8, 5, 5, is_being_controlled_osc() ? FL_GREEN : fl_inactive( FL_GREEN ) );
|
||||||
|
}
|
||||||
|
|
||||||
if ( control_output.size() )
|
if ( control_output.size() )
|
||||||
fl_draw_box( FL_ROUNDED_BOX, tx + tw - 8, ty + 4, 5, 5, is_controlling() ? FL_YELLOW : fl_inactive( FL_YELLOW ) );
|
fl_draw_box( FL_ROUNDED_BOX, tx + tw - 8, ty + 4, 5, 5, is_controlling() ? FL_YELLOW : fl_inactive( FL_YELLOW ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@ public:
|
||||||
bool is_default ( void ) const { return _is_default; }
|
bool is_default ( void ) const { return _is_default; }
|
||||||
void is_default ( bool v ) { _is_default = v; }
|
void is_default ( bool v ) { _is_default = v; }
|
||||||
|
|
||||||
|
virtual bool allows_external_control ( void ) const { return true; }
|
||||||
|
|
||||||
class Port
|
class Port
|
||||||
{
|
{
|
||||||
/* char *type_names[] = { "Audio", "Control" }; */
|
/* char *type_names[] = { "Audio", "Control" }; */
|
||||||
|
@ -160,7 +162,10 @@ public:
|
||||||
|
|
||||||
const char *osc_path ( )
|
const char *osc_path ( )
|
||||||
{
|
{
|
||||||
|
if ( _scaled_signal )
|
||||||
return _scaled_signal->path();
|
return _scaled_signal->path();
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_osc_port ( )
|
void update_osc_port ( )
|
||||||
|
@ -205,6 +210,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool connected ( void ) const { return _connected; }
|
bool connected ( void ) const { return _connected; }
|
||||||
|
bool connected_osc ( void ) const;
|
||||||
|
|
||||||
Port *connected_port ( void ) const
|
Port *connected_port ( void ) const
|
||||||
{
|
{
|
||||||
|
@ -293,6 +299,15 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
is_being_controlled_osc ( void ) const
|
||||||
|
{
|
||||||
|
for ( nframes_t i = control_input.size(); i--; )
|
||||||
|
if ( control_input[i].connected_osc() )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual const char *name ( void ) const = 0;
|
virtual const char *name ( void ) const = 0;
|
||||||
|
|
||||||
std::vector<Port> audio_input;
|
std::vector<Port> audio_input;
|
||||||
|
|
|
@ -80,6 +80,8 @@ NSM_Client::command_open ( const char *name, const char *display_name, const cha
|
||||||
|
|
||||||
instance_name = strdup( client_id );
|
instance_name = strdup( client_id );
|
||||||
|
|
||||||
|
mixer->osc_endpoint->name( client_id );
|
||||||
|
|
||||||
int r = ERR_OK;
|
int r = ERR_OK;
|
||||||
|
|
||||||
if ( Project::validate( name ) )
|
if ( Project::validate( name ) )
|
||||||
|
|
|
@ -85,6 +85,21 @@ namespace OSC
|
||||||
_path = strdup( path );
|
_path = strdup( path );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Signal::is_connected_to ( const OSC::Signal *s ) const
|
||||||
|
{
|
||||||
|
for ( std::list<Target*>::const_iterator i = _outgoing.begin();
|
||||||
|
i != _outgoing.end();
|
||||||
|
++i )
|
||||||
|
{
|
||||||
|
if ( (*i)->peer == s->_peer &&
|
||||||
|
(*i)->signal_id == s->id() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Signal::value ( float f )
|
Signal::value ( float f )
|
||||||
{
|
{
|
||||||
|
@ -92,8 +107,6 @@ namespace OSC
|
||||||
i != _outgoing.end();
|
i != _outgoing.end();
|
||||||
++i )
|
++i )
|
||||||
{
|
{
|
||||||
// DMESSAGE( "Sending signal value %i %f", (*i)->signal_id, f );
|
|
||||||
|
|
||||||
if ( (*i)->value != f )
|
if ( (*i)->value != f )
|
||||||
{
|
{
|
||||||
(*i)->value = f;
|
(*i)->value = f;
|
||||||
|
@ -140,10 +153,14 @@ namespace OSC
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
add_method( "/signal/hello", "s", &Endpoint::osc_sig_hello, this, "" );
|
||||||
|
add_method( "/signal/connect", "ii", &Endpoint::osc_sig_connect, this, "" );
|
||||||
|
add_method( "/signal/disconnect", "ii", &Endpoint::osc_sig_disconnect, this, "" );
|
||||||
add_method( "/signal/renamed", "is", &Endpoint::osc_sig_renamed, this, "" );
|
add_method( "/signal/renamed", "is", &Endpoint::osc_sig_renamed, this, "" );
|
||||||
add_method( "/signal/change", "if", &Endpoint::osc_sig_handler, this, "" );
|
add_method( "/signal/change", "if", &Endpoint::osc_sig_handler, this, "" );
|
||||||
add_method( NULL, "", &Endpoint::osc_generic, this, "" );
|
add_method( NULL, "", &Endpoint::osc_generic, this, "" );
|
||||||
add_method( NULL, NULL, &Endpoint::osc_signal_lister, this, "" );
|
add_method( "/signal/list", NULL, &Endpoint::osc_signal_lister, this, "" );
|
||||||
add_method( "/reply", NULL, &Endpoint::osc_reply, this, "" );
|
add_method( "/reply", NULL, &Endpoint::osc_reply, this, "" );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -215,6 +232,135 @@ namespace OSC
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Endpoint::hello ( const char *url )
|
||||||
|
{
|
||||||
|
lo_address addr = lo_address_new_from_url ( url );
|
||||||
|
|
||||||
|
send( addr, "/signal/hello", name() );
|
||||||
|
|
||||||
|
lo_address_free( addr );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Endpoint::osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
||||||
|
{
|
||||||
|
Endpoint *ep = (Endpoint*)user_data;
|
||||||
|
|
||||||
|
const char *peer_name = &argv[0]->s;
|
||||||
|
|
||||||
|
DMESSAGE( "Got hello from %s", peer_name );
|
||||||
|
|
||||||
|
if ( ! ep->find_peer_by_name( peer_name ) )
|
||||||
|
{
|
||||||
|
char *url = lo_address_get_url( lo_message_get_source( msg ));
|
||||||
|
|
||||||
|
ep->scan_peer( peer_name, url );
|
||||||
|
|
||||||
|
ep->send( lo_message_get_source( msg ), "/signal/hello", ep->name() );
|
||||||
|
|
||||||
|
free(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Endpoint::osc_sig_disconnect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
||||||
|
{
|
||||||
|
int their_id = argv[0]->i;
|
||||||
|
int our_id = argv[1]->i;
|
||||||
|
|
||||||
|
Endpoint *ep = (Endpoint*)user_data;
|
||||||
|
|
||||||
|
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
|
||||||
|
|
||||||
|
if ( ! p )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Signal *ps = ep->find_peer_signal_by_id( p, their_id );
|
||||||
|
|
||||||
|
if ( ! ps )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Signal *s = ep->find_signal_by_id( our_id );
|
||||||
|
|
||||||
|
if ( ! s )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( s->_direction == Signal::Input )
|
||||||
|
{
|
||||||
|
for ( std::list<Target*>::iterator i = s->_incoming.begin();
|
||||||
|
i != s->_incoming.end();
|
||||||
|
++i )
|
||||||
|
{
|
||||||
|
if ( (*i)->peer == p &&
|
||||||
|
(*i)->signal_id == ps->id() )
|
||||||
|
{
|
||||||
|
DMESSAGE( "Peer %s has disconnected from signal %s", p->name, ps->path() );
|
||||||
|
|
||||||
|
delete *i;
|
||||||
|
i = s->_incoming.erase( i );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Endpoint::osc_sig_connect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
||||||
|
{
|
||||||
|
int their_id = argv[0]->i;
|
||||||
|
int our_id = argv[1]->i;
|
||||||
|
|
||||||
|
Endpoint *ep = (Endpoint*)user_data;
|
||||||
|
|
||||||
|
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
|
||||||
|
|
||||||
|
if ( ! p )
|
||||||
|
{
|
||||||
|
WARNING( "Got connection signal from unknown peer" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Signal *ps = ep->find_peer_signal_by_id( p, their_id );
|
||||||
|
|
||||||
|
if ( ! ps )
|
||||||
|
{
|
||||||
|
WARNING( "Unknown source signal" );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Signal *s = ep->find_signal_by_id( our_id );
|
||||||
|
|
||||||
|
if ( ! s )
|
||||||
|
{
|
||||||
|
WARNING( "Unknown destination signal" );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DMESSAGE( "Peer %s has connected to signal %s", p->name, s->path() );
|
||||||
|
|
||||||
|
if ( s->_direction == Signal::Input )
|
||||||
|
{
|
||||||
|
Target *t = new Target;
|
||||||
|
|
||||||
|
t->peer = p;
|
||||||
|
t->signal_id = ps->id();
|
||||||
|
|
||||||
|
s->_incoming.push_back( t );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Endpoint::osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
Endpoint::osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
||||||
|
@ -346,19 +492,6 @@ namespace OSC
|
||||||
{
|
{
|
||||||
// OSC_DMSG();
|
// OSC_DMSG();
|
||||||
|
|
||||||
Signal::Direction dir;
|
|
||||||
|
|
||||||
if ( ! strcmp( path, "/signal/list_inputs" ) )
|
|
||||||
{
|
|
||||||
dir = Signal::Input;
|
|
||||||
}
|
|
||||||
else if ( ! strcmp( path, "/signal/list_outputs" ) )
|
|
||||||
{
|
|
||||||
dir = Signal::Output;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
const char *prefix = NULL;
|
const char *prefix = NULL;
|
||||||
|
|
||||||
if ( argc )
|
if ( argc )
|
||||||
|
@ -370,15 +503,13 @@ namespace OSC
|
||||||
{
|
{
|
||||||
Signal *o = *i;
|
Signal *o = *i;
|
||||||
|
|
||||||
if ( dir == Signal::Bidirectional ||
|
|
||||||
dir == o->_direction )
|
|
||||||
{
|
|
||||||
if ( ! prefix || ! strncmp( o->path(), prefix, strlen(prefix) ) )
|
if ( ! prefix || ! strncmp( o->path(), prefix, strlen(prefix) ) )
|
||||||
{
|
{
|
||||||
ep->send( lo_message_get_source( msg ),
|
ep->send( lo_message_get_source( msg ),
|
||||||
"/reply",
|
"/reply",
|
||||||
path,
|
path,
|
||||||
o->path(),
|
o->path(),
|
||||||
|
o->_direction == Signal::Input ? "in" : "out",
|
||||||
o->id(),
|
o->id(),
|
||||||
o->parameter_limits().min,
|
o->parameter_limits().min,
|
||||||
o->parameter_limits().max,
|
o->parameter_limits().max,
|
||||||
|
@ -386,7 +517,6 @@ namespace OSC
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ep->send( lo_message_get_source( msg ), "/reply", path );
|
ep->send( lo_message_get_source( msg ), "/reply", path );
|
||||||
|
|
||||||
|
@ -468,6 +598,48 @@ namespace OSC
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Endpoint::disconnect_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( "Disconnecting signal output \"%s\" to %s:%i", s->path(), peer_name, ps->_id );
|
||||||
|
|
||||||
|
for ( std::list<Target*>::iterator i = s->_outgoing.begin();
|
||||||
|
i != s->_outgoing.end();
|
||||||
|
++i )
|
||||||
|
{
|
||||||
|
if ( (*i)->peer == p &&
|
||||||
|
(*i)->signal_id == ps->id() )
|
||||||
|
{
|
||||||
|
send( p->addr, "/signal/disconnect",
|
||||||
|
s->_id, /* our signal id */
|
||||||
|
(*i)->signal_id /* their signal id */ );
|
||||||
|
|
||||||
|
delete *i;
|
||||||
|
i = s->_outgoing.erase( i );
|
||||||
|
|
||||||
|
DMESSAGE( "Number of outgoing connections: %i", s->_outgoing.size() );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path )
|
Endpoint::connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path )
|
||||||
{
|
{
|
||||||
|
@ -483,10 +655,13 @@ namespace OSC
|
||||||
if ( ! ps )
|
if ( ! ps )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, s->_id );
|
if ( s->is_connected_to( ps ) )
|
||||||
|
|
||||||
if ( p )
|
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MESSAGE( "Connecting signal output \"%s\" to %s:%i", s->path(), peer_name, ps->_id );
|
||||||
|
|
||||||
Target *t = new Target();
|
Target *t = new Target();
|
||||||
|
|
||||||
t->peer = p;
|
t->peer = p;
|
||||||
|
@ -500,7 +675,6 @@ namespace OSC
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -557,7 +731,7 @@ namespace OSC
|
||||||
{
|
{
|
||||||
Endpoint *ep = (Endpoint*)user_data;
|
Endpoint *ep = (Endpoint*)user_data;
|
||||||
|
|
||||||
if ( argc && !strcmp( &argv[0]->s, "/signal/list_inputs" ) )
|
if ( argc && !strcmp( &argv[0]->s, "/signal/list" ) )
|
||||||
{
|
{
|
||||||
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
|
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
|
||||||
|
|
||||||
|
@ -576,12 +750,20 @@ namespace OSC
|
||||||
{
|
{
|
||||||
DMESSAGE( "Peer %s has signal %s", p->name, &argv[1]->s );
|
DMESSAGE( "Peer %s has signal %s", p->name, &argv[1]->s );
|
||||||
|
|
||||||
Signal *s = new Signal( &argv[1]->s, Signal::Input );
|
int dir = 0;
|
||||||
|
|
||||||
s->_id = argv[2]->i;
|
if ( !strcmp( &argv[2]->s, "in" ) )
|
||||||
s->parameter_limits().min = argv[3]->f;
|
dir = Signal::Input;
|
||||||
s->parameter_limits().max = argv[4]->f;
|
else if ( !strcmp( &argv[2]->s, "out" ) )
|
||||||
s->parameter_limits().default_value = argv[4]->f;
|
dir = Signal::Output;
|
||||||
|
|
||||||
|
Signal *s = new Signal( &argv[1]->s, (Signal::Direction)dir );
|
||||||
|
|
||||||
|
s->_peer = p;
|
||||||
|
s->_id = argv[3]->i;
|
||||||
|
s->parameter_limits().min = argv[4]->f;
|
||||||
|
s->parameter_limits().max = argv[5]->f;
|
||||||
|
s->parameter_limits().default_value = argv[6]->f;
|
||||||
|
|
||||||
p->_signals.push_back( s );
|
p->_signals.push_back( s );
|
||||||
}
|
}
|
||||||
|
@ -690,13 +872,15 @@ namespace OSC
|
||||||
{
|
{
|
||||||
Peer *p = new Peer;
|
Peer *p = new Peer;
|
||||||
|
|
||||||
|
DMESSAGE( "Scanning peer %s @ %s...", name, url );
|
||||||
|
|
||||||
p->name = strdup( name );
|
p->name = strdup( name );
|
||||||
p->addr = lo_address_new_from_url( url );
|
p->addr = lo_address_new_from_url( url );
|
||||||
p->_scanning = true;
|
p->_scanning = true;
|
||||||
|
|
||||||
_peers.push_back( p );
|
_peers.push_back( p );
|
||||||
|
|
||||||
send( p->addr, "/signal/list_inputs" );
|
send( p->addr, "/signal/list" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -940,6 +1124,12 @@ namespace OSC
|
||||||
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssifff", v1, v2, v3, v4, v5, v6 );
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssifff", v1, v2, v3, v4, v5, v6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, float v5, float v6, float v7 )
|
||||||
|
{
|
||||||
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssifff", v1, v2, v3, v4, v5, v6, 7 );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3 )
|
Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -150,6 +150,8 @@ namespace OSC
|
||||||
|
|
||||||
Endpoint *_endpoint;
|
Endpoint *_endpoint;
|
||||||
|
|
||||||
|
Peer *_peer;
|
||||||
|
|
||||||
int _id;
|
int _id;
|
||||||
|
|
||||||
char *_path;
|
char *_path;
|
||||||
|
@ -182,6 +184,7 @@ namespace OSC
|
||||||
_id = ++next_id;
|
_id = ++next_id;
|
||||||
_value = 0.0f;
|
_value = 0.0f;
|
||||||
_endpoint = NULL;
|
_endpoint = NULL;
|
||||||
|
_peer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Signal ( );
|
~Signal ( );
|
||||||
|
@ -213,6 +216,8 @@ namespace OSC
|
||||||
/* get current value */
|
/* get current value */
|
||||||
float value ( void ) const { return _value; }
|
float value ( void ) const { return _value; }
|
||||||
|
|
||||||
|
bool is_connected_to ( const Signal *s ) const;
|
||||||
|
|
||||||
friend class Endpoint;
|
friend class Endpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -246,6 +251,11 @@ namespace OSC
|
||||||
static int osc_generic ( 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_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 );
|
static int osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
||||||
|
static int osc_sig_disconnect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
||||||
|
static int osc_sig_connect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
||||||
|
static int osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );
|
||||||
|
|
||||||
|
void scan_peer ( const char *name, const char *url );
|
||||||
|
|
||||||
Thread _thread;
|
Thread _thread;
|
||||||
|
|
||||||
|
@ -269,6 +279,8 @@ namespace OSC
|
||||||
|
|
||||||
static Target *find_target_by_peer_address ( std::list<Target*> *l, lo_address addr );
|
static Target *find_target_by_peer_address ( std::list<Target*> *l, lo_address addr );
|
||||||
|
|
||||||
|
char *_name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void list_peers ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v );
|
void list_peers ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v );
|
||||||
|
@ -279,6 +291,7 @@ namespace OSC
|
||||||
~Endpoint ( );
|
~Endpoint ( );
|
||||||
|
|
||||||
|
|
||||||
|
bool disconnect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path );
|
||||||
bool connect_signal( OSC::Signal *s, const char *peer_name, const char *signal_path );
|
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 );
|
bool connect_signal( OSC::Signal *s, const char *peer_name, int signal_id );
|
||||||
|
|
||||||
|
@ -293,12 +306,15 @@ namespace OSC
|
||||||
int port ( void ) const;
|
int port ( void ) const;
|
||||||
char * url ( void ) const;
|
char * url ( void ) const;
|
||||||
|
|
||||||
void scan_peer ( const char *name, const char *url );
|
|
||||||
|
|
||||||
void check ( void ) const;
|
void check ( void ) const;
|
||||||
void wait ( int timeout ) const;
|
void wait ( int timeout ) const;
|
||||||
void run ( void ) const;
|
void run ( void ) const;
|
||||||
|
|
||||||
|
void name ( const char *name ) { _name = strdup( name ); }
|
||||||
|
const char *name ( void ) { return _name; }
|
||||||
|
|
||||||
|
void hello ( const char *url );
|
||||||
|
|
||||||
int send ( lo_address to, const char *path, std::list< OSC_Value > values );
|
int send ( lo_address to, const char *path, std::list< OSC_Value > values );
|
||||||
|
|
||||||
/* overloads for common message formats */
|
/* overloads for common message formats */
|
||||||
|
@ -331,6 +347,8 @@ namespace OSC
|
||||||
|
|
||||||
int send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, float v4, float v5, float v6 );
|
int send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, float v4, float v5, float v6 );
|
||||||
|
|
||||||
|
int send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, float v5, float v6, float v7 );
|
||||||
|
|
||||||
// can be used to point back to owning object.
|
// can be used to point back to owning object.
|
||||||
void *owner;
|
void *owner;
|
||||||
};
|
};
|
||||||
|
|
|
@ -779,7 +779,7 @@ private:
|
||||||
int err = argv[1]->i;
|
int err = argv[1]->i;
|
||||||
|
|
||||||
if ( err != 0 )
|
if ( err != 0 )
|
||||||
fl_alert( "ERROR: %s failed with: %s", &argv[0]->s, &argv[2]->s );
|
fl_alert( "Command %s failed with:\n\n%s", &argv[0]->s, &argv[2]->s );
|
||||||
}
|
}
|
||||||
else if (!strcmp( path, "/reply" ))
|
else if (!strcmp( path, "/reply" ))
|
||||||
{
|
{
|
||||||
|
|
|
@ -146,8 +146,9 @@ Control_Sequence::get_unjournaled ( Log_Entry &e ) const
|
||||||
|
|
||||||
_osc_output->get_connected_peer_name_and_path( &peer, &path );
|
_osc_output->get_connected_peer_name_and_path( &peer, &path );
|
||||||
|
|
||||||
e.add( ":osc_peer", peer );
|
e.add( ":osc-peer", peer );
|
||||||
e.add( ":osc_path", path );
|
|
||||||
|
e.add( ":osc-path", path );
|
||||||
|
|
||||||
free( path );
|
free( path );
|
||||||
free( peer );
|
free( peer );
|
||||||
|
@ -182,16 +183,20 @@ Control_Sequence::set ( Log_Entry &e )
|
||||||
t->add( this );
|
t->add( this );
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( ":name", s ) )
|
else if ( ! strcmp( ":name", s ) )
|
||||||
|
{
|
||||||
name( v );
|
name( v );
|
||||||
|
}
|
||||||
else if ( ! strcmp( ":interpolation", s ) )
|
else if ( ! strcmp( ":interpolation", s ) )
|
||||||
|
{
|
||||||
interpolation( (curve_type_e)atoi( v ) );
|
interpolation( (curve_type_e)atoi( v ) );
|
||||||
|
}
|
||||||
/* else if ( ! strcmp( ":frequency", s ) ) */
|
/* else if ( ! strcmp( ":frequency", s ) ) */
|
||||||
/* frequency( atoi( v ) ); */
|
/* frequency( atoi( v ) ); */
|
||||||
else if ( ! strcmp( ":osc_peer", s ) )
|
else if ( ! strcmp( ":osc-peer", s ) )
|
||||||
{
|
{
|
||||||
_osc_connected_peer = strdup( v );
|
_osc_connected_peer = strdup( v );
|
||||||
}
|
}
|
||||||
else if ( !strcmp( ":osc_path", s ) )
|
else if ( !strcmp( ":osc-path", s ) )
|
||||||
{
|
{
|
||||||
_osc_connected_path = strdup( v );
|
_osc_connected_path = strdup( v );
|
||||||
}
|
}
|
||||||
|
@ -369,23 +374,28 @@ Control_Sequence::menu_cb ( const Fl_Menu_ *m )
|
||||||
|
|
||||||
if ( ! strncmp( picked, "Connect To/", strlen( "Connect To/" ) ) )
|
if ( ! strncmp( picked, "Connect To/", strlen( "Connect To/" ) ) )
|
||||||
{
|
{
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int id = ((OSC::Signal*)m->mvalue()->user_data())->id();
|
|
||||||
|
|
||||||
char *peer_name = index( picked, '/' ) + 1;
|
char *peer_name = index( picked, '/' ) + 1;
|
||||||
|
|
||||||
*index( peer_name, '/' ) = 0;
|
*index( peer_name, '/' ) = 0;
|
||||||
|
|
||||||
timeline->osc->connect_signal( _osc_output, peer_name, id );
|
_osc_connected_peer = strdup( peer_name );
|
||||||
|
|
||||||
|
_osc_connected_path = strdup( ((OSC::Signal*)m->mvalue()->user_data())->path() );
|
||||||
|
|
||||||
|
if ( ! _osc_output->is_connected_to( ((OSC::Signal*)m->mvalue()->user_data()) ) )
|
||||||
|
{
|
||||||
|
connect_osc();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timeline->osc->disconnect_signal( _osc_output, _osc_connected_peer, _osc_connected_path );
|
||||||
|
|
||||||
|
free( _osc_connected_path );
|
||||||
|
free( _osc_connected_peer );
|
||||||
|
_osc_connected_peer = _osc_connected_path = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ( ! strcmp( picked, "Interpolation/Linear" ) )
|
else if ( ! strcmp( picked, "Interpolation/Linear" ) )
|
||||||
interpolation( Linear );
|
interpolation( Linear );
|
||||||
|
@ -437,7 +447,15 @@ Control_Sequence::connect_osc ( void )
|
||||||
{
|
{
|
||||||
if ( ! 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 */
|
// MESSAGE( "Failed to connect output %s to %s:%s", _osc_output->path(), _osc_connected_peer, _osc_connected_path );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tooltip( _osc_connected_path );
|
||||||
|
|
||||||
|
// _osc_connected_peer = _osc_connected_path =
|
||||||
|
|
||||||
|
MESSAGE( "Connected output %s to %s:%s", _osc_output->path(), _osc_connected_peer, _osc_connected_path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,6 +478,40 @@ Control_Sequence::process_osc ( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control_Sequence::peer_callback( const char *name, const OSC::Signal *sig, void *v )
|
||||||
|
{
|
||||||
|
((Control_Sequence*)v)->peer_callback( name, sig );
|
||||||
|
}
|
||||||
|
|
||||||
|
static Fl_Menu_Button *peer_menu;
|
||||||
|
static const char *peer_prefix;
|
||||||
|
|
||||||
|
void
|
||||||
|
Control_Sequence::peer_callback( const char *name, const OSC::Signal *sig )
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
asprintf( &s, "%s/%s%s", peer_prefix, name, sig->path() );
|
||||||
|
|
||||||
|
peer_menu->add( s, 0, NULL, (void*)( sig ),
|
||||||
|
FL_MENU_TOGGLE |
|
||||||
|
( _osc_output->is_connected_to( sig ) ? FL_MENU_VALUE : 0 ) );
|
||||||
|
|
||||||
|
free( s );
|
||||||
|
|
||||||
|
connect_osc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control_Sequence::add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix )
|
||||||
|
{
|
||||||
|
peer_menu = m;
|
||||||
|
peer_prefix = prefix;
|
||||||
|
|
||||||
|
timeline->osc->list_peers( &Control_Sequence::peer_callback, this );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Control_Sequence::handle ( int m )
|
Control_Sequence::handle ( int m )
|
||||||
{
|
{
|
||||||
|
@ -509,7 +561,7 @@ Control_Sequence::handle ( int m )
|
||||||
|
|
||||||
menu.clear();
|
menu.clear();
|
||||||
|
|
||||||
timeline->add_osc_peers_to_menu( &menu, "Connect To" );
|
add_osc_peers_to_menu( &menu, "Connect To" );
|
||||||
|
|
||||||
/* menu.add( "Connect To", 0, 0, 0); */
|
/* menu.add( "Connect To", 0, 0, 0); */
|
||||||
/* menu.add( "Connect To", 0, 0, const_cast< Fl_Menu_Item *>( con->menu() ), FL_SUBMENU_POINTER ); */
|
/* menu.add( "Connect To", 0, 0, const_cast< Fl_Menu_Item *>( con->menu() ), FL_SUBMENU_POINTER ); */
|
||||||
|
|
|
@ -49,6 +49,10 @@ private:
|
||||||
/* osc output port */
|
/* osc output port */
|
||||||
OSC::Signal *_osc_output;
|
OSC::Signal *_osc_output;
|
||||||
|
|
||||||
|
static void peer_callback( const char *name, const OSC::Signal *sig, void *v );
|
||||||
|
void peer_callback( const char *name, const OSC::Signal *sig );
|
||||||
|
void add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix );
|
||||||
|
|
||||||
bool _highlighted;
|
bool _highlighted;
|
||||||
|
|
||||||
curve_type_e _interpolation;
|
curve_type_e _interpolation;
|
||||||
|
|
|
@ -58,6 +58,8 @@ NSM_Client::command_open ( const char *name, const char *display_name, const cha
|
||||||
|
|
||||||
instance_name = strdup( client_id );
|
instance_name = strdup( client_id );
|
||||||
|
|
||||||
|
timeline->osc->name( client_id );
|
||||||
|
|
||||||
if ( Project::validate( name ) )
|
if ( Project::validate( name ) )
|
||||||
{
|
{
|
||||||
if ( timeline->command_load( name, display_name ) )
|
if ( timeline->command_load( name, display_name ) )
|
||||||
|
|
|
@ -1528,7 +1528,7 @@ Timeline::command_load ( const char *name, const char *display_name )
|
||||||
|
|
||||||
Project::set_name ( display_name ? display_name : name );
|
Project::set_name ( display_name ? display_name : name );
|
||||||
|
|
||||||
discover_peers();
|
// discover_peers();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1553,7 +1553,7 @@ Timeline::command_new ( const char *name, const char *display_name )
|
||||||
|
|
||||||
/* tle->main_window->redraw(); */
|
/* tle->main_window->redraw(); */
|
||||||
|
|
||||||
discover_peers();
|
// discover_peers();
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -1623,7 +1623,9 @@ Timeline::osc_non_hello ( const char *path, const char *types, lo_arg **argv, in
|
||||||
|
|
||||||
MESSAGE( "Scanning..." );
|
MESSAGE( "Scanning..." );
|
||||||
|
|
||||||
timeline->osc->scan_peer( id, url );
|
// timeline->osc->scan_peer( id, url );
|
||||||
|
|
||||||
|
timeline->osc->hello( url );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1684,44 +1686,13 @@ Timeline::discover_peers ( void )
|
||||||
|
|
||||||
MESSAGE( "Waiting for OSC peers..." );
|
MESSAGE( "Waiting for OSC peers..." );
|
||||||
|
|
||||||
// osc->wait( 1000 );
|
osc->wait( 1000 );
|
||||||
|
|
||||||
MESSAGE( "Reconnecting signals." );
|
MESSAGE( "Reconnecting signals." );
|
||||||
|
|
||||||
connect_osc();
|
connect_osc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Timeline::peer_callback( const char *name, const OSC::Signal *sig, void *v )
|
|
||||||
{
|
|
||||||
((Timeline*)v)->peer_callback( name, sig );
|
|
||||||
}
|
|
||||||
|
|
||||||
static Fl_Menu_Button *peer_menu;
|
|
||||||
static const char *peer_prefix;
|
|
||||||
|
|
||||||
void
|
|
||||||
Timeline::peer_callback( const char *name, const OSC::Signal *sig )
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
asprintf( &s, "%s/%s%s", peer_prefix, name, sig->path() );
|
|
||||||
|
|
||||||
peer_menu->add( s, 0, NULL, (void*)( sig ) );
|
|
||||||
|
|
||||||
free( s );
|
|
||||||
|
|
||||||
connect_osc();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Timeline::add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix )
|
|
||||||
{
|
|
||||||
peer_menu = m;
|
|
||||||
peer_prefix = prefix;
|
|
||||||
|
|
||||||
osc->list_peers( &Timeline::peer_callback, this );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* runs in the OSC thread... */
|
/* runs in the OSC thread... */
|
||||||
void
|
void
|
||||||
|
|
|
@ -236,12 +236,9 @@ public:
|
||||||
|
|
||||||
/* OSC */
|
/* OSC */
|
||||||
|
|
||||||
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 connect_osc ( void );
|
||||||
void add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix );
|
|
||||||
|
|
||||||
void discover_peers ( void );
|
void discover_peers ( void );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue