Browse Source

nonlib: Clean up signals handshaking.

tags/non-daw-v1.2.0
Jonathan Moore Liles 13 years ago
parent
commit
9df0e9d665
14 changed files with 359 additions and 219 deletions
  1. +16
    -33
      mixer/src/Mixer.C
  2. +3
    -3
      mixer/src/Mixer.H
  3. +2
    -2
      mixer/src/NSM.C
  4. +0
    -2
      mixer/src/main.C
  5. +200
    -63
      nonlib/OSC/Endpoint.C
  6. +24
    -3
      nonlib/OSC/Endpoint.H
  7. +44
    -30
      timeline/src/Control_Sequence.C
  8. +3
    -2
      timeline/src/Control_Sequence.H
  9. +5
    -5
      timeline/src/NSM.C
  10. +10
    -5
      timeline/src/OSC_Thread.C
  11. +37
    -69
      timeline/src/Timeline.C
  12. +4
    -2
      timeline/src/Timeline.H
  13. +10
    -0
      timeline/src/Track.C
  14. +1
    -0
      timeline/src/Track.H

+ 16
- 33
mixer/src/Mixer.C View File

@@ -94,34 +94,30 @@ static int osc_add_strip ( const char *path, const char *, lo_arg **, int , lo_m
return 0; return 0;
} }


int
Mixer::osc_non_hello ( const char *, const char *, lo_arg **, int , lo_message msg, void * )
{
mixer->handle_hello( msg );
return 0;
}


void void
Mixer::reply_to_finger ( lo_message msg )
Mixer::handle_hello ( lo_message msg )
{ {
int argc = lo_message_get_argc( msg ); int argc = lo_message_get_argc( msg );
lo_arg **argv = lo_message_get_argv( msg ); lo_arg **argv = lo_message_get_argv( msg );

if ( argc >= 4 ) if ( argc >= 4 )
{ {
const char *url = &argv[0]->s; const char *url = &argv[0]->s;
const char *name = &argv[1]->s; const char *name = &argv[1]->s;
const char *version = &argv[2]->s; const char *version = &argv[2]->s;
const char *id = &argv[3]->s; const char *id = &argv[3]->s;

MESSAGE( "Discovered NON peer %s (%s) @ %s with ID \"%s\"", name, version, url, id );
MESSAGE( "Registering Signals" );

lo_address to = lo_address_new_from_url( &argv[0]->s );
osc_endpoint->send( to,
"/non/hello",
osc_endpoint->url(),
APP_NAME,
VERSION,
instance_name );
mixer->osc_endpoint->hello( url );
lo_address_free( to );
MESSAGE( "Got hello from NON peer %s (%s) @ %s with ID \"%s\"", name, version, url, id );
mixer->osc_endpoint->handle_hello( id, url );
} }
} }


@@ -450,6 +446,9 @@ Mixer::init_osc ( const char *osc_port )
printf( "OSC=%s\n", osc_endpoint->url() ); printf( "OSC=%s\n", osc_endpoint->url() );


osc_endpoint->add_method( "/non/hello", "ssss", &Mixer::osc_non_hello, osc_endpoint, "" );
//
osc_endpoint->add_method( "/non/mixer/add_strip", "", osc_add_strip, osc_endpoint, "" ); osc_endpoint->add_method( "/non/mixer/add_strip", "", osc_add_strip, osc_endpoint, "" );
osc_endpoint->start(); osc_endpoint->start();
@@ -732,22 +731,6 @@ Mixer::handle ( int m )




void
Mixer::discover_peers ( void )
{
if ( nsm->is_active() )
{
lo_message m = lo_message_new();
lo_message_add_string( m, "/non/finger" );
lo_message_add_string( m, osc_endpoint->url() );

nsm->broadcast( m );
lo_message_free( m );
}
}

/************/ /************/
/* Commands */ /* Commands */
/************/ /************/


+ 3
- 3
mixer/src/Mixer.H View File

@@ -71,6 +71,8 @@ private:


static void handle_dirty ( int, void *v ); static void handle_dirty ( int, void *v );


static int osc_non_hello ( const char *, const char *, lo_arg **, int , lo_message msg, void * );

protected: protected:


int handle ( int m ); int handle ( int m );
@@ -100,7 +102,7 @@ public:
Mixer ( int X, int Y, int W, int H, const char *L ); Mixer ( int X, int Y, int W, int H, const char *L );
virtual ~Mixer(); virtual ~Mixer();


void reply_to_finger ( lo_message msg );
void handle_hello ( lo_message msg );


void announce ( const char *nash_url, const char *process_name ); void announce ( const char *nash_url, const char *process_name );


@@ -110,8 +112,6 @@ public:


void say_hello ( void ); void say_hello ( void );


void discover_peers ( void );

public: public:


bool command_save ( void ); bool command_save ( void );


