diff options
-rw-r--r-- | gtk2_ardour/route_ui.cc | 23 | ||||
-rw-r--r-- | libs/ardour/ardour/mute_master.h | 24 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 7 | ||||
-rw-r--r-- | libs/ardour/audio_track.cc | 2 | ||||
-rw-r--r-- | libs/ardour/mute_master.cc | 57 | ||||
-rw-r--r-- | libs/ardour/route.cc | 53 | ||||
-rw-r--r-- | libs/ardour/session.cc | 24 |
7 files changed, 146 insertions, 44 deletions
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 816343a2cb..ae36ccba86 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -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 { 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); } } |