Browse Source

Add hack to support 'renaming' of JACK::Client.

We wouldn't need this if JACK had jack_client_set_name().
tags/non-daw-v1.1.0
Jonathan Moore Liles 15 years ago
parent
commit
e1a41ba9c9
11 changed files with 283 additions and 35 deletions
  1. +11
    -0
      Mixer/Chain.C
  2. +3
    -3
      Mixer/Controller_Module.C
  3. +4
    -4
      Mixer/JACK_Module.C
  4. +2
    -0
      Mixer/const.h
  5. +2
    -2
      Timeline/Control_Sequence.C
  6. +2
    -2
      Timeline/Engine/Track.C
  7. +1
    -1
      Timeline/Transport.C
  8. +65
    -0
      nonlib/JACK/Client.C
  9. +14
    -1
      nonlib/JACK/Client.H
  10. +132
    -12
      nonlib/JACK/Port.C
  11. +47
    -10
      nonlib/JACK/Port.H

+ 11
- 0
Mixer/Chain.C View File

@@ -77,6 +77,8 @@


#include <FL/Fl_Flip_Button.H> #include <FL/Fl_Flip_Button.H>


#include "const.h"



std::list <Chain*> Chain::chain; std::list <Chain*> Chain::chain;
@@ -437,8 +439,17 @@ Chain::can_support_input_channels ( int n )
void void
Chain::name ( const char *name ) 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; _name = name;



for ( int i = 0; i < modules(); ++i ) for ( int i = 0; i < modules(); ++i )
module( i )->handle_chain_name_changed(); module( i )->handle_chain_name_changed();
} }


+ 3
- 3
Mixer/Controller_Module.C View File