+ 2
- 2
mixer/src/NSM.C View File

@@ -45,7 +45,7 @@ NSM_Client::command_broadcast ( const char *path, lo_message msg )


if ( !strcmp( path, "/non/hello" ) ) if ( !strcmp( path, "/non/hello" ) )
{ {
mixer->reply_to_finger( msg );
mixer->handle_hello( msg );
return 0; return 0;
} }
else else
@@ -103,7 +103,7 @@ NSM_Client::command_open ( const char *name, const char *display_name, const cha
} }
} }


mixer->discover_peers();
mixer->say_hello();


Fl::unlock(); Fl::unlock();




+ 0
- 2
mixer/src/main.C View File

@@ -305,8 +305,6 @@ main ( int argc, char **argv )
} }
} }


mixer->say_hello();

Fl::add_check( check_sigterm ); Fl::add_check( check_sigterm );
if ( ! no_ui ) if ( ! no_ui )


+ 200
- 63
nonlib/OSC/Endpoint.C View File

@@ -60,7 +60,9 @@ namespace OSC
Signal::Signal ( const char *path, Direction dir ) Signal::Signal ( const char *path, Direction dir )
{ {
_direction = dir; _direction = dir;
_path = strdup( path );
_path = NULL;
if ( path )
_path = strdup( path );
_id = ++next_id; _id = ++next_id;
_value = 0.0f; _value = 0.0f;
_endpoint = NULL; _endpoint = NULL;
@@ -77,8 +79,9 @@ namespace OSC
{ {
_endpoint->del_signal( this ); _endpoint->del_signal( this );
} }
free( _path );
if ( _path )
free( _path );
_path = NULL; _path = NULL;


_endpoint = NULL; _endpoint = NULL;
@@ -170,7 +173,9 @@ namespace OSC
} }


Endpoint::Endpoint ( ) Endpoint::Endpoint ( )
{
{
_peer_signal_notification_callback = 0;
_peer_signal_notification_userdata = 0;
_peer_scan_complete_callback = 0; _peer_scan_complete_callback = 0;
_peer_scan_complete_userdata = 0; _peer_scan_complete_userdata = 0;
_server = 0; _server = 0;
@@ -289,30 +294,62 @@ namespace OSC
lo_address_free( addr ); 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 )
void
Endpoint::handle_hello ( const char *peer_name, const char *peer_url )
{ {

Endpoint *ep = (Endpoint*)user_data;

const char *peer_name = &argv[0]->s;
const char *peer_url = &argv[1]->s;
DMESSAGE( "Got hello from %s", peer_name ); DMESSAGE( "Got hello from %s", peer_name );


if ( ! ep->find_peer_by_name( peer_name ) )
Peer *p = find_peer_by_name( peer_name );
if ( ! p )
{
scan_peer( peer_name, peer_url );
}
else
{ {
ep->scan_peer( peer_name, peer_url );
/* maybe the peer has a new URL */
/* update address */
lo_address addr = lo_address_new_from_url( peer_url );


if ( ep->name() )
{
ep->hello( peer_url );
}
else
if ( address_matches( addr, p->addr ) )
{ {
DMESSAGE( "Not sending hello because we don't have a name yet!" );
free( addr );
return;
} }
if ( p->addr )
free( p->addr );

p->addr = addr;

/* scan it while we're at it */
p->_scanning = true;
DMESSAGE( "Scanning peer %s", peer_name );

send( p->addr, "/signal/list" );
} }
if ( name() )
{
hello( peer_url );
}
else
{
DMESSAGE( "Not sending hello because we don't have a name yet!" );
}
}

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;
const char *peer_url = &argv[1]->s;
ep->handle_hello( peer_name, peer_url );


return 0; return 0;
} }
@@ -374,13 +411,24 @@ namespace OSC


Signal *ps = ep->find_peer_signal_by_id( p, their_id ); Signal *ps = ep->find_peer_signal_by_id( p, their_id );


/* if ( ! ps ) */
/* { */
/* WARNING( "Unknown source signal" ); */
/* WARNIN */
/* return 0; */
/* } */

if ( ! ps ) if ( ! ps )
{ {
WARNING( "Unknown source signal" );
/* we don't know about this signal yet */
/* just add a stub signal and fill in the blanks later */
ps = new Signal( NULL, Signal::Output);
ps->_id = their_id;
ps->_peer = p;


return 0;
p->_signals.push_back( ps );
} }

Signal *s = ep->find_signal_by_id( our_id ); Signal *s = ep->find_signal_by_id( our_id );


if ( ! s ) if ( ! s )
@@ -427,27 +475,44 @@ namespace OSC


if ( ! o ) if ( ! o )
{ {
WARNING( "Unknown signal id %i", id );
WARNING( "Unknown signal ID %i", id );
return 0; return 0;
} }


