Mixer: Enforce stability of module OSC path over close/open cycles.

Also, allow CV input of for multiple instances of the same plugin/parameter on the same strip.
This commit is contained in:
Jonathan Moore Liles 2020-12-25 17:41:37 -08:00
parent ab469f8a23
commit 393684f376
8 changed files with 130 additions and 74 deletions

View File

@ -29,8 +29,6 @@ AUX_Module::AUX_Module ( ) : JACK_Module ( false )
{
is_default( false );
_number = 0;
{
Port p( this, Port::INPUT, Port::CONTROL, "Gain (dB)" );
p.hints.type = Port::Hints::LINEAR;
@ -49,8 +47,6 @@ AUX_Module::AUX_Module ( ) : JACK_Module ( false )
color( FL_DARK1 );
copy_label( "Aux" );
smoothing.sample_rate( sample_rate() );
}
@ -62,35 +58,10 @@ AUX_Module::~AUX_Module ( )
void
AUX_Module::get ( Log_Entry &e ) const
{
e.add( ":number", number() );
JACK_Module::get(e);
}
void
AUX_Module::set ( Log_Entry &e )
{
for ( int i = 0; i < e.size(); ++i )
{
const char *s, *v;
e.get( i, &s, &v );
if ( ! ( strcmp( s, ":number" ) ) )
{
number( atoi(v) );
}
}
JACK_Module::set(e);
}
void
AUX_Module::number ( int n )
{
_number = n;
JACK_Module::number(n);
char s[10];
snprintf( s, sizeof(s), "aux-%c", 'A' + n );

View File

@ -24,17 +24,12 @@
class AUX_Module : public JACK_Module
{
int _number;
Value_Smoothing_Filter smoothing;
protected:
virtual void get ( Log_Entry &e ) const;
virtual void set ( Log_Entry &e );
public:
virtual void number ( int v );
virtual const char *name ( void ) const { return "AUX"; }
int can_support_inputs ( int n ) { return n > 0 ? n : -1; }
@ -42,9 +37,6 @@ public:
virtual bool configure_outputs ( int n );
virtual bool configure_inputs ( int n );
void number ( int n );
int number ( void ) const { return _number; }
AUX_Module ( );
virtual ~AUX_Module ( );

View File

@ -450,8 +450,8 @@ Chain::get_module_instance_number ( Module *m )
{
int n = 0;
for ( int i = 0; i < modules() && module(i) != m; ++i )
if ( ! strcmp( module(i)->label(), m->label() ) )
for ( int i = 0; i < modules(); ++i )
if ( ! strcmp( module(i)->base_label(), m->base_label() ) )
n++;
return n;
@ -575,6 +575,10 @@ Chain::insert ( Module *m, Module *n )
Module::sample_rate( client()->sample_rate() );
n->resize_buffers( client()->nframes() );
/* inserting a new instance */
if ( -1 == n->number() )
n->number( get_module_instance_number( n ) );
if ( !m )
{

View File

@ -189,7 +189,6 @@ Controller_Module::set ( Log_Entry &e )
{
connect_to( &module->control_input[port] );
module->chain()->add_control( this );
label( module->control_input[port].name() );
}
for ( int i = 0; i < e.size(); ++i )
@ -220,8 +219,15 @@ Controller_Module::mode ( Mode m )
Port *p = control_output[0].connected_port();
char prefix[512];
snprintf( prefix, sizeof(prefix), "CV-%s", p->name() );
const Module *m = p->module();
if ( m->number() >= 0 )
/* we do it this way now to ensure uniqueness */
snprintf( prefix, sizeof(prefix), "CV-%s/%s", m->label(), p->name() );
else
snprintf( prefix, sizeof(prefix), "CV-%s", p->name() );
add_aux_cv_input( prefix, 0 );
chain()->client()->unlock();
@ -404,6 +410,19 @@ Controller_Module::connect_spatializer_to ( Module *m )
return true;
}
void
Controller_Module::apply_label ( Port *p, Fl_Widget *o )
{
char path[256];
if ( is_default() )
snprintf( path, sizeof(path) - 1, "%s", p->name() );
else
snprintf( path, sizeof(path) - 1, "%s/%s", p->module()->label(), p->name() );
o->copy_label(path);
}
void
Controller_Module::connect_to ( Port *p )
{
@ -415,7 +434,7 @@ Controller_Module::connect_to ( Port *p )
if ( p->hints.type == Module::Port::Hints::BOOLEAN )
{
Fl_Button *o = new Fl_Button( 0, 0, 40, 40, p->name() );
Fl_Button *o = new Fl_Button( 0, 0, 40, 40 );
w = o;
o->type( FL_TOGGLE_BUTTON );
o->value( p->control_value() );
@ -429,7 +448,8 @@ Controller_Module::connect_to ( Port *p )
else if ( p->hints.type == Module::Port::Hints::INTEGER )
{
Fl_Counter *o = new Fl_Counter(0, 0, 58, 24, p->name() );
Fl_Counter *o = new Fl_Counter(0, 0, 58, 24 );
control = o;
w = o;
@ -449,7 +469,8 @@ Controller_Module::connect_to ( Port *p )
// else if ( p->hints.type == Module::Port::Hints::LOGARITHMIC )
else
{
Fl_Value_SliderX *o = new Fl_Value_SliderX(0, 0, 30, 250, p->name() );
Fl_Value_SliderX *o = new Fl_Value_SliderX(0, 0, 30, 250 );
control = o;
w = o;
@ -513,6 +534,8 @@ Controller_Module::connect_to ( Port *p )
/* _type = KNOB; */
/* } */
apply_label(p,control);
control_value = p->control_value();
w->clear_visible_focus();

View File

@ -119,6 +119,7 @@ protected:
private:
void apply_label ( Port *p, Fl_Widget *o );
void maybe_create_panner ( void );
char *generate_osc_path ( void );
void change_osc_path ( char *path );

View File

@ -170,6 +170,8 @@ Module::init ( void )
_instances = 1;
_bypass = 0;
_pending_feedback = false;
_base_label = NULL;
_number = -2; /* magic number indicates old instance, before numbering */
box( FL_UP_BOX );
labeltype( FL_NO_LABEL );
@ -208,6 +210,8 @@ Module::get ( Log_Entry &e ) const
e.add( ":is_default", is_default() );
e.add( ":chain", chain() );
e.add( ":active", ! bypass() );
if ( number() >= 0 )
e.add( ":number", number() );
}
bool
@ -238,7 +242,8 @@ Module::copy ( void ) const
/* we don't want this module to get added to the current
chain... */
if ( !( !strcmp( s, ":chain" ) ||
!strcmp( s, ":is_default" ) ) )
!strcmp( s, ":is_default" ) ||
!strcmp( s, ":number" ) ) )
{
DMESSAGE( "%s = %s", s, v );
ne->add_raw( s, v );
@ -251,6 +256,7 @@ Module::copy ( void ) const
return true;
}
void
Module::paste_before ( void )
{
@ -267,6 +273,8 @@ Module::paste_before ( void )
m->set( le );
m->number(-1);
if ( ! chain()->insert( this, m ) )
{
fl_alert( "Copied module cannot be inserted at this point in the chain" );
@ -280,6 +288,33 @@ Module::paste_before ( void )
m->copy();
}
void
Module::number ( int v )
{
_number = v;
char s[255];
if ( v > 0 && !is_default() )
snprintf( s, sizeof(s), "%s.%i", base_label(), v );
else
snprintf( s, sizeof(s), "%s", base_label() );
copy_label( s );
}
void
Module::base_label ( const char *s )
{
if ( _base_label )
free( _base_label );
_base_label = NULL;
if ( s )
_base_label = strdup(s);
}
void
@ -430,12 +465,7 @@ Module::Port::generate_osc_path ()
return NULL;
}
int n = module()->chain()->get_module_instance_number( module() );
if ( n > 0 )
asprintf( &path, "/strip/%s/%s.%i/%s", module()->chain()->name(), p->module()->label(), n, p->name() );
else
asprintf( &path, "/strip/%s/%s/%s", module()->chain()->name(), p->module()->label(), p->name() );
asprintf( &path, "/strip/%s/%s/%s", module()->chain()->name(), p->module()->label(), p->name() );
char *s = escape_url( path );
@ -574,6 +604,24 @@ Module::Port::osc_control_change_cv ( float v, void *user_data )
void
Module::set ( Log_Entry &e )
{
/* have to do this before adding to chain... */
int n = -2;
for ( int i = 0; i < e.size(); ++i )
{
const char *s, *v;
e.get( i, &s, &v );
if ( ! strcmp(s, ":number" ) )
{
n = atoi(v);
}
}
number(n);
for ( int i = 0; i < e.size(); ++i )
{
const char *s, *v;
@ -901,19 +949,7 @@ Module::insert_menu_cb ( const Fl_Menu_ *m )
if ( !strcmp( picked, "Aux" ) )
{
int n = 0;
for ( int i = 0; i < chain()->modules(); i++ )
{
if ( !strcmp( chain()->module(i)->name(), "AUX" ) )
n++;
}
AUX_Module *jm = new AUX_Module();
jm->chain( chain() );
jm->number( n );
jm->configure_inputs( ninputs() );
jm->configure_outputs( ninputs() );
jm->initialize();
mod = jm;
}
@ -931,9 +967,6 @@ Module::insert_menu_cb ( const Fl_Menu_ *m )
Spatializer_Module *jm = new Spatializer_Module();
jm->chain( chain() );
// jm->number( n );
// jm->configure_inputs( ninputs() );
// jm->configure_outputs( ninputs() );
jm->initialize();
mod = jm;
@ -941,8 +974,6 @@ Module::insert_menu_cb ( const Fl_Menu_ *m )
}
else if ( !strcmp( picked, "Gain" ) )
mod = new Gain_Module();
/* else if ( !strcmp( picked, "Spatializer" ) ) */
/* mod = new Spatializer_Module(); */
else if ( !strcmp( picked, "Meter" ) )
mod = new Meter_Module();
else if ( !strcmp( picked, "Mono Pan" ))
@ -963,6 +994,8 @@ Module::insert_menu_cb ( const Fl_Menu_ *m )
if ( mod )
{
mod->number(-1);
if ( ! chain()->insert( this, mod ) )
{
fl_alert( "Cannot insert this module at this point in the chain" );

View File

@ -49,12 +49,15 @@ class Module : public Fl_Group, public Loggable {
Chain *_chain;
bool _is_default;
bool _pending_feedback;
char *_base_label;
nframes_t _nframes;
static nframes_t _sample_rate;
static Module *_copied_module_empty;
static char *_copied_module_settings;
int _number;
void init ( void );
void insert_menu_cb ( const Fl_Menu_ *m );
@ -75,6 +78,13 @@ protected:
public:
virtual int number ( void ) const { return _number; }
virtual void number ( int v );
virtual const char * base_label ( void ) const { return _base_label ? _base_label : name(); }
virtual void base_label ( const char * );
virtual nframes_t get_module_latency ( void ) const { return 0; }
virtual void get_latency ( JACK::Port::direction_e dir, nframes_t *min, nframes_t *max ) const;

View File

@ -98,6 +98,24 @@ Plugin_Module::get ( Log_Entry &e ) const
void
Plugin_Module::set ( Log_Entry &e )
{
int n = 0;
/* we need to have number() defined before we create the control inputs in load() */
for ( int i = 0; i < e.size(); ++i )
{
const char *s, *v;
e.get( i, &s, &v );
if ( ! strcmp(s, ":number" ) )
{
n = atoi(v);
}
}
/* need to call this to set label even for version 0 modules */
number(n);
for ( int i = 0; i < e.size(); ++i )
{
const char *s, *v;
@ -443,11 +461,15 @@ Plugin_Module::load ( unsigned long id )
{
/* unknown plugin ID */
WARNING( "Unknown plugin ID: %lu", id );
label( "----" );
char s[25];
snprintf( s, 24, "! %lu", id );
base_label( s );
return false;
}
label( _idata->descriptor->Name );
base_label( _idata->descriptor->Name );
if ( _idata->descriptor )
{