| @@ -30,7 +30,7 @@ Port::Port ( jack_port_t *port ) | |||||
| _name = jack_port_name( _port ); | _name = jack_port_name( _port ); | ||||
| } | } | ||||
| Port::Port ( const char *name, direction_e dir ) | |||||
| Port::Port ( const char *name, type_e dir ) | |||||
| { | { | ||||
| _name = name; | _name = name; | ||||
| @@ -42,8 +42,26 @@ Port::Port ( const char *name, direction_e dir ) | |||||
| Port::~Port ( ) | Port::~Port ( ) | ||||
| { | { | ||||
| /* close port? */ | |||||
| // jack_port_unregister( engine->client(), _port ); | |||||
| /* if ( _port ) */ | |||||
| /* jack_port_unregister( engine->client(), _port ); */ | |||||
| } | |||||
| void | |||||
| Port::shutdown ( void ) | |||||
| { | |||||
| if ( _port ) | |||||
| jack_port_unregister( engine->client(), _port ); | |||||
| } | |||||
| /** rename port */ | |||||
| bool | |||||
| Port::name ( const char *name ) | |||||
| { | |||||
| _name = name; | |||||
| return 0 == jack_port_set_name( _port, name ); | |||||
| } | } | ||||
| void | void | ||||
| @@ -25,21 +25,34 @@ | |||||
| class Port | class Port | ||||
| { | { | ||||
| jack_port_t *_port; | jack_port_t *_port; | ||||
| const char *_name; | const char *_name; | ||||
| public: | public: | ||||
| enum direction_e { Output, Input }; | |||||
| enum type_e { Output, Input }; | |||||
| Port ( jack_port_t *port ); | Port ( jack_port_t *port ); | ||||
| Port ( const char *name, direction_e dir ); | |||||
| Port ( const char *name, type_e dir ); | |||||
| ~Port ( ); | ~Port ( ); | ||||
| /* Port ( const Port & rhs ) */ | |||||
| /* { */ | |||||
| /* _port = rhs.port; */ | |||||
| /* _name = rhs.name; */ | |||||
| /* } */ | |||||
| bool valid ( void ) const { return _port; } | |||||
| bool connected ( void ) const { return jack_port_connected( _port ); } | bool connected ( void ) const { return jack_port_connected( _port ); } | ||||
| type_e type ( void ) const | |||||
| { | |||||
| return jack_port_flags( _port ) == JackPortIsOutput ? Output : Input; | |||||
| } | |||||
| const char * name ( void ) const { return _name; } | const char * name ( void ) const { return _name; } | ||||
| bool name ( const char *name ); | |||||
| void shutdown ( void ); | |||||
| void write ( sample_t *buf, nframes_t nframes ); | void write ( sample_t *buf, nframes_t nframes ); | ||||
| 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 ); | ||||
| @@ -47,10 +47,7 @@ Track::cb_input_field ( void ) | |||||
| { | { | ||||
| log_start(); | log_start(); | ||||
| if ( _name ) | |||||
| free( _name ); | |||||
| _name = strdup( name_field->value() ); | |||||
| name( name_field->value() ); | |||||
| log_end(); | log_end(); | ||||
| } | } | ||||
| @@ -125,8 +122,6 @@ Track::init ( void ) | |||||
| o->textcolor( 32 ); | o->textcolor( 32 ); | ||||
| o->callback( cb_input_field, (void*)this ); | o->callback( cb_input_field, (void*)this ); | ||||
| // o->hide(); | |||||
| } | } | ||||
| { | { | ||||
| @@ -205,24 +200,26 @@ Track::init ( void ) | |||||
| } | } | ||||
| end(); | end(); | ||||
| /* FIXME: should be configurable, but where? */ | |||||
| create_outputs( 2 ); | |||||
| create_inputs( 2 ); | |||||
| /* /\* FIXME: should be configurable, but where? *\/ */ | |||||
| /* create_outputs( 2 ); */ | |||||
| /* create_inputs( 2 ); */ | |||||
| playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), output.size() ); | playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), output.size() ); | ||||
| record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), input.size() ); | record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), input.size() ); | ||||
| } | } | ||||
| Track::Track ( const char *L ) : | |||||
| Fl_Group ( 0, 0, 0, 0, L ) | |||||
| Track::Track ( const char *L, int channels ) : | |||||
| Fl_Group ( 0, 0, 0, 0, 0 ) | |||||
| { | { | ||||
| init(); | init(); | ||||
| if ( L ) | if ( L ) | ||||
| name( L ); | name( L ); | ||||
| configure_inputs( channels ); | |||||
| configure_outputs( channels ); | |||||
| log_create(); | log_create(); | ||||
| } | } | ||||
| @@ -361,14 +358,6 @@ Track::draw ( void ) | |||||
| } | } | ||||
| else | else | ||||
| Fl_Group::draw(); | Fl_Group::draw(); | ||||
| /* if ( ! name_field->visible() ) */ | |||||
| /* { */ | |||||
| /* fl_color( FL_WHITE ); */ | |||||
| /* fl_font( FL_HELVETICA, 14 ); */ | |||||
| /* fl_draw( name_field->value(), name_field->x(), name_field->y(), name_field->w(), name_field->h(), FL_ALIGN_CENTER ); */ | |||||
| /* } */ | |||||
| } | } | ||||
| int | int | ||||
| @@ -406,15 +395,53 @@ Track::handle ( int m ) | |||||
| /* Engine */ | /* Engine */ | ||||
| /**********/ | /**********/ | ||||
| const char * | |||||
| Track::name_for_port ( Port::type_e type, int n ) | |||||
| { | |||||
| static char pname[256]; | |||||
| snprintf( pname, sizeof( pname ), "%s/%s-%d", | |||||
| name(), | |||||
| type == Port::Output ? "out" : "in", | |||||
| n + 1 ); | |||||
| return pname; | |||||
| } | |||||
| void | |||||
| Track::update_port_names ( void ) | |||||
| { | |||||
| for ( int i = 0; i < output.size(); ++i ) | |||||
| output[ i ].name( name_for_port( output[ i ].type(), i ) ); | |||||
| for ( int i = 0; i < input.size(); ++i ) | |||||
| input[ i ].name( name_for_port( input[ i ].type(), i ) ); | |||||
| } | |||||
| bool | bool | ||||
| Track::create_outputs ( int n ) | |||||
| Track::configure_outputs ( int n ) | |||||
| { | { | ||||
| char pname[256]; | |||||
| int on = output.size(); | |||||
| for ( int i = 0; i < n; ++i ) | |||||
| if ( n > on ) | |||||
| { | { | ||||
| snprintf( pname, sizeof( pname ), "%s/out-%d", name(), i + 1 ); | |||||
| output.push_back( Port( strdup( pname ), Port::Output ) ); | |||||
| for ( int i = on; i < n; ++i ) | |||||
| { | |||||
| Port p( strdup( name_for_port( Port::Output, i ) ), Port::Output ); | |||||
| if ( p.valid() ) | |||||
| output.push_back( p ); | |||||
| else | |||||
| printf( "error: could not create output port!\n" ); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| for ( int i = on; i > n; --i ) | |||||
| { | |||||
| output.back().shutdown(); | |||||
| output.pop_back(); | |||||
| } | |||||
| } | } | ||||
| /* FIXME: bogus */ | /* FIXME: bogus */ | ||||
| @@ -422,23 +449,35 @@ Track::create_outputs ( int n ) | |||||
| } | } | ||||
| bool | bool | ||||
| Track::create_inputs ( int n ) | |||||
| Track::configure_inputs ( int n ) | |||||
| { | { | ||||
| char pname[256]; | |||||
| int on = input.size(); | |||||
| if ( n > on ) | |||||
| { | |||||
| for ( int i = on; i < n; ++i ) | |||||
| { | |||||
| Port p( strdup( name_for_port( Port::Input, i ) ), Port::Input ); | |||||
| for ( int i = 0; i < n; ++i ) | |||||
| if ( p.valid() ) | |||||
| input.push_back( p ); | |||||
| else | |||||
| printf( "error: could not create input port!\n" ); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | { | ||||
| snprintf( pname, sizeof( pname ), "%s/in-%d", name(), i + 1 ); | |||||
| input.push_back( Port( strdup( pname ), Port::Input ) ); | |||||
| for ( int i = on; i > n; --i ) | |||||
| { | |||||
| input.back().shutdown(); | |||||
| input.pop_back(); | |||||
| } | |||||
| } | } | ||||
| /* FIXME: bogus */ | /* FIXME: bogus */ | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* THREAD: RT */ | /* THREAD: RT */ | ||||
| nframes_t | nframes_t | ||||
| Track::process ( nframes_t nframes ) | Track::process ( nframes_t nframes ) | ||||
| @@ -51,7 +51,7 @@ class Track : public Fl_Group, public Loggable | |||||
| public: | public: | ||||
| Track ( const char *L ); | |||||
| Track ( const char *L, int channels=1 ); | |||||
| ~Track ( ); | ~Track ( ); | ||||
| private: | private: | ||||
| @@ -72,8 +72,11 @@ private: | |||||
| Region *_capture; /* capture region */ | Region *_capture; /* capture region */ | ||||
| bool create_outputs ( int n ); | |||||
| bool create_inputs ( int n ); | |||||
| bool configure_outputs ( int n ); | |||||
| bool configure_inputs ( int n ); | |||||
| void update_port_names ( void ); | |||||
| const char *name_for_port( Port::type_e type, int n ); | |||||
| Track ( ) : Fl_Group( 0, 0, 1, 1 ) | Track ( ) : Fl_Group( 0, 0, 1, 1 ) | ||||
| @@ -126,12 +129,11 @@ public: | |||||
| _selected = atoi( v ); | _selected = atoi( v ); | ||||
| // else if ( ! strcmp( s, ":armed" | // else if ( ! strcmp( s, ":armed" | ||||
| else if ( ! strcmp( s, ":n" ) ) | else if ( ! strcmp( s, ":n" ) ) | ||||
| { | |||||
| _name = strdup( v ); | |||||
| /* FIXME: bogus */ | |||||
| if ( name_field ) | |||||
| name_field->value( _name ); | |||||
| } | |||||
| name( v ); | |||||
| else if ( ! strcmp( s, ":i" ) ) | |||||
| configure_inputs( atoi( v ) ); | |||||
| else if ( ! strcmp( s, ":o" ) ) | |||||
| configure_outputs( atoi( v ) ); | |||||
| else if ( ! strcmp( s, ":t" ) ) | else if ( ! strcmp( s, ":t" ) ) | ||||
| { | { | ||||
| int i; | int i; | ||||
| @@ -153,10 +155,12 @@ public: | |||||
| void | void | ||||
| get ( Log_Entry &e ) | get ( Log_Entry &e ) | ||||
| { | { | ||||
| e.add( ":n", _name ); | |||||
| e.add( ":t", track() ); | |||||
| e.add( ":s", _selected ); | |||||
| e.add( ":h", size() ); | |||||
| e.add( ":n", _name ); | |||||
| e.add( ":t", track() ); | |||||
| e.add( ":s", _selected ); | |||||
| e.add( ":h", size() ); | |||||
| e.add( ":i", input.size() ); | |||||
| e.add( ":o", output.size() ); | |||||
| } | } | ||||
| /* for loggable */ | /* for loggable */ | ||||
| @@ -187,9 +191,15 @@ public: | |||||
| void name ( const char *name ) | void name ( const char *name ) | ||||
| { | { | ||||
| if ( _name ) free( _name ); | |||||
| if ( _name ) | |||||
| free( _name ); | |||||
| _name = strdup( name ); | _name = strdup( name ); | ||||
| name_field->value( _name ); | |||||
| if ( name_field ) | |||||
| name_field->value( _name ); | |||||
| update_port_names(); | |||||
| } | } | ||||
| const char * name ( void ) const { return _name; } | const char * name ( void ) const { return _name; } | ||||