DMESSAGE( "Signal %s:%s was removed", o->_peer->name, o->path() ); DMESSAGE( "Signal %s:%s was removed", o->_peer->name, o->path() );


/* disconnect it */ /* disconnect it */
for ( std::list<Signal*>::iterator i = o->_outgoing.begin();
i != o->_outgoing.end();
++i )
if ( o->_outgoing.size() )
{ {
ep->disconnect_signal( o, *i );
for ( std::list<Signal*>::iterator i = o->_outgoing.begin();
i != o->_outgoing.end();
)
{
Signal *s = *i;
/* avoid messing up iterator */
++i;

ep->disconnect_signal( o, s );
}
} }


for ( std::list<Signal*>::iterator i = o->_incoming.begin();
i != o->_incoming.end();
++i )
if ( o->_incoming.size() )
{ {
ep->disconnect_signal( *i, o );
for ( std::list<Signal*>::iterator i = o->_incoming.begin();
i != o->_incoming.end();
)
{
Signal *s = *i;
/* avoid messing up iterator */
++i;
ep->disconnect_signal( s, o );
}
} }


if ( ep->_peer_signal_notification_callback )
ep->_peer_signal_notification_callback( o, Signal::Removed, ep->_peer_signal_notification_userdata );
p->_signals.remove( o ); p->_signals.remove( o );


delete o; delete o;
@@ -459,14 +524,6 @@ namespace OSC
Endpoint::osc_sig_created ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) Endpoint::osc_sig_created ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
{ {
Endpoint *ep = (Endpoint*)user_data; Endpoint *ep = (Endpoint*)user_data;

Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );

if ( ! p )
{
WARNING( "Got signal creation from unknown peer." );
return 0;
}
const char *name = &argv[0]->s; const char *name = &argv[0]->s;
const char *direction = &argv[1]->s; const char *direction = &argv[1]->s;
@@ -475,9 +532,14 @@ namespace OSC
const float max = argv[4]->f; const float max = argv[4]->f;
const float default_value = argv[5]->f; const float default_value = argv[5]->f;


DMESSAGE( "Peer %s has created signal %s with id %i (%s %f %f %f)", p->name,
name, id, direction, min, max, default_value );
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );

if ( ! p )
{
WARNING( "Got signal creation notification from unknown peer" );
return 0;
}
Signal::Direction dir = Signal::Input; Signal::Direction dir = Signal::Input;
if ( !strcmp( direction, "in" ) ) if ( !strcmp( direction, "in" ) )
@@ -492,6 +554,12 @@ namespace OSC
s->parameter_limits( min, max, default_value ); s->parameter_limits( min, max, default_value );
p->_signals.push_back( s ); p->_signals.push_back( s );

DMESSAGE( "Peer %s has created signal %s with id %i (%s %f %f %f)", p->name,
name, id, direction, min, max, default_value );
if ( ep->_peer_signal_notification_callback )
ep->_peer_signal_notification_callback( s, Signal::Created, ep->_peer_signal_notification_userdata );
return 0; return 0;
} }
@@ -652,6 +720,8 @@ namespace OSC
Endpoint::osc_signal_lister ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) Endpoint::osc_signal_lister ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
{ {
// OSC_DMSG(); // OSC_DMSG();
DMESSAGE( "Listing signals." );


const char *prefix = NULL; const char *prefix = NULL;


@@ -700,7 +770,7 @@ namespace OSC




void void
Endpoint::list_peer_signals ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v )
Endpoint::list_peer_signals ( void *v )
{ {
for ( std::list<Peer*>::iterator i = _peers.begin(); for ( std::list<Peer*>::iterator i = _peers.begin();
i != _peers.end(); i != _peers.end();
@@ -711,7 +781,8 @@ namespace OSC
++j ) ++j )
{ {
// DMESSAGE( "Running callback" ); // DMESSAGE( "Running callback" );
callback( (*i)->name, *j, v );
if ( _peer_signal_notification_callback )
_peer_signal_notification_callback( *j, OSC::Signal::Created, v );
} }
} }
} }
@@ -764,15 +835,22 @@ namespace OSC
{ {
if ( ! s->is_connected_to( d ) ) if ( ! s->is_connected_to( d ) )
return false; return false;

MESSAGE( "Disconnecting signal output \"%s\" to %s:%i", s->path(), d->_peer->name, d->_id );
send( d->_peer->addr, "/signal/disconnect",
s->_id, /* our signal id */
d->_id /* their signal id */ );
if ( d->_peer )
{
MESSAGE( "Disconnecting signal output \"%s\" from %s:%s", s->path(), d->_peer->name, d->_path );
send( d->_peer->addr, "/signal/disconnect",
s->_id, /* our signal id */
d->_id /* their signal id */ );
}
else
{
MESSAGE( "Disconnecting signal output \"%s\" to (unknown):%i", s->path(), d->_id );
}

s->_outgoing.remove( d ); s->_outgoing.remove( d );
s->_incoming.remove( d );
d->_incoming.remove( s );


return true; return true;
} }
@@ -801,6 +879,9 @@ namespace OSC
return false; return false;
} }


