a variety of changes that get closer to correctly functioning behaviour for VCA solo...
[ardour.git] / libs / ardour / mute_control.cc
1 /*
2     Copyright (C) 2016 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify it
5     under the terms of the GNU General Public License as published by the Free
6     Software Foundation; either version 2 of the License, or (at your option)
7     any later version.
8
9     This program is distributed in the hope that it will be useful, but WITHOUT
10     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12     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     675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include "evoral/ControlList.hpp"
20
21 #include "ardour/mute_master.h"
22 #include "ardour/session.h"
23 #include "ardour/mute_control.h"
24
25 #include "i18n.h"
26
27 using namespace ARDOUR;
28 using namespace std;
29
30
31 MuteControl::MuteControl (Session& session, std::string const & name, Muteable& m)
32         : SlavableAutomationControl (session, MuteAutomation, ParameterDescriptor (MuteAutomation),
33                                      boost::shared_ptr<AutomationList> (new AutomationList (Evoral::Parameter (MuteAutomation))),
34                                      name)
35         , _muteable (m)
36 {
37         _list->set_interpolation (Evoral::ControlList::Discrete);
38         /* mute changes must be synchronized by the process cycle */
39         set_flags (Controllable::Flag (flags() | Controllable::RealTime));
40 }
41
42 void
43 MuteControl::actually_set_value (double val, Controllable::GroupControlDisposition gcd)
44 {
45         if (muted_by_self() != bool (val)) {
46                 _muteable.mute_master()->set_muted_by_self (val);
47
48                 /* allow the Muteable to respond to the mute change
49                    before anybody else knows about it.
50                 */
51                 _muteable.act_on_mute ();
52         }
53
54         AutomationControl::actually_set_value (val, gcd);
55 }
56
57 void
58 MuteControl::master_changed (bool self_change, Controllable::GroupControlDisposition gcd)
59 {
60         double m = get_masters_value ();
61         const int32_t old_muted_by_others = _muteable.mute_master()->muted_by_others ();
62         std::cerr << "master " << (self_change ? " self " : " not-self") << " changed to " << m << " old others = " << old_muted_by_others << std::endl;
63
64         _muteable.mute_master()->mod_muted_by_others (m ? 1 : -1);
65
66         if (m) {
67                 /* master(s) are now muted. If we are self-muted, this
68                    doesn't change our status. If we are not self-muted,
69                    then it changes our status if either:
70
71                    - the master had its own self-muted status changed OR
72                    - the total number of masters that are muted used to be zero
73                 */
74
75                 if (!muted_by_self()) {
76                         if (self_change || old_muted_by_others == 0) {
77                                 /* note false as the first argument - our own
78                                    value was not changed
79                                 */
80                                 Changed (false, gcd);
81                         } else {
82                                 cerr << " no Change signal\n";
83                         }
84                 } else {
85                         cerr << "muted by self, not relevant\n";
86                 }
87         } else {
88                 /* no master(s) are now muted. If we are self-muted, this
89                    doesn't change our status. If we are not self-muted,
90                    then it changes our status if either:
91
92                    - the master had its own self-muted status changed OR
93                    - the total number of masters that are muted used to be non-zero
94                 */
95
96                 if (!muted_by_self()) {
97                         if (self_change || old_muted_by_others != 0) {
98                                 Changed (false, gcd);
99                         } else {
100                                 cerr << " No change signal\n";
101                         }
102                 } else {
103                         cerr << "muted by self, not relevant\n";
104                 }
105         }
106 }
107
108 double
109 MuteControl::get_value () const
110 {
111         if (slaved ()) {
112                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
113                 return get_masters_value_locked ();
114         }
115
116         if (_list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback()) {
117                 // Playing back automation, get the value from the list
118                 return AutomationControl::get_value();
119         }
120
121         return muted() ? 1.0 : 0.0;
122 }
123
124 void
125 MuteControl::set_mute_points (MuteMaster::MutePoint mp)
126 {
127         _muteable.mute_master()->set_mute_points (mp);
128         _muteable.mute_points_changed (); /* EMIT SIGNAL */
129
130         if (_muteable.mute_master()->muted_by_self()) {
131                 Changed (true, Controllable::UseGroup); /* EMIT SIGNAL */
132         }
133 }
134
135 MuteMaster::MutePoint
136 MuteControl::mute_points () const
137 {
138         return _muteable.mute_master()->mute_points ();
139 }
140
141 bool
142 MuteControl::muted () const
143 {
144         return _muteable.mute_master()->muted_by_self() || _muteable.mute_master()->muted_by_others();
145 }
146
147 bool
148 MuteControl::muted_by_self () const
149 {
150         return _muteable.mute_master()->muted_by_self();
151 }
152
153 bool
154 MuteControl::muted_by_others () const
155 {
156         return _muteable.mute_master()->muted_by_others ();
157 }