summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-03-26 01:03:46 +0100
committerRobin Gareus <robin@gareus.org>2016-03-26 01:03:46 +0100
commit1503db4a28fe01650bb8619f5f38fccb312474ab (patch)
tree932db17b137ebb5cce85b36d4366bbe8c4d7a911 /libs
parent0954efffd3a1d642be313aed9b5b7070eb307a9c (diff)
prototype support for arbitrary plugin channel maps
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/plugin_insert.h39
-rw-r--r--libs/ardour/luabindings.cc23
-rw-r--r--libs/ardour/plugin_insert.cc74
3 files changed, 124 insertions, 12 deletions
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> ("ChanMapping")
+ .addVoidConstructor ()
+ .addFunction ("get", static_cast<uint32_t(ChanMapping::*)(DataType, uint32_t)>(&ChanMapping::get))
+ .addFunction ("set", &ChanMapping::set)
+ .addConst ("Invalid", 4294967295) // UINT32_MAX
+ .endClass ()
+
.beginNamespace ("Properties")
// templated class definitions
.beginClass <PBD::PropertyDescriptor<bool> > ("BoolProperty").endClass ()
@@ -344,7 +351,7 @@ LuaBindings::common (lua_State* L)
.addFunction ("automation_control", (boost::shared_ptr<AutomationControl>(Automatable::*)(const Evoral::Parameter&, bool))&Automatable::automation_control)
.endClass ()
- .deriveWSPtrClass <Plugin, PBD::StatefulDestructible> ("PluginInsert")
+ .deriveWSPtrClass <Plugin, PBD::StatefulDestructible> ("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, Evoral::Control> ("AutomationControl")
@@ -633,12 +648,6 @@ LuaBindings::dsp (lua_State* L)
.addFunction ("get_audio", static_cast<AudioBuffer&(BufferSet::*)(size_t)>(&BufferSet::get_audio))
.addFunction ("count", static_cast<const ChanCount&(BufferSet::*)()const>(&BufferSet::count))
.endClass()
-
- .beginClass <ChanMapping> ("ChanMapping")
- .addFunction ("get", static_cast<uint32_t(ChanMapping::*)(DataType, uint32_t)>(&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<Plugin> 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 ();
+ }
}
}