/** Connect to name signal. If the destination doesn't currently *
exist, but appears at some later point, the connection will be made
then */
bool bool
Endpoint::connect_signal( OSC::Signal *s, const char *peer_and_path ) Endpoint::connect_signal( OSC::Signal *s, const char *peer_and_path )
{ {
@@ -930,13 +1011,28 @@ namespace OSC
else if ( !strcmp( &argv[2]->s, "out" ) ) else if ( !strcmp( &argv[2]->s, "out" ) )
dir = Signal::Output; dir = Signal::Output;


Signal *s = new Signal( &argv[1]->s, (Signal::Direction)dir );
Signal *s = ep->find_peer_signal_by_id( p, argv[3]->i );

if ( s && s->id() == argv[3]->i )
{
/* found a stub signal, fill in the blanks */
s->_path = strdup(&argv[1]->s);
s->parameter_limits( argv[4]->f, argv[5]->f, argv[6]->f );
}
else
{
s = new Signal( &argv[1]->s, (Signal::Direction)dir );
s->_peer = p; s->_peer = p;
s->_id = argv[3]->i; s->_id = argv[3]->i;
s->parameter_limits( argv[4]->f, argv[5]->f, argv[6]->f ); s->parameter_limits( argv[4]->f, argv[5]->f, argv[6]->f );


p->_signals.push_back( s ); p->_signals.push_back( s );
}

if ( ep->_peer_signal_notification_callback )
ep->_peer_signal_notification_callback( s, Signal::Created, ep->_peer_signal_notification_userdata );
} }


return 0; return 0;
@@ -985,7 +1081,6 @@ namespace OSC
lo_server_add_method( _server, path, NULL, osc_sig_handler, o ); lo_server_add_method( _server, path, NULL, osc_sig_handler, o );
} }



o->parameter_limits( min, max, default_value ); o->parameter_limits( min, max, default_value );


/* tell our peers about it */ /* tell our peers about it */
@@ -994,7 +1089,7 @@ namespace OSC
++i ) ++i )
{ {
send( (*i)->addr, send( (*i)->addr,
"/signal/created",
"/signal/created",
o->path(), o->path(),
o->_direction == Signal::Input ? "in" : "out", o->_direction == Signal::Input ? "in" : "out",
o->id(), o->id(),
@@ -1074,24 +1169,66 @@ namespace OSC
o->id() ); o->id() );
} }


Endpoint *ep = this;

/* disconnect it */
if ( o->_outgoing.size() )
{
for ( std::list<Signal*>::iterator i = o->_outgoing.begin();
i != o->_outgoing.end();
)
{
Signal *s = *i;
/* avoid messing up iterator */
++i;

ep->disconnect_signal( o, s );
}
}

if ( o->_incoming.size() )
{
for ( std::list<Signal*>::iterator i = o->_incoming.begin();
i != o->_incoming.end();
)
{
Signal *s = *i;
/* avoid messing up iterator */
++i;
ep->disconnect_signal( s, o );
}
}

/* FIXME: clear loopback connections first! */ /* FIXME: clear loopback connections first! */
// delete o; // delete o;


_signals.remove( o ); _signals.remove( o );
} }


void
Endpoint::scan_peer ( const char *name, const char *url )
Peer *
Endpoint::add_peer ( const char *name, const char *url )
{ {
Peer *p = new Peer; Peer *p = new Peer;


DMESSAGE( "Scanning peer %s @ %s...", name, url );
DMESSAGE( "Adding 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 );
_peers.push_back( p );
return p;
}

void
Endpoint::scan_peer ( const char *name, const char *url )
{
Peer *p = add_peer(name,url);

p->_scanning = true; p->_scanning = true;


_peers.push_back( p );
DMESSAGE( "Scanning peer %s", name );


send( p->addr, "/signal/list" ); send( p->addr, "/signal/list" );
} }
@@ -1184,15 +1321,15 @@ namespace OSC
switch ( ov->type() ) switch ( ov->type() )
{ {
case 'f': case 'f':
DMESSAGE( "Adding float %f", ((OSC_Float*)ov)->value() );
// DMESSAGE( "Adding float %f", ((OSC_Float*)ov)->value() );
lo_message_add_float( m, ((OSC_Float*)ov)->value() ); lo_message_add_float( m, ((OSC_Float*)ov)->value() );
break; break;
case 'i': case 'i':
DMESSAGE( "Adding int %i", ((OSC_Int*)ov)->value() );
// DMESSAGE( "Adding int %i", ((OSC_Int*)ov)->value() );
lo_message_add_int32( m, ((OSC_Int*)ov)->value() ); lo_message_add_int32( m, ((OSC_Int*)ov)->value() );
break; break;
case 's': case 's':
DMESSAGE( "Adding string %s", ((OSC_String*)ov)->value() );
// DMESSAGE( "Adding string %s", ((OSC_String*)ov)->value() );
lo_message_add_string( m, ((OSC_String*)ov)->value() ); lo_message_add_string( m, ((OSC_String*)ov)->value() );
break; break;
default: default:
@@ -1201,7 +1338,7 @@ namespace OSC
} }
} }


