a slew of as-yet incomplete work to get VCA solo+mute closer to working
[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() != 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 double
58 MuteControl::get_value () const
59 {
60         if (slaved()) {
61                 Glib::Threads::RWLock::ReaderLock lm (master_lock);
62                 return get_masters_value_locked () ? 1.0 : 0.0;
63         }
64
65         if (_list && boost::dynamic_pointer_cast<AutomationList>(_list)->automation_playback()) {
66                 // Playing back automation, get the value from the list
67                 return AutomationControl::get_value();
68         }
69
70         return muted() ? 1.0 : 0.0;
71 }
72
73 void
74 MuteControl::set_mute_points (MuteMaster::MutePoint mp)
75 {
76         _muteable.mute_master()->set_mute_points (mp);
77         _muteable.mute_points_changed (); /* EMIT SIGNAL */
78
79         if (_muteable.mute_master()->muted_by_self()) {
80                 Changed (true, Controllable::UseGroup); /* EMIT SIGNAL */
81         }
82 }
83
84 MuteMaster::MutePoint
85 MuteControl::mute_points () const
86 {
87         return _muteable.mute_master()->mute_points ();
88 }
89
90 bool
91 MuteControl::muted () const
92 {
93         return _muteable.mute_master()->muted_by_self();
94 }
95
96 bool
97 MuteControl::muted_by_others () const
98 {
99         return _muteable.mute_master()->muted_by_others () || get_masters_value();
100 }