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:
parent
898482dba2
commit
6c3bad48f9
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user