Adapt some MSVC projects to accommodate the changes to 'ptformat' library
[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 "pbd/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::post_add_master (boost::shared_ptr<AutomationControl> m)
44 {
45         if (m->get_value()) {
46
47                 /* boolean masters records are not updated until AFTER
48                  * ::post_add_master() is called, so we can use them to check
49                  * on whether any master was already enabled before the new
50                  * one was added.
51                  */
52
53                 if (!muted_by_self() && !get_boolean_masters()) {
54                         _muteable.mute_master()->set_muted_by_masters (true);
55                         Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
56                 }
57         }
58 }
59
60 void
61 MuteControl::pre_remove_master (boost::shared_ptr<AutomationControl> m)
62 {
63         if (!m) {
64                 /* null control ptr means we're removing all masters */
65                 _muteable.mute_master()->set_muted_by_masters (false);
66                 /* Changed will be emitted in SlavableAutomationControl::clear_masters() */
67                 return;
68         }
69
70         if (m->get_value() && get_boolean_masters() == 1) {
71                 _muteable.mute_master()->set_muted_by_masters (false);
72                 if (!muted_by_self()) {
73                         Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
74                 }
75         }
76 }
77
78 void
79 MuteControl::actually_set_value (double val, Controllable::GroupControlDisposition gcd)
80 {
81         if (muted_by_self() != bool (val)) {
82                 _muteable.mute_master()->set_muted_by_self (val);
83
84                 /* allow the Muteable to respond to the mute change
85                    before anybody else knows about it.
86                 */
87                 _muteable.act_on_mute ();
88         }
89
90         SlavableAutomationControl::actually_set_value (val, gcd);
91 }
92
93 bool
94 MuteControl::handle_master_change (boost::shared_ptr<AutomationControl> m)
95 {
96         bool send_signal = false;
97         boost::shared_ptr<MuteControl> mc = boost::dynamic_pointer_cast<MuteControl> (m);
98         if (!mc) {
99                 return false;
100         }
101
102         if (m->get_value()) {
103                 /* this master is now enabled */
104                 if (get_boolean_masters() == 0) {
105                         _muteable.mute_master()->set_muted_by_masters (true);
106                         if (!muted_by_self()) {
107                                 send_signal = true;
108                         }
109                 }
110         } else {
111                 /* this master is disabled and there was only 1 enabled before */
112                 if (get_boolean_masters() == 1) {
113                         _muteable.mute_master()->set_muted_by_masters (false);
114                         if (!muted_by_self()) {
115                                 send_signal = true;
116                         }
117                 }
118         }
119         return send_signal;
120 }
121
122 double
123 MuteControl::get_value () const
124 {
125         if (slaved ()) {
126                 return muted_by_self() || muted_by_masters ();
127         }
128
129         if (_list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback()) {
130                 // Playing back automation, get the value from the list
131                 return AutomationControl::get_value();
132         }
133
134         return muted();
135 }
136
137 void
138 MuteControl::set_mute_points (MuteMaster::MutePoint mp)
139 {
140         _muteable.mute_master()->set_mute_points (mp);
141         _muteable.mute_points_changed (); /* EMIT SIGNAL */
142
143         if (_muteable.mute_master()->muted_by_self()) {
144                 Changed (true, Controllable::UseGroup); /* EMIT SIGNAL */
145         }
146 }
147
148 MuteMaster::MutePoint
149 MuteControl::mute_points () const
150 {
151         return _muteable.mute_master()->mute_points ();
152 }
153
154 bool
155 MuteControl::muted () const
156 {
157         /* have to get (self-muted) value from somewhere. could be our own
158            Control, or the Muteable that we sort-of proxy for. Since this
159            method is called by ::get_value(), use the latter to avoid recursion.
160         */
161         return _muteable.mute_master()->muted_by_self() || muted_by_masters ();
162 }
163
164 bool
165 MuteControl::muted_by_self () const
166 {
167         return _muteable.mute_master()->muted_by_self();
168 }
169
170 bool
171 MuteControl::muted_by_masters () const
172 {
173         return _muteable.mute_master()->muted_by_masters ();
174 }
175
176 bool
177 MuteControl::muted_by_others_soloing () const
178 {
179         return _muteable.muted_by_others_soloing ();
180 }
181
182 void
183 MuteControl::automation_run (samplepos_t start, pframes_t len)
184 {
185         boolean_automation_run (start, len);
186
187         bool valid = false;
188         bool mute  = false;
189
190         if (list() && automation_playback()) {
191                 mute = list()->rt_safe_eval (start, valid) >= 0.5;
192         }
193
194         if (!valid) {
195                 return;
196         }
197
198         if (muted_by_masters ()) {
199                 /* already muted, no need to check further,
200                  * except we need to up update implicit/explict mute
201                  */
202                 if (muted_by_self () != mute) {
203                         set_value_unchecked (mute ? 1. : 0.);
204                         Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
205                 }
206                 return;
207         }
208
209         if (mute && !muted()) {
210                 set_value_unchecked (1.0);  // mute
211                 Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
212         } else if (!mute && muted()) {
213                 set_value_unchecked (0.0);  // unmute
214                 Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
215         }
216 }