DMESSAGE( "Path: %s", path );
// DMESSAGE( "Path: %s", path );


lo_bundle b = lo_bundle_new( LO_TT_IMMEDIATE ); lo_bundle b = lo_bundle_new( LO_TT_IMMEDIATE );




+ 24
- 3
nonlib/OSC/Endpoint.H View File

@@ -133,6 +133,11 @@ namespace OSC


public: public:


enum State {
Created = 0,
Removed = 1
};

enum Direction { enum Direction {
Input, Input,
Output, Output,
@@ -166,6 +171,10 @@ namespace OSC


public: public:


const char * peer_name ( void ) const {
return _peer->name;
}

Signal ( const char *path, Direction dir ); Signal ( const char *path, Direction dir );
~Signal ( ); ~Signal ( );


@@ -259,6 +268,8 @@ namespace OSC
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_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 ); static int osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );



Peer * add_peer ( const char *name, const char *url );
void scan_peer ( const char *name, const char *url ); void scan_peer ( const char *name, const char *url );


private: private:
@@ -279,12 +290,22 @@ namespace OSC
void del_signal ( Signal *signal ); void del_signal ( Signal *signal );
void send_signal_rename_notifications( Signal *s ); void send_signal_rename_notifications( Signal *s );


public:
void (*_peer_signal_notification_callback)( OSC::Signal *, OSC::Signal::State, void*);
void *_peer_signal_notification_userdata;


public:
void peer_signal_notification_callback ( void (*cb)(OSC::Signal *, OSC::Signal::State, void*), void *userdata )
{
_peer_signal_notification_callback = cb;
_peer_signal_notification_userdata = userdata;
}
// can be used to point back to owning object. // can be used to point back to owning object.
void *owner; void *owner;


void list_peer_signals ( void (*callback) (const char *, const OSC::Signal *, void * ), void *v );
void list_peer_signals ( void *v );


int init ( int proto, const char *port = 0 ); int init ( int proto, const char *port = 0 );


@@ -299,7 +320,6 @@ namespace OSC
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 );
bool connect_signal ( OSC::Signal *s, const char *peer_and_path ); bool connect_signal ( OSC::Signal *s, const char *peer_and_path );



Signal * add_signal ( const char *path, Signal::Direction dir, float min, float max, float default_value, signal_handler handler, void *user_data ); Signal * add_signal ( const char *path, Signal::Direction dir, float min, float max, float default_value, signal_handler handler, void *user_data );
Method *add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description ); Method *add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description );
void del_method ( const char *path, const char *typespec ); void del_method ( const char *path, const char *typespec );
@@ -317,6 +337,7 @@ namespace OSC
const char *name ( void ) { return _name; } const char *name ( void ) { return _name; }


void hello ( const char *url ); void hello ( const char *url );
void handle_hello ( const char *peer_name, const char *peer_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 );




+ 44
- 30
timeline/src/Control_Sequence.C View File

@@ -66,10 +66,10 @@ Control_Sequence::Control_Sequence ( Track *track, const char *name ) : Sequence


_track = track; _track = track;


mode( OSC );

this->name( name ); this->name( name );


mode( OSC );

if ( track ) if ( track )
track->add( this ); track->add( this );


