Experimental patch to ensure playback buffer bounds use minimal beat->frame rounding.
[ardour.git] / libs / ardour / ardour / solo_control.h
index 7f7e532669412d72144520884da1ff5f853784c5..89aa16d02277bc017d42ccf7e38f9c7565141d0e 100644 (file)
@@ -23,7 +23,7 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include "ardour/automation_control.h"
+#include "ardour/slavable_automation_control.h"
 #include "ardour/libardour_visibility.h"
 
 namespace ARDOUR {
@@ -39,6 +39,8 @@ class LIBARDOUR_API SoloControl : public SlavableAutomationControl
 
        double get_value () const;
 
+       bool can_solo() const;
+
        /* Export additional API so that objects that only get access
         * to a Controllable/AutomationControl can do more fine-grained
         * operations with respect to solo. Obviously, they would need
@@ -60,8 +62,17 @@ class LIBARDOUR_API SoloControl : public SlavableAutomationControl
        /* API to check different aspects of solo substate
         */
 
+       bool self_soloed () const {
+               return _self_solo;
+       }
+       bool soloed_by_masters () const {
+               return get_masters_value();
+       }
+       bool soloed_by_self_or_masters () const {
+               return self_soloed() || get_masters_value ();
+       }
        bool soloed_by_others () const {
-               return _soloed_by_others_downstream || _soloed_by_others_downstream;
+               return _soloed_by_others_downstream || _soloed_by_others_downstream || get_masters_value ();
        }
        uint32_t soloed_by_others_upstream () const {
                return _soloed_by_others_upstream;
@@ -69,26 +80,34 @@ class LIBARDOUR_API SoloControl : public SlavableAutomationControl
        uint32_t soloed_by_others_downstream () const {
                return _soloed_by_others_downstream;
        }
-       bool self_soloed () const {
-               return _self_solo;
-       }
        bool soloed() const { return self_soloed() || soloed_by_others(); }
 
+       /* The session object needs to respond to solo
+          changes, but to do so accurately it needs to know if we transition
+          into or out of solo. The normal Changed signal doesn't make that
+          possible.
+       */
+
+       int32_t transitioned_into_solo () const { return _transition_into_solo; }
+
        void clear_all_solo_state ();
 
        int set_state (XMLNode const&, int);
        XMLNode& get_state ();
 
   protected:
-       void master_changed (bool, PBD::Controllable::GroupControlDisposition);
        void actually_set_value (double, PBD::Controllable::GroupControlDisposition group_override);
+       void master_changed (bool from_self, GroupControlDisposition, boost::shared_ptr<AutomationControl> m);
+       void pre_remove_master (boost::shared_ptr<AutomationControl>);
+       void post_add_master (boost::shared_ptr<AutomationControl>);
 
   private:
-       Soloable&      _soloable;
-       Muteable&      _muteable;
-       bool           _self_solo;
-       uint32_t       _soloed_by_others_upstream;
-       uint32_t       _soloed_by_others_downstream;
+       Soloable& _soloable;
+       Muteable& _muteable;
+       bool      _self_solo;
+       uint32_t  _soloed_by_others_upstream;
+       uint32_t  _soloed_by_others_downstream;
+       int32_t   _transition_into_solo;
 
        void set_self_solo (bool yn);
        void set_mute_master_solo ();