From bfd50cdeb0416b106a7813177148dffb1af6db8e Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 2 Aug 2013 03:39:00 +0200 Subject: [PATCH] rework MIDI [processor|plugin] chain * forward midi-data around plugins that have no MIDI-out * allow to insert plugins with no MIDI-input at a point with one MIDI-channel This works because excess ports (both plugin and route) remain unconnected and use scratch-buffers. Tested with LV2, LXVST and LADSPA. (AU plugins with variable in/out retain the old behavior, no bypass) fixes http://tracker.ardour.org/view.php?id=5630 --- libs/ardour/amp.cc | 2 +- libs/ardour/ardour/amp.h | 2 +- libs/ardour/ardour/audio_unit.h | 2 +- libs/ardour/ardour/capturing_processor.h | 2 +- libs/ardour/ardour/delivery.h | 2 +- libs/ardour/ardour/internal_return.h | 2 +- libs/ardour/ardour/internal_send.h | 2 +- libs/ardour/ardour/meter.h | 2 +- libs/ardour/ardour/monitor_processor.h | 2 +- libs/ardour/ardour/panner_shell.h | 2 +- libs/ardour/ardour/plugin.h | 2 +- libs/ardour/ardour/plugin_insert.h | 6 +++-- libs/ardour/ardour/port_insert.h | 2 +- libs/ardour/ardour/processor.h | 2 +- libs/ardour/ardour/return.h | 2 +- libs/ardour/ardour/send.h | 2 +- libs/ardour/ardour/unknown_processor.h | 2 +- libs/ardour/audio_unit.cc | 2 +- libs/ardour/capturing_processor.cc | 2 +- libs/ardour/delivery.cc | 2 +- libs/ardour/internal_return.cc | 2 +- libs/ardour/internal_send.cc | 2 +- libs/ardour/meter.cc | 2 +- libs/ardour/monitor_processor.cc | 2 +- libs/ardour/plugin_insert.cc | 28 +++++++++++++++++------- libs/ardour/port_insert.cc | 2 +- libs/ardour/return.cc | 2 +- libs/ardour/route.cc | 6 ++--- libs/ardour/send.cc | 2 +- 29 files changed, 53 insertions(+), 39 deletions(-) diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc index f60240fd57..c97d624440 100644 --- a/libs/ardour/amp.cc +++ b/libs/ardour/amp.cc @@ -61,7 +61,7 @@ Amp::display_name() const } bool -Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +Amp::can_support_io_configuration (const ChanCount& in, ChanCount& out) { out = in; return true; diff --git a/libs/ardour/ardour/amp.h b/libs/ardour/ardour/amp.h index 23cc0ad0a8..e21cf62d62 100644 --- a/libs/ardour/ardour/amp.h +++ b/libs/ardour/ardour/amp.h @@ -40,7 +40,7 @@ public: bool visible () const; - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool); diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h index 36e82da802..007390b34a 100644 --- a/libs/ardour/ardour/audio_unit.h +++ b/libs/ardour/ardour/audio_unit.h @@ -104,7 +104,7 @@ class AUPlugin : public ARDOUR::Plugin bool has_editor () const; - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); ChanCount output_streams() const; ChanCount input_streams() const; bool configure_io (ChanCount in, ChanCount out); diff --git a/libs/ardour/ardour/capturing_processor.h b/libs/ardour/ardour/capturing_processor.h index b672d1ac07..5b9ea51557 100644 --- a/libs/ardour/ardour/capturing_processor.h +++ b/libs/ardour/ardour/capturing_processor.h @@ -38,7 +38,7 @@ class CapturingProcessor : public Processor int set_block_size (pframes_t nframes); void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required); bool configure_io (ChanCount in, ChanCount out); - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); virtual XMLNode& state (bool); private: diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h index 314b223538..4a6d4368a6 100644 --- a/libs/ardour/ardour/delivery.h +++ b/libs/ardour/ardour/delivery.h @@ -67,7 +67,7 @@ public: std::string display_name() const; Role role() const { return _role; } - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool); diff --git a/libs/ardour/ardour/internal_return.h b/libs/ardour/ardour/internal_return.h index c7fe04cc42..4d2b32f031 100644 --- a/libs/ardour/ardour/internal_return.h +++ b/libs/ardour/ardour/internal_return.h @@ -39,7 +39,7 @@ class InternalReturn : public Return void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool); bool configure_io (ChanCount, ChanCount); - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); void add_send (InternalSend *); void remove_send (InternalSend *); diff --git a/libs/ardour/ardour/internal_send.h b/libs/ardour/ardour/internal_send.h index 8bfb0de887..a7f0f73e6e 100644 --- a/libs/ardour/ardour/internal_send.h +++ b/libs/ardour/ardour/internal_send.h @@ -42,7 +42,7 @@ class InternalSend : public Send void cycle_start (pframes_t); void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool); bool feeds (boost::shared_ptr other) const; - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); int set_block_size (pframes_t); diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h index a4ad8ecff4..df1e381bb4 100644 --- a/libs/ardour/ardour/meter.h +++ b/libs/ardour/ardour/meter.h @@ -56,7 +56,7 @@ public: void reset (); void reset_max (); - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); /* special method for meter, to ensure that it can always handle the maximum diff --git a/libs/ardour/ardour/monitor_processor.h b/libs/ardour/ardour/monitor_processor.h index 5b724b5e8d..64d3b86bfb 100644 --- a/libs/ardour/ardour/monitor_processor.h +++ b/libs/ardour/ardour/monitor_processor.h @@ -118,7 +118,7 @@ public: int set_state (const XMLNode&, int /* version */); bool configure_io (ChanCount in, ChanCount out); - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); void set_cut_all (bool); void set_dim_all (bool); diff --git a/libs/ardour/ardour/panner_shell.h b/libs/ardour/ardour/panner_shell.h index 7d24adb46f..dba5826370 100644 --- a/libs/ardour/ardour/panner_shell.h +++ b/libs/ardour/ardour/panner_shell.h @@ -53,7 +53,7 @@ public: std::string describe_parameter (Evoral::Parameter param); - bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return true; }; + bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) { return true; }; void configure_io (ChanCount in, ChanCount out); /// The fundamental Panner function diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 9e4f5c40fd..55b76fbb08 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -242,7 +242,7 @@ class Plugin : public PBD::StatefulDestructible, public Latent /* specific types of plugins can overload this. As of September 2008, only AUPlugin does this. */ - virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return false; } + virtual bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) { return false; } virtual ChanCount output_streams() const; virtual ChanCount input_streams() const; diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index d80c759cff..a1b9c5a685 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -69,7 +69,7 @@ class PluginInsert : public Processor bool set_count (uint32_t num); uint32_t get_count () const { return _plugins.size(); } - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); bool has_no_inputs() const; @@ -160,6 +160,8 @@ class PluginInsert : public Processor BufferSet _signal_analysis_inputs; BufferSet _signal_analysis_outputs; + ChanCount midi_bypass; + /** Description of how we can match our plugin's IO to our own insert IO */ struct Match { Match () : method (Impossible), plugins (0) {} @@ -170,7 +172,7 @@ class PluginInsert : public Processor ChanCount hide; ///< number of channels to hide }; - Match private_can_support_io_configuration (ChanCount const &, ChanCount &) const; + Match private_can_support_io_configuration (ChanCount const &, ChanCount &); /** details of the match currently being used */ Match _match; diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h index 657c2c0de6..abd9fb73cc 100644 --- a/libs/ardour/ardour/port_insert.h +++ b/libs/ardour/ardour/port_insert.h @@ -57,7 +57,7 @@ class PortInsert : public IOProcessor bool set_name (const std::string& name); - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); void activate (); diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index d497f56dd3..772ae3520d 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -82,7 +82,7 @@ class Processor : public SessionObject, public Automatable, public Latent /* Derived classes should override these, or processor appears as an in-place pass-through */ - virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const = 0; + virtual bool can_support_io_configuration (const ChanCount& in, ChanCount& out) = 0; virtual ChanCount input_streams () const { return _configured_input; } virtual ChanCount output_streams() const { return _configured_output; } diff --git a/libs/ardour/ardour/return.h b/libs/ardour/ardour/return.h index 55ca2d84f6..6dcd6ac2fc 100644 --- a/libs/ardour/ardour/return.h +++ b/libs/ardour/ardour/return.h @@ -56,7 +56,7 @@ public: uint32_t pans_required() const { return _configured_input.n_audio(); } - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); static uint32_t how_many_returns(); diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index fa023a3b68..1a21d1d050 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -56,7 +56,7 @@ class Send : public Delivery void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool); - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; + bool can_support_io_configuration (const ChanCount& in, ChanCount& out); bool configure_io (ChanCount in, ChanCount out); void activate (); diff --git a/libs/ardour/ardour/unknown_processor.h b/libs/ardour/ardour/unknown_processor.h index 36981030ce..61a5734df2 100644 --- a/libs/ardour/ardour/unknown_processor.h +++ b/libs/ardour/ardour/unknown_processor.h @@ -49,7 +49,7 @@ public: return false; } - bool can_support_io_configuration (const ChanCount &, ChanCount &) const { + bool can_support_io_configuration (const ChanCount &, ChanCount &) { return false; } diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index e43033eb67..538a905ca2 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -998,7 +998,7 @@ AUPlugin::output_streams() const } bool -AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +AUPlugin::can_support_io_configuration (const ChanCount& in, ChanCount& out) { // Note: We never attempt to multiply-instantiate plugins to meet io configurations. diff --git a/libs/ardour/capturing_processor.cc b/libs/ardour/capturing_processor.cc index c4b463aba7..4a31d92cc8 100644 --- a/libs/ardour/capturing_processor.cc +++ b/libs/ardour/capturing_processor.cc @@ -62,7 +62,7 @@ CapturingProcessor::configure_io (ChanCount in, ChanCount out) } bool -CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +CapturingProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) { out = in; return true; diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc index 9eaf843f7c..dfbe4c960a 100644 --- a/libs/ardour/delivery.cc +++ b/libs/ardour/delivery.cc @@ -124,7 +124,7 @@ Delivery::display_name () const } bool -Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +Delivery::can_support_io_configuration (const ChanCount& in, ChanCount& out) { if (_role == Main) { diff --git a/libs/ardour/internal_return.cc b/libs/ardour/internal_return.cc index af6b6110b6..fc5963603b 100644 --- a/libs/ardour/internal_return.cc +++ b/libs/ardour/internal_return.cc @@ -80,7 +80,7 @@ InternalReturn::get_state() } bool -InternalReturn::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +InternalReturn::can_support_io_configuration (const ChanCount& in, ChanCount& out) { out = in; return true; diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc index 26631d0fad..029a46ce53 100644 --- a/libs/ardour/internal_send.cc +++ b/libs/ardour/internal_send.cc @@ -284,7 +284,7 @@ InternalSend::connect_when_legal () } bool -InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out) { out = in; return true; diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc index 490b75dcb2..a7857f5859 100644 --- a/libs/ardour/meter.cc +++ b/libs/ardour/meter.cc @@ -165,7 +165,7 @@ PeakMeter::reset_max () } bool -PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out) { out = in; return true; diff --git a/libs/ardour/monitor_processor.cc b/libs/ardour/monitor_processor.cc index e55428b666..ed06647860 100644 --- a/libs/ardour/monitor_processor.cc +++ b/libs/ardour/monitor_processor.cc @@ -355,7 +355,7 @@ MonitorProcessor::configure_io (ChanCount in, ChanCount out) } bool -MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) { out = in; return true; diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index d519dbd7a7..b191cf4890 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -145,7 +145,7 @@ PluginInsert::output_streams() const ChanCount out = info->n_outputs; // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size())); out.set_audio (out.n_audio() * _plugins.size()); - out.set_midi (out.n_midi() * _plugins.size()); + out.set_midi (out.n_midi() * _plugins.size() + midi_bypass.n_midi()); return out; } } @@ -465,7 +465,6 @@ PluginInsert::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end } } else { - if (has_no_audio_inputs()) { /* silence all (audio) outputs. Should really declick @@ -704,7 +703,7 @@ PluginInsert::configure_io (ChanCount in, ChanCount out) * @return true if the given IO configuration can be supported. */ bool -PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) { return private_can_support_io_configuration (in, out).method != Impossible; } @@ -714,9 +713,11 @@ PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) * it can be. */ PluginInsert::Match -PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCount& out) const +PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out) { PluginInfoPtr info = _plugins.front()->get_info(); + ChanCount in; in += inx; + midi_bypass.reset(); if (info->reconfigurable_io()) { /* Plugin has flexible I/O, so delegate to it */ @@ -731,6 +732,15 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo ChanCount inputs = info->n_inputs; ChanCount outputs = info->n_outputs; + if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) { + DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name())); + midi_bypass.set(DataType::MIDI, 1); + } + if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) { + DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name())); + in.set(DataType::MIDI, 0); + } + bool no_inputs = true; for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { if (inputs.get (*t) != 0) { @@ -741,13 +751,13 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo if (no_inputs) { /* no inputs so we can take any input configuration since we throw it away */ - out = outputs; + out = outputs + midi_bypass; return Match (NoInputs, 1); } /* Plugin inputs match requested inputs exactly */ if (inputs == in) { - out = outputs; + out = outputs + midi_bypass; return Match (ExactMatch, 1); } @@ -789,6 +799,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { out.set (*t, outputs.get(*t) * f); } + out += midi_bypass; return Match (Replicate, f); } @@ -812,7 +823,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo } if (can_split) { - out = outputs; + out = outputs + midi_bypass; return Match (Split, 1); } @@ -836,10 +847,11 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & in, ChanCo } if (could_hide && !cannot_hide) { - out = outputs; + out = outputs + midi_bypass; return Match (Hide, 1, hide_channels); } + midi_bypass.reset(); return Match (Impossible, 0); } diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc index c13927449a..411d8d1e19 100644 --- a/libs/ardour/port_insert.cc +++ b/libs/ardour/port_insert.cc @@ -266,7 +266,7 @@ PortInsert::configure_io (ChanCount in, ChanCount out) } bool -PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +PortInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out) { out = in; return true; diff --git a/libs/ardour/return.cc b/libs/ardour/return.cc index 921be6a53a..4f9e8b958a 100644 --- a/libs/ardour/return.cc +++ b/libs/ardour/return.cc @@ -136,7 +136,7 @@ Return::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pfra } bool -Return::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +Return::can_support_io_configuration (const ChanCount& in, ChanCount& out) { out = in + _input->n_ports(); return true; diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index a394c73d20..b78217ff49 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -543,11 +543,10 @@ Route::process_output_buffers (BufferSet& bufs, if (bufs.count() != (*i)->input_streams()) { DEBUG_TRACE ( DEBUG::Processors, string_compose ( - "%1 bufs = %2 input for %3 = %4\n", + "input port mismatch %1 bufs = %2 input for %3 = %4\n", _name, bufs.count(), (*i)->name(), (*i)->input_streams() ) ); - continue; } } #endif @@ -1654,7 +1653,8 @@ Route::try_configure_processors_unlocked (ChanCount in, ProcessorStreams* err) if (boost::dynamic_pointer_cast (*p)) { DEBUG_TRACE (DEBUG::Processors, "--- CONFIGURE ABORTED due to unknown processor.\n"); - break; + DEBUG_TRACE (DEBUG::Processors, "}\n"); + return list > (); } if ((*p)->can_support_io_configuration(in, out)) { diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index 107cf9862b..e74fd7f8ce 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -270,7 +270,7 @@ Send::set_state_2X (const XMLNode& node, int /* version */) } bool -Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) const +Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) { /* sends have no impact at all on the channel configuration of the streams passing through the route. so, out == in.