@@ -198,6 +198,8 @@ Control_Sequence::cb_button ( Fl_Widget *w )
void void
Control_Sequence::init ( void ) Control_Sequence::init ( void )
{ {
timeline->osc->peer_signal_notification_callback( &Control_Sequence::peer_callback, NULL );

labeltype( FL_NO_LABEL ); labeltype( FL_NO_LABEL );
{ {
Control_Sequence_Header *o = new Control_Sequence_Header( x(), y(), Track::width(), 52 ); Control_Sequence_Header *o = new Control_Sequence_Header( x(), y(), Track::width(), 52 );
@@ -332,7 +334,7 @@ Control_Sequence::mode ( Mode m )
{ {
/* FIXME: use name here... */ /* FIXME: use name here... */
char *path; char *path;
asprintf( &path, "/track/%s/control/%i", track()->name(), track()->ncontrols() );
asprintf( &path, "/track/%s/%s", track()->name(), name() );


char *s = escape_url( path ); char *s = escape_url( path );


@@ -348,8 +350,6 @@ Control_Sequence::mode ( Mode m )


DMESSAGE( "osc_output: %p", _osc_output() ); DMESSAGE( "osc_output: %p", _osc_output() );


connect_osc();

header()->outputs_indicator->label( "osc" ); header()->outputs_indicator->label( "osc" );
} }


@@ -589,6 +589,8 @@ Control_Sequence::menu_cb ( const Fl_Menu_ *m )
void void
Control_Sequence::connect_osc ( void ) Control_Sequence::connect_osc ( void )
{ {
timeline->osc_thread->lock();

if ( _persistent_osc_connections.size() ) if ( _persistent_osc_connections.size() )
{ {
for ( std::list<char*>::iterator i = _persistent_osc_connections.begin(); for ( std::list<char*>::iterator i = _persistent_osc_connections.begin();
@@ -597,7 +599,7 @@ Control_Sequence::connect_osc ( void )
{ {
if ( ! timeline->osc->connect_signal( _osc_output(), *i ) ) if ( ! timeline->osc->connect_signal( _osc_output(), *i ) )
{ {
// MESSAGE( "Failed to connect output %s to ", _osc_output->path(), *i );
/* WARNING( "Failed to connect output %s to %s", _osc_output()->path(), *i ); */
} }
else else
{ {
@@ -606,6 +608,10 @@ Control_Sequence::connect_osc ( void )
} }
} }
} }

header()->outputs_indicator->value( _osc_output() && _osc_output()->connected() );
timeline->osc_thread->unlock();
} }


void void
@@ -614,28 +620,26 @@ Control_Sequence::process_osc ( void )
if ( mode() != OSC ) if ( mode() != OSC )
return; return;


header()->outputs_indicator->value( _osc_output() && _osc_output()->connected() );

if ( _osc_output() && _osc_output()->connected() ) if ( _osc_output() && _osc_output()->connected() )
{ {
sample_t buf[1]; sample_t buf[1];
play( buf, (nframes_t)transport->frame, (nframes_t) 1 ); play( buf, (nframes_t)transport->frame, (nframes_t) 1 );
_osc_output()->value( (float)buf[0] ); _osc_output()->value( (float)buf[0] );
} }
} }


static Fl_Menu_Button *peer_menu;
static const char *peer_prefix;

void void
Control_Sequence::peer_callback( const char *name, const OSC::Signal *sig, void *v )
Control_Sequence::update_osc_connection_state ( void )
{ {
((Control_Sequence*)v)->peer_callback( name, sig );
header()->outputs_indicator->value( _osc_output() && _osc_output()->connected() );
} }


static Fl_Menu_Button *peer_menu;
static const char *peer_prefix;

void void
Control_Sequence::peer_callback( const char *name, const OSC::Signal *sig )
Control_Sequence::peer_callback( OSC::Signal *sig, OSC::Signal::State state, void *v )
{ {
char *s; char *s;


@@ -647,34 +651,44 @@ Control_Sequence::peer_callback( const char *name, const OSC::Signal *sig )
if ( ! ( sig->parameter_limits().min == 0.0 && if ( ! ( sig->parameter_limits().min == 0.0 &&
sig->parameter_limits().max == 1.0 ) ) sig->parameter_limits().max == 1.0 ) )
return; return;


assert( sig->path() );

char *path = strdup( sig->path() );

unescape_url( path );
if ( ! v )
{
if( state == OSC::Signal::Created )
timeline->connect_osc();
else
timeline->update_osc_connection_state();
}
else
{
/* building menu */
const char *name = sig->peer_name();
assert( sig->path() );


asprintf( &s, "%s/%s%s", peer_prefix, name, path );
char *path = strdup( sig->path() );


peer_menu->add( s, 0, NULL, (void*)( sig ),
FL_MENU_TOGGLE |
( _osc_output()->is_connected_to( sig ) ? FL_MENU_VALUE : 0 ) );
unescape_url( path );


free( path );
asprintf( &s, "%s/%s%s", peer_prefix, name, path );


free( s );
peer_menu->add( s, 0, NULL, (void*)( sig ),
FL_MENU_TOGGLE |
( ((Control_Sequence*)v)->_osc_output()->is_connected_to( sig ) ? FL_MENU_VALUE : 0 ) );
free( path );


connect_osc();
free( s );
}
} }


void void
Control_Sequence::add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix ) Control_Sequence::add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix )
{ {
peer_menu = m;
peer_menu = m;
peer_prefix = prefix; peer_prefix = prefix;


timeline->osc->list_peer_signals( &Control_Sequence::peer_callback, this );
timeline->osc->list_peer_signals( this );
} }


Fl_Menu_Button & Fl_Menu_Button &


+ 3
- 2
timeline/src/Control_Sequence.H View File

@@ -71,8 +71,8 @@ private:
} }




