From 4014b79c5c2ac987bda585d77a52301980d7bb63 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Fri, 25 Dec 2009 13:16:07 -0600 Subject: [PATCH] Mixer: Properly handle multiple plugin instances in one Plugin module.. --- Mixer/Chain.C | 2 + Mixer/Meter_Indicator_Module.C | 22 --- Mixer/Module.H | 3 + Mixer/Plugin_Module.C | 259 +++++++++++++++++++++------------ Mixer/Plugin_Module.H | 22 +-- 5 files changed, 174 insertions(+), 134 deletions(-) diff --git a/Mixer/Chain.C b/Mixer/Chain.C index 995c947..d6f0f14 100644 --- a/Mixer/Chain.C +++ b/Mixer/Chain.C @@ -471,6 +471,8 @@ Chain::build_process_queue ( void ) { m->audio_output[j].connect_to( &port[j] ); } + + m->handle_port_connection_change(); } DMESSAGE( "Process queue looks like:" ); diff --git a/Mixer/Meter_Indicator_Module.C b/Mixer/Meter_Indicator_Module.C index 97c9d99..4694caf 100644 --- a/Mixer/Meter_Indicator_Module.C +++ b/Mixer/Meter_Indicator_Module.C @@ -135,28 +135,6 @@ Meter_Indicator_Module::connect_to ( Port *p ) dpm_pack->add( o ); } - -// control = o; -// w = o; - -// o->value( p->control_value() ); -/* } */ - -/* w->align(FL_ALIGN_TOP); */ -/* w->labelsize( 10 ); */ - -/* if ( _pad ) */ -/* { */ -/* Fl_Labelpad_Group *flg = new Fl_Labelpad_Group( w ); */ -/* size( flg->w(), flg->h() ); */ -/* add( flg ); */ -/* } */ -/* else */ -/* { */ -/* w->resize( x(), y(), this->w(), h() ); */ -/* add( w ); */ -/* resizable( w ); */ -/* } */ } int diff --git a/Mixer/Module.H b/Mixer/Module.H index 9a94aab..b74485a 100644 --- a/Mixer/Module.H +++ b/Mixer/Module.H @@ -228,6 +228,7 @@ public: int instances ( void ) const { return _instances; } + void instances ( int i ) { _instances = i; } bool is_being_controlled ( void ) const { @@ -309,6 +310,8 @@ public: * the name of the mixer strip changed). */ virtual void handle_chain_name_changed () {} + virtual void handle_port_connection_change () {} + protected: void draw_connections ( void ); diff --git a/Mixer/Plugin_Module.C b/Mixer/Plugin_Module.C index b970718..d9ae6f5 100644 --- a/Mixer/Plugin_Module.C +++ b/Mixer/Plugin_Module.C @@ -48,7 +48,7 @@ struct Plugin_Module::ImplementationData { const LADSPA_Descriptor *descriptor; // std::vector m_LADSPABufVec; - LADSPA_Handle handle; + std::vector handle; }; @@ -63,7 +63,7 @@ Plugin_Module::Plugin_Module ( int , int , const char *L ) : Module( 50, 50, L ) Plugin_Module::~Plugin_Module ( ) { - + plugin_instances( 0 ); } @@ -81,7 +81,6 @@ Plugin_Module::~Plugin_Module ( ) Plugin_Module * Plugin_Module::pick_plugin ( void ) { - /**************/ /* build menu */ /**************/ @@ -109,8 +108,6 @@ Plugin_Module::pick_plugin ( void ) Plugin_Module *m = new Plugin_Module( 50, 50 ); -// Plugin_Module *plugin = new Plugin_Module(); - m->load( pi ); const char *plugin_name = pi->path; @@ -129,12 +126,10 @@ void Plugin_Module::init ( void ) { _idata = new Plugin_Module::ImplementationData(); + _idata->handle.clear(); _active = false; - _crosswire = true; + _crosswire = false; - _instances = 1; -// box( FL_ROUNDED_BOX ); -// box( FL_NO_BOX ); align( (Fl_Align)FL_ALIGN_CENTER | FL_ALIGN_INSIDE ); color( (Fl_Color)fl_color_average( FL_BLUE, FL_GREEN, 0.5f ) ); int tw, th, tx, ty; @@ -198,10 +193,9 @@ Plugin_Module::can_support_inputs ( int n ) /* e.g. STEREO going into MONO */ /* we'll run multiple instances of the plugin */ else if ( n > plugin_ins() && - plugin_ins() == 1 && plugin_outs() == 1 ) + ( plugin_ins() == 1 && plugin_outs() == 1 ) ) { - return plugin_outs() * n; -// instances( i ); + return n; } return -1; @@ -210,45 +204,56 @@ Plugin_Module::can_support_inputs ( int n ) bool Plugin_Module::configure_inputs( int n ) { + + int inst = 1; + _crosswire = false; + if ( 1 == n && plugin_ins() > 1 ) { + DMESSAGE( "Cross-wiring plugin inputs" ); _crosswire = true; + audio_input.clear(); - audio_input.push_back( Port( this, Port::INPUT, Port::AUDIO ) ); + + for ( int i = n; i--; ) + audio_input.push_back( Port( this, Port::INPUT, Port::AUDIO ) ); + } + else if ( n > plugin_ins() && + ( plugin_ins() == 1 && plugin_outs() == 1 ) ) + { + DMESSAGE( "Running multiple instances of plugin" ); + + audio_input.clear(); + audio_output.clear(); + + for ( int i = n; i--; ) + { + add_port( Port( this, Port::INPUT, Port::AUDIO ) ); + add_port( Port( this, Port::OUTPUT, Port::AUDIO ) ); + } + + inst = n; + } + else if ( n == plugin_ins() ) + { + + } + else + { + // unsupported configuration + return false; } -/* audio_input.clear(); */ -/* audio_output.clear(); */ + if ( _active ) + deactivate(); -/* for ( int i = 0; i < n; ++i ) */ -/* { */ -/* add_port( Port( Port::INPUT, Port::AUDIO ) ); */ -/* } */ - -/* if ( n > plugin_ins() ) */ -/* { */ -/* /\* multiple instances *\/ */ -/* instances( n / plugin_ins() ); */ -/* } */ -/* else if ( n < plugin_ins() ) */ -/* { */ -/* /\* duplication of input *\/ */ - - -/* } */ - -/* for ( int i = 0; i < plugin_outs() * instances(); ++i ) */ -/* { */ -/* add_port( Port( this, Port::OUTPUT, Port::AUDIO ) ); */ -/* } */ + if ( plugin_instances( inst ) ) + instances( inst ); + else + return false; if ( ! _active ) activate(); -/* // _plugin->deactivate(); */ -/* /\* if ( _plugin->active() ) *\/ */ -/* /\* _plugin->activate(); *\/ */ - - /* FIXME: do controls */ return true; } @@ -275,6 +280,67 @@ Plugin_Module::discover ( void ) return pi; } +bool +Plugin_Module::plugin_instances ( unsigned int n ) +{ + if ( _idata->handle.size() > n ) + { + for ( int i = _idata->handle.size() - n; i--; ) + { + LADSPA_Handle h = _idata->handle.back(); + + if ( _idata->descriptor->deactivate ) + _idata->descriptor->deactivate( h ); + if ( _idata->descriptor->cleanup ) + _idata->descriptor->cleanup( h ); + + _idata->handle.pop_back(); + } + } + else if ( _idata->handle.size() < n ) + { + for ( int i = n - _idata->handle.size(); i--; ) + { + LADSPA_Handle h; + + DMESSAGE( "Instantiating plugin..." ); + + if ( ! (h = _idata->descriptor->instantiate( _idata->descriptor, engine->sample_rate() ) ) ) + { + WARNING( "Failed to instantiate plugin" ); + return false; + } + + DMESSAGE( "Instantiated: %p", h ); + + _idata->handle.push_back( h ); + + DMESSAGE( "Connecting control ports..." ); + + int ij = 0; + int oj = 0; + for ( unsigned int k = 0; k < _idata->descriptor->PortCount; ++k ) + { + if ( LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[k] ) ) + { + if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[k] ) ) + _idata->descriptor->connect_port( h, k, (LADSPA_Data*)control_input[ij++].buffer() ); + else if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[k] ) ) + _idata->descriptor->connect_port( h, k, (LADSPA_Data*)control_output[oj++].buffer() ); + } + } + + // connect ports to magic bogus value to aid debugging. + for ( unsigned int k = 0; k < _idata->descriptor->PortCount; ++k ) + if ( LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[k] ) ) + _idata->descriptor->connect_port( h, k, (LADSPA_Data*)0x42 ); + + } + } + + return true; +} + bool Plugin_Module::load ( Plugin_Module::Plugin_Info *pi ) { @@ -295,14 +361,6 @@ Plugin_Module::load ( Plugin_Module::Plugin_Info *pi ) return false; } - /* FIXME: bogus rate */ - if ( ! (_idata->handle = _idata->descriptor->instantiate( _idata->descriptor, engine->sample_rate() ) ) ) - { - WARNING( "Failed to load plugin" ); - return false; - } -// _idata->descriptor->activate( _idata->handle ); - MESSAGE( "Name: %s", _idata->descriptor->Name ); for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i ) @@ -328,7 +386,7 @@ Plugin_Module::load ( Plugin_Module::Plugin_Info *pi ) { if ( LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[i] ) ) { - Port::Direction d; + Port::Direction d = Port::INPUT; if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) ) { @@ -474,8 +532,6 @@ Plugin_Module::load ( Plugin_Module::Plugin_Info *pi ) add_port( p ); - _idata->descriptor->connect_port( _idata->handle, i, (LADSPA_Data*)control_input.back().buffer() ); - DMESSAGE( "Plugin has control port \"%s\" (default: %f)", _idata->descriptor->PortNames[ i ], p.hints.default_value ); } } @@ -486,44 +542,47 @@ Plugin_Module::load ( Plugin_Module::Plugin_Info *pi ) return false; } - - return true; + return plugin_instances( 1 ); } -/* const char * */ -/* Plugin_Module::name ( void ) const */ -/* { */ -/* return _idata->descriptor->Name; */ -/* } */ - void Plugin_Module::set_input_buffer ( int n, void *buf ) { + LADSPA_Handle h; + + if ( instances() > 1 ) + { + h = _idata->handle[n]; + n = 0; + } + else + h = _idata->handle[0]; + for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i ) if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) && LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) ) if ( n-- == 0 ) - _idata->descriptor->connect_port( _idata->handle, i, (LADSPA_Data*)buf ); + _idata->descriptor->connect_port( h, i, (LADSPA_Data*)buf ); } void Plugin_Module::set_output_buffer ( int n, void *buf ) { + LADSPA_Handle h; + + if ( instances() > 1 ) + { + h = _idata->handle[n]; + n = 0; + } + else + h = _idata->handle[0]; + for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i ) if ( LADSPA_IS_PORT_OUTPUT( _idata->descriptor->PortDescriptors[i] ) && LADSPA_IS_PORT_AUDIO( _idata->descriptor->PortDescriptors[i] ) ) if ( n-- == 0 ) - _idata->descriptor->connect_port( _idata->handle, i, (LADSPA_Data*)buf ); -} - -void -Plugin_Module::set_control_buffer ( int n, void *buf ) -{ - for ( unsigned int i = 0; i < _idata->descriptor->PortCount; ++i ) - if ( LADSPA_IS_PORT_INPUT( _idata->descriptor->PortDescriptors[i] ) && - LADSPA_IS_PORT_CONTROL( _idata->descriptor->PortDescriptors[i] ) ) - if ( n-- == 0 ) - _idata->descriptor->connect_port( _idata->handle, i, (LADSPA_Data*)buf ); + _idata->descriptor->connect_port( h, i, (LADSPA_Data*)buf ); } void @@ -533,7 +592,9 @@ Plugin_Module::activate ( void ) FATAL( "Attempt to activate already active plugin" ); if ( _idata->descriptor->activate ) - _idata->descriptor->activate( _idata->handle ); + for ( unsigned int i = 0; i < _idata->handle.size(); ++i ) + _idata->descriptor->activate( _idata->handle[i] ); + _active = true; } @@ -541,37 +602,43 @@ void Plugin_Module::deactivate( void ) { if ( _idata->descriptor->deactivate ) - _idata->descriptor->deactivate( _idata->handle ); + for ( unsigned int i = 0; i < _idata->handle.size(); ++i ) + _idata->descriptor->activate( _idata->handle[i] ); + _active = false; } +void +Plugin_Module::handle_port_connection_change ( void ) +{ +// DMESSAGE( "Connecting audio ports" ); + + if ( _crosswire ) + { + for ( int i = 0; i < plugin_ins(); ++i ) + set_input_buffer( i, audio_input[0].buffer() ); + } + else + { + for ( unsigned int i = 0; i < audio_input.size(); ++i ) + set_input_buffer( i, audio_input[i].buffer() ); + } + + for ( unsigned int i = 0; i < audio_output.size(); ++i ) + set_output_buffer( i, audio_output[i].buffer() ); +} + void Plugin_Module::process ( ) { - if ( _crosswire ) - { - for ( int i = 0; i < plugin_ins(); ++i ) - { - set_input_buffer( i, audio_input[0].buffer() ); - } - } - else - { - for ( unsigned int i = 0; i < audio_input.size(); ++i ) - { - set_input_buffer( i, audio_input[i].buffer() ); - } - } - - for ( unsigned int i = 0; i < audio_output.size(); ++i ) - { - set_output_buffer( i, audio_output[i].buffer() ); - } + handle_port_connection_change(); if ( _active ) - { - _idata->descriptor->run( _idata->handle, nframes() ); - } + for ( unsigned int i = 0; i < _idata->handle.size(); ++i ) + { + volatile int n = i; + _idata->descriptor->run( _idata->handle[n], nframes() ); + } } diff --git a/Mixer/Plugin_Module.H b/Mixer/Plugin_Module.H index 36a0684..1e7f2b5 100644 --- a/Mixer/Plugin_Module.H +++ b/Mixer/Plugin_Module.H @@ -25,10 +25,6 @@ class Plugin_Module : Module { void init ( void ); - int _ins; - int _outs; - int _instances; - void bbox ( int &X, int &Y, int &W, int &H ) { X = x(); @@ -47,8 +43,6 @@ class Plugin_Module : Module { ImplementationData *_idata; bool _active; - - int _plugin_ins; int _plugin_outs; bool _crosswire; @@ -77,6 +71,10 @@ class Plugin_Module : Module { void process ( unsigned long nframes ); bool active ( void ) const { return _active; } + bool plugin_instances ( unsigned int ); + + void connect_ports ( void ); + public: Plugin_Module( int W, int H, const char *L = 0 ); @@ -88,15 +86,6 @@ public: int plugin_ins ( void ) const { return _plugin_ins; } int plugin_outs ( void ) const { return _plugin_outs; } - bool ins ( int i ); - int ins ( void ) const { return _ins; } - int outs ( void ) const { return plugin_outs() * _instances; } - - bool controllable ( void ) const { return false; } - - int instances ( void ) const { return _instances; } - void instances ( int i ) { _instances = i; } - void select_plugin ( unsigned long id ); const char *name ( void ) const { return "Plugin"; } @@ -106,9 +95,10 @@ public: void process ( void ); + void handle_port_connection_change ( void ); + protected: -// virtual void draw ( void ); virtual int handle ( int ); };