1 /* 2 * Copyright (C) 2016-2017 Paul Davis <paul@linuxaudiosystems.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 */ 18 19 #ifndef __ardour_solo_control_h__ 20 #define __ardour_solo_control_h__ 21 22 #include <string> 23 24 #include <boost/shared_ptr.hpp> 25 26 #include "ardour/slavable_automation_control.h" 27 #include "ardour/libardour_visibility.h" 28 29 namespace ARDOUR { 30 31 class Session; 32 class Soloable; 33 class Muteable; 34 35 class LIBARDOUR_API SoloControl : public SlavableAutomationControl 36 { 37 public: 38 SoloControl (Session& session, std::string const & name, Soloable& soloable, Muteable& m); 39 40 double get_value () const; get_save_value()41 double get_save_value() const { return self_soloed(); } 42 43 bool can_solo() const; 44 45 /* Export additional API so that objects that only get access 46 * to a Controllable/AutomationControl can do more fine-grained 47 * operations with respect to solo. Obviously, they would need 48 * to dynamic_cast<SoloControl> first. 49 * 50 * Solo state is not representable by a single scalar value, 51 * so set_value() and get_value() is not enough. 52 * 53 * This means that the Controllable is technically 54 * asymmetric. It is possible to call ::set_value (0.0) to 55 * disable (self)solo, and then call ::get_value() and get a 56 * return of 1.0 because the control is soloed by 57 * upstream/downstream or a master. 58 */ 59 60 void mod_solo_by_others_upstream (int32_t delta); 61 void mod_solo_by_others_downstream (int32_t delta); 62 63 /* API to check different aspects of solo substate 64 */ 65 self_soloed()66 bool self_soloed () const { 67 return _self_solo; 68 } soloed_by_masters()69 bool soloed_by_masters () const { 70 return get_masters_value(); 71 } soloed_by_self_or_masters()72 bool soloed_by_self_or_masters () const { 73 return self_soloed() || get_masters_value (); 74 } soloed_by_others()75 bool soloed_by_others () const { 76 return _soloed_by_others_downstream || _soloed_by_others_upstream || get_masters_value (); 77 } soloed_by_others_upstream()78 uint32_t soloed_by_others_upstream () const { 79 return _soloed_by_others_upstream; 80 } soloed_by_others_downstream()81 uint32_t soloed_by_others_downstream () const { 82 return _soloed_by_others_downstream; 83 } soloed()84 bool soloed() const { return self_soloed() || soloed_by_others(); } 85 86 /* The session object needs to respond to solo 87 changes, but to do so accurately it needs to know if we transition 88 into or out of solo. The normal Changed signal doesn't make that 89 possible. 90 */ 91 transitioned_into_solo()92 int32_t transitioned_into_solo () const { return _transition_into_solo; } 93 94 void clear_all_solo_state (); 95 96 int set_state (XMLNode const&, int); 97 XMLNode& get_state (); 98 99 protected: 100 void actually_set_value (double, PBD::Controllable::GroupControlDisposition group_override); 101 void master_changed (bool from_self, GroupControlDisposition, boost::weak_ptr<AutomationControl> m); 102 void pre_remove_master (boost::shared_ptr<AutomationControl>); 103 void post_add_master (boost::shared_ptr<AutomationControl>); 104 105 private: 106 Soloable& _soloable; 107 Muteable& _muteable; 108 bool _self_solo; 109 uint32_t _soloed_by_others_upstream; 110 uint32_t _soloed_by_others_downstream; 111 int32_t _transition_into_solo; 112 113 void set_self_solo (bool yn); 114 void set_mute_master_solo (); 115 }; 116 117 } /* namespace */ 118 119 #endif /* __libardour_solo_control_h__ */ 120