static void peer_callback( const char *name, const OSC::Signal *sig, void *v );
void peer_callback( const char *name, const OSC::Signal *sig );
static void peer_callback( OSC::Signal *sig, OSC::Signal::State state, void *v );
void peer_callback( OSC::Signal *sig, OSC::Signal::State state );
void add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix ); void add_osc_peers_to_menu ( Fl_Menu_Button *m, const char *prefix );


static Fl_Widget *_highlighted; static Fl_Widget *_highlighted;
@@ -116,6 +116,7 @@ public:


void process_osc ( void ); void process_osc ( void );
void connect_osc ( void ); void connect_osc ( void );
void update_osc_connection_state ( void );


static bool draw_with_polygon; static bool draw_with_polygon;
static bool draw_with_grid; static bool draw_with_grid;


+ 5
- 5
timeline/src/NSM.C View File

@@ -56,7 +56,7 @@ command_open ( const char *name, const char *display_name, const char *client_id
instance_name = strdup( client_id ); instance_name = strdup( client_id );


timeline->osc->name( client_id ); timeline->osc->name( client_id );
int r = 0; int r = 0;


if ( Project::validate( name ) ) if ( Project::validate( name ) )
@@ -79,8 +79,10 @@ command_open ( const char *name, const char *display_name, const char *client_id
r = ERR_GENERAL; r = ERR_GENERAL;
} }
} }
timeline->say_hello();


timeline->discover_peers();
// timeline->connect_osc();


return r; return r;
} }
@@ -89,8 +91,6 @@ static void
command_session_is_loaded ( void *userdata ) command_session_is_loaded ( void *userdata )
{ {
MESSAGE( "NSM says session is loaded." ); MESSAGE( "NSM says session is loaded." );

timeline->discover_peers();
} }


static int static int
@@ -101,7 +101,7 @@ command_broadcast ( const char *path, lo_message msg, void *userdata )


if ( !strcmp( path, "/non/hello" ) ) if ( !strcmp( path, "/non/hello" ) )
{ {
timeline->reply_to_finger( msg );
timeline->handle_hello( msg );
return 0; return 0;
} }
else else


+ 10
- 5
timeline/src/OSC_Thread.C View File

@@ -26,6 +26,8 @@


#include "debug.h" #include "debug.h"


#include "OSC/Endpoint.H"

extern Timeline *timeline; extern Timeline *timeline;


OSC_Thread::OSC_Thread ( ) OSC_Thread::OSC_Thread ( )
@@ -61,14 +63,17 @@ OSC_Thread::process ( void )
_thread.name( "OSC" ); _thread.name( "OSC" );


DMESSAGE( "OSC Thread starting" ); DMESSAGE( "OSC Thread starting" );
while ( !_shutdown ) while ( !_shutdown )
{ {
if ( trylock() )
{
timeline->osc->check();
timeline->process_osc();
unlock();
}

usleep( 100 * 1000 ); usleep( 100 * 1000 );
/* lock(); */
timeline->process_osc();
/* unlock(); */
} }


DMESSAGE( "OSC Thread stopping." ); DMESSAGE( "OSC Thread stopping." );


+ 37
- 69
timeline/src/Timeline.C View File

@@ -2082,15 +2082,6 @@ Timeline::session_manager_name ( void )
/* OSC */ /* OSC */
/*******/ /*******/


const double OSC_INTERVAL = 0.2f;

void
Timeline::check_osc ( void * v )
{
((Timeline*)v)->osc->check();
Fl::repeat_timeout( OSC_INTERVAL, &Timeline::check_osc, v );
}

