prepare strict-i/o configuration.
This commit is contained in:
parent
79d63d8701
commit
edaeaf57ba
|
@ -143,6 +143,14 @@ class LIBARDOUR_API PluginInsert : public Processor
|
||||||
|
|
||||||
void collect_signal_for_analysis (framecnt_t nframes);
|
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 {
|
bool splitting () const {
|
||||||
return _match.method == Split;
|
return _match.method == Split;
|
||||||
}
|
}
|
||||||
|
@ -191,6 +199,9 @@ class LIBARDOUR_API PluginInsert : public Processor
|
||||||
ChanCount _configured_in;
|
ChanCount _configured_in;
|
||||||
ChanCount _configured_out;
|
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 */
|
/** Description of how we can match our plugin's IO to our own insert IO */
|
||||||
struct Match {
|
struct Match {
|
||||||
Match () : method (Impossible), plugins (0) {}
|
Match () : method (Impossible), plugins (0) {}
|
||||||
|
|
|
@ -274,6 +274,9 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
|
||||||
void clear_processors (Placement);
|
void clear_processors (Placement);
|
||||||
void all_visible_processors_active (bool);
|
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;
|
framecnt_t set_private_port_latencies (bool playback) const;
|
||||||
void set_public_port_latencies (framecnt_t, 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;
|
friend class ProcessorState;
|
||||||
|
|
||||||
|
bool _strict_io;
|
||||||
|
|
||||||
/* no copy construction */
|
/* no copy construction */
|
||||||
Route (Route const &);
|
Route (Route const &);
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,8 @@ 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)
|
||||||
|
, _strict_io (false)
|
||||||
|
, _strict_io_configured (false)
|
||||||
{
|
{
|
||||||
/* the first is the master */
|
/* the first is the master */
|
||||||
|
|
||||||
|
@ -138,7 +140,10 @@ PluginInsert::output_streams() const
|
||||||
|
|
||||||
PluginInfoPtr info = _plugins.front()->get_info();
|
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 ();
|
ChanCount out = _plugins.front()->output_streams ();
|
||||||
// DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
|
// DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
|
||||||
return out;
|
return out;
|
||||||
|
@ -807,6 +812,7 @@ PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
||||||
PluginInsert::Match
|
PluginInsert::Match
|
||||||
PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
|
PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
|
||||||
{
|
{
|
||||||
|
_strict_io_configured = false;
|
||||||
if (_plugins.empty()) {
|
if (_plugins.empty()) {
|
||||||
return Match();
|
return Match();
|
||||||
}
|
}
|
||||||
|
@ -822,6 +828,11 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
|
||||||
return Match (Impossible, 0);
|
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);
|
return Match (Delegate, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,7 +863,7 @@ PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanC
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Plugin inputs match requested inputs exactly */
|
/* Plugin inputs match requested inputs exactly */
|
||||||
if (inputs == in) {
|
if (inputs == in && (!_strict_io || outputs.n_audio() == inputs.n_audio())) {
|
||||||
out = outputs + midi_bypass;
|
out = outputs + midi_bypass;
|
||||||
return Match (ExactMatch, 1);
|
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 ...
|
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) {
|
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 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) {
|
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);
|
return Match (Hide, 1, hide_channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
|
||||||
, _track_number (0)
|
, _track_number (0)
|
||||||
, _in_configure_processors (false)
|
, _in_configure_processors (false)
|
||||||
, _initial_io_setup (false)
|
, _initial_io_setup (false)
|
||||||
|
, _strict_io (false)
|
||||||
, _custom_meter_position_noted (false)
|
, _custom_meter_position_noted (false)
|
||||||
{
|
{
|
||||||
processor_max_streams.reset();
|
processor_max_streams.reset();
|
||||||
|
@ -1257,6 +1258,13 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
|
||||||
return 1;
|
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::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
|
||||||
Glib::Threads::RWLock::WriterLock lm (_processor_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) {
|
if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
|
||||||
pi->set_count (1);
|
pi->set_count (1);
|
||||||
|
pi->set_strict_io (_strict_io);
|
||||||
}
|
}
|
||||||
|
|
||||||
_processors.insert (loc, *i);
|
_processors.insert (loc, *i);
|
||||||
|
@ -1839,6 +1848,11 @@ Route::replace_processor (boost::shared_ptr<Processor> old, boost::shared_ptr<Pr
|
||||||
return 1;
|
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::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
|
||||||
Glib::Threads::RWLock::WriterLock lm (_processor_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;
|
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)) {
|
if (configure_processors_unlocked (err)) {
|
||||||
pstate.restore ();
|
pstate.restore ();
|
||||||
configure_processors_unlocked (0);
|
configure_processors_unlocked (0);
|
||||||
|
@ -2376,6 +2397,44 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
|
||||||
return 0;
|
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&
|
XMLNode&
|
||||||
Route::get_state()
|
Route::get_state()
|
||||||
{
|
{
|
||||||
|
@ -2404,6 +2463,7 @@ Route::state(bool full_state)
|
||||||
node->add_property("id", buf);
|
node->add_property("id", buf);
|
||||||
node->add_property ("name", _name);
|
node->add_property ("name", _name);
|
||||||
node->add_property("default-type", _default_type.to_string());
|
node->add_property("default-type", _default_type.to_string());
|
||||||
|
node->add_property ("strict-io", _strict_io);
|
||||||
|
|
||||||
if (_flags) {
|
if (_flags) {
|
||||||
node->add_property("flags", enum_2_string (_flags));
|
node->add_property("flags", enum_2_string (_flags));
|
||||||
|
@ -2527,6 +2587,10 @@ Route::set_state (const XMLNode& node, int version)
|
||||||
_flags = Flag (0);
|
_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()) {
|
if (is_master() || is_monitor() || is_auditioner()) {
|
||||||
_mute_master->set_solo_ignore (true);
|
_mute_master->set_solo_ignore (true);
|
||||||
}
|
}
|
||||||
|
@ -3078,6 +3142,11 @@ Route::set_processor_state (const XMLNode& node)
|
||||||
processor.reset (new UnknownProcessor (_session, **niter));
|
processor.reset (new UnknownProcessor (_session, **niter));
|
||||||
} else {
|
} else {
|
||||||
processor.reset (new PluginInsert (_session));
|
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") {
|
} else if (prop->value() == "port") {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user