summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-04-27 17:10:04 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-04-27 17:10:04 +0000
commit47de938e998ffceb0d9cfa829b47dad721445dc9 (patch)
tree4b45ec998720dca102820df648595a16d3c28dc6 /libs
parenta8e354ed7bb38f8be8bfdda33841f3f238e8bbab (diff)
add muted-by-other concept to solo support infrastructure
git-svn-id: svn://localhost/ardour2/branches/3.0@7005 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/mute_master.h24
-rw-r--r--libs/ardour/ardour/route.h7
-rw-r--r--libs/ardour/audio_track.cc2
-rw-r--r--libs/ardour/mute_master.cc57
-rw-r--r--libs/ardour/route.cc53
-rw-r--r--libs/ardour/session.cc24
6 files changed, 135 insertions, 32 deletions
diff --git a/libs/ardour/ardour/mute_master.h b/libs/ardour/ardour/mute_master.h
index 925d679674..610ca20dff 100644
--- a/libs/ardour/ardour/mute_master.h
+++ b/libs/ardour/ardour/mute_master.h
@@ -44,28 +44,38 @@ class MuteMaster : public PBD::Stateful
MuteMaster (Session& s, const std::string& name);
~MuteMaster() {}
- bool muted_pre_fader() const { return _mute_point & PreFader; }
- bool muted_post_fader() const { return _mute_point & PostFader; }
- bool muted_listen() const { return _mute_point & Listen; }
- bool muted_main () const { return _mute_point & Main; }
+ bool self_muted() const { return _self_muted && (_mute_point != MutePoint (0)); }
+ bool muted_by_others() const { return _muted_by_others && (_mute_point != MutePoint (0)); }
+ bool muted() const { return (_self_muted || (_muted_by_others > 0)) && (_mute_point != MutePoint (0)); }
+ bool muted_at (MutePoint mp) const { return (_self_muted || (_muted_by_others > 0)) && (_mute_point & mp); }
- bool muted_at (MutePoint mp) const { return _mute_point & mp; }
- bool muted() const { return _mute_point != MutePoint (0); }
+ bool muted_pre_fader() const { return muted_at (PreFader); }
+ bool muted_post_fader() const { return muted_at (PostFader); }
+ bool muted_listen() const { return muted_at (Listen); }
+ bool muted_main () const { return muted_at (Main); }
gain_t mute_gain_at (MutePoint) const;
+ void set_self_muted (bool yn) { _self_muted = yn; }
+ void mod_muted_by_others (int delta);
+
void clear_mute ();
void mute_at (MutePoint);
void unmute_at (MutePoint);
+ void set_mute_points (const std::string& mute_point);
+ void set_mute_points (MutePoint);
+ MutePoint mute_points() const { return _mute_point; }
+
PBD::Signal0<void> MutePointChanged;
XMLNode& get_state();
int set_state(const XMLNode&, int version);
- int set_state(std::string mute_point);
private:
MutePoint _mute_point;
+ bool _self_muted;
+ uint32_t _muted_by_others;
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 6068103896..bdb041c7dd 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -124,8 +124,13 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
void set_mute_points (MuteMaster::MutePoint);
MuteMaster::MutePoint mute_points() const { return _mute_points; }
- void set_mute (bool yn, void* src);
+
bool muted () const;
+ bool self_muted () const;
+ bool muted_by_others () const;
+
+ void set_mute (bool yn, void* src);
+ void mod_muted_by_others (int delta);
/* controls use set_solo() to modify this route's solo state
*/
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 862f15b68c..e90c569753 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -527,7 +527,7 @@ int
AudioTrack::export_stuff (BufferSet& buffers, sframes_t start, nframes_t nframes, bool enable_processing)
{
boost::scoped_array<gain_t> gain_buffer (new gain_t[nframes]);
- boost::scoped_array<float> mix_buffer (new float[nframes]);
+ boost::scoped_array<Sample> mix_buffer (new Sample[nframes]);
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
Glib::RWLock::ReaderLock rlock (_processor_lock);
diff --git a/libs/ardour/mute_master.cc b/libs/ardour/mute_master.cc
index 45499696a9..b3b3d23724 100644
--- a/libs/ardour/mute_master.cc
+++ b/libs/ardour/mute_master.cc
@@ -36,6 +36,8 @@ const MuteMaster::MutePoint MuteMaster::AllPoints = MutePoint (MuteMaster::PreFa
MuteMaster::MuteMaster (Session&, const std::string&)
: _mute_point (MutePoint (0))
+ , _self_muted (false)
+ , _muted_by_others (0)
{
}
@@ -66,22 +68,49 @@ MuteMaster::unmute_at (MutePoint mp)
}
}
+void
+MuteMaster::mod_muted_by_others (int32_t delta)
+{
+ if (delta < 0) {
+ if (_muted_by_others >= (uint32_t) abs (delta)) {
+ _muted_by_others += delta;
+ } else {
+ _muted_by_others = 0;
+ }
+ } else {
+ _muted_by_others += delta;
+ }
+}
+
gain_t
MuteMaster::mute_gain_at (MutePoint mp) const
{
- if (_mute_point & mp) {
+ if (muted_at (mp)) {
return Config->get_solo_mute_gain ();
} else {
return 1.0;
}
}
-int
-MuteMaster::set_state (std::string mute_point)
+void
+MuteMaster::set_mute_points (const std::string& mute_point)
{
+ MutePoint old = _mute_point;
+
_mute_point = (MutePoint) string_2_enum (mute_point, _mute_point);
- return 0;
+ if (old != _mute_point) {
+ MutePointChanged(); /* EMIT SIGNAL */
+ }
+}
+
+void
+MuteMaster::set_mute_points (MutePoint mp)
+{
+ if (_mute_point != mp) {
+ _mute_point = mp;
+ MutePointChanged (); /* EMIT SIGNAL */
+ }
}
int
@@ -93,6 +122,20 @@ MuteMaster::set_state (const XMLNode& node, int /*version*/)
_mute_point = (MutePoint) string_2_enum (prop->value(), _mute_point);
}
+ if ((prop = node.property ("muted")) != 0) {
+ _self_muted = string_is_affirmative (prop->value());
+ } else {
+ _self_muted = (_mute_point != MutePoint (0));
+ }
+
+ if ((prop = node.property ("muted-by-others")) != 0) {
+ if (sscanf (prop->value().c_str(), "%u", &_muted_by_others) != 1) {
+ _muted_by_others = 0;
+ }
+ } else {
+ _muted_by_others = 0;
+ }
+
return 0;
}
@@ -101,5 +144,11 @@ MuteMaster::get_state()
{
XMLNode* node = new XMLNode (X_("MuteMaster"));
node->add_property ("mute-point", enum_2_string (_mute_point));
+ node->add_property ("muted", (_self_muted ? X_("yes") : X_("no")));
+
+ char buf[32];
+ snprintf (buf, sizeof (buf), "%u", _muted_by_others);
+ node->add_property ("muted-by-others", buf);
+
return *node;
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 325e6c42fa..239a189a0d 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -687,13 +687,15 @@ Route::solo_isolated () const
void
Route::set_mute_points (MuteMaster::MutePoint mp)
{
- _mute_points = mp;
- mute_points_changed (); /* EMIT SIGNAL */
+ if (mp != _mute_points) {
+ _mute_points = mp;
+ _mute_master->set_mute_points (_mute_points);
+ mute_points_changed (); /* EMIT SIGNAL */
- if (_mute_master->muted()) {
- _mute_master->mute_at (_mute_points);
- mute_changed (this); /* EMIT SIGNAL */
- }
+ if (_mute_master->muted()) {
+ mute_changed (this); /* EMIT SIGNAL */
+ }
+ }
}
void
@@ -704,21 +706,40 @@ Route::set_mute (bool yn, void *src)
return;
}
- if (muted() != yn) {
- if (yn) {
- _mute_master->mute_at (_mute_points);
- } else {
- _mute_master->clear_mute ();
- }
-
+ if (self_muted() != yn) {
+ _mute_master->set_self_muted (yn);
mute_changed (src); /* EMIT SIGNAL */
}
}
bool
-Route::muted() const
+Route::muted () const
{
- return _mute_master->muted ();
+ return self_muted() || muted_by_others();
+}
+
+bool
+Route::self_muted() const
+{
+ return _mute_master->self_muted ();
+}
+
+bool
+Route::muted_by_others() const
+{
+ return _mute_master->muted_by_others ();
+}
+
+void
+Route::mod_muted_by_others (int delta)
+{
+ bool old = muted ();
+
+ _mute_master->mod_muted_by_others (delta);
+
+ if (old != muted()) {
+ mute_changed (this);
+ }
}
#if 0
@@ -1969,7 +1990,7 @@ Route::_set_state_2X (const XMLNode& node, int version)
}
}
- _mute_master->set_state (mute_point);
+ _mute_master->set_mute_points (mute_point);
}
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index b213439aba..3d569d22be 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -2169,20 +2169,30 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p
solo_update_disabled = true;
- /* from IRC:
+ /*
- <las> oofus_lt: solo a route, do NOT mute anything in the feed-forward chain for the route
- <las> oofus_lt: and do solo-by-other everything in the feed-backward chain
+ solo a route:
+ for anything in the signal path for this route, increment its soloed-by-other count
+ for anything not in the signal path for this route, increment its muted-by-other count
+
+ unsolo a route:
+ for anything in the signal path for this route, decrement its soloed-by-other count
+ for anything not in the signal path for this route, decrement its muted-by-other count
*/
+ RouteList uninvolved;
+
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;
+
/* feed-backwards (other route to solo change route):
if (*i) feeds the one whose solo status changed
@@ -2195,6 +2205,8 @@ 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);
+ (*i)->mod_muted_by_others (-delta);
+ in_signal_flow = true;
}
}
@@ -2208,6 +2220,12 @@ 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);
+ (*i)->mod_muted_by_others (-delta);
+ in_signal_flow = true;
+ }
+
+ if (!in_signal_flow) {
+ (*i)->mod_muted_by_others (delta);
}
}