From d0e4555656aca17b4d447e58208006465fd569b9 Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 4 May 2010 16:39:03 +0000 Subject: [PATCH] remove muted-by-others, a concept that turns out to have been a red herring; add auditioning alert button to monitor section; start adding exclusive solo button to monitor section git-svn-id: http://subversion.ardour.org/svn/ardour2/ardour2/branches/3.0@7052 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour3_ui_dark.rc.in | 15 +++---- gtk2_ardour/monitor_section.cc | 50 ++++++++++++++++++++++- gtk2_ardour/monitor_section.h | 5 +++ gtk2_ardour/route_ui.cc | 14 +++---- libs/ardour/ardour/mute_master.h | 19 +++------ libs/ardour/ardour/route.h | 8 ---- libs/ardour/ardour/types.h | 7 ---- libs/ardour/mute_master.cc | 73 +++++----------------------------- libs/ardour/route.cc | 84 ++++++++++----------------------------- libs/ardour/session.cc | 43 ++++++-------------- 10 files changed, 117 insertions(+), 201 deletions(-) diff --git a/gtk2_ardour/ardour3_ui_dark.rc.in b/gtk2_ardour/ardour3_ui_dark.rc.in index bfef1d0a6..da13db4e9 100644 --- a/gtk2_ardour/ardour3_ui_dark.rc.in +++ b/gtk2_ardour/ardour3_ui_dark.rc.in @@ -328,18 +328,15 @@ style "solo_button" = "small_button" style "solo_button_alternate" = "small_button" { # - # this is the "solo-safe" solo theme + # this is the "solo-isolated" solo theme # - bg[NORMAL] = { 0.19, 0.97, 0.69 } # solo-safe - bg[ACTIVE] = { 0.19, 0.97, 0.69 } # solo-safe - bg[SELECTED] = { 0.19, 0.97, 0.69 } # solo-safe - bg[PRELIGHT] = { 0.19, 0.97, 0.69 } # solo-safe + bg[ACTIVE] = { 0.66, 0.97, 0.19 } - fg[ACTIVE] = { 0, 0, 0 } - fg[SELECTED] = { 0, 0, 0 } - fg[NORMAL] = { 0, 0, 0 } - fg[PRELIGHT] = { 0, 0, 0 } + fg[ACTIVE] = { 1.0, 0, 0 } + fg[SELECTED] = { 1.0, 0, 0 } + fg[NORMAL] = { 1.0, 0, 0 } + fg[PRELIGHT] = { 1.0, 0, 0 } } style "solo_button_alternate2" = "small_button" diff --git a/gtk2_ardour/monitor_section.cc b/gtk2_ardour/monitor_section.cc index b9e4c1b8a..95b9e5c6a 100644 --- a/gtk2_ardour/monitor_section.cc +++ b/gtk2_ardour/monitor_section.cc @@ -51,7 +51,8 @@ MonitorSection::MonitorSection (Session* s) , dim_all_button (_("dim")) , mono_button (_("mono")) , rude_solo_button (_("soloing")) - + , rude_audition_button (_("auditioning")) + , exclusive_solo_button (_("Exclusive solo")) { Glib::RefPtr act; @@ -90,10 +91,16 @@ MonitorSection::MonitorSection (Session* s) rude_solo_button.set_name ("TransportSoloAlert"); rude_solo_button.show (); - ARDOUR_UI::Blink.connect (sigc::mem_fun (*this, &MonitorSection::solo_blink)); + rude_audition_button.set_name ("TransportAuditioningAlert"); + rude_audition_button.show (); + + ARDOUR_UI::Blink.connect (sigc::mem_fun (*this, &MonitorSection::do_blink)); + rude_solo_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_solo), false); UI::instance()->set_tip (rude_solo_button, _("When active, something is soloed.\nClick to de-solo everything")); + rude_audition_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MonitorSection::cancel_audition), false); + UI::instance()->set_tip (rude_audition_button, _("When active, auditioning is active.\nClick to stop the audition")); solo_model_box.set_spacing (6); solo_model_box.pack_start (solo_in_place_button, false, false); @@ -151,9 +158,13 @@ MonitorSection::MonitorSection (Session* s) solo_packer->pack_start (*spin_packer, true, true); + exclusive_solo_button.set_name (X_("MonitorCutButton")); + upper_packer.set_spacing (12); upper_packer.pack_start (rude_solo_button, false, false); + upper_packer.pack_start (rude_audition_button, false, false); upper_packer.pack_start (solo_model_box, false, false); + upper_packer.pack_start (exclusive_solo_button, false, false); upper_packer.pack_start (*solo_packer, false, false); act = ActionManager::get_action (X_("Monitor"), X_("monitor-cut-all")); @@ -808,6 +819,32 @@ MonitorSection::map_state () } void +MonitorSection::do_blink (bool onoff) +{ + solo_blink (onoff); + audition_blink (onoff); +} + +void +MonitorSection::audition_blink (bool onoff) +{ + if (_session == 0) { + return; + } + + if (_session->is_auditioning()) { + if (onoff) { + rude_audition_button.set_state (STATE_ACTIVE); + } else { + rude_audition_button.set_state (STATE_NORMAL); + } + } else { + rude_audition_button.set_active (false); + rude_audition_button.set_state (STATE_NORMAL); + } +} + +void MonitorSection::solo_blink (bool onoff) { if (_session == 0) { @@ -840,6 +877,15 @@ MonitorSection::cancel_solo (GdkEventButton* ev) return true; } +bool +MonitorSection::cancel_audition (GdkEventButton* ev) +{ + if (_session) { + _session->cancel_audition(); + } + return true; +} + void MonitorSection::solo_cut_changed () { diff --git a/gtk2_ardour/monitor_section.h b/gtk2_ardour/monitor_section.h index da20857ae..a77efdb82 100644 --- a/gtk2_ardour/monitor_section.h +++ b/gtk2_ardour/monitor_section.h @@ -113,9 +113,14 @@ class MonitorSection : public RouteUI BindableToggleButton dim_all_button; BindableToggleButton mono_button; BindableToggleButton rude_solo_button; + BindableToggleButton rude_audition_button; + BindableToggleButton exclusive_solo_button; + void do_blink (bool); void solo_blink (bool); + void audition_blink (bool); bool cancel_solo (GdkEventButton*); + bool cancel_audition (GdkEventButton*); void solo_cut_changed (); void update_solo_model (); void parameter_changed (std::string); diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index f3430ccc4..851a96da5 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -294,7 +294,7 @@ RouteUI::mute_press (GdkEventButton* ev) return true; } - _mute_release = new SoloMuteRelease (_route->self_muted ()); + _mute_release = new SoloMuteRelease (_route->muted ()); } if (ev->button == 1 || Keyboard::is_button2_event (ev)) { @@ -305,7 +305,7 @@ RouteUI::mute_press (GdkEventButton* ev) _mute_release->routes = _session->get_routes (); } - _session->set_mute (_session->get_routes(), !_route->self_muted()); + _session->set_mute (_session->get_routes(), !_route->muted()); } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { @@ -318,7 +318,7 @@ RouteUI::mute_press (GdkEventButton* ev) _mute_release->routes = _session->get_routes (); } - _session->set_mute (_session->get_routes(), !_route->self_muted(), Session::rt_cleanup, true); + _session->set_mute (_session->get_routes(), !_route->muted(), Session::rt_cleanup, true); } } else { @@ -332,7 +332,7 @@ RouteUI::mute_press (GdkEventButton* ev) _mute_release->routes = rl; } - _session->set_mute (rl, !_route->self_muted()); + _session->set_mute (rl, !_route->muted()); } } @@ -835,7 +835,7 @@ RouteUI::mute_visual_state (Session* s, boost::shared_ptr r) if (Config->get_show_solo_mutes()) { - if (r->self_muted ()) { + if (r->muted ()) { /* full mute */ return 2; } else if (s->soloing() && !r->soloed() && !r->solo_isolated()) { @@ -847,7 +847,7 @@ RouteUI::mute_visual_state (Session* s, boost::shared_ptr r) } else { - if (r->self_muted()) { + if (r->muted()) { /* full mute */ return 2; } else { @@ -866,7 +866,7 @@ RouteUI::update_mute_display () return; } - bool model = _route->self_muted(); + bool model = _route->muted(); bool view = mute_button->get_active(); /* first make sure the button's "depressed" visual diff --git a/libs/ardour/ardour/mute_master.h b/libs/ardour/ardour/mute_master.h index ad383d883..2a90a0284 100644 --- a/libs/ardour/ardour/mute_master.h +++ b/libs/ardour/ardour/mute_master.h @@ -46,12 +46,8 @@ class MuteMaster : public SessionHandleRef, public PBD::Stateful MuteMaster (Session& s, const std::string& name); ~MuteMaster() {} - 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 self_muted_at (MutePoint mp) const { return _self_muted && (_mute_point & mp); } - bool muted_by_others_at (MutePoint mp) const { return (_muted_by_others > 0) && (_mute_point & mp); } + bool muted() const { return _muted && (_mute_point != MutePoint (0)); } + bool muted_at (MutePoint mp) const { return _muted && (_mute_point & mp); } bool muted_pre_fader() const { return muted_at (PreFader); } bool muted_post_fader() const { return muted_at (PostFader); } @@ -60,9 +56,7 @@ class MuteMaster : public SessionHandleRef, public PBD::Stateful 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_muted_by_others (); + void set_muted (bool yn) { _muted = yn; } void mute_at (MutePoint); void unmute_at (MutePoint); @@ -71,7 +65,7 @@ class MuteMaster : public SessionHandleRef, public PBD::Stateful void set_mute_points (MutePoint); MutePoint mute_points() const { return _mute_point; } - void set_solo_level (SoloLevel); + void set_soloed (bool); void set_solo_ignore (bool yn) { _solo_ignore = yn; } PBD::Signal0 MutePointChanged; @@ -81,9 +75,8 @@ class MuteMaster : public SessionHandleRef, public PBD::Stateful private: volatile MutePoint _mute_point; - volatile bool _self_muted; - volatile uint32_t _muted_by_others; - volatile SoloLevel _solo_level; + volatile bool _muted; + volatile bool _soloed; volatile bool _solo_ignore; }; diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index b4a392c23..689090cd5 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -126,14 +126,7 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou MuteMaster::MutePoint mute_points() const { return _mute_points; } bool muted () const; - 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); /* controls use set_solo() to modify this route's solo state */ @@ -437,7 +430,6 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou boost::shared_ptr _mute_control; boost::shared_ptr _mute_master; MuteMaster::MutePoint _mute_points; - volatile uint32_t _path_muted_by_others; std::string _comment; bool _have_internal_generator; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 39b763a41..2bbb140bb 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -306,13 +306,6 @@ namespace ARDOUR { PreFaderListen }; - enum SoloLevel { - NotSoloed, - DownstreamSoloed, - UpstreamSoloed, - SelfSoloed - }; - enum AutoConnectOption { ManualConnect = 0x0, AutoConnectPhysical = 0x1, diff --git a/libs/ardour/mute_master.cc b/libs/ardour/mute_master.cc index b06a64e72..bc3cca787 100644 --- a/libs/ardour/mute_master.cc +++ b/libs/ardour/mute_master.cc @@ -38,8 +38,8 @@ const MuteMaster::MutePoint MuteMaster::AllPoints = MutePoint (MuteMaster::PreFa MuteMaster::MuteMaster (Session& s, const std::string&) : SessionHandleRef (s) , _mute_point (AllPoints) - , _self_muted (false) - , _muted_by_others (0) + , _muted (false) + , _soloed (false) , _solo_ignore (false) { } @@ -49,7 +49,6 @@ MuteMaster::mute_at (MutePoint mp) { if ((_mute_point & mp) != mp) { _mute_point = MutePoint (_mute_point | mp); - cerr << "Mute point set, now " << _mute_point << endl; MutePointChanged (); // EMIT SIGNAL } } @@ -59,53 +58,25 @@ MuteMaster::unmute_at (MutePoint mp) { if ((_mute_point & mp) == mp) { _mute_point = MutePoint (_mute_point & ~mp); - cerr << "Mute point unset, now " << _mute_point << endl; MutePointChanged (); // EMIT SIGNAL } } void -MuteMaster::clear_muted_by_others () +MuteMaster::set_soloed (bool yn) { - _muted_by_others = 0; -} - -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; - } -} - -void -MuteMaster::set_solo_level (SoloLevel l) -{ - _solo_level = l; + _soloed = yn; } gain_t MuteMaster::mute_gain_at (MutePoint mp) const { gain_t gain; - 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 == SelfSoloed) || (l == UpstreamSoloed)) { + if (_soloed) { gain = 1.0; - } else if (self_muted_at (mp)) { // self-muted - gain = Config->get_solo_mute_gain (); - } else if (l == DownstreamSoloed) { - gain = 1.0; - } else if (muted_by_others_at (mp)) { // muted by others + } else if (muted_at (mp)) { // self-muted gain = Config->get_solo_mute_gain (); } else { if (!_solo_ignore && _session.soloing()) { @@ -115,13 +86,9 @@ MuteMaster::mute_gain_at (MutePoint mp) const } } } else { - if (self_muted_at (mp)) { // self-muted - gain = Config->get_solo_mute_gain (); - } else if ((l == SelfSoloed) || (l == UpstreamSoloed)) { - gain = 1.0; - } else if (muted_by_others_at (mp)) { // muted by others + if (muted_at (mp)) { // self-muted gain = Config->get_solo_mute_gain (); - } else if (l == DownstreamSoloed) { // soloed by others + } else if (_soloed) { gain = 1.0; } else { if (!_solo_ignore && _session.soloing()) { @@ -132,8 +99,6 @@ MuteMaster::mute_gain_at (MutePoint mp) const } } - // cerr << "\tgain = " << gain << endl; - return gain; } @@ -143,7 +108,6 @@ MuteMaster::set_mute_points (const std::string& mute_point) MutePoint old = _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 */ @@ -155,7 +119,6 @@ MuteMaster::set_mute_points (MutePoint mp) { if (_mute_point != mp) { _mute_point = mp; - cerr << "Mute point set from mp, now " << _mute_point << endl; MutePointChanged (); /* EMIT SIGNAL */ } } @@ -167,21 +130,12 @@ MuteMaster::set_state (const XMLNode& node, int /*version*/) if ((prop = node.property ("mute-point")) != 0) { _mute_point = (MutePoint) string_2_enum (prop->value(), _mute_point); - cerr << "Mute point set from STATE string, now " << _mute_point << endl; } if ((prop = node.property ("muted")) != 0) { - _self_muted = string_is_affirmative (prop->value()); + _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; + _muted = (_mute_point != MutePoint (0)); } return 0; @@ -192,11 +146,6 @@ 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); - + node->add_property ("muted", (_muted ? X_("yes") : X_("no"))); return *node; } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 287e3c219..29184ab94 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -91,7 +91,6 @@ 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) @@ -617,13 +616,26 @@ Route::mod_solo_by_others_upstream (int32_t delta) _soloed_by_others_upstream += delta; } + /* push the inverse solo change to everything that feeds us. + + This is important for solo-within-group. When we solo 1 track out of N that + feed a bus, that track will cause mod_solo_by_upstream (+1) to be called + on the bus. The bus then needs to call mod_solo_by_downstream (-1) on all + tracks that feed it. This will silence them if they were audible because + of a bus solo, but the newly soloed track will still be audible (because + it is self-soloed). + + but .. do this only when we are being told to solo-by-upstream (i.e delta = +1), + not in reverse. */ - for (FedBy::iterator i = _fed_by.begin(); i != _fed_by.end(); ++i) { - boost::shared_ptr sr = i->r.lock(); - if (sr) { - sr->mod_solo_by_others_downstream (-delta); + if (delta > 0) { + for (FedBy::iterator i = _fed_by.begin(); i != _fed_by.end(); ++i) { + boost::shared_ptr sr = i->r.lock(); + if (sr) { + sr->mod_solo_by_others_downstream (-delta); + } } } @@ -655,19 +667,7 @@ Route::mod_solo_by_others_downstream (int32_t delta) void Route::set_mute_master_solo () { - SoloLevel level; - - if (self_soloed()) { - level = SelfSoloed; - } else if (soloed_by_others_upstream()) { - level = UpstreamSoloed; - } else if (soloed_by_others_downstream()) { - level = DownstreamSoloed; - } else { - level = NotSoloed; - } - - _mute_master->set_solo_level (level); + _mute_master->set_soloed (self_soloed() || soloed_by_others_downstream() || soloed_by_others_upstream()); } void @@ -745,8 +745,8 @@ Route::set_mute (bool yn, void *src) return; } - if (self_muted() != yn) { - _mute_master->set_self_muted (yn); + if (muted() != yn) { + _mute_master->set_muted (yn); mute_changed (src); /* EMIT SIGNAL */ } } @@ -754,47 +754,7 @@ Route::set_mute (bool yn, void *src) bool Route::muted () const { - 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) -{ - 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; - } + return _mute_master->muted(); } #if 0 @@ -3069,7 +3029,7 @@ Route::MuteControllable::set_value (float val) float Route::MuteControllable::get_value (void) const { - return route.self_muted() ? 1.0f : 0.0f; + return route.muted() ? 1.0f : 0.0f; } void diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index a643ee21c..10c040757 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2251,7 +2251,7 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg; return; } - + shared_ptr r = routes.reader (); int32_t delta; @@ -2260,21 +2260,19 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p } else { delta = -1; } + + if (delta == 1 && !Config->get_solo_latched()) { + /* new solo: disable all other solos */ + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_hidden()) { + continue; + } + (*i)->set_solo (false, this); + } + } solo_update_disabled = true; - - /* - - 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) { @@ -2287,15 +2285,6 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p in_signal_flow = false; - /* feed-backwards (other route to solo change route): - - if (*i) feeds the one whose solo status changed - it should be soloed by other if the change was -> solo OR de-soloed by other if change was -> !solo - else - do nothing - - */ - if ((*i)->feeds (route, &via_sends_only)) { if (!via_sends_only) { (*i)->mod_solo_by_others_downstream (delta); @@ -2303,14 +2292,6 @@ Session::route_solo_changed (bool self_solo_change, void* /*src*/, boost::weak_p } } - /* feed-forward (solo change route to other routes): - - if the route whose solo status changed feeds (*i) - do nothing - else - mute if the change was -> solo OR demute if change was -> !solo - */ - if (route->feeds (*i, &via_sends_only)) { (*i)->mod_solo_by_others_upstream (delta); in_signal_flow = true; -- 2.11.4.GIT