Retain sidechain ports into unknown processors

This fixes an issue when loading sessions in "safe mode".
Internal side-chain sends are removed if the target port
does not exist. Also other port connections are lost if the
target port does not exist.
This commit is contained in:
Robin Gareus 2022-03-06 17:12:23 +01:00
parent e51e2c57c6
commit fbce2d73a8
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 70 additions and 10 deletions

View File

@ -1,7 +1,7 @@
/*
* Copyright (C) 2010 Carl Hetherington <carl@carlh.net>
* Copyright (C) 2013-2017 Paul Davis <paul@linuxaudiosystems.com>
* Copyright (C) 2013-2017 Robin Gareus <robin@gareus.org>
* Copyright (C) 2013-2022 Robin Gareus <robin@gareus.org>
*
* 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
@ -21,9 +21,11 @@
#ifndef __ardour_unknown_processor_h__
#define __ardour_unknown_processor_h__
#include "ardour/libardour_visibility.h"
#include "ardour/processor.h"
namespace ARDOUR {
class SideChain;
/** A stub Processor that can be used in place of a `real' one that cannot be
* created for some reason; usually because it requires a plugin which is not
@ -43,7 +45,7 @@ namespace ARDOUR {
class LIBARDOUR_API UnknownProcessor : public Processor
{
public:
UnknownProcessor (Session &, XMLNode const &);
UnknownProcessor (Session&, XMLNode const&, SessionObject*);
virtual ~UnknownProcessor ();
bool can_support_io_configuration (const ChanCount &, ChanCount &);
@ -54,9 +56,13 @@ protected:
private:
XMLNode _state;
bool have_ioconfig;
ChanCount *saved_input;
ChanCount *saved_output;
bool have_ioconfig;
ChanCount* saved_input;
ChanCount* saved_output;
void add_sidechain_from_xml (const XMLNode& node, int version);
boost::shared_ptr<SideChain> _sidechain;
};
}

View File

@ -946,7 +946,7 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
prop->value() == "audiounit") {
if (_session.get_disable_all_loaded_plugins ()) {
processor.reset (new UnknownProcessor (_session, node));
processor.reset (new UnknownProcessor (_session, node, this));
} else {
processor.reset (new PluginInsert (_session, time_domain()));
processor->set_owner (this);
@ -3262,7 +3262,7 @@ Route::set_processor_state (XMLNode const& node, int version, XMLProperty const*
prop->value() == "audiounit") {
if (_session.get_disable_all_loaded_plugins ()) {
processor.reset (new UnknownProcessor (_session, node));
processor.reset (new UnknownProcessor (_session, node, this));
} else {
processor.reset (new PluginInsert (_session, time_domain()));
processor->set_owner (this);
@ -3287,7 +3287,7 @@ Route::set_processor_state (XMLNode const& node, int version, XMLProperty const*
if (processor->set_state (node, version) != 0) {
/* This processor could not be configured. Turn it into a UnknownProcessor */
processor.reset (new UnknownProcessor (_session, node));
processor.reset (new UnknownProcessor (_session, node, this));
}
/* set strict I/O only after loading plugin state, because

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2010-2011 Carl Hetherington <carl@carlh.net>
* Copyright (C) 2013-2017 Robin Gareus <robin@gareus.org>
* Copyright (C) 2013-2022 Robin Gareus <robin@gareus.org>
* Copyright (C) 2016-2017 Paul Davis <paul@linuxaudiosystems.com>
*
* This program is free software; you can redistribute it and/or modify
@ -18,7 +18,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "pbd/types_convert.h"
#include "pbd/xml++.h"
#include "ardour/audio_buffer.h"
#include "ardour/sidechain.h"
#include "ardour/io.h"
#include "ardour/types_convert.h"
#include "ardour/unknown_processor.h"
#include "pbd/i18n.h"
@ -51,13 +57,15 @@ proc_type_map (std::string const& str)
}
}
UnknownProcessor::UnknownProcessor (Session& s, XMLNode const & state)
UnknownProcessor::UnknownProcessor (Session&s, XMLNode const &state, SessionObject* o)
: Processor (s, "", Temporal::AudioTime)
, _state (state)
, have_ioconfig (false)
, saved_input (0)
, saved_output (0)
{
set_owner (o);
XMLProperty const* pname = state.property (X_("name"));
if (pname) {
XMLProperty const* ptype = state.property (X_("type"));
@ -80,6 +88,13 @@ UnknownProcessor::UnknownProcessor (Session& s, XMLNode const & state)
have_io |= 2;
saved_output = new ChanCount(**i);
}
/* sidechain is a Processor (IO)
* add a SC port to retain connections
*/
if ((*i)->name () == Processor::state_node_name) {
add_sidechain_from_xml (**i, Stateful::loading_state_version);
}
}
have_ioconfig = (have_io == 3);
}
@ -152,3 +167,42 @@ UnknownProcessor::run (BufferSet& bufs, samplepos_t /*start_sample*/, samplepos_
bufs.get_audio (i).silence (nframes);
}
}
void
UnknownProcessor::add_sidechain_from_xml (const XMLNode& node, int version)
{
if (version < 3000) {
return;
}
XMLNodeList nlist = node.children();
if (nlist.size() == 0) {
return;
}
uint32_t n_audio = 0;
uint32_t n_midi = 0;
XMLNodeConstIterator it = nlist.front()->children().begin();
for ( ; it != nlist.front()->children().end(); ++ it) {
if ((*it)->name() == "Port") {
DataType type (DataType::NIL);
(*it)->get_property ("type", type);
if (type == DataType::AUDIO) {
++n_audio;
} else if (type == DataType::MIDI) {
++n_midi;
}
}
}
_sidechain.reset (new SideChain (_session, "toBeRenamed"));
for (uint32_t n = 0; n < n_audio; ++n) {
_sidechain->input()->add_port ("", owner(), DataType::AUDIO); // add a port, don't connect.
}
for (uint32_t n = 0; n < n_midi; ++n) {
_sidechain->input()->add_port ("", owner(), DataType::MIDI); // add a port, don't connect.
}
_sidechain->set_state (node, version);
}