Add hack to support 'renaming' of JACK::Client.
We wouldn't need this if JACK had jack_client_set_name().
This commit is contained in:
parent
a971175c8e
commit
e1a41ba9c9
|
@ -77,6 +77,8 @@
|
|||
|
||||
#include <FL/Fl_Flip_Button.H>
|
||||
|
||||
#include "const.h"
|
||||
|
||||
|
||||
|
||||
std::list <Chain*> Chain::chain;
|
||||
|
@ -437,8 +439,17 @@ Chain::can_support_input_channels ( int n )
|
|||
void
|
||||
Chain::name ( const char *name )
|
||||
{
|
||||
|
||||
char ename[512];
|
||||
snprintf( ename, sizeof(ename), "%s/%s", APP_NAME, name );
|
||||
|
||||
_name = engine()->name( ename );
|
||||
|
||||
/* FIXME: discarding the name jack picked is technically wrong! */
|
||||
|
||||
_name = name;
|
||||
|
||||
|
||||
for ( int i = 0; i < modules(); ++i )
|
||||
module( i )->handle_chain_name_changed();
|
||||
}
|
||||
|
|
|
@ -166,10 +166,10 @@ Controller_Module::connect_to ( Port *p )
|
|||
{
|
||||
chain()->engine()->lock();
|
||||
|
||||
char name[256];
|
||||
snprintf( name, sizeof( name ), "%s-CV", p->name() );
|
||||
// char name[256];
|
||||
// snprintf( name, sizeof( name ), "%s-CV", p->name() );
|
||||
|
||||
JACK::Port po( chain()->engine()->client(), JACK::Port::Input, chain()->name(), 0, name );
|
||||
JACK::Port po( chain()->engine(), JACK::Port::Input, p->name(), 0, "CV" );
|
||||
|
||||
if ( po.valid() )
|
||||
{
|
||||
|
|
|
@ -86,7 +86,7 @@ JACK_Module::configure_inputs ( int n )
|
|||
{
|
||||
for ( int i = on; i < n; ++i )
|
||||
{
|
||||
JACK::Port po( chain()->engine()->client(), JACK::Port::Output, chain()->name(), i );
|
||||
JACK::Port po( chain()->engine(), JACK::Port::Output, i );
|
||||
|
||||
if ( po.valid() )
|
||||
{
|
||||
|
@ -120,7 +120,7 @@ JACK_Module::configure_outputs ( int n )
|
|||
{
|
||||
for ( int i = on; i < n; ++i )
|
||||
{
|
||||
JACK::Port po( chain()->engine()->client(), JACK::Port::Input, chain()->name(), i );
|
||||
JACK::Port po( chain()->engine(), JACK::Port::Input, i );
|
||||
|
||||
if ( po.valid() )
|
||||
{
|
||||
|
@ -188,10 +188,10 @@ void
|
|||
JACK_Module::handle_chain_name_changed ( void )
|
||||
{
|
||||
for ( unsigned int i = 0; i < jack_output.size(); ++i )
|
||||
jack_output[ i ].name( chain()->name(), i );
|
||||
jack_output[ i ].name( NULL, i );
|
||||
|
||||
for ( unsigned int i = 0; i < jack_input.size(); ++i )
|
||||
jack_input[ i ].name( chain()->name(), i );
|
||||
jack_input[ i ].name( NULL, i );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define APP_NAME "Non-Mixer"
|
||||
#define APP_TITLE "The Non-Mixer"
|
||||
#define __MODULE__ "non-mixer"
|
||||
|
|
|
@ -41,7 +41,7 @@ Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0 )
|
|||
|
||||
_track = track;
|
||||
|
||||
_output = new JACK::Port( engine->client(), JACK::Port::Output, track->name(), track->ncontrols(), "cv" );
|
||||
_output = new JACK::Port( engine, JACK::Port::Output, track->name(), track->ncontrols(), "cv" );
|
||||
|
||||
if ( track )
|
||||
track->add( this );
|
||||
|
@ -110,7 +110,7 @@ Control_Sequence::set ( Log_Entry &e )
|
|||
|
||||
assert( t );
|
||||
|
||||
_output = new JACK::Port( engine->client(), JACK::Port::Output, t->name(), t->ncontrols(), "cv" );
|
||||
_output = new JACK::Port( engine, JACK::Port::Output, t->name(), t->ncontrols(), "cv" );
|
||||
|
||||
t->add( this );
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ Track::configure_outputs ( int n )
|
|||
{
|
||||
for ( int i = on; i < n; ++i )
|
||||
{
|
||||
JACK::Port p( engine->client(), JACK::Port::Output, name(), i );
|
||||
JACK::Port p( engine, JACK::Port::Output, name(), i );
|
||||
|
||||
if ( p.valid() )
|
||||
output.push_back( p );
|
||||
|
@ -124,7 +124,7 @@ Track::configure_inputs ( int n )
|
|||
{
|
||||
for ( int i = on; i < n; ++i )
|
||||
{
|
||||
JACK::Port p( engine->client(), JACK::Port::Input, name(), i );
|
||||
JACK::Port p( engine, JACK::Port::Input, name(), i );
|
||||
|
||||
if ( p.valid() )
|
||||
input.push_back( p );
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// Transport transport;
|
||||
|
||||
#define client engine->client()
|
||||
#define client engine->jack_client()
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
/*******************************************************************************/
|
||||
|
||||
#include "Client.H"
|
||||
#include "Port.H"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
|
@ -146,4 +149,66 @@ namespace JACK
|
|||
// WARNING( "Unkown error while setting freewheeling mode" );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Client::port_added ( Port *p )
|
||||
{
|
||||
std::list < JACK::Port * >::iterator i = std::find( _active_ports.begin(), _active_ports.end(), p );
|
||||
|
||||
if ( i != _active_ports.end() )
|
||||
return;
|
||||
|
||||
_active_ports.push_back( p );
|
||||
}
|
||||
|
||||
void
|
||||
Client::port_removed ( Port *p )
|
||||
{
|
||||
_active_ports.remove( p );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Client::freeze_ports ( void )
|
||||
{
|
||||
for ( std::list < JACK::Port * >::iterator i = _active_ports.begin();
|
||||
i != _active_ports.end();
|
||||
++i )
|
||||
{
|
||||
(*i)->freeze();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Client::thaw_ports ( void )
|
||||
{
|
||||
for ( std::list < JACK::Port * >::iterator i = _active_ports.begin();
|
||||
i != _active_ports.end();
|
||||
++i )
|
||||
{
|
||||
(*i)->thaw();
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
Client::name ( const char *s )
|
||||
{
|
||||
/* Because the JACK API does not provide a mechanism for renaming
|
||||
* clients, we have to save connections, destroy our client,
|
||||
* create a client with the new name, and restore our
|
||||
* connections. Lovely. */
|
||||
|
||||
freeze_ports();
|
||||
|
||||
jack_deactivate( _client );
|
||||
jack_client_close( _client );
|
||||
|
||||
_client = NULL;
|
||||
|
||||
s = init( s );
|
||||
|
||||
thaw_ports();
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,10 +24,16 @@
|
|||
typedef jack_nframes_t nframes_t;
|
||||
typedef float sample_t;
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace JACK
|
||||
{
|
||||
class Port;
|
||||
class Client
|
||||
{
|
||||
|
||||
std::list <JACK::Port*> _active_ports;
|
||||
|
||||
jack_client_t *_client;
|
||||
|
||||
nframes_t _sample_rate;
|
||||
|
@ -55,6 +61,9 @@ namespace JACK
|
|||
Client ( const Client &rhs );
|
||||
Client & operator = ( const Client &rhs );
|
||||
|
||||
void freeze_ports ( void );
|
||||
void thaw_ports ( void );
|
||||
|
||||
protected:
|
||||
|
||||
void deactivate ( void );
|
||||
|
@ -66,12 +75,16 @@ namespace JACK
|
|||
|
||||
public:
|
||||
|
||||
jack_client_t * client ( void ) { return _client; }
|
||||
jack_client_t * jack_client ( void ) { return _client; }
|
||||
|
||||
void port_added ( JACK::Port * p );
|
||||
void port_removed ( JACK::Port *p );
|
||||
|
||||
Client ( );
|
||||
virtual ~Client ( );
|
||||
|
||||
const char * init ( const char *client_name );
|
||||
const char * name ( const char * );
|
||||
|
||||
nframes_t nframes ( void ) const { return jack_get_buffer_size( _client ); }
|
||||
float frame_rate ( void ) const { return jack_get_sample_rate( _client ); }
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdio.h> // sprintf
|
||||
#include <errno.h>
|
||||
|
||||
namespace JACK
|
||||
{
|
||||
|
@ -35,22 +36,36 @@ namespace JACK
|
|||
return jack_port_name_size() - jack_client_name_size() - 6;
|
||||
}
|
||||
|
||||
/* nframes is the number of frames to buffer */
|
||||
Port::Port ( jack_client_t *client, jack_port_t *port )
|
||||
|
||||
Port::Port ( const Port &rhs )
|
||||
{
|
||||
_client = client;
|
||||
_port = port;
|
||||
_name = jack_port_name( _port );
|
||||
_freezer = rhs._freezer;
|
||||
_client = rhs._client;
|
||||
_port = rhs._port;
|
||||
_name = strdup( rhs._name );
|
||||
|
||||
_client->port_added( this );
|
||||
}
|
||||
|
||||
Port::Port ( jack_client_t *client, const char *name, type_e dir )
|
||||
/* nframes is the number of frames to buffer */
|
||||
Port::Port ( JACK::Client *client, jack_port_t *port )
|
||||
{
|
||||
_freezer = NULL;
|
||||
_client = client;
|
||||
_port = port;
|
||||
_name = strdup( jack_port_name( _port ) );
|
||||
}
|
||||
|
||||
Port::Port ( JACK::Client *client, const char *name, type_e dir )
|
||||
{
|
||||
_freezer = NULL;
|
||||
_client = client;
|
||||
activate( name, dir );
|
||||
}
|
||||
|
||||
Port::Port ( jack_client_t *client, type_e dir, const char *base, int n, const char *type )
|
||||
Port::Port ( JACK::Client *client, type_e dir, const char *base, int n, const char *type )
|
||||
{
|
||||
_freezer = NULL;
|
||||
_client = client;
|
||||
|
||||
const char *name = name_for_port( dir, base, n, type );
|
||||
|
@ -58,8 +73,28 @@ namespace JACK
|
|||
activate( name, dir );
|
||||
}
|
||||
|
||||
Port::Port ( JACK::Client *client, type_e dir, int n, const char *type )
|
||||
{
|
||||
_freezer = NULL;
|
||||
_client = client;
|
||||
|
||||
const char *name = name_for_port( dir, NULL, n, type );
|
||||
|
||||
activate( name, dir );
|
||||
}
|
||||
|
||||
Port::~Port ( )
|
||||
{
|
||||
if ( _name )
|
||||
free( _name );
|
||||
|
||||
_client->port_removed( this );
|
||||
/* if ( _freezer ) */
|
||||
/* { */
|
||||
/* delete _freezer; */
|
||||
/* _freezer = NULL; */
|
||||
/* } */
|
||||
|
||||
/* if ( _port ) */
|
||||
/* jack_port_unregister( _client, _port ); */
|
||||
|
||||
|
@ -74,15 +109,22 @@ namespace JACK
|
|||
|
||||
const char *dir_s = dir == Port::Output ? "out" : "in";
|
||||
|
||||
strncpy( pname, base, Port::max_name() );
|
||||
pname[0] = '\0';
|
||||
|
||||
if ( base )
|
||||
{
|
||||
strncpy( pname, base, Port::max_name() );
|
||||
strcat( pname, "/" );
|
||||
}
|
||||
|
||||
pname[ Port::max_name() - 1 ] = '\0';
|
||||
|
||||
int l = strlen( pname );
|
||||
|
||||
if ( type )
|
||||
snprintf( pname + l, sizeof( pname ) - l, "/%s-%s-%d", type, dir_s, n + 1 );
|
||||
snprintf( pname + l, sizeof( pname ) - l, "%s-%s-%d", type, dir_s, n + 1 );
|
||||
else
|
||||
snprintf( pname + l, sizeof( pname ) - l, "/%s-%d", dir_s, n + 1 );
|
||||
snprintf( pname + l, sizeof( pname ) - l, "%s-%d", dir_s, n + 1 );
|
||||
|
||||
return pname;
|
||||
}
|
||||
|
@ -90,11 +132,13 @@ namespace JACK
|
|||
void
|
||||
Port::activate ( const char *name, type_e dir )
|
||||
{
|
||||
_name = name;
|
||||
_port = jack_port_register( _client, _name,
|
||||
_name = strdup( name );
|
||||
_port = jack_port_register( _client->jack_client(), _name,
|
||||
JACK_DEFAULT_AUDIO_TYPE,
|
||||
dir == Output ? JackPortIsOutput : JackPortIsInput,
|
||||
0 );
|
||||
|
||||
_client->port_added( this );
|
||||
}
|
||||
|
||||
/** returns the sum of latency of all ports between this one and a
|
||||
|
@ -107,7 +151,7 @@ namespace JACK
|
|||
nframes_t
|
||||
Port::total_latency ( void ) const
|
||||
{
|
||||
return jack_port_get_total_latency( _client, _port );
|
||||
return jack_port_get_total_latency( _client->jack_client() , _port );
|
||||
}
|
||||
|
||||
/** returns the number of frames of latency assigned to this port */
|
||||
|
@ -128,14 +172,16 @@ namespace JACK
|
|||
Port::shutdown ( void )
|
||||
{
|
||||
if ( _port )
|
||||
jack_port_unregister( _client, _port );
|
||||
jack_port_unregister( _client->jack_client(), _port );
|
||||
|
||||
_client->port_removed( this );
|
||||
}
|
||||
|
||||
/** rename port */
|
||||
bool
|
||||
Port::name ( const char *name )
|
||||
{
|
||||
_name = name;
|
||||
_name = strdup( name );
|
||||
|
||||
return 0 == jack_port_set_name( _port, name );
|
||||
}
|
||||
|
@ -170,4 +216,78 @@ namespace JACK
|
|||
memset( buffer( nframes ), 0, nframes * sizeof( sample_t ) );
|
||||
}
|
||||
|
||||
/** Return a malloc()'d null terminated array of strings
|
||||
* representing all ports to which this port is connected. */
|
||||
const char **
|
||||
Port::connections ( void )
|
||||
{
|
||||
return jack_port_get_connections( _port );
|
||||
}
|
||||
|
||||
/** Restore the connections returned by connections() */
|
||||
bool
|
||||
Port::connections ( const char **port_names )
|
||||
{
|
||||
if ( ! port_names )
|
||||
return true;
|
||||
|
||||
for ( const char **port_name = port_names; *port_name; ++port_name )
|
||||
{
|
||||
const char *src;
|
||||
const char *dst;
|
||||
const char *name = jack_port_name( _port );
|
||||
|
||||
if ( type() == Output )
|
||||
{
|
||||
src = name;
|
||||
dst = *port_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
src = *port_name;
|
||||
dst = name;
|
||||
}
|
||||
|
||||
if ( int err = jack_connect( _client->jack_client(), src, dst ) )
|
||||
{
|
||||
if ( EEXIST == err )
|
||||
{
|
||||
/* connection already exists, not a problem */
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Port::freeze ( void )
|
||||
{
|
||||
if ( _freezer )
|
||||
delete _freezer;
|
||||
|
||||
freeze_state *f = new freeze_state();
|
||||
|
||||
f->connections = connections();
|
||||
f->direction = type();
|
||||
f->name = strdup( name() );
|
||||
|
||||
_freezer = f;
|
||||
}
|
||||
|
||||
void
|
||||
Port::thaw ( void )
|
||||
{
|
||||
activate( name(), _freezer->direction );
|
||||
|
||||
connections( _freezer->connections );
|
||||
|
||||
delete _freezer;
|
||||
_freezer = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,15 @@
|
|||
|
||||
// #include <jack/jack.h>
|
||||
#include "Client.H"
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace JACK
|
||||
{
|
||||
class Port
|
||||
{
|
||||
jack_port_t *_port;
|
||||
const char *_name;
|
||||
jack_client_t *_client;
|
||||
char *_name;
|
||||
JACK::Client *_client;
|
||||
|
||||
/* FIXME: reference count? */
|
||||
|
||||
|
@ -42,18 +43,15 @@ namespace JACK
|
|||
|
||||
static int max_name ( void );
|
||||
|
||||
Port ( jack_client_t *client, jack_port_t *port );
|
||||
Port ( jack_client_t *client, const char *name, type_e dir );
|
||||
Port ( jack_client_t *client, type_e dir, const char *base, int n, const char *type=0 );
|
||||
Port ( JACK::Client *client, jack_port_t *port );
|
||||
Port ( JACK::Client *client, const char *name, type_e dir );
|
||||
Port ( JACK::Client *client, type_e dir, const char *base, int n, const char *type=0 );
|
||||
Port ( JACK::Client *client, type_e dir, int n, const char *type=0 );
|
||||
|
||||
// Port ( );
|
||||
~Port ( );
|
||||
|
||||
/* Port ( const Port & rhs ) */
|
||||
/* { */
|
||||
/* _port = rhs.port; */
|
||||
/* _name = rhs.name; */
|
||||
/* } */
|
||||
Port ( const Port & rhs );
|
||||
|
||||
|
||||
bool valid ( void ) const { return _port; }
|
||||
|
@ -76,6 +74,45 @@ namespace JACK
|
|||
void read ( sample_t *buf, nframes_t nframes );
|
||||
void *buffer ( nframes_t nframes );
|
||||
void silence ( nframes_t nframes );
|
||||
|
||||
/* */
|
||||
const char ** connections ( void );
|
||||
bool connections ( const char **port_names );
|
||||
void freeze ( void );
|
||||
void thaw ( void );
|
||||
|
||||
private:
|
||||
|
||||
/* holds all we need to know about a jack port to recreate it on a
|
||||
new client */
|
||||
struct freeze_state
|
||||
{
|
||||
const char **connections;
|
||||
type_e direction;
|
||||
char *name;
|
||||
|
||||
freeze_state ( )
|
||||
{
|
||||
connections = NULL;
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
~freeze_state ( )
|
||||
{
|
||||
if ( connections )
|
||||
{
|
||||
free( connections );
|
||||
connections = NULL;
|
||||
}
|
||||
if ( name )
|
||||
{
|
||||
free( name );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
freeze_state *_freezer;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue