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
This commit is contained in:
parent
e99cf351f5
commit
576cdb08b5
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -306,6 +306,13 @@ namespace ARDOUR {
|
|||
PreFaderListen
|
||||
};
|
||||
|
||||
enum SoloLevel {
|
||||
NotSoloed,
|
||||
DownstreamSoloed,
|
||||
UpstreamSoloed,
|
||||
SelfSoloed
|
||||
};
|
||||
|
||||
enum AutoConnectOption {
|
||||
ManualConnect = 0x0,
|
||||
AutoConnectPhysical = 0x1,
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
@ -2531,6 +2581,12 @@ Route::direct_feeds (boost::shared_ptr<Route> other, bool* only_send)
|
|||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
*/
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <stdint.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -1350,6 +1353,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue