prepare strict-i/o configuration.

This commit is contained in:
Robin Gareus 2016-03-25 20:00:48 +01:00
parent 79d63d8701
commit edaeaf57ba
4 changed files with 105 additions and 4 deletions

View File

@ -143,6 +143,14 @@ class LIBARDOUR_API PluginInsert : public Processor
void collect_signal_for_analysis (framecnt_t nframes);
void set_strict_io (bool b) {
_strict_io = b;
}
bool strict_io_configured () const {
return _strict_io_configured;
}
bool splitting () const {
return _match.method == Split;
}
@ -191,6 +199,9 @@ class LIBARDOUR_API PluginInsert : public Processor
ChanCount _configured_in;
ChanCount _configured_out;
bool _strict_io;
bool _strict_io_configured;
/** Description of how we can match our plugin's IO to our own insert IO */
struct Match {
Match () : method (Impossible), plugins (0) {}

View File

@ -274,6 +274,9 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
void clear_processors (Placement);
void all_visible_processors_active (bool);
bool strict_io () const { return _strict_io; }
bool set_strict_io (bool);
framecnt_t set_private_port_latencies (bool playback) const;
void set_public_port_latencies (framecnt_t, bool playback) const;
@ -833,6 +836,8 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
friend class ProcessorState;
bool _strict_io;
/* no copy construction */
Route (Route const &);

View File

@ -68,6 +68,8 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
: Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
, _signal_analysis_collected_nframes(0)
, _signal_analysis_collect_nframes_max(0)
, _strict_io (false)
, _strict_io_configured (false)
{
/* the first is the master */
@ -138,7 +140,10 @@ PluginInsert::output_streams() const
PluginInfoPtr info = _plugins.front()->get_info();
if (info->reconfigurable_io()) {
if (_strict_io_configured) {
return _configured_in; // XXX, check initial configuration
}
else if (info->reconfigurable_io()) {
ChanCount out = _plugins.front()->output_streams ();
// DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
return out;
@ -807,6 +812,7 @@ PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
PluginInsert::Match
PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
{
_strict_io_configured = false;
if (_plugins.empty()) {
return Match();
}
@ -822,6 +828,11 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
return Match (Impossible, 0);
}
if (_strict_io && in.n_audio() < out.n_audio()) {
DEBUG_TRACE (DEBUG::Processors, string_compose ("hiding output ports of reconfigurable %1\n", name()));
out.set (DataType::AUDIO, in.get (DataType::AUDIO));
}
return Match (Delegate, 1);
}
@ -852,7 +863,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
}
/* Plugin inputs match requested inputs exactly */
if (inputs == in) {
if (inputs == in && (!_strict_io || outputs.n_audio() == inputs.n_audio())) {
out = outputs + midi_bypass;
return Match (ExactMatch, 1);
}
@ -907,7 +918,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
plugin inputs? Let me count the ways ...
*/
bool can_split = true;
bool can_split = !_strict_io;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
@ -943,7 +954,12 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
}
if (could_hide && !cannot_hide) {
out = outputs + midi_bypass;
if (_strict_io && inputs.get (DataType::AUDIO) == outputs.get (DataType::AUDIO)) {
_strict_io_configured = true;
outputs = inputs;
} else {
out = outputs + midi_bypass;
}
return Match (Hide, 1, hide_channels);
}

View File

@ -115,6 +115,7 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _track_number (0)
, _in_configure_processors (false)
, _initial_io_setup (false)
, _strict_io (false)
, _custom_meter_position_noted (false)
{
processor_max_streams.reset();
@ -1257,6 +1258,13 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
return 1;
}
if (_strict_io) {
boost::shared_ptr<PluginInsert> pi;
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) {
pi->set_strict_io (true);
}
}
{
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
@ -1456,6 +1464,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
pi->set_count (1);
pi->set_strict_io (_strict_io);
}
_processors.insert (loc, *i);
@ -1839,6 +1848,11 @@ Route::replace_processor (boost::shared_ptr<Processor> old, boost::shared_ptr<Pr
return 1;
}
/* ensure that sub is not owned by another route */
if (sub->owner ()) {
return 1;
}
{
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
Glib::Threads::RWLock::WriterLock lm (_processor_lock);
@ -1866,6 +1880,13 @@ Route::replace_processor (boost::shared_ptr<Processor> old, boost::shared_ptr<Pr
return 1;
}
if (_strict_io) {
boost::shared_ptr<PluginInsert> pi;
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(sub)) != 0) {
pi->set_strict_io (true);
}
}
if (configure_processors_unlocked (err)) {
pstate.restore ();
configure_processors_unlocked (0);
@ -2376,6 +2397,44 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
return 0;
}
bool
Route::set_strict_io (const bool enable)
{
if (_strict_io != enable) {
_strict_io = enable;
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
boost::shared_ptr<PluginInsert> pi;
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*p)) != 0) {
pi->set_strict_io (_strict_io);
}
}
list<pair<ChanCount, ChanCount> > c = try_configure_processors_unlocked (n_inputs (), 0);
if (c.empty()) {
// not possible
_strict_io = !enable; // restore old value
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p) {
boost::shared_ptr<PluginInsert> pi;
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*p)) != 0) {
pi->set_strict_io (_strict_io);
}
}
return false;
}
lm.release ();
{
Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
configure_processors (0);
}
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
_session.set_dirty ();
}
return true;
}
XMLNode&
Route::get_state()
{
@ -2404,6 +2463,7 @@ Route::state(bool full_state)
node->add_property("id", buf);
node->add_property ("name", _name);
node->add_property("default-type", _default_type.to_string());
node->add_property ("strict-io", _strict_io);
if (_flags) {
node->add_property("flags", enum_2_string (_flags));
@ -2527,6 +2587,10 @@ Route::set_state (const XMLNode& node, int version)
_flags = Flag (0);
}
if ((prop = node.property (X_("strict-io"))) != 0) {
_strict_io = string_is_affirmative (prop->value());
}
if (is_master() || is_monitor() || is_auditioner()) {
_mute_master->set_solo_ignore (true);
}
@ -3078,6 +3142,11 @@ Route::set_processor_state (const XMLNode& node)
processor.reset (new UnknownProcessor (_session, **niter));
} else {
processor.reset (new PluginInsert (_session));
if (_strict_io) {
boost::shared_ptr<PluginInsert> pi = boost::dynamic_pointer_cast<PluginInsert>(processor);
pi->set_strict_io (true);
}
}
} else if (prop->value() == "port") {