handle sidechain input changes

This commit is contained in:
Robin Gareus 2016-04-03 05:14:05 +02:00
parent 071c72a977
commit 6739b6a1e3
4 changed files with 33 additions and 10 deletions

View file

@ -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 ();

View file

@ -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 ();

View file

@ -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);
}

View file

@ -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
{