@@ -166,10 +166,10 @@ Controller_Module::connect_to ( Port *p )
{ {
chain()->engine()->lock(); 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() ) if ( po.valid() )
{ {


+ 4
- 4
Mixer/JACK_Module.C View File

@@ -86,7 +86,7 @@ JACK_Module::configure_inputs ( int n )
{ {
for ( int i = on; i < n; ++i ) 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() ) if ( po.valid() )
{ {
@@ -120,7 +120,7 @@ JACK_Module::configure_outputs ( int n )
{ {
for ( int i = on; i < n; ++i ) 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() ) if ( po.valid() )
{ {
@@ -188,10 +188,10 @@ void
JACK_Module::handle_chain_name_changed ( void ) JACK_Module::handle_chain_name_changed ( void )
{ {
for ( unsigned int i = 0; i < jack_output.size(); ++i ) 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 ) for ( unsigned int i = 0; i < jack_input.size(); ++i )
jack_input[ i ].name( chain()->name(), i );
jack_input[ i ].name( NULL, i );
} }




+ 2
- 0
Mixer/const.h View File

@@ -17,6 +17,8 @@
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/ /*******************************************************************************/


#pragma once

#define APP_NAME "Non-Mixer" #define APP_NAME "Non-Mixer"
#define APP_TITLE "The Non-Mixer" #define APP_TITLE "The Non-Mixer"
#define __MODULE__ "non-mixer" #define __MODULE__ "non-mixer"

+ 2
- 2
Timeline/Control_Sequence.C View File

@@ -41,7 +41,7 @@ Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0 )


_track = track; _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 ) if ( track )
track->add( this ); track->add( this );
@@ -110,7 +110,7 @@ Control_Sequence::set ( Log_Entry &e )


assert( t ); 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 ); t->add( this );
} }


+ 2
- 2
Timeline/Engine/Track.C View File

@@ -77,7 +77,7 @@ Track::configure_outputs ( int n )
{ {
for ( int i = on; i < n; ++i ) 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() ) if ( p.valid() )
output.push_back( p ); output.push_back( p );
@@ -124,7 +124,7 @@ Track::configure_inputs ( int n )
{ {
for ( int i = on; i < n; ++i ) 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() ) if ( p.valid() )
input.push_back( p ); input.push_back( p );


+ 1
- 1
Timeline/Transport.C View File

@@ -25,7 +25,7 @@


// Transport transport; // Transport transport;


#define client engine->client()
#define client engine->jack_client()






+ 65
- 0
nonlib/JACK/Client.C View File

@@ -18,6 +18,9 @@
/*******************************************************************************/ /*******************************************************************************/


#include "Client.H" #include "Client.H"
#include "Port.H"

#include <algorithm>




@@ -146,4 +149,66 @@ namespace JACK
// WARNING( "Unkown error while setting freewheeling mode" ); // 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;
}
} }

+ 14
- 1
nonlib/JACK/Client.H View File

@@ -24,10 +24,16 @@
typedef jack_nframes_t nframes_t; typedef jack_nframes_t nframes_t;
typedef float sample_t; typedef float sample_t;


#include <list>

namespace JACK namespace JACK
{ {
class Port;
class Client class Client
{ {

std::list <JACK::Port*> _active_ports;

jack_client_t *_client; jack_client_t *_client;


nframes_t _sample_rate; nframes_t _sample_rate;
@@ -55,6 +61,9 @@ namespace JACK
Client ( const Client &rhs ); Client ( const Client &rhs );
Client & operator = ( const Client &rhs ); Client & operator = ( const Client &rhs );


void freeze_ports ( void );
void thaw_ports ( void );

protected: protected:


void deactivate ( void ); void deactivate ( void );
@@ -66,12 +75,16 @@ namespace JACK


public: 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 ( ); Client ( );
virtual ~Client ( ); virtual ~Client ( );


const char * init ( const char *client_name ); const char * init ( const char *client_name );
const char * name ( const char * );


nframes_t nframes ( void ) const { return jack_get_buffer_size( _client ); } nframes_t nframes ( void ) const { return jack_get_buffer_size( _client ); }
float frame_rate ( void ) const { return jack_get_sample_rate( _client ); } float frame_rate ( void ) const { return jack_get_sample_rate( _client ); }


+ 132
- 12
nonlib/JACK/Port.C View File

@@ -23,6 +23,7 @@


#include <string.h> #include <string.h>
#include <stdio.h> // sprintf #include <stdio.h> // sprintf
#include <errno.h>


namespace JACK namespace JACK
{ {
@@ -35,22 +36,36 @@ namespace JACK
return jack_port_name_size() - jack_client_name_size() - 6; return jack_port_name_size() - jack_client_name_size() - 6;
} }



Port::Port ( const Port &rhs )
{
_freezer = rhs._freezer;
_client = rhs._client;
_port = rhs._port;
_name = strdup( rhs._name );

_client->port_added( this );
}

/* nframes is the number of frames to buffer */ /* nframes is the number of frames to buffer */
Port::Port ( jack_client_t *client, jack_port_t *port )
Port::Port ( JACK::Client *client, jack_port_t *port )
{ {
_freezer = NULL;
_client = client; _client = client;
_port = port; _port = port;
_name = jack_port_name( _port );
_name = strdup( jack_port_name( _port ) );
} }


Port::Port ( jack_client_t *client, const char *name, type_e dir )
Port::Port ( JACK::Client *client, const char *name, type_e dir )
{ {
_freezer = NULL;
_client = client; _client = client;
activate( name, dir ); 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; _client = client;


const char *name = name_for_port( dir, base, n, type ); const char *name = name_for_port( dir, base, n, type );
@@ -58,8 +73,28 @@ namespace JACK
activate( name, dir ); 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 ( ) Port::~Port ( )
{ {
if ( _name )
free( _name );

_client->port_removed( this );
/* if ( _freezer ) */
/* { */
/* delete _freezer; */
/* _freezer = NULL; */
/* } */

/* if ( _port ) */ /* if ( _port ) */
/* jack_port_unregister( _client, _port ); */ /* jack_port_unregister( _client, _port ); */


@@ -74,15 +109,22 @@ namespace JACK


const char *dir_s = dir == Port::Output ? "out" : "in"; 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'; pname[ Port::max_name() - 1 ] = '\0';


int l = strlen( pname ); int l = strlen( pname );


if ( type ) 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 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; return pname;
} }
@@ -90,11 +132,13 @@ namespace JACK
void void
Port::activate ( const char *name, type_e dir ) 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, JACK_DEFAULT_AUDIO_TYPE,
dir == Output ? JackPortIsOutput : JackPortIsInput, dir == Output ? JackPortIsOutput : JackPortIsInput,
0 ); 0 );

_client->port_added( this );
} }


/** returns the sum of latency of all ports between this one and a /** returns the sum of latency of all ports between this one and a
@@ -107,7 +151,7 @@ namespace JACK
nframes_t nframes_t
Port::total_latency ( void ) const 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 */ /** returns the number of frames of latency assigned to this port */
@@ -128,14 +172,16 @@ namespace JACK
Port::shutdown ( void ) Port::shutdown ( void )
{ {
if ( _port ) if ( _port )
jack_port_unregister( _client, _port );
jack_port_unregister( _client->jack_client(), _port );

_client->port_removed( this );
} }


/** rename port */ /** rename port */
bool bool
Port::name ( const char *name ) Port::name ( const char *name )
{ {
_name = name;
_name = strdup( name );


return 0 == jack_port_set_name( _port, name ); return 0 == jack_port_set_name( _port, name );
} }
@@ -170,4 +216,78 @@ namespace JACK
memset( buffer( nframes ), 0, nframes * sizeof( sample_t ) ); 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;
}
} }

+ 47
- 10
nonlib/JACK/Port.H View File

@@ -21,14 +21,15 @@


// #include <jack/jack.h> // #include <jack/jack.h>
#include "Client.H" #include "Client.H"
#include <stdlib.h>


namespace JACK namespace JACK
{ {
class Port class Port
{ {
jack_port_t *_port; jack_port_t *_port;
const char *_name;
jack_client_t *_client;
char *_name;
JACK::Client *_client;


/* FIXME: reference count? */ /* FIXME: reference count? */


@@ -42,18 +43,15 @@ namespace JACK


static int max_name ( void ); 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 ( ); ~Port ( );


/* Port ( const Port & rhs ) */
/* { */
/* _port = rhs.port; */
/* _name = rhs.name; */
/* } */
Port ( const Port & rhs );




bool valid ( void ) const { return _port; } bool valid ( void ) const { return _port; }
@@ -76,6 +74,45 @@ namespace JACK
void read ( sample_t *buf, nframes_t nframes ); void read ( sample_t *buf, nframes_t nframes );
void *buffer ( nframes_t nframes ); void *buffer ( nframes_t nframes );
void silence ( 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…
Cancel
Save