From 393684f376a1ae617fc0a6f92a91ad7d8ed373c7 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Fri, 25 Dec 2020 17:41:37 -0800 Subject: [PATCH] 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. --- mixer/src/AUX_Module.C | 31 +------------- mixer/src/AUX_Module.H | 12 +----- mixer/src/Chain.C | 8 +++- mixer/src/Controller_Module.C | 35 ++++++++++++--- mixer/src/Controller_Module.H | 1 + mixer/src/Module.C | 81 ++++++++++++++++++++++++----------- mixer/src/Module.H | 10 +++++ mixer/src/Plugin_Module.C | 26 ++++++++++- 8 files changed, 130 insertions(+), 74 deletions(-) diff --git a/mixer/src/AUX_Module.C b/mixer/src/AUX_Module.C index d8aa58e..5566998 100644 --- a/mixer/src/AUX_Module.C +++ b/mixer/src/AUX_Module.C @@ -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 ); diff --git a/mixer/src/AUX_Module.H b/mixer/src/AUX_Module.H index e422a54..6d37879 100644 --- a/mixer/src/AUX_Module.H +++ b/mixer/src/AUX_Module.H @@ -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 ( ); diff --git a/mixer/src/Chain.C b/mixer/src/Chain.C index ef4f9dd..650c45e 100644 --- a/mixer/src/Chain.C +++ b/mixer/src/Chain.C @@ -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 ) { diff --git a/mixer/src/Controller_Module.C b/mixer/src/Controller_Module.C index c3e3a92..5a4a39a 100644 --- a/mixer/src/Controller_Module.C +++ b/mixer/src/Controller_Module.C @@ -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(); diff --git a/mixer/src/Controller_Module.H b/mixer/src/Controller_Module.H index c466a50..26909bd 100644 --- a/mixer/src/Controller_Module.H +++ b/mixer/src/Controller_Module.H @@ -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 ); diff --git a/mixer/src/Module.C b/mixer/src/Module.C index dfb4381..050440a 100644 --- a/mixer/src/Module.C +++ b/mixer/src/Module.C @@ -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" ); diff --git a/mixer/src/Module.H b/mixer/src/Module.H index 2b85146..48bfde0 100644 --- a/mixer/src/Module.H +++ b/mixer/src/Module.H @@ -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; diff --git a/mixer/src/Plugin_Module.C b/mixer/src/Plugin_Module.C index 29c38df..45f73ee 100644 --- a/mixer/src/Plugin_Module.C +++ b/mixer/src/Plugin_Module.C @@ -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 ) {