summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-05-01 15:09:19 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-05-01 15:09:19 +0000
commit576cdb08b5eab456eea91263fac1709dd7931a9d (patch)
tree393d7d17bfb283f37a5158d9c1db35af5944874d
parente99cf351f58d4c1d848f8138e5dd295b34ffcf0e (diff)
perhaps, just possibly, a working solo model. needs to be fixed so that connections to other JACK clients count as "physical" connections, so don't use this with ardour connected to other JACK apps just yet. Oh, this also invalidates existing a3 sessions again
git-svn-id: svn://localhost/ardour2/branches/3.0@7033 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/route_ui.cc2
-rw-r--r--libs/ardour/ardour/io.h3
-rw-r--r--libs/ardour/ardour/mute_master.h8
-rw-r--r--libs/ardour/ardour/port.h4
-rw-r--r--libs/ardour/ardour/route.h24
-rw-r--r--libs/ardour/ardour/session.h1
-rw-r--r--libs/ardour/ardour/types.h7
-rw-r--r--libs/ardour/delivery.cc1
-rw-r--r--libs/ardour/io.cc12
-rw-r--r--libs/ardour/mute_master.cc27
-rw-r--r--libs/ardour/port.cc26
-rw-r--r--libs/ardour/route.cc100
-rw-r--r--libs/ardour/session.cc111
13 files changed, 273 insertions, 53 deletions
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 010f0714b9..e6c8fbf574 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -838,7 +838,7 @@ RouteUI::mute_visual_state (Session* s, boost::shared_ptr<Route> r)
if (r->self_muted ()) {
/* full mute */
return 2;
- } else if (r->muted_by_others()) {
+ } else if (r->muted_by_others() || r->path_muted_by_others()) {
return 1;
} else {
/* no mute at all */
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index a7ba3a23a9..72815c17cc 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -108,7 +108,8 @@ class IO : public SessionObject, public Latent
int disconnect (void *src);
bool connected_to (boost::shared_ptr<const IO>) const;
bool connected () const;
-
+ bool physically_connected () const;
+
nframes_t signal_latency() const { return _own_latency; }
nframes_t latency() const;
void set_port_latency (nframes_t);
diff --git a/libs/ardour/ardour/mute_master.h b/libs/ardour/ardour/mute_master.h
index 4ddb7075da..a0207f9817 100644
--- a/libs/ardour/ardour/mute_master.h
+++ b/libs/ardour/ardour/mute_master.h
@@ -25,11 +25,13 @@
#include "pbd/stateful.h"
#include <string>
+#include "ardour/session_handle.h"
+
namespace ARDOUR {
class Session;
-class MuteMaster : public PBD::Stateful
+class MuteMaster : public SessionHandleRef, public PBD::Stateful
{
public:
enum MutePoint {
@@ -69,7 +71,7 @@ class MuteMaster : public PBD::Stateful
void set_mute_points (MutePoint);
MutePoint mute_points() const { return _mute_point; }
- void set_solo_level (int32_t);
+ void set_solo_level (SoloLevel);
PBD::Signal0<void> MutePointChanged;
@@ -80,7 +82,7 @@ class MuteMaster : public PBD::Stateful
volatile MutePoint _mute_point;
volatile bool _self_muted;
volatile uint32_t _muted_by_others;
- volatile int32_t _solo_level;
+ volatile SoloLevel _solo_level;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h
index ce4b88f8f2..cc37bf0821 100644
--- a/libs/ardour/ardour/port.h
+++ b/libs/ardour/ardour/port.h
@@ -116,6 +116,8 @@ public:
}
virtual void transport_stopped () {}
+ bool physically_connected () const;
+
static void set_engine (AudioEngine *);
PBD::Signal1<void,bool> MonitorInputChanged;
@@ -128,7 +130,7 @@ protected:
static nframes_t _port_offset;
static nframes_t _buffer_size;
-
+
static AudioEngine* _engine; ///< the AudioEngine
private:
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 5efb9c111b..b4a392c23b 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -129,6 +129,9 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
bool self_muted () const;
bool muted_by_others () const;
+ bool path_muted_by_others() const { return _path_muted_by_others > 0; }
+ void mod_path_muted_by_others (int delta);
+
void set_mute (bool yn, void* src);
void mod_muted_by_others (int delta);
@@ -138,7 +141,9 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
void set_solo (bool yn, void *src);
bool soloed () const { return self_soloed () || soloed_by_others (); }
- bool soloed_by_others () const { return !_solo_isolated && _soloed_by_others; }
+ bool soloed_by_others () const { return _soloed_by_others_upstream||_soloed_by_others_downstream; }
+ bool soloed_by_others_upstream () const { return _soloed_by_others_upstream; }
+ bool soloed_by_others_downstream () const { return _soloed_by_others_downstream; }
bool self_soloed () const { return _self_solo; }
void set_solo_isolated (bool yn, void *src);
@@ -372,8 +377,15 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
protected:
friend class Session;
+ void set_graph_level (int32_t);
+ int32_t graph_level() const { return _graph_level; }
+ void check_physical_connections ();
+ // this functions may ONLY be called during a route resort
+ bool physically_connected () const { return _physically_connected; }
+
void catch_up_on_solo_mute_override ();
- void mod_solo_by_others (int32_t);
+ void mod_solo_by_others_upstream (int32_t);
+ void mod_solo_by_others_downstream (int32_t);
bool has_external_redirects() const;
void curve_reallocate ();
void just_meter_input (sframes_t start_frame, sframes_t end_frame, nframes_t nframes);
@@ -411,7 +423,8 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
MeterPoint _meter_point;
uint32_t _phase_invert;
bool _self_solo;
- uint32_t _soloed_by_others;
+ uint32_t _soloed_by_others_upstream;
+ uint32_t _soloed_by_others_downstream;
uint32_t _solo_isolated;
bool _denormal_protection;
@@ -424,9 +437,12 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
boost::shared_ptr<MuteControllable> _mute_control;
boost::shared_ptr<MuteMaster> _mute_master;
MuteMaster::MutePoint _mute_points;
-
+ volatile uint32_t _path_muted_by_others;
+
std::string _comment;
bool _have_internal_generator;
+ bool _physically_connected; // valid ONLY during a route resort
+ int32_t _graph_level;
bool _solo_safe;
DataType _default_type;
FedBy _fed_by;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 014b49b318..b399745187 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -415,6 +415,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void remove_route (boost::shared_ptr<Route>);
void resort_routes ();
void resort_routes_using (boost::shared_ptr<RouteList>);
+ void find_route_levels (boost::shared_ptr<RouteList>);
void set_remote_control_ids();
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 25a6ea4c98..2bd08cbcdf 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -306,6 +306,13 @@ namespace ARDOUR {
PreFaderListen
};
+ enum SoloLevel {
+ NotSoloed,
+ DownstreamSoloed,
+ UpstreamSoloed,
+ SelfSoloed
+ };
+
enum AutoConnectOption {
ManualConnect = 0x0,
AutoConnectPhysical = 0x1,
diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc
index e2928c1f5b..5861e5ea2c 100644
--- a/libs/ardour/delivery.cc
+++ b/libs/ardour/delivery.cc
@@ -500,6 +500,7 @@ Delivery::target_gain ()
break;
}
+ // cerr << name() << ' ';
desired_gain = _mute_master->mute_gain_at (mp);
if (_role == Listen && _session.monitor_out() && !_session.listening()) {
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index a41003cf89..8b52bfaea5 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -1553,3 +1553,15 @@ IO::port_by_name (const std::string& str) const
return 0;
}
+
+bool
+IO::physically_connected () const
+{
+ for (PortSet::const_iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ if (i->physically_connected()) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/libs/ardour/mute_master.cc b/libs/ardour/mute_master.cc
index 0182e205d0..df9a66ef7f 100644
--- a/libs/ardour/mute_master.cc
+++ b/libs/ardour/mute_master.cc
@@ -23,7 +23,7 @@
#include "ardour/types.h"
#include "ardour/mute_master.h"
-#include "ardour/rc_configuration.h"
+#include "ardour/session.h"
#include "i18n.h"
@@ -35,8 +35,9 @@ const MuteMaster::MutePoint MuteMaster::AllPoints = MutePoint (MuteMaster::PreFa
MuteMaster::Listen|
MuteMaster::Main);
-MuteMaster::MuteMaster (Session&, const std::string&)
- : _mute_point (AllPoints)
+MuteMaster::MuteMaster (Session& s, const std::string&)
+ : SessionHandleRef (s)
+ , _mute_point (AllPoints)
, _self_muted (false)
, _muted_by_others (0)
{
@@ -83,7 +84,7 @@ MuteMaster::mod_muted_by_others (int32_t delta)
}
void
-MuteMaster::set_solo_level (int32_t l)
+MuteMaster::set_solo_level (SoloLevel l)
{
_solo_level = l;
}
@@ -92,14 +93,16 @@ gain_t
MuteMaster::mute_gain_at (MutePoint mp) const
{
gain_t gain;
- int32_t l = _solo_level;
+ const SoloLevel l = _solo_level;
+ // cerr << "solo level = " << _solo_level << " selfmuted " << self_muted_at (mp) << " omute " << muted_by_others_at (mp) << endl;
+
if (Config->get_solo_mute_override()) {
- if (l == 2) { // self-soloed
+ if ((l == SelfSoloed) || (l == DownstreamSoloed)) {
gain = 1.0;
} else if (self_muted_at (mp)) { // self-muted
gain = Config->get_solo_mute_gain ();
- } else if (l == 1) { // soloed by others
+ } else if (l == UpstreamSoloed) {
gain = 1.0;
} else if (muted_by_others_at (mp)) { // muted by others
gain = Config->get_solo_mute_gain ();
@@ -109,17 +112,19 @@ MuteMaster::mute_gain_at (MutePoint mp) const
} else {
if (self_muted_at (mp)) { // self-muted
gain = Config->get_solo_mute_gain ();
- } else if (l == 2) { // self-soloed
+ } else if ((l == SelfSoloed) || (l == DownstreamSoloed)) {
gain = 1.0;
} else if (muted_by_others_at (mp)) { // muted by others
gain = Config->get_solo_mute_gain ();
- } else if (l == 1) { // soloed by others
+ } else if (l == UpstreamSoloed) { // soloed by others
gain = 1.0;
} else {
gain = 1.0;
}
}
+ // cerr << "\tgain = " << gain << endl;
+
return gain;
}
@@ -130,7 +135,7 @@ MuteMaster::set_mute_points (const std::string& mute_point)
_mute_point = (MutePoint) string_2_enum (mute_point, _mute_point);
cerr << "Mute point set from string, now " << _mute_point << endl;
-
+
if (old != _mute_point) {
MutePointChanged(); /* EMIT SIGNAL */
}
@@ -152,7 +157,7 @@ MuteMaster::set_state (const XMLNode& node, int /*version*/)
const XMLProperty* prop;
if ((prop = node.property ("mute-point")) != 0) {
- //_mute_point = (MutePoint) string_2_enum (prop->value(), _mute_point);
+ _mute_point = (MutePoint) string_2_enum (prop->value(), _mute_point);
cerr << "Mute point set from STATE string, now " << _mute_point << endl;
}
diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc
index 5897015b27..9cbdd14172 100644
--- a/libs/ardour/port.cc
+++ b/libs/ardour/port.cc
@@ -99,7 +99,8 @@ Port::get_connections (std::vector<std::string> & c) const
c.push_back (jc[i]);
++n;
}
- free (jc);
+
+ jack_free (jc);
}
return n;
@@ -148,7 +149,7 @@ Port::disconnect (std::string const & other)
_connections.erase (other);
}
-return r;
+ return r;
}
@@ -290,3 +291,24 @@ Port::set_latency (nframes_t n)
jack_port_set_latency (_jack_port, n);
}
+bool
+Port::physically_connected () const
+{
+ const char** jc = jack_port_get_connections (_jack_port);
+
+ if (jc) {
+ for (int i = 0; jc[i]; ++i) {
+
+ jack_port_t* port = jack_port_by_name (_engine->jack(), jc[i]);
+
+ if (port && (jack_port_flags (port) & JackPortIsPhysical)) {
+ jack_free (jc);
+ return true;
+ }
+ }
+
+ jack_free (jc);
+ }
+
+ return false;
+}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 392ac7b0ca..ddb227c6bb 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -80,7 +80,8 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _meter_point (MeterPostFader)
, _phase_invert (0)
, _self_solo (false)
- , _soloed_by_others (0)
+ , _soloed_by_others_upstream (0)
+ , _soloed_by_others_downstream (0)
, _solo_isolated (0)
, _denormal_protection (false)
, _recordable (true)
@@ -90,7 +91,10 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
, _mute_control (new MuteControllable (X_("mute"), *this))
, _mute_master (new MuteMaster (sess, name))
, _mute_points (MuteMaster::AllPoints)
+ , _path_muted_by_others (false)
, _have_internal_generator (false)
+ , _physically_connected (false)
+ , _graph_level (-1)
, _solo_safe (false)
, _default_type (default_type)
, _remote_control_id (0)
@@ -447,6 +451,10 @@ Route::process_output_buffers (BufferSet& bufs,
Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK);
if (rm.locked()) {
+ //cerr << name() << " upstream solo " << _soloed_by_others_upstream
+ // << " downstream solo " << _soloed_by_others_downstream
+ // << " self " << _self_solo
+ //<< endl;
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if (bufs.count() != (*i)->input_streams()) {
@@ -589,20 +597,41 @@ Route::set_self_solo (bool yn)
}
void
-Route::mod_solo_by_others (int32_t delta)
+Route::mod_solo_by_others_upstream (int32_t delta)
{
if (_solo_safe) {
return;
}
if (delta < 0) {
- if (_soloed_by_others >= (uint32_t) abs (delta)) {
- _soloed_by_others += delta;
+ if (_soloed_by_others_upstream >= (uint32_t) abs (delta)) {
+ _soloed_by_others_upstream += delta;
} else {
- _soloed_by_others = 0;
+ _soloed_by_others_upstream = 0;
}
} else {
- _soloed_by_others += delta;
+ _soloed_by_others_upstream += delta;
+ }
+
+ set_mute_master_solo ();
+ solo_changed (false, this);
+}
+
+void
+Route::mod_solo_by_others_downstream (int32_t delta)
+{
+ if (_solo_safe) {
+ return;
+ }
+
+ if (delta < 0) {
+ if (_soloed_by_others_downstream >= (uint32_t) abs (delta)) {
+ _soloed_by_others_downstream += delta;
+ } else {
+ _soloed_by_others_downstream = 0;
+ }
+ } else {
+ _soloed_by_others_downstream += delta;
}
set_mute_master_solo ();
@@ -612,14 +641,16 @@ Route::mod_solo_by_others (int32_t delta)
void
Route::set_mute_master_solo ()
{
- int32_t level;
+ SoloLevel level;
if (self_soloed()) {
- level = 2;
- } else if (soloed_by_others()) {
- level = 1;
+ level = SelfSoloed;
+ } else if (soloed_by_others_upstream()) {
+ level = UpstreamSoloed;
+ } else if (soloed_by_others_downstream()) {
+ level = DownstreamSoloed;
} else {
- level = 0;
+ level = NotSoloed;
}
_mute_master->set_solo_level (level);
@@ -722,19 +753,31 @@ Route::muted_by_others() const
void
Route::mod_muted_by_others (int delta)
{
- bool old = muted ();
-
if (_solo_isolated) {
return;
}
+ bool old = muted ();
_mute_master->mod_muted_by_others (delta);
-
if (old != muted()) {
mute_changed (this);
}
}
+void
+Route::mod_path_muted_by_others (int32_t delta)
+{
+ if (delta < 0) {
+ if (_path_muted_by_others >= (uint32_t) abs (delta)) {
+ _path_muted_by_others += delta;
+ } else {
+ _path_muted_by_others = 0;
+ }
+ } else {
+ _path_muted_by_others += delta;
+ }
+}
+
#if 0
static void
dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& procs)
@@ -1683,8 +1726,10 @@ Route::state(bool full_state)
}
node->add_property ("order-keys", order_string);
node->add_property ("self-solo", (_self_solo ? "yes" : "no"));
- snprintf (buf, sizeof (buf), "%d", _soloed_by_others);
- node->add_property ("soloed-by-others", buf);
+ snprintf (buf, sizeof (buf), "%d", _soloed_by_others_upstream);
+ node->add_property ("soloed-by-upstream", buf);
+ snprintf (buf, sizeof (buf), "%d", _soloed_by_others_downstream);
+ node->add_property ("soloed-by-downstream", buf);
node->add_child_nocopy (_input->state (full_state));
node->add_child_nocopy (_output->state (full_state));
@@ -1782,9 +1827,14 @@ Route::_set_state (const XMLNode& node, int version, bool /*call_base*/)
set_self_solo (string_is_affirmative (prop->value()));
}
- if ((prop = node.property ("soloed-by-others")) != 0) {
- _soloed_by_others = 0; // needed for mod_solo_by_others () to work
- mod_solo_by_others (atoi (prop->value()));
+ if ((prop = node.property ("soloed-by-upstream")) != 0) {
+ _soloed_by_others_upstream = 0; // needed for mod_.... () to work
+ mod_solo_by_others_upstream (atoi (prop->value()));
+ }
+
+ if ((prop = node.property ("soloed-by-downstream")) != 0) {
+ _soloed_by_others_downstream = 0; // needed for mod_.... () to work
+ mod_solo_by_others_downstream (atoi (prop->value()));
}
if ((prop = node.property ("solo-isolated")) != 0) {
@@ -2532,6 +2582,12 @@ Route::direct_feeds (boost::shared_ptr<Route> other, bool* only_send)
}
void
+Route::check_physical_connections ()
+{
+ _physically_connected = _output->physically_connected ();
+}
+
+void
Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool can_flush_processors)
{
nframes_t now = _session.transport_frame();
@@ -3301,3 +3357,9 @@ Route::has_io_processor_named (const string& name)
return false;
}
+
+void
+Route::set_graph_level (int32_t l)
+{
+ _graph_level = l;
+}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 4ba092dd91..2da383b810 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -17,6 +17,9 @@
*/
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+
#include <algorithm>
#include <string>
#include <vector>
@@ -1351,6 +1354,10 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
RouteList::iterator i, j;
for (i = r->begin(); i != r->end(); ++i) {
+ (*i)->check_physical_connections ();
+ }
+
+ for (i = r->begin(); i != r->end(); ++i) {
(*i)->clear_fed_by ();
@@ -1381,15 +1388,102 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
RouteSorter cmp;
r->sort (cmp);
+ find_route_levels (r);
+
#ifndef NDEBUG
DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n", (*i)->name(), (*i)->order_key ("signal")));
+ DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2 level %3\n",
+ (*i)->name(), (*i)->order_key ("signal"),
+ (*i)->graph_level()));
}
#endif
}
+void
+Session::find_route_levels (shared_ptr<RouteList> rl)
+{
+ uint32_t setcnt = 0;
+ uint32_t limit = rl->size();
+ RouteList last_level;
+ RouteList this_level;
+
+ for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+
+ /* find routes with direct physical connections,
+ or routes with no connections at all. Mark them
+ with "special" level values, and push them into
+ the "last_level" set.
+
+ All other routes get marked with a graph level
+ of -1, which indicates that it needs to be set.
+
+ */
+
+ if ((*r)->physically_connected()) {
+ last_level.push_back (*r);
+ (*r)->set_graph_level (0);
+ setcnt++;
+ } else if (!(*r)->output()->connected()) {
+ last_level.push_back (*r);
+ (*r)->set_graph_level (INT32_MAX/2);
+ setcnt++;
+ } else {
+ (*r)->set_graph_level (-1);
+ }
+ }
+
+ // until we've set the graph level for every route ...
+
+ while (setcnt < limit) {
+
+ for (RouteList::reverse_iterator r = rl->rbegin(); r != rl->rend(); ++r) {
+
+ int32_t l = INT32_MAX;
+ bool found = false;
+
+ if ((*r)->graph_level() != -1) {
+ // we already have the graph level for this route
+ continue;
+ }
+
+ /* check if this route (r) has a direction connection to anything in
+ the set of routes we processed last time. On the first pass
+ through this, last_level will contain routes with either
+ no connections or direct "physical" connections. If there is
+ at least 1 connection, store the lowest graph level of whatever
+ r is connected to.
+ */
+
+ for (RouteList::iterator o = last_level.begin(); o != last_level.end(); ++o) {
+ bool sends_only;
+ if ((*r)->direct_feeds (*o, &sends_only)) {
+ if (!sends_only) {
+ l = min (l, (*o)->graph_level());
+ found = true;
+ }
+ }
+ }
+
+ /* if we found any connections, then mark the graph level of r, and push
+ it into the "this_level" set that will become "last_level" next time
+ around the while() loop.
+ */
+
+ if (found) {
+ (*r)->set_graph_level (l + 1);
+ this_level.push_back (*r);
+ setcnt++;
+ }
+ }
+
+ last_level = this_level;
+ this_level.clear ();
+ }
+}
+
+
/** Find the route name starting with \a base with the lowest \a id.
*
* Names are constructed like e.g. "Audio 3" for base="Audio" and id=3.
@@ -2185,13 +2279,14 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
bool via_sends_only;
- bool in_signal_flow;
if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) {
continue;
}
- in_signal_flow = false;
+ if ((*i)->graph_level () == route->graph_level()) {
+ (*i)->mod_muted_by_others (delta);
+ }
/* feed-backwards (other route to solo change route):
@@ -2204,8 +2299,7 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p
if ((*i)->feeds (route, &via_sends_only)) {
if (!via_sends_only) {
- (*i)->mod_solo_by_others (delta);
- in_signal_flow = true;
+ (*i)->mod_solo_by_others_upstream (delta);
}
}
@@ -2218,12 +2312,7 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p
*/
if (route->feeds (*i, &via_sends_only)) {
- (*i)->mod_solo_by_others (delta);
- in_signal_flow = true;
- }
-
- if (!in_signal_flow) {
- (*i)->mod_muted_by_others (delta);
+ (*i)->mod_solo_by_others_downstream (delta);
}
}