add muted-by-other concept to solo support infrastructure
git-svn-id: svn://localhost/ardour2/branches/3.0@7005 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
a8e354ed7b
commit
47de938e99
@ -295,7 +295,7 @@ RouteUI::mute_press (GdkEventButton* ev)
|
||||
return true;
|
||||
}
|
||||
|
||||
_mute_release = new SoloMuteRelease (_route->muted ());
|
||||
_mute_release = new SoloMuteRelease (_route->self_muted ());
|
||||
}
|
||||
|
||||
if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
|
||||
@ -306,7 +306,7 @@ RouteUI::mute_press (GdkEventButton* ev)
|
||||
_mute_release->routes = _session->get_routes ();
|
||||
}
|
||||
|
||||
_session->set_mute (_session->get_routes(), !_route->muted());
|
||||
_session->set_mute (_session->get_routes(), !_route->self_muted());
|
||||
|
||||
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
|
||||
|
||||
@ -319,7 +319,7 @@ RouteUI::mute_press (GdkEventButton* ev)
|
||||
_mute_release->routes = _session->get_routes ();
|
||||
}
|
||||
|
||||
_session->set_mute (_session->get_routes(), !_route->muted(), Session::rt_cleanup, true);
|
||||
_session->set_mute (_session->get_routes(), !_route->self_muted(), Session::rt_cleanup, true);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -333,7 +333,7 @@ RouteUI::mute_press (GdkEventButton* ev)
|
||||
_mute_release->routes = rl;
|
||||
}
|
||||
|
||||
_session->set_mute (rl, !_route->muted());
|
||||
_session->set_mute (rl, !_route->self_muted());
|
||||
|
||||
}
|
||||
}
|
||||
@ -390,7 +390,7 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||
return true;
|
||||
}
|
||||
|
||||
_solo_release = new SoloMuteRelease (_route->soloed());
|
||||
_solo_release = new SoloMuteRelease (_route->self_soloed());
|
||||
}
|
||||
|
||||
if (ev->button == 1 || Keyboard::is_button2_event (ev)) {
|
||||
@ -406,7 +406,7 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||
if (Config->get_solo_control_is_listen_control()) {
|
||||
_session->set_listen (_session->get_routes(), !_route->listening(), Session::rt_cleanup, true);
|
||||
} else {
|
||||
_session->set_solo (_session->get_routes(), !_route->soloed(), Session::rt_cleanup, true);
|
||||
_session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, true);
|
||||
}
|
||||
|
||||
} else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
|
||||
@ -456,7 +456,7 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||
if (Config->get_solo_control_is_listen_control()) {
|
||||
_session->set_listen (_route->route_group()->route_list(), !_route->listening(), Session::rt_cleanup, true);
|
||||
} else {
|
||||
_session->set_solo (_route->route_group()->route_list(), !_route->soloed(), Session::rt_cleanup, true);
|
||||
_session->set_solo (_route->route_group()->route_list(), !_route->self_soloed(), Session::rt_cleanup, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,7 +474,7 @@ RouteUI::solo_press(GdkEventButton* ev)
|
||||
if (Config->get_solo_control_is_listen_control()) {
|
||||
_session->set_listen (rl, !_route->listening());
|
||||
} else {
|
||||
_session->set_solo (rl, !_route->soloed());
|
||||
_session->set_solo (rl, !_route->self_soloed());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -836,11 +836,10 @@ RouteUI::mute_visual_state (Session* s, boost::shared_ptr<Route> r)
|
||||
|
||||
if (Config->get_show_solo_mutes()) {
|
||||
|
||||
if (r->muted ()) {
|
||||
if (r->self_muted ()) {
|
||||
/* full mute */
|
||||
return 2;
|
||||
} else if (s->soloing() && !r->soloed() && !r->solo_isolated()) {
|
||||
/* mute-because-not-soloed */
|
||||
} else if (r->muted_by_others()) {
|
||||
return 1;
|
||||
} else {
|
||||
/* no mute at all */
|
||||
@ -849,7 +848,7 @@ RouteUI::mute_visual_state (Session* s, boost::shared_ptr<Route> r)
|
||||
|
||||
} else {
|
||||
|
||||
if (r->muted()) {
|
||||
if (r->self_muted()) {
|
||||
/* full mute */
|
||||
return 2;
|
||||
} else {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user