We wouldn't need this if JACK had jack_client_set_name().tags/non-daw-v1.1.0
@@ -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; | |||
} | |||
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 */ | |||
Port::Port ( jack_client_t *client, jack_port_t *port ) | |||
Port::Port ( JACK::Client *client, jack_port_t *port ) | |||
{ | |||
_freezer = NULL; | |||
_client = client; | |||
_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; | |||
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; | |||
}; | |||
} |