13
0

Allow plugins with >1 input to be inserted into mono tracks; the input is passed to each plugin input equally (#3746).

git-svn-id: svn://localhost/ardour2/branches/3.0@8628 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2011-01-31 15:28:15 +00:00
parent 898482dba2
commit 6c3bad48f9
3 changed files with 82 additions and 17 deletions

View File

@ -133,6 +133,9 @@ class PluginInsert : public Processor
BufferSet _signal_analysis_inputs;
BufferSet _signal_analysis_outputs;
/** true if we are splitting one processor input to >1 plugin inputs */
bool _splitting;
void automation_run (BufferSet& bufs, pframes_t nframes);
void connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now = 0);

View File

@ -620,7 +620,7 @@ LV2Plugin::connect_and_run (BufferSet& bufs,
pframes_t nframes, framecnt_t offset)
{
Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
cycles_t then = get_cycles ();
uint32_t audio_in_index = 0;

View File

@ -66,6 +66,7 @@ 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)
, _splitting (false)
{
/* the first is the master */
@ -147,7 +148,19 @@ PluginInsert::input_streams() const
{
ChanCount in = _plugins[0]->get_info()->n_inputs;
if (in == ChanCount::INFINITE) {
if (_splitting) {
/* we are splitting 1 processor input to multiple plugin inputs,
so we have a maximum of 1 stream of each type.
*/
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
if (in.get (*t) > 1) {
in.set (*t, 1);
}
}
return in;
} else if (in == ChanCount::INFINITE) {
return _plugins[0]->input_streams ();
} else {
in.set_audio (in.n_audio() * _plugins.size());
@ -275,6 +288,18 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of
ChanMapping in_map(input_streams());
ChanMapping out_map(output_streams());
if (_splitting) {
/* fix the input mapping so that we have maps for each of the plugin's inputs */
in_map = ChanMapping (natural_input_streams ());
/* copy the first stream's buffer contents to the others */
/* XXX: audio only */
Sample const * mono = bufs.get_audio (in_map.get (DataType::AUDIO, 0)).data (offset);
for (uint32_t i = input_streams().n_audio(); i < natural_input_streams().n_audio(); ++i) {
memcpy (bufs.get_audio (in_map.get (DataType::AUDIO, i)).data() + offset, mono + offset, sizeof (Sample) * (nframes - offset));
}
}
/* Note that we've already required that plugins
be able to handle in-place processing.
*/
@ -357,13 +382,20 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of
void
PluginInsert::silence (framecnt_t nframes)
{
if (!active ()) {
return;
}
ChanMapping in_map(input_streams());
ChanMapping out_map(output_streams());
if (active()) {
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->connect_and_run (_session.get_silent_buffers ((*i)->get_info()->n_inputs), in_map, out_map, nframes, 0);
}
if (_splitting) {
/* fix the input mapping so that we have maps for each of the plugin's inputs */
in_map = ChanMapping (natural_input_streams ());
}
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->connect_and_run (_session.get_silent_buffers ((*i)->get_info()->n_inputs), in_map, out_map, nframes, 0);
}
}
@ -540,15 +572,16 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
return false;
}
/* if we're running replicated plugins, each plugin has
the same i/o configuration and we may need to announce how many
output streams there are.
if we running a single plugin, we need to configure it.
*/
if (_plugins.front()->configure_io (in, out) == false) {
return false;
if (_plugins.front()->get_info()->n_inputs <= in) {
if (_plugins.front()->configure_io (in, out) == false) {
return false;
}
} else {
/* we must be splitting a single processor input to
multiple plugin inputs
*/
_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out);
_splitting = true;
}
// we don't know the analysis window size, so we must work with the
@ -620,9 +653,33 @@ PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
out.set (*t, outputs.get(*t) * f);
}
return true;
} else {
return false;
}
/* If the processor has exactly one input of a given type, and
the plugin has more, we can feed the single processor input
to some or all of the plugin inputs. This is rather
special-case-y, but the 1-to-many case is by far the
simplest. How do I split thy 2 processor inputs to 3
plugin inputs? Let me count the ways ...
*/
bool can_split = true;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
if (!can_split_type && !nothing_to_do_for_type) {
can_split = false;
}
}
if (can_split) {
out = outputs;
return true;
}
return false;
}
/* Number of plugin instances required to support a given channel configuration.
@ -659,6 +716,11 @@ PluginInsert::count_for_configuration (ChanCount in, ChanCount /*out*/) const
return 1;
}
if (inputs > in) {
/* more plugin inputs than processor inputs, so we are splitting */
return 1;
}
// assumes in is valid, so we must be replicating
if (inputs.n_total() < in.n_total()
&& (in.n_total() % inputs.n_total() == 0)) {