Fix graph ordering incl. Inserts, Returns and SideChains

When building the process graph. Ardour usess
   Route::direct_feeds_according_to_reality()
This function only tests if the current route (or any ioprocessors)
is feeding another route's *input*.

Inserts, Return and now Sidechains are ignored as destinations on the
destination route are not taken into account.

This is now resolved by adding an IOVector, a collection of all inputs
of the destination route.
This commit is contained in:
Robin Gareus 2016-04-03 20:24:14 +02:00
parent 650f2802a0
commit daa10a6a38
3 changed files with 112 additions and 3 deletions

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2016 Robin Gareus <robin@gareus.org>
* Copyright (C) 2006 Paul Davis
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __ardour_io_vector_h__
#define __ardour_io_vector_h__
#include <vector>
#include <boost/shared_ptr.hpp>
#include "ardour/io.h"
namespace ARDOUR {
class IOVector : public std::vector<boost::weak_ptr<ARDOUR::IO> >
{
public:
bool connected_to (const IOVector& other) const {
for (IOVector::const_iterator i = other.begin(); i != other.end(); ++i) {
boost::shared_ptr<const IO> io = i->lock();
if (!io) continue;
if (connected_to (io)) {
return true;
}
}
return false;
}
bool connected_to (boost::shared_ptr<const IO> other) const {
for (IOVector::const_iterator i = begin(); i != end(); ++i) {
boost::shared_ptr<const IO> io = i->lock();
if (!io) continue;
if (io->connected_to (other)) {
return true;
}
}
return false;
}
bool fed_by (boost::shared_ptr<const IO> other) const {
for (IOVector::const_iterator i = begin(); i != end(); ++i) {
boost::shared_ptr<const IO> io = i->lock();
if (!io) continue;
if (other->connected_to (io)) {
return true;
}
}
return false;
}
};
} // namespace ARDOUR
#endif

View File

@ -44,6 +44,7 @@
#include "ardour/gain_control.h"
#include "ardour/instrument_info.h"
#include "ardour/io.h"
#include "ardour/io_vector.h"
#include "ardour/libardour_visibility.h"
#include "ardour/types.h"
#include "ardour/mute_master.h"
@ -89,6 +90,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
boost::shared_ptr<IO> input() const { return _input; }
boost::shared_ptr<IO> output() const { return _output; }
IOVector all_inputs () const;
ChanCount n_inputs() const { return _input->n_ports(); }
ChanCount n_outputs() const { return _output->n_ports(); }

View File

@ -3601,12 +3601,43 @@ Route::feeds (boost::shared_ptr<Route> other, bool* via_sends_only)
return false;
}
IOVector
Route::all_inputs () const
{
/* TODO, if this works as expected,
* cache the IOVector and maintain it via
* input_change_handler(), sidechain_change_handler() etc
*/
IOVector ios;
ios.push_back (_input);
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::const_iterator r = _processors.begin(); r != _processors.end(); ++r) {
boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor>(*r);
boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert>(*r);
if (pi != 0) {
assert (iop == 0);
iop = pi->sidechain();
}
if (iop != 0 && iop->input()) {
ios.push_back (iop->input());
}
}
return ios;
}
bool
Route::direct_feeds_according_to_reality (boost::shared_ptr<Route> other, bool* via_send_only)
{
DEBUG_TRACE (DEBUG::Graph, string_compose ("Feeds? %1\n", _name));
if (_output->connected_to (other->input())) {
#if 0
if (_output->connected_to (other->input()))
#else
if (other->all_inputs().fed_by (_output))
#endif
{
DEBUG_TRACE (DEBUG::Graph, string_compose ("\tdirect FEEDS %2\n", other->name()));
if (via_send_only) {
*via_send_only = false;
@ -3616,6 +3647,7 @@ Route::direct_feeds_according_to_reality (boost::shared_ptr<Route> other, bool*
}
Glib::Threads::RWLock::ReaderLock lm (_processor_lock); // XXX
for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) {
boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor>(*r);
@ -3626,7 +3658,13 @@ Route::direct_feeds_according_to_reality (boost::shared_ptr<Route> other, bool*
}
if (iop != 0) {
if (iop->feeds (other)) {
#if 0
if (iop->feeds (other))
#else
boost::shared_ptr<const IO> iop_out = iop->output();
if (iop_out && other->all_inputs().fed_by (iop_out))
#endif
{
DEBUG_TRACE (DEBUG::Graph, string_compose ("\tIOP %1 does feed %2\n", iop->name(), other->name()));
if (via_send_only) {
*via_send_only = true;