#include "ardour/port.h"
#include "ardour/port_insert.h"
#include "ardour/processor.h"
+#include "ardour/profile.h"
#include "ardour/route.h"
#include "ardour/route_group.h"
#include "ardour/send.h"
, _initial_delay (0)
, _roll_delay (0)
, _pending_process_reorder (0)
+ , _pending_signals (0)
, _flags (flg)
, _pending_declick (true)
, _meter_point (MeterPostFader)
, _self_solo (false)
, _soloed_by_others_upstream (0)
, _soloed_by_others_downstream (0)
- , _solo_isolated (0)
+ , _solo_isolated (false)
+ , _solo_isolated_by_upstream (0)
, _denormal_protection (false)
, _recordable (true)
, _silent (false)
, _initial_io_setup (false)
, _custom_meter_position_noted (false)
{
- if (is_master()) {
- _meter_type = MeterK20;
- }
processor_max_streams.reset();
}
int
Route::init ()
{
+ /* set default meter type */
+ if (is_master()) {
+ _meter_type = Config->get_meter_type_master ();
+ }
+ else if (dynamic_cast<Track*>(this)) {
+ _meter_type = Config->get_meter_type_track ();
+ } else {
+ _meter_type = Config->get_meter_type_bus ();
+ }
+
/* add standard controls */
_solo_control.reset (new SoloControllable (X_("solo"), shared_from_this ()));
/* Tell main outs what to do about monitoring. We do this so that
on a transition between monitoring states we get a de-clicking gain
- change in the _main_outs delivery.
+ change in the _main_outs delivery, if config.get_use_monitor_fades()
+ is true.
+
+ We override this in the case where we have an internal generator.
*/
- bool silence = monitoring_state () == MonitoringSilence;
-
- //but we override this in the case where we have an internal generator
- if ( _have_internal_generator )
- silence = false;
-
+ bool silence = _have_internal_generator ? false : (monitoring_state () == MonitoringSilence);
+
_main_outs->no_outs_cuz_we_no_monitor (silence);
/* -------------------------------------------------------------------------------------------
solo_changed (true, src); /* EMIT SIGNAL */
_solo_control->Changed (); /* EMIT SIGNAL */
}
+
+ /* XXX TRACKS DEVELOPERS: THIS LOGIC SUGGESTS THAT YOU ARE NOT AWARE OF
+ Config->get_solo_mute_overrride().
+ */
+
+ if (yn && Profile->get_trx()) {
+ set_mute (false, src);
+ }
}
void
_mute_master->set_soloed (self_soloed() || soloed_by_others_downstream() || soloed_by_others_upstream());
}
+void
+Route::mod_solo_isolated_by_upstream (bool yn, void* src)
+{
+ bool old = solo_isolated ();
+
+ if (!yn) {
+ if (_solo_isolated_by_upstream >= 1) {
+ _solo_isolated_by_upstream--;
+ } else {
+ _solo_isolated_by_upstream = 0;
+ }
+ } else {
+ _solo_isolated_by_upstream++;
+ }
+
+ if (solo_isolated() != old) {
+ /* solo isolated status changed */
+ _mute_master->set_solo_ignore (yn);
+ solo_isolated_changed (src);
+ }
+}
+
void
Route::set_solo_isolated (bool yn, void *src)
{
return;
}
+ bool changed = false;
+
+ if (yn) {
+ if (_solo_isolated == false) {
+ _mute_master->set_solo_ignore (true);
+ changed = true;
+ }
+ _solo_isolated = true;
+ } else {
+ if (_solo_isolated == true) {
+ _solo_isolated = false;
+ _mute_master->set_solo_ignore (false);
+ changed = true;
+ }
+ }
+
+
+ if (!changed) {
+ return;
+ }
+
/* forward propagate solo-isolate status to everything fed by this route, but not those via sends only */
boost::shared_ptr<RouteList> routes = _session.get_routes ();
for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
-
+
if ((*i).get() == this || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
continue;
}
-
+
bool sends_only;
- bool does_feed = direct_feeds_according_to_graph (*i, &sends_only); // we will recurse anyway, so don't use ::feeds()
-
+ bool does_feed = feeds (*i, &sends_only);
+
if (does_feed && !sends_only) {
- (*i)->set_solo_isolated (yn, (*i)->route_group());
+ (*i)->mod_solo_isolated_by_upstream (yn, src);
}
}
-
+
/* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */
- bool changed = false;
-
- if (yn) {
- if (_solo_isolated == 0) {
- _mute_master->set_solo_ignore (true);
- changed = true;
- }
- _solo_isolated++;
- } else {
- if (_solo_isolated > 0) {
- _solo_isolated--;
- if (_solo_isolated == 0) {
- _mute_master->set_solo_ignore (false);
- changed = true;
- }
- }
- }
-
- if (changed) {
- solo_isolated_changed (src);
- }
+ solo_isolated_changed (src);
}
bool
Route::solo_isolated () const
{
- return _solo_isolated > 0;
+ return (_solo_isolated == true) || (_solo_isolated_by_upstream > 0);
}
void
return _mute_master->muted_by_self();
}
+bool
+Route::muted_by_others () const
+{
+ //master is never muted by others
+ if (is_master())
+ return false;
+
+ //now check to see if something is soloed (and I am not)
+ return (_session.soloing() && !self_soloed() && !solo_isolated());
+}
+
#if 0
static void
dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& procs)
}
- if (activation_allowed && !_session.get_disable_all_loaded_plugins()) {
+ if (activation_allowed && (!_session.get_bypass_all_loaded_plugins () || !processor->display_to_user ())) {
processor->activate ();
}
prop->value() == "lxvst" ||
prop->value() == "audiounit") {
- processor.reset (new PluginInsert (_session));
+ if (_session.get_disable_all_loaded_plugins ()) {
+ processor.reset (new UnknownProcessor (_session, node));
+ } else {
+ processor.reset (new PluginInsert (_session));
+ }
} else {
//A2 uses the "active" flag in the toplevel redirect node, not in the child plugin/IO
if (i != children.end()) {
if ((prop = (*i)->property (X_("active"))) != 0) {
- if ( string_is_affirmative (prop->value()) && !_session.get_disable_all_loaded_plugins() )
+ if ( string_is_affirmative (prop->value()) && (!_session.get_bypass_all_loaded_plugins () || !processor->display_to_user () ) )
processor->activate();
else
processor->deactivate();
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
- if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
- DEBUG_TRACE (DEBUG::Processors, "--- CONFIGURE ABORTED due to unknown processor.\n");
- DEBUG_TRACE (DEBUG::Processors, "}\n");
- return list<pair<ChanCount, ChanCount> > ();
- }
-
if ((*p)->can_support_io_configuration(in, out)) {
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1 ID=%2 in=%3 out=%4\n",(*p)->name(), (*p)->id(), in, out));
configuration.push_back(make_pair(in, out));
list< pair<ChanCount,ChanCount> >::iterator c = configuration.begin();
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++c) {
- if (boost::dynamic_pointer_cast<UnknownProcessor> (*p)) {
- break;
+ if (!(*p)->configure_io(c->first, c->second)) {
+ DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: configuration failed\n", _name));
}
-
- (*p)->configure_io(c->first, c->second);
processor_max_streams = ChanCount::max(processor_max_streams, c->first);
processor_max_streams = ChanCount::max(processor_max_streams, c->second);
prop->value() == "lxvst" ||
prop->value() == "audiounit") {
- processor.reset (new PluginInsert(_session));
-
+ if (_session.get_disable_all_loaded_plugins ()) {
+ processor.reset (new UnknownProcessor (_session, **niter));
+ } else {
+ processor.reset (new PluginInsert (_session));
+ }
} else if (prop->value() == "port") {
processor.reset (new PortInsert (_session, _pannable, _mute_master));
if (d && d->target_route() == route) {
rl.release ();
- remove_processor (*x, &err, false);
+ if (remove_processor (*x, &err, false) > 0) {
+ rl.acquire ();
+ continue;
+ }
rl.acquire ();
/* list could have been demolished while we dropped the lock
so start over.
*/
-
- goto again;
+ if (_session.engine().connected()) {
+ /* i/o processors cannot be removed if the engine is not running
+ * so don't live-loop in case the engine is N/A or dies
+ */
+ goto again;
+ }
}
}
}
bool had_amp = false;
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
(*i)->set_pre_fader (!had_amp);
- if (boost::dynamic_pointer_cast<Amp> (*i)) {
+ if (*i == _amp) {
had_amp = true;
}
}
{
list<string> p;
+ if (_session.get_disable_all_loaded_plugins ()) {
+ // Do not list "missing plugins" if they are explicitly disabled
+ return p;
+ }
+
Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
if (boost::dynamic_pointer_cast<UnknownProcessor const> (*i)) {
/* find the amp */
ProcessorList::iterator amp = new_processors.begin ();
- while (amp != new_processors.end() && boost::dynamic_pointer_cast<Amp> (*amp) == 0) {
+ while (amp != new_processors.end() && *amp != _amp) {
++amp;
}
_processors = new_processors;
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ if (!(*i)->display_to_user () && !(*i)->active ()) {
+ (*i)->activate ();
+ }
+ }
+
DEBUG_TRACE (DEBUG::Processors, string_compose ("%1: setup_invisible_processors\n", _name));
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
DEBUG_TRACE (DEBUG::Processors, string_compose ("\t%1\n", (*i)->name ()));