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; | |||
| }; | |||
| } | |||