diff options
-rw-r--r-- | libs/ardour/ardour/plugin_insert.h | 9 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 2 | ||||
-rw-r--r-- | libs/ardour/plugin_insert.cc | 5 | ||||
-rw-r--r-- | libs/ardour/route.cc | 27 |
4 files changed, 33 insertions, 10 deletions
diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index d9e4b28d72..db7f0bc3be 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -119,6 +119,7 @@ class LIBARDOUR_API PluginInsert : public Processor void set_custom_cfg (bool b); bool add_sidechain (uint32_t n_audio = 1); bool del_sidechain (); + boost::shared_ptr<SideChain> sidechain () const { return _sidechain; } // end C++ class slavery! uint32_t get_count () const { return _plugins.size(); } @@ -185,14 +186,6 @@ class LIBARDOUR_API PluginInsert : public Processor return _sidechain ? true : false; } - // XXX dangerous - boost::shared_ptr<SideChain> sidechain () const { - return _sidechain; - } - - // XXX even more dangerous (adding/removing ports - // must be done by the owning route and the plugin - // needs to be reconfigured afterwards) boost::shared_ptr<IO> sidechain_input () const { if (_sidechain) { return _sidechain->input (); diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 8c71e87e94..d673bc75bf 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -783,12 +783,14 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou void input_change_handler (IOChange, void *src); void output_change_handler (IOChange, void *src); + void sidechain_change_handler (IOChange, void *src); bool input_port_count_changing (ChanCount); bool output_port_count_changing (ChanCount); bool _in_configure_processors; bool _initial_io_setup; + bool _in_sidechain_setup; int configure_processors_unlocked (ProcessorStreams*); bool set_meter_point_unlocked (); diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 250eaae11e..3f1146c861 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -687,7 +687,7 @@ PluginInsert::silence (framecnt_t nframes) ChanMapping in_map (natural_input_streams ()); ChanMapping out_map (natural_output_streams ()); - // TODO fake run sidechain, too? (maybe once it has meters) + // TODO run sidechain (delaylines) for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0); } @@ -700,7 +700,8 @@ PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame /* run as normal if we are active or moving from inactive to active */ if (_sidechain) { - // collect sidechain input for complete cycle. + // collect sidechain input for complete cycle (!) + // TODO we need delaylines here for latency compensation _sidechain->run (bufs, start_frame, end_frame, nframes, true); } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 76f88a3ce2..44c0028926 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -115,6 +115,7 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type) , _track_number (0) , _in_configure_processors (false) , _initial_io_setup (false) + , _in_sidechain_setup (false) , _strict_io (false) , _custom_meter_position_noted (false) { @@ -2439,6 +2440,7 @@ Route::add_remove_sidechain (boost::shared_ptr<Processor> proc, bool add) { Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); // take before Writerlock to avoid deadlock Glib::Threads::RWLock::WriterLock lm (_processor_lock); + PBD::Unwinder<bool> uw (_in_sidechain_setup, true); lx.release (); // IO::add_port() and ~IO takes process lock - XXX check if this is safe if (add) { @@ -2468,6 +2470,10 @@ Route::add_remove_sidechain (boost::shared_ptr<Processor> proc, bool add) configure_processors_unlocked (0); } + if (pi->has_sidechain ()) { + pi->sidechain_input ()->changed.connect_same_thread (*this, boost::bind (&Route::sidechain_change_handler, this, _1, _2)); + } + processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */ _session.set_dirty (); return true; @@ -3300,6 +3306,12 @@ Route::set_processor_state (const XMLNode& node) processor.reset (new UnknownProcessor (_session, **niter)); } + /* subscribe to Sidechain IO changes */ + boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert> (processor); + if (pi && pi->has_sidechain ()) { + pi->sidechain_input ()->changed.connect_same_thread (*this, boost::bind (&Route::sidechain_change_handler, this, _1, _2)); + } + /* we have to note the monitor send here, otherwise a new one will be created and the state of this one will be lost. */ @@ -3808,6 +3820,21 @@ Route::output_change_handler (IOChange change, void * /*src*/) } } +void +Route::sidechain_change_handler (IOChange change, void * /*src*/) +{ + if (_initial_io_setup || _in_sidechain_setup) { + return; + } + + if ((change.type & IOChange::ConfigurationChanged)) { + /* This is called with the process lock held if change + contains ConfigurationChanged + */ + configure_processors (0); + } +} + uint32_t Route::pans_required () const { |