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_inputs;
BufferSet _signal_analysis_outputs; 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 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); 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) pframes_t nframes, framecnt_t offset)
{ {
Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset); Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
cycles_t then = get_cycles (); cycles_t then = get_cycles ();
uint32_t audio_in_index = 0; 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"))) : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
, _signal_analysis_collected_nframes(0) , _signal_analysis_collected_nframes(0)
, _signal_analysis_collect_nframes_max(0) , _signal_analysis_collect_nframes_max(0)
, _splitting (false)
{ {
/* the first is the master */ /* the first is the master */
@ -147,7 +148,19 @@ PluginInsert::input_streams() const
{ {
ChanCount in = _plugins[0]->get_info()->n_inputs; 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 (); return _plugins[0]->input_streams ();
} else { } else {
in.set_audio (in.n_audio() * _plugins.size()); 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 in_map(input_streams());
ChanMapping out_map(output_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 /* Note that we've already required that plugins
be able to handle in-place processing. be able to handle in-place processing.
*/ */
@ -357,13 +382,20 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of
void void
PluginInsert::silence (framecnt_t nframes) PluginInsert::silence (framecnt_t nframes)
{ {
if (!active ()) {
return;
}
ChanMapping in_map(input_streams()); ChanMapping in_map(input_streams());
ChanMapping out_map(output_streams()); ChanMapping out_map(output_streams());
if (active()) { if (_splitting) {
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { /* fix the input mapping so that we have maps for each of the plugin's inputs */
(*i)->connect_and_run (_session.get_silent_buffers ((*i)->get_info()->n_inputs), in_map, out_map, nframes, 0); 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; return false;
} }
/* if we're running replicated plugins, each plugin has if (_plugins.front()->get_info()->n_inputs <= in) {
the same i/o configuration and we may need to announce how many if (_plugins.front()->configure_io (in, out) == false) {
output streams there are. return false;
}
if we running a single plugin, we need to configure it. } else {
*/ /* we must be splitting a single processor input to
multiple plugin inputs
if (_plugins.front()->configure_io (in, out) == false) { */
return false; _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 // 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); out.set (*t, outputs.get(*t) * f);
} }
return true; 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. /* 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; 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 // assumes in is valid, so we must be replicating
if (inputs.n_total() < in.n_total() if (inputs.n_total() < in.n_total()
&& (in.n_total() % inputs.n_total() == 0)) { && (in.n_total() % inputs.n_total() == 0)) {