mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-07 22:25:46 +01:00
prototype support for arbitrary plugin channel maps
This commit is contained in:
parent
0954efffd3
commit
1503db4a28
3 changed files with 124 additions and 12 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue