enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[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);
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()) {
71                 if (!muted_by_self() && (get_boolean_masters() == 1)) {
72                         Changed (false, Controllable::NoGroup);
73                 }
74         }
75 }
76
77 void
78 MuteControl::actually_set_value (double val, Controllable::GroupControlDisposition gcd)
79 {
80         if (muted_by_self() != bool (val)) {
81                 _muteable.mute_master()->set_muted_by_self (val);
82
83                 /* allow the Muteable to respond to the mute change
84                    before anybody else knows about it.
85                 */
86                 _muteable.act_on_mute ();
87         }
88
89         SlavableAutomationControl::actually_set_value (val, gcd);
90 }
91
92 void
93 MuteControl::master_changed (bool self_change, Controllable::GroupControlDisposition gcd, boost::shared_ptr<AutomationControl> m)
94 {
95         bool send_signal = false;
96         boost::shared_ptr<MuteControl> mc = boost::dynamic_pointer_cast<MuteControl> (m);
97
98         if (m->get_value()) {
99                 /* this master is now enabled */
100                 if (!muted_by_self() && get_boolean_masters() == 0) {
101                         _muteable.mute_master()->set_muted_by_masters (true);
102                         send_signal = true;
103                 }
104         } else {
105                 /* this master is disabled and there was only 1 enabled before */
106                 if (!muted_by_self() && get_boolean_masters() == 1) {
107                         _muteable.mute_master()->set_muted_by_masters (false);
108                         send_signal = true;
109                 }
110         }
111
112         update_boolean_masters_records (m);
113
114         if (send_signal) {
115                 Changed (false, Controllable::NoGroup);
116         }
117 }
118
119 double
120 MuteControl::get_value () const
121 {
122         if (slaved ()) {
123                 return muted_by_self() || get_masters_value ();
124         }
125
126         if (_list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback()) {
127                 // Playing back automation, get the value from the list
128                 return AutomationControl::get_value();
129         }
130
131         return muted();
132 }
133
134 void
135 MuteControl::set_mute_points (MuteMaster::MutePoint mp)
136 {
137         _muteable.mute_master()->set_mute_points (mp);
138         _muteable.mute_points_changed (); /* EMIT SIGNAL */
139
140         if (_muteable.mute_master()->muted_by_self()) {
141                 Changed (true, Controllable::UseGroup); /* EMIT SIGNAL */
142         }
143 }
144
145 MuteMaster::MutePoint
146 MuteControl::mute_points () const
147 {
148         return _muteable.mute_master()->mute_points ();
149 }
150
151 bool
152 MuteControl::muted () const
153 {
154         /* have to get (self-muted) value from somewhere. could be our own
155            Control, or the Muteable that we sort-of proxy for. Since this
156            method is called by ::get_value(), use the latter to avoid recursion.
157         */
158         return _muteable.mute_master()->muted_by_self() || get_masters_value ();
159 }
160
161 bool
162 MuteControl::muted_by_self () const
163 {
164         return _muteable.mute_master()->muted_by_self();
165 }
166
167 bool
168 MuteControl::muted_by_masters () const
169 {
170         return get_masters_value ();
171 }
172
173 bool
174 MuteControl::muted_by_others_soloing () const
175 {
176         return _muteable.muted_by_others_soloing ();
177 }
178
179 void
180 MuteControl::automation_run (framepos_t start, pframes_t)
181 {
182         if (!list() || !automation_playback()) {
183                 return;
184         }
185
186         bool        valid = false;
187         const float mute  = list()->rt_safe_eval (start, valid);
188
189         if (mute >= 0.5 && !muted()) {
190                 set_value_unchecked (1.0);  // mute
191         } else if (mute < 0.5 && muted ()) {
192                 set_value_unchecked (0.0);  // unmute
193         }
194 }