int int
Timeline::init_osc ( const char *osc_port ) Timeline::init_osc ( const char *osc_port )
{ {
@@ -2107,11 +2098,6 @@ Timeline::init_osc ( const char *osc_port )
// osc->start(); // osc->start();
/* poll so we can keep OSC handlers running in the GUI thread and avoid extra sync */
Fl::add_timeout( OSC_INTERVAL, &Timeline::check_osc, this );

osc->peer_scan_complete_callback( &Timeline::handle_peer_scan_complete, this );

if ( ! osc_thread ) if ( ! osc_thread )
{ {
osc_thread = new OSC_Thread(); osc_thread = new OSC_Thread();
@@ -2123,9 +2109,19 @@ Timeline::init_osc ( const char *osc_port )
} }


int int
Timeline::osc_non_hello ( const char *path, const char *, lo_arg **argv, int argc, lo_message, void * )
Timeline::osc_non_hello ( const char *, const char *, lo_arg **, int , lo_message msg, void * )
{ {
OSC_DMSG();
THREAD_ASSERT( OSC );

timeline->handle_hello(msg);
return 0;
}

void
Timeline::handle_hello ( lo_message msg )
{
int argc = lo_message_get_argc( msg );
lo_arg **argv = lo_message_get_argv( msg );


if ( argc >= 4 ) if ( argc >= 4 )
{ {
@@ -2134,88 +2130,60 @@ Timeline::osc_non_hello ( const char *path, const char *, lo_arg **argv, int arg
const char *version = &argv[2]->s; const char *version = &argv[2]->s;
const char *id = &argv[3]->s; const char *id = &argv[3]->s;


MESSAGE( "Discovered NON peer %s (%s) @ %s with ID \"%s\"", name, version, url, id );
MESSAGE( "Registering Signals" );

timeline->osc->hello( url );
MESSAGE( "Got hello from NON peer %s (%s) @ %s with ID \"%s\"", name, version, url, id );
return 0;
osc->handle_hello( &argv[3]->s, &argv[0]->s );
} }
return -1;
} }


void void
Timeline::reply_to_finger ( lo_message msg )
{
int argc = lo_message_get_argc( msg );
lo_arg **argv = lo_message_get_argv( msg );

if ( argc < 1 )
return;

lo_address reply = lo_address_new_from_url( &argv[0]->s );
osc->send( reply,
"/non/hello",
osc->url(),
APP_NAME,
VERSION,
instance_name );

osc->hello( &argv[0]->s );

lo_address_free( reply );
}

void
Timeline::handle_peer_scan_complete ( void *o )
Timeline::say_hello ( void )
{ {
((Timeline*)o)->connect_osc();
if ( nsm_is_active( nsm ) )
{
lo_message m = lo_message_new();
lo_message_add( m, "sssss",
"/non/hello",
osc->url(),
APP_NAME,
VERSION,
instance_name );
nsm_send_broadcast( nsm, m );
}
} }


void void
Timeline::connect_osc ( void ) Timeline::connect_osc ( void )
{ {
// rdlock();

/* try to (re)connect OSC signals */
/* reconnect OSC signals */
for ( int i = tracks->children(); i-- ; ) for ( int i = tracks->children(); i-- ; )
{ {
Track *t = (Track*)tracks->child( i ); Track *t = (Track*)tracks->child( i );

t->connect_osc(); t->connect_osc();
} }

// unlock();
} }

void void
Timeline::discover_peers ( void )
Timeline::update_osc_connection_state ( void )
{ {
if ( nsm_is_active( nsm ) )
/* reconnect OSC signals */
for ( int i = tracks->children(); i-- ; )
{ {
lo_message m = lo_message_new();
lo_message_add( m, "sssss",
"/non/hello",
osc->url(),
APP_NAME,
VERSION,
instance_name );
Track *t = (Track*)tracks->child( i );
nsm_send_broadcast( nsm, m );
t->update_osc_connection_state();
} }
} }



/* runs in the OSC thread... */ /* runs in the OSC thread... */
void void
Timeline::process_osc ( void ) Timeline::process_osc ( void )
{ {
THREAD_ASSERT( OSC ); THREAD_ASSERT( OSC );


rdlock();
/* rdlock(); */


/* reconnect OSC signals */ /* reconnect OSC signals */
for ( int i = tracks->children(); i-- ; ) for ( int i = tracks->children(); i-- ; )
@@ -2225,6 +2193,6 @@ Timeline::process_osc ( void )
t->process_osc(); t->process_osc();
} }


unlock();
/* unlock(); */
} }



+ 4
- 2
timeline/src/Timeline.H View File

@@ -294,7 +294,9 @@ public:
void connect_osc ( void ); void connect_osc ( void );


void discover_peers ( void );
void update_osc_connection_state ( void );

void say_hello ( void );


static void check_osc ( void * v ); static void check_osc ( void * v );
@@ -304,7 +306,7 @@ public:
static int osc_non_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ); static int osc_non_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data );


void reply_to_finger ( lo_message msg );
void handle_hello ( lo_message msg );


void add_cursor ( Cursor_Region *o ); void add_cursor ( Cursor_Region *o );
void add_cursor ( Cursor_Point *o ); void add_cursor ( Cursor_Point *o );


+ 10
- 0
timeline/src/Track.C View File

@@ -1095,6 +1095,16 @@ Track::connect_osc ( void )
} }
} }


void
Track::update_osc_connection_state ( void )
{
for ( int j = control->children(); j--; )
{
Control_Sequence *c = (Control_Sequence*)control->child( j );
c->update_osc_connection_state();
}
}

void void
Track::process_osc ( void ) Track::process_osc ( void )
{ {


+ 1
- 0
timeline/src/Track.H View File

@@ -242,6 +242,7 @@ public:


void process_osc ( void ); void process_osc ( void );
void connect_osc ( void ); void connect_osc ( void );
void update_osc_connection_state ( void );


/* Engine */ /* Engine */
const Audio_Region *capture_region ( void ) const; const Audio_Region *capture_region ( void ) const;


Loading…
Cancel
Save