X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fplugin_insert.cc;h=a1c2e4b165c029d0360f92846ed62365dd0f1da6;hb=e77729125ec262b6a01e8fc22b236995cd37a7f6;hp=55b592561cf3bac2925a9e3aa6be7a071a58479f;hpb=e27096b054cbaa5c58063f96ee64b3af3af3e7bd;p=ardour.git diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 55b592561c..a1c2e4b165 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -80,7 +80,7 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr plug) add_plugin (plug); create_automatable_parameters (); const ChanCount& sc (sidechain_input_pins ()); - if (sc.n_total () > 0) { + if (sc.n_audio () > 0) { add_sidechain (sc.n_audio ()); } } @@ -166,9 +166,13 @@ PluginInsert::add_sidechain (uint32_t n_audio) if (_sidechain) { return false; } - // TODO add route-name, plugin name and shorten.. (plugin name can be long and conatain odd chars) - std::string n = "Sidechain " + id().to_s(); /// XXX - SideChain *sc = new SideChain (_session, n); + std::ostringstream n; + if (n_audio > 0) { + n << "Sidechain " << Session::next_name_id (); + } else { + n << "TO BE RESET FROM XML"; + } + SideChain *sc = new SideChain (_session, n.str ()); _sidechain = boost::shared_ptr (sc); _sidechain->activate (); for (uint32_t n = 0; n < n_audio; ++n) { @@ -331,6 +335,11 @@ PluginInsert::has_no_audio_inputs() const return _plugins[0]->get_info()->n_inputs.n_audio() == 0; } +framecnt_t +PluginInsert::plugin_latency () const { + return _plugins.front()->signal_latency (); +} + bool PluginInsert::is_midi_instrument() const { @@ -472,11 +481,28 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of PinMappings in_map (_in_map); PinMappings out_map (_out_map); ChanMapping thru_map (_thru_map); - if (_mapping_changed) { + if (_mapping_changed) { // ToDo use a counters, increment until match. _no_inplace = check_inplace (); _mapping_changed = false; } + if (_latency_changed) { + /* delaylines are configured with the max possible latency (as reported by the plugin) + * so this won't allocate memory (unless the plugin lied about its max latency) + * It may still 'click' though, since the fixed delaylines are not de-clicked. + * Then again plugin-latency changes are not click-free to begin with. + * + * This is also worst case, there is currently no concept of per-stream latency. + * + * e.g. Two identical latent plugins: + * 1st plugin: process left (latent), bypass right. + * 2nd plugin: bypass left, process right (latent). + * -> currently this yields 2 times latency of the plugin, + */ + _latency_changed = false; + _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ()); + } + if (_match.method == Split && !_no_inplace) { // TODO: also use this optimization if one source-buffer // feeds _all_ *connected* inputs. @@ -600,7 +626,7 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of uint32_t in_idx = thru_map.get (*t, out, &valid); if (valid) { uint32_t m = out + natural_input_streams ().get (*t); - inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset); + _delaybuffers.delay (*t, out, inplace_bufs.get (*t, m), bufs.get (*t, in_idx), nframes, offset, offset); used_outputs.set (*t, out, 1); // mark as used } } @@ -1419,6 +1445,9 @@ PluginInsert::configure_io (ChanCount in, ChanCount out) PluginIoReConfigure (); /* EMIT SIGNAL */ } + _delaybuffers.configure (_configured_out, _plugins.front()->max_latency ()); + _latency_changed = true; + // we don't know the analysis window size, so we must work with the // current buffer size here. each request for data fills in these // buffers and the analyser makes sure it gets enough data for the @@ -2395,6 +2424,7 @@ PluginInsert::add_plugin (boost::shared_ptr plugin) plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2)); plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1)); plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1)); + plugin->LatencyChanged.connect_same_thread (*this, boost::bind (&PluginInsert::latency_changed, this, _1, _2)); // cache sidechain ports _cached_sidechain_pins.reset (); const ChanCount& nis (plugin->get_info()->n_inputs); @@ -2407,6 +2437,11 @@ PluginInsert::add_plugin (boost::shared_ptr plugin) } } } + + boost::shared_ptr vst = boost::dynamic_pointer_cast (plugin); + if (vst) { + vst->set_insert (this, _plugins.size ()); + } _plugins.push_back (plugin); } @@ -2434,6 +2469,13 @@ PluginInsert::monitoring_changed () } } +void +PluginInsert::latency_changed (framecnt_t, framecnt_t) +{ + // this is called in RT context, LatencyChanged is emitted after run() + _latency_changed = true; +} + void PluginInsert::start_touch (uint32_t param_id) {