From: Robin Gareus Date: Sat, 26 Mar 2016 00:03:46 +0000 (+0100) Subject: prototype support for arbitrary plugin channel maps X-Git-Tag: 5.0-pre0~1210 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=1503db4a28fe01650bb8619f5f38fccb312474ab;p=ardour.git prototype support for arbitrary plugin channel maps --- diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index 453b9a0f0c..d9db98dee4 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -69,6 +69,35 @@ class LIBARDOUR_API PluginInsert : public Processor int set_block_size (pframes_t nframes); + ChanMapping input_map (uint32_t num=0) const { + if (num < _in_map.size()) { + return _in_map.find (num)->second; + } else { + return ChanMapping (); + } + } + + ChanMapping output_map (uint32_t num=0) const { + if (num < _out_map.size()) { + return _out_map.find (num)->second; + } else { + return ChanMapping (); + } + } + +#ifndef NDEBUG // prototyping -- this should be done synchroneously in configure_io() + void set_input_map (uint32_t num, ChanMapping m) { + if (num < _in_map.size()) { + _in_map[num] = m; + } + } + void set_output_map (uint32_t num, ChanMapping m) { + if (num < _in_map.size()) { + _out_map[num] = m; + } + } +#endif + ChanCount output_streams() const; ChanCount input_streams() const; ChanCount natural_output_streams() const; @@ -143,6 +172,14 @@ class LIBARDOUR_API PluginInsert : public Processor void collect_signal_for_analysis (framecnt_t nframes); + bool no_inplace () const { + return _pending_no_inplace; + } + + void set_no_inplace (bool b) { + _pending_no_inplace = b; + } + void set_strict_io (bool b) { _strict_io = b; } @@ -199,6 +236,8 @@ class LIBARDOUR_API PluginInsert : public Processor ChanCount _configured_in; ChanCount _configured_out; + bool _no_inplace; + bool _pending_no_inplace; bool _strict_io; bool _strict_io_configured; diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc index 1c8630790b..61e3f817a5 100644 --- a/libs/ardour/luabindings.cc +++ b/libs/ardour/luabindings.cc @@ -179,6 +179,13 @@ LuaBindings::common (lua_State* L) .endClass () .endNamespace () + .beginClass ("ChanMapping") + .addVoidConstructor () + .addFunction ("get", static_cast(&ChanMapping::get)) + .addFunction ("set", &ChanMapping::set) + .addConst ("Invalid", 4294967295) // UINT32_MAX + .endClass () + .beginNamespace ("Properties") // templated class definitions .beginClass > ("BoolProperty").endClass () @@ -344,7 +351,7 @@ LuaBindings::common (lua_State* L) .addFunction ("automation_control", (boost::shared_ptr(Automatable::*)(const Evoral::Parameter&, bool))&Automatable::automation_control) .endClass () - .deriveWSPtrClass ("PluginInsert") + .deriveWSPtrClass ("Plugin") .addFunction ("label", &Plugin::label) .addFunction ("name", &Plugin::name) .addFunction ("maker", &Plugin::maker) @@ -365,6 +372,14 @@ LuaBindings::common (lua_State* L) .addFunction ("deactivate", &PluginInsert::deactivate) .addFunction ("strict_io_configured", &PluginInsert::strict_io_configured) .addFunction ("set_strict_io", &PluginInsert::set_strict_io) + .addFunction ("no_inplace", &PluginInsert::no_inplace) + .addFunction ("input_map", &PluginInsert::input_map) + .addFunction ("output_map", &PluginInsert::output_map) +#ifndef NDEBUG -- this is not safe, prototyping only + .addFunction ("set_no_inplace", &PluginInsert::set_no_inplace) + .addFunction ("set_input_map", &PluginInsert::set_input_map) + .addFunction ("set_output_map", &PluginInsert::set_output_map) +#endif .endClass () .deriveWSPtrClass ("AutomationControl") @@ -633,12 +648,6 @@ LuaBindings::dsp (lua_State* L) .addFunction ("get_audio", static_cast(&BufferSet::get_audio)) .addFunction ("count", static_cast(&BufferSet::count)) .endClass() - - .beginClass ("ChanMapping") - .addFunction ("get", static_cast(&ChanMapping::get)) - .addFunction ("set", &ChanMapping::set) - .addConst ("Invalid", 4294967295) // UINT32_MAX - .endClass () .endNamespace (); luabridge::getGlobalNamespace (L) diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index cb386b940c..b174ceb2fe 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -68,6 +68,8 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr plug) : Processor (s, (plug ? plug->name() : string ("toBeRenamed"))) , _signal_analysis_collected_nframes(0) , _signal_analysis_collect_nframes_max(0) + , _no_inplace (false) + , _pending_no_inplace (false) , _strict_io (false) , _strict_io_configured (false) { @@ -364,6 +366,7 @@ PluginInsert::flush () void PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now) { + _no_inplace = _pending_no_inplace; // Calculate if, and how many frames we need to collect for analysis framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max - _signal_analysis_collected_nframes); @@ -374,13 +377,13 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of ChanCount const in_streams = input_streams (); ChanCount const out_streams = output_streams (); - bool valid; if (_match.method == Split) { assert (_in_map.size () == 1); /* fix the input mapping so that we have maps for each of the plugin's inputs */ /* copy the first stream's buffer contents to the others */ /* XXX: audio only */ + bool valid; uint32_t first_idx = _in_map[0].get (DataType::AUDIO, 0, &valid); if (valid) { for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) { @@ -444,10 +447,71 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of } - uint32_t pc = 0; - for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) { - if ((*i)->connect_and_run(bufs, _in_map[pc], _out_map[pc], nframes, offset)) { - deactivate (); + if (_no_inplace) { + BufferSet& inplace_bufs = _session.get_noinplace_buffers(); + + uint32_t pc = 0; + for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) { + + ARDOUR::ChanMapping in_map (natural_input_streams()); + ARDOUR::ChanMapping out_map; + ARDOUR::ChanCount mapped; + ARDOUR::ChanCount backmap; + + // map inputs sequentially + for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { + for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) { + bool valid; + uint32_t in_idx = _in_map[pc].get (*t, in, &valid); + uint32_t m = mapped.get (*t); + if (valid) { + inplace_bufs.get (*t, m).read_from (bufs.get (*t, in_idx), nframes, offset, offset); + } else { + inplace_bufs.get (*t, m).silence (nframes, offset); + } + mapped.set (*t, m + 1); + } + } + + backmap = mapped; + + // map outputs + for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { + for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) { + uint32_t m = mapped.get (*t); + inplace_bufs.get (*t, m).silence (nframes, offset); + out_map.set (*t, out, m); + mapped.set (*t, m + 1); + } + } + + if ((*i)->connect_and_run(inplace_bufs, in_map, out_map, nframes, offset)) { + deactivate (); + } + + // clear output buffers + bufs.silence (nframes, offset); + + // copy back outputs + for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { + for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) { + uint32_t m = backmap.get (*t); + bool valid; + uint32_t out_idx = _out_map[pc].get (*t, out, &valid); + if (valid) { + bufs.get (*t, out_idx).read_from (inplace_bufs.get (*t, m), nframes, offset, offset); + } + backmap.set (*t, m + 1); + } + } + } + + } else { + uint32_t pc = 0; + for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) { + if ((*i)->connect_and_run(bufs, _in_map[pc], _out_map[pc], nframes, offset)) { + deactivate (); + } } }