Mixer: Implement port autoconnection system.
This commit is contained in:
parent
a05384a8c3
commit
fc5c59c61d
2
lib/ntk
2
lib/ntk
|
@ -1 +1 @@
|
||||||
Subproject commit 645579913d0bfbfdcc9cd0107dd55bd121a99990
|
Subproject commit d7f94164bc2d44b7ddf39e19e90a1fc172e62c7d
|
|
@ -791,6 +791,47 @@ Chain::resize ( int X, int Y, int W, int H )
|
||||||
controls_pack->size( W, controls_pack->h() );
|
controls_pack->size( W, controls_pack->h() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Chain::get_output_ports ( std::list<std::string> &sl)
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < modules(); i++ )
|
||||||
|
{
|
||||||
|
Module *m = module(i);
|
||||||
|
|
||||||
|
for ( unsigned int j = 0; j < m->aux_audio_output.size(); j++ )
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
asprintf( &s, "%s/%s",
|
||||||
|
strip()->group()->single() ? "*" : strip()->group()->name(),
|
||||||
|
m->aux_audio_output[j].jack_port()->name() );
|
||||||
|
|
||||||
|
sl.push_back( s );
|
||||||
|
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Chain::auto_connect_outputs ( void )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < modules(); i++ )
|
||||||
|
{
|
||||||
|
module(i)->auto_connect_outputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Chain::auto_disconnect_outputs ( void )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < modules(); i++ )
|
||||||
|
{
|
||||||
|
module(i)->auto_disconnect_outputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************/
|
/*****************/
|
||||||
|
|
|
@ -77,6 +77,11 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
void auto_connect_outputs ( void );
|
||||||
|
void auto_disconnect_outputs ( void );
|
||||||
|
|
||||||
|
void get_output_ports ( std::list<std::string> &sl);
|
||||||
|
|
||||||
void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect );
|
void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect );
|
||||||
void buffer_size ( nframes_t nframes );
|
void buffer_size ( nframes_t nframes );
|
||||||
int sample_rate_change ( nframes_t nframes );
|
int sample_rate_change ( nframes_t nframes );
|
||||||
|
|
|
@ -161,7 +161,7 @@ JACK_Module::JACK_Module ( bool log )
|
||||||
{
|
{
|
||||||
Fl_Browser *o = connection_display = new Fl_Browser( 0, 0, w(), h() );
|
Fl_Browser *o = connection_display = new Fl_Browser( 0, 0, w(), h() );
|
||||||
o->has_scrollbar(Fl_Browser_::VERTICAL);
|
o->has_scrollbar(Fl_Browser_::VERTICAL);
|
||||||
o->textsize( 11 );
|
o->textsize( 10 );
|
||||||
o->textcolor( FL_LIGHT3 );
|
o->textcolor( FL_LIGHT3 );
|
||||||
o->textfont( FL_COURIER );
|
o->textfont( FL_COURIER );
|
||||||
o->box( FL_FLAT_BOX );
|
o->box( FL_FLAT_BOX );
|
||||||
|
@ -497,13 +497,38 @@ JACK_Module::handle_control_changed ( Port *p )
|
||||||
int
|
int
|
||||||
JACK_Module::handle ( int m )
|
JACK_Module::handle ( int m )
|
||||||
{
|
{
|
||||||
|
static unsigned long _event_state = 0;
|
||||||
|
|
||||||
|
unsigned long evstate = Fl::event_state();
|
||||||
|
|
||||||
switch ( m )
|
switch ( m )
|
||||||
{
|
{
|
||||||
case FL_PUSH:
|
case FL_PUSH:
|
||||||
|
if ( Fl::event_inside( output_connection_handle ) ||
|
||||||
|
Fl::event_inside( output_connection2_handle ) ||
|
||||||
|
Fl::event_inside( input_connection_handle ) )
|
||||||
|
{
|
||||||
|
_event_state = evstate;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return Module::handle(m) || 1;
|
return Module::handle(m) || 1;
|
||||||
|
|
||||||
case FL_RELEASE:
|
case FL_RELEASE:
|
||||||
Fl::selection_owner(0);
|
Fl::selection_owner(0);
|
||||||
receptive_to_drop = NULL;
|
receptive_to_drop = NULL;
|
||||||
|
|
||||||
|
if ( Fl::event_inside( output_connection_handle ) ||
|
||||||
|
Fl::event_inside( output_connection2_handle ) ||
|
||||||
|
Fl::event_inside( input_connection_handle ) )
|
||||||
|
{
|
||||||
|
if ( _event_state & FL_BUTTON3 )
|
||||||
|
{
|
||||||
|
/* was a right click */
|
||||||
|
// TODO: Pop up connection menu.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Module::handle(m) || 1;
|
return Module::handle(m) || 1;
|
||||||
case FL_DRAG:
|
case FL_DRAG:
|
||||||
{
|
{
|
||||||
|
@ -516,8 +541,6 @@ JACK_Module::handle ( int m )
|
||||||
if ( Fl::event_inside( output_connection2_handle ) )
|
if ( Fl::event_inside( output_connection2_handle ) )
|
||||||
connection_handle = 1;
|
connection_handle = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( Fl::event_button1() &&
|
if ( Fl::event_button1() &&
|
||||||
connection_handle >= 0
|
connection_handle >= 0
|
||||||
&& ! Fl::selection_owner() )
|
&& ! Fl::selection_owner() )
|
||||||
|
@ -555,6 +578,15 @@ JACK_Module::handle ( int m )
|
||||||
}
|
}
|
||||||
/* we have to prevent Fl_Group::handle() from getting these, otherwise it will mess up Fl::belowmouse() */
|
/* we have to prevent Fl_Group::handle() from getting these, otherwise it will mess up Fl::belowmouse() */
|
||||||
case FL_MOVE:
|
case FL_MOVE:
|
||||||
|
if ( Fl::event_inside( output_connection_handle ) ||
|
||||||
|
Fl::event_inside( output_connection2_handle ) ||
|
||||||
|
Fl::event_inside( input_connection_handle ) )
|
||||||
|
{
|
||||||
|
fl_cursor( FL_CURSOR_HAND );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fl_cursor( FL_CURSOR_DEFAULT );
|
||||||
|
|
||||||
Module::handle(m);
|
Module::handle(m);
|
||||||
return 1;
|
return 1;
|
||||||
case FL_ENTER:
|
case FL_ENTER:
|
||||||
|
@ -569,6 +601,7 @@ JACK_Module::handle ( int m )
|
||||||
receptive_to_drop = NULL;
|
receptive_to_drop = NULL;
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
fl_cursor( FL_CURSOR_DEFAULT );
|
||||||
return 1;
|
return 1;
|
||||||
case FL_DND_RELEASE:
|
case FL_DND_RELEASE:
|
||||||
Fl::selection_owner(0);
|
Fl::selection_owner(0);
|
||||||
|
|
|
@ -1101,6 +1101,89 @@ Mixer::handle ( int m )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
std::list <std::string>
|
||||||
|
Mixer::get_auto_connect_targets ( void )
|
||||||
|
{
|
||||||
|
std::list <std::string> sl;
|
||||||
|
std::list <std::string> rl;
|
||||||
|
|
||||||
|
for ( int i = mixer_strips->children(); i--; )
|
||||||
|
{
|
||||||
|
((Mixer_Strip*)mixer_strips->child(i))->get_output_ports(sl);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( std::list<std::string>::iterator i = sl.begin(); i != sl.end(); i++ )
|
||||||
|
{
|
||||||
|
char *s = strdup( i->c_str() );
|
||||||
|
|
||||||
|
*rindex( s, '/' ) = 0;
|
||||||
|
|
||||||
|
if ( !index( s, '/' ) )
|
||||||
|
{
|
||||||
|
char *o;
|
||||||
|
asprintf( &o, "%s/mains", s );
|
||||||
|
free(s);
|
||||||
|
s = o;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( std::find( rl.begin(), rl.end(), s ) == rl.end() )
|
||||||
|
{
|
||||||
|
rl.push_back( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mixer::auto_connect ( void )
|
||||||
|
{
|
||||||
|
/* give strips with group affinity the first shot */
|
||||||
|
for ( int i = 0; i < mixer_strips->children(); i++ )
|
||||||
|
{
|
||||||
|
Mixer_Strip *s = ((Mixer_Strip*)mixer_strips->child(i));
|
||||||
|
|
||||||
|
if ( s->has_group_affinity() )
|
||||||
|
s->auto_connect_outputs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now do that catch-alls, first one wins! */
|
||||||
|
for ( int i = 0; i < mixer_strips->children(); i++ )
|
||||||
|
{
|
||||||
|
Mixer_Strip *s = ((Mixer_Strip*)mixer_strips->child(i));
|
||||||
|
|
||||||
|
if ( ! s->has_group_affinity() )
|
||||||
|
s->auto_connect_outputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mixer::maybe_auto_connect_output ( Module::Port *p )
|
||||||
|
{
|
||||||
|
/* give strips with group affinity the first shot */
|
||||||
|
for ( int i = 0; i < mixer_strips->children(); i++ )
|
||||||
|
{
|
||||||
|
Mixer_Strip *s = ((Mixer_Strip*)mixer_strips->child(i));
|
||||||
|
|
||||||
|
if ( s->has_group_affinity() )
|
||||||
|
if ( s->maybe_auto_connect_output( p ) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now do that catch-alls, first one wins! */
|
||||||
|
for ( int i = 0; i < mixer_strips->children(); i++ )
|
||||||
|
{
|
||||||
|
Mixer_Strip *s = ((Mixer_Strip*)mixer_strips->child(i));
|
||||||
|
|
||||||
|
if ( ! s->has_group_affinity() )
|
||||||
|
if ( s->maybe_auto_connect_output( p ) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
/************/
|
/************/
|
||||||
/* Commands */
|
/* Commands */
|
||||||
/************/
|
/************/
|
||||||
|
@ -1152,6 +1235,8 @@ Mixer::command_load ( const char *path, const char *display_name )
|
||||||
|
|
||||||
update_menu();
|
update_menu();
|
||||||
|
|
||||||
|
auto_connect();
|
||||||
|
|
||||||
mixer->activate();
|
mixer->activate();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -92,6 +92,9 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
void auto_connect ( void );
|
||||||
|
void maybe_auto_connect_output ( Module::Port *p );
|
||||||
|
std::list<std::string> get_auto_connect_targets ( void );
|
||||||
Group * group_by_name ( const char * name );
|
Group * group_by_name ( const char * name );
|
||||||
char *get_unique_group_name ( const char *name );
|
char *get_unique_group_name ( const char *name );
|
||||||
|
|
||||||
|
|
|
@ -132,8 +132,8 @@ Mixer_Strip::get ( Log_Entry &e ) const
|
||||||
e.add( ":group", _group );
|
e.add( ":group", _group );
|
||||||
else
|
else
|
||||||
e.add( ":group", (Loggable*)0 );
|
e.add( ":group", (Loggable*)0 );
|
||||||
|
e.add( ":auto_input", _auto_input );
|
||||||
|
e.add( ":manual_connection", _manual_connection );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -170,6 +170,14 @@ Mixer_Strip::set ( Log_Entry &e )
|
||||||
{
|
{
|
||||||
_mute_controller_mode = atoi( v );
|
_mute_controller_mode = atoi( v );
|
||||||
}
|
}
|
||||||
|
else if ( ! strcmp( s, ":auto_input" ) )
|
||||||
|
{
|
||||||
|
auto_input( v );
|
||||||
|
}
|
||||||
|
else if ( ! strcmp( s, ":manual_connection" ) )
|
||||||
|
{
|
||||||
|
manual_connection( atoi( v ) );
|
||||||
|
}
|
||||||
else if ( ! strcmp( s, ":group" ) )
|
else if ( ! strcmp( s, ":group" ) )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -291,6 +299,17 @@ void Mixer_Strip::cb_handle(Fl_Widget* o) {
|
||||||
if ( parent() )
|
if ( parent() )
|
||||||
parent()->parent()->redraw();
|
parent()->parent()->redraw();
|
||||||
}
|
}
|
||||||
|
else if ( o == output_connection_button )
|
||||||
|
{
|
||||||
|
if ( output_connection_button->value() == 1 )
|
||||||
|
o->label( output_connection_button->mvalue()->label() );
|
||||||
|
else
|
||||||
|
o->label( NULL );
|
||||||
|
|
||||||
|
manual_connection( output_connection_button->value() );
|
||||||
|
|
||||||
|
// _manual_connection = output_connection_button->value();
|
||||||
|
}
|
||||||
else if ( o == group_choice )
|
else if ( o == group_choice )
|
||||||
{
|
{
|
||||||
// group(group_choice->value());
|
// group(group_choice->value());
|
||||||
|
@ -501,6 +520,8 @@ Mixer_Strip::init ( )
|
||||||
{
|
{
|
||||||
selection_color( FL_MAGENTA );
|
selection_color( FL_MAGENTA );
|
||||||
|
|
||||||
|
_manual_connection = 0;
|
||||||
|
_auto_input = 0;
|
||||||
_mute_controller_mode = 0;
|
_mute_controller_mode = 0;
|
||||||
_gain_controller_mode = 0;
|
_gain_controller_mode = 0;
|
||||||
_chain = 0;
|
_chain = 0;
|
||||||
|
@ -663,6 +684,17 @@ Mixer_Strip::init ( )
|
||||||
}
|
}
|
||||||
/* o->end(); */
|
/* o->end(); */
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
|
{ Fl_Menu_Button *o = output_connection_button = new Fl_Menu_Button( 0, 0, 10, 18 );
|
||||||
|
o->labelsize( 9 );
|
||||||
|
o->add("- auto -");
|
||||||
|
o->add("- manual -");
|
||||||
|
o->align( FL_ALIGN_CLIP );
|
||||||
|
o->labelcolor( FL_YELLOW );
|
||||||
|
o->callback( cb_handle, this );
|
||||||
|
o->hide();
|
||||||
|
}
|
||||||
|
|
||||||
o->end();
|
o->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,6 +865,23 @@ Mixer_Strip::menu_cb ( const Fl_Menu_ *m )
|
||||||
if ( Fl::event_shift() || 1 == fl_choice( "Are you sure you want to remove this strip?\n\n(this action cannot be undone)", "Cancel", "Remove", NULL ) )
|
if ( Fl::event_shift() || 1 == fl_choice( "Are you sure you want to remove this strip?\n\n(this action cannot be undone)", "Cancel", "Remove", NULL ) )
|
||||||
command_close();
|
command_close();
|
||||||
}
|
}
|
||||||
|
else if ( ! strcmp( picked, "Auto Output/On" ) )
|
||||||
|
{
|
||||||
|
manual_connection( false );
|
||||||
|
}
|
||||||
|
else if ( ! strcmp( picked, "Auto Output/Off" ) )
|
||||||
|
{
|
||||||
|
manual_connection( true );
|
||||||
|
}
|
||||||
|
else if ( ! strncmp( picked, "Auto Input/", strlen( "Auto Input/" ) ))
|
||||||
|
{
|
||||||
|
const char *s = index( picked, '/' ) + 1;
|
||||||
|
|
||||||
|
if ( ! strcmp( s, "Off" ) )
|
||||||
|
auto_input( NULL );
|
||||||
|
else
|
||||||
|
auto_input( s );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -841,6 +890,153 @@ Mixer_Strip::menu_cb ( Fl_Widget *w, void *v )
|
||||||
((Mixer_Strip*)v)->menu_cb( (Fl_Menu_*) w );
|
((Mixer_Strip*)v)->menu_cb( (Fl_Menu_*) w );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mixer_Strip::auto_input ( const char *s )
|
||||||
|
{
|
||||||
|
if ( _auto_input )
|
||||||
|
free( _auto_input );
|
||||||
|
|
||||||
|
_auto_input = NULL;
|
||||||
|
|
||||||
|
if ( s )
|
||||||
|
_auto_input = strdup( s );
|
||||||
|
|
||||||
|
mixer->auto_connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mixer_Strip::manual_connection ( bool b )
|
||||||
|
{
|
||||||
|
_manual_connection = b;
|
||||||
|
output_connection_button->value(b);
|
||||||
|
|
||||||
|
if ( chain() )
|
||||||
|
{
|
||||||
|
if ( b )
|
||||||
|
chain()->auto_disconnect_outputs();
|
||||||
|
else
|
||||||
|
chain()->auto_connect_outputs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool matches_pattern ( const char *pattern, Module::Port *p )
|
||||||
|
{
|
||||||
|
char group_name[256];
|
||||||
|
char port_group[256];
|
||||||
|
|
||||||
|
if ( 2 == sscanf( pattern, "%[^/]/%[^\n]", group_name, port_group ))
|
||||||
|
{
|
||||||
|
if ( strcmp( group_name, "*" ) &&
|
||||||
|
strcmp( group_name, p->module()->chain()->strip()->group()->name() ))
|
||||||
|
{
|
||||||
|
/* group mismatch */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* group matches... try port group */
|
||||||
|
if ( ! strcmp( port_group, "mains" ) )
|
||||||
|
{
|
||||||
|
if ( index( p->jack_port()->name(), '/' ) )
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *pn = p->jack_port()->name();
|
||||||
|
const char *n = rindex( pn, '/' );
|
||||||
|
|
||||||
|
if ( n )
|
||||||
|
{
|
||||||
|
// *n = 0;
|
||||||
|
if ( ! strncmp( port_group, pn, ( n - 1 ) - pn ) )
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "JACK_Module.H"
|
||||||
|
|
||||||
|
void
|
||||||
|
Mixer_Strip::auto_connect_outputs ( void )
|
||||||
|
{
|
||||||
|
chain()->auto_connect_outputs();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Mixer_Strip::has_group_affinity ( void ) const
|
||||||
|
{
|
||||||
|
return _auto_input && strncmp( _auto_input, "*/", 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Mixer_Strip::maybe_auto_connect_output ( Module::Port *p )
|
||||||
|
{
|
||||||
|
if ( p->module()->chain()->strip()->_manual_connection )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( p->module()->chain()->strip() == this )
|
||||||
|
/* don't auto connect to self! */
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( ! _auto_input )
|
||||||
|
{
|
||||||
|
if ( p->connected_port() && p->connected_port()->module()->chain()->strip() == this )
|
||||||
|
{
|
||||||
|
/* first break previous auto connection */
|
||||||
|
p->connected_port()->jack_port()->disconnect( p->jack_port()->jack_name() );
|
||||||
|
p->disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _auto_input && matches_pattern( _auto_input, p ) )
|
||||||
|
{
|
||||||
|
DMESSAGE( "Auto connecting port" );
|
||||||
|
|
||||||
|
if ( p->connected_port() )
|
||||||
|
{
|
||||||
|
/* first break previous auto connection */
|
||||||
|
p->connected_port()->jack_port()->disconnect( p->jack_port()->jack_name() );
|
||||||
|
p->disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* jack_name = p->jack_port()->jack_name();
|
||||||
|
|
||||||
|
/* get port number */
|
||||||
|
const char *s = rindex( jack_name, '-' );
|
||||||
|
unsigned int n = atoi( s + 1 ) - 1;
|
||||||
|
|
||||||
|
/* FIXME: safe assumption? */
|
||||||
|
JACK_Module *m = (JACK_Module*)chain()->module(0);
|
||||||
|
|
||||||
|
if ( n < m->aux_audio_input.size() )
|
||||||
|
{
|
||||||
|
m->aux_audio_input[n].jack_port()->connect( jack_name );
|
||||||
|
/* make a note of the connection so we know to disconnected later */
|
||||||
|
m->aux_audio_input[n].connect_to( p );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( p->module()->is_default() )
|
||||||
|
{
|
||||||
|
/* only do this for mains */
|
||||||
|
p->module()->chain()->strip()->output_connection_button->copy_label( name() );
|
||||||
|
p->module()->chain()->strip()->output_connection_button->labelcolor( FL_FOREGROUND_COLOR );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** build the context menu */
|
/** build the context menu */
|
||||||
Fl_Menu_Button &
|
Fl_Menu_Button &
|
||||||
|
@ -854,29 +1050,37 @@ Mixer_Strip::menu ( void ) const
|
||||||
|
|
||||||
// int c = output.size();
|
// int c = output.size();
|
||||||
|
|
||||||
Fl_Menu_Item menu[] =
|
m.clear();
|
||||||
|
|
||||||
|
std::list<std::string> sl = mixer->get_auto_connect_targets();
|
||||||
|
|
||||||
|
|
||||||
|
m.add( "Auto Output/On", 0, 0, 0, FL_MENU_RADIO | ( _manual_connection ? 0 : FL_MENU_VALUE ) );
|
||||||
|
m.add( "Auto Output/Off", 0, 0, 0, FL_MENU_RADIO | ( ! _manual_connection ? 0 : FL_MENU_VALUE ) );
|
||||||
|
m.add( "Auto Input/Off", 0, 0, 0, FL_MENU_DIVIDER | FL_MENU_RADIO | ( _auto_input ? 0 : FL_MENU_VALUE ) );
|
||||||
|
|
||||||
|
for ( std::list<std::string>::iterator i = sl.begin(); i != sl.end(); i++ )
|
||||||
{
|
{
|
||||||
{ "Width", 0, 0, 0, FL_SUBMENU },
|
char *s;
|
||||||
{ "Narrow", 'n', 0, 0, FL_MENU_RADIO | ( ! width_button->value() ? FL_MENU_VALUE : 0 ) },
|
asprintf( &s, "Auto Input/%s", i->c_str() );
|
||||||
{ "Wide", 'w', 0, 0, FL_MENU_RADIO | ( width_button->value() ? FL_MENU_VALUE : 0 ) },
|
|
||||||
{ 0 },
|
|
||||||
{ "View", 0, 0, 0, FL_SUBMENU },
|
|
||||||
{ "Fader", 'f', 0, 0, FL_MENU_RADIO | ( 0 == tab_button->value() ? FL_MENU_VALUE : 0 ) },
|
|
||||||
{ "Signal", 's', 0, 0, FL_MENU_RADIO | ( 1 == tab_button->value() ? FL_MENU_VALUE : 0 ) },
|
|
||||||
{ 0 },
|
|
||||||
{ "Move Left", '[', 0, 0 },
|
|
||||||
{ "Move Right", ']', 0, 0 },
|
|
||||||
{ "Color", 0, 0, 0 },
|
|
||||||
{ "Copy", FL_CTRL + 'c', 0, 0 },
|
|
||||||
{ "Export Strip", 0, 0, 0 },
|
|
||||||
{ "Rename", FL_CTRL + 'n', 0, 0 },
|
|
||||||
{ "Remove", FL_Delete, 0, 0 },
|
|
||||||
{ 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
menu_set_callback( menu, &Mixer_Strip::menu_cb, (void*)this );
|
m.add( s, 0,0,0, FL_MENU_RADIO | ( _auto_input && !strcmp( _auto_input, i->c_str() ) ? FL_MENU_VALUE : 0 ));
|
||||||
|
free(s );
|
||||||
|
}
|
||||||
|
|
||||||
m.copy( menu, (void*)this );
|
m.add( "Width/Narrow", 'n', 0, 0, FL_MENU_RADIO | ( ! width_button->value() ? FL_MENU_VALUE : 0 ));
|
||||||
|
m.add( "Width/Wide", 'w', 0, 0, FL_MENU_RADIO | ( width_button->value() ? FL_MENU_VALUE : 0 ) );
|
||||||
|
m.add( "View/Fader", 'f', 0, 0, FL_MENU_RADIO | ( 0 == tab_button->value() ? FL_MENU_VALUE : 0 ) );
|
||||||
|
m.add( "View/Signal", 's', 0, 0, FL_MENU_RADIO | ( 1 == tab_button->value() ? FL_MENU_VALUE : 0 ) );
|
||||||
|
m.add( "Move Left", '[', 0, 0 );
|
||||||
|
m.add( "Move Right", ']', 0, 0 );
|
||||||
|
m.add( "Color", 0, 0, 0 );
|
||||||
|
m.add( "Copy", FL_CTRL + 'c', 0, 0 );
|
||||||
|
m.add( "Export Strip", 0, 0, 0 );
|
||||||
|
m.add( "Rename", FL_CTRL + 'n', 0, 0 );
|
||||||
|
m.add( "Remove", FL_Delete, 0, 0 );
|
||||||
|
|
||||||
|
menu_set_callback( const_cast<Fl_Menu_Item*>(m.menu()), &Mixer_Strip::menu_cb, (void*)this );
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@ -887,6 +1091,12 @@ Mixer_Strip::spatializer ( void )
|
||||||
return spatialization_controller;
|
return spatialization_controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mixer_Strip::get_output_ports ( std::list<std::string> &ports )
|
||||||
|
{
|
||||||
|
_chain->get_output_ports(ports);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Mixer_Strip::handle ( int m )
|
Mixer_Strip::handle ( int m )
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,8 @@ class Fl_Menu_Button;
|
||||||
class Fl_Choice;
|
class Fl_Choice;
|
||||||
class Group;
|
class Group;
|
||||||
|
|
||||||
|
#include "Module.H"
|
||||||
|
|
||||||
class Mixer_Strip : public Fl_Group, public Loggable {
|
class Mixer_Strip : public Fl_Group, public Loggable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -85,6 +87,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
char *_auto_input;
|
||||||
|
void auto_input ( const char *s );
|
||||||
|
|
||||||
unsigned int _dsp_load_index;
|
unsigned int _dsp_load_index;
|
||||||
|
|
||||||
/* used to defer setting the mode of the gain controller until the
|
/* used to defer setting the mode of the gain controller until the
|
||||||
|
@ -92,7 +97,9 @@ private:
|
||||||
module */
|
module */
|
||||||
int _gain_controller_mode;
|
int _gain_controller_mode;
|
||||||
int _mute_controller_mode;
|
int _mute_controller_mode;
|
||||||
|
bool _manual_connection;
|
||||||
|
|
||||||
|
Fl_Menu_Button *output_connection_button;
|
||||||
Fl_Flip_Button *width_button;
|
Fl_Flip_Button *width_button;
|
||||||
Fl_Flip_Button *tab_button;
|
Fl_Flip_Button *tab_button;
|
||||||
Fl_Button *close_button;
|
Fl_Button *close_button;
|
||||||
|
@ -151,6 +158,13 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
void manual_connection ( bool b );
|
||||||
|
bool has_group_affinity ( void ) const;
|
||||||
|
void auto_connect_outputs ( void );
|
||||||
|
bool maybe_auto_connect_output ( Module::Port *p );
|
||||||
|
|
||||||
|
void get_output_ports ( std::list<std::string> &ports );
|
||||||
|
|
||||||
void update_group_choice ( void );
|
void update_group_choice ( void );
|
||||||
|
|
||||||
Controller_Module *spatializer ( void );
|
Controller_Module *spatializer ( void );
|
||||||
|
|
|
@ -1110,6 +1110,32 @@ Module::thaw_ports ( void )
|
||||||
aux_audio_output[i].jack_port()->client( chain()->client() );
|
aux_audio_output[i].jack_port()->client( chain()->client() );
|
||||||
aux_audio_output[i].jack_port()->trackname( trackname );
|
aux_audio_output[i].jack_port()->trackname( trackname );
|
||||||
aux_audio_output[i].jack_port()->thaw();
|
aux_audio_output[i].jack_port()->thaw();
|
||||||
|
|
||||||
|
mixer->maybe_auto_connect_output( &aux_audio_output[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Module::auto_connect_outputs ( void )
|
||||||
|
{
|
||||||
|
for ( unsigned int i = 0; i < aux_audio_output.size(); ++i )
|
||||||
|
{
|
||||||
|
mixer->maybe_auto_connect_output( &aux_audio_output[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Module::auto_disconnect_outputs ( void )
|
||||||
|
{
|
||||||
|
for ( unsigned int i = 0; i < aux_audio_output.size(); ++i )
|
||||||
|
{
|
||||||
|
Module::Port *p = &aux_audio_output[i];
|
||||||
|
|
||||||
|
if ( p->connected_port() )
|
||||||
|
{
|
||||||
|
p->connected_port()->jack_port()->disconnect( p->jack_port()->jack_name() );
|
||||||
|
p->disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1233,7 +1259,12 @@ Module::add_aux_port ( bool input, const char *prefix, int i )
|
||||||
bool
|
bool
|
||||||
Module::add_aux_audio_output( const char *prefix, int i )
|
Module::add_aux_audio_output( const char *prefix, int i )
|
||||||
{
|
{
|
||||||
return add_aux_port ( false, prefix, i );
|
bool r = add_aux_port ( false, prefix, i );
|
||||||
|
|
||||||
|
if ( r )
|
||||||
|
mixer->maybe_auto_connect_output( &aux_audio_output.back() );
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1243,8 +1274,6 @@ Module::add_aux_audio_input( const char *prefix, int i )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************/
|
/************/
|
||||||
/* Commands */
|
/* Commands */
|
||||||
/************/
|
/************/
|
||||||
|
|
|
@ -493,6 +493,9 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
void auto_connect_outputs();
|
||||||
|
void auto_disconnect_outputs();
|
||||||
|
|
||||||
void freeze_ports ( void );
|
void freeze_ports ( void );
|
||||||
void thaw_ports ( void );
|
void thaw_ports ( void );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue