more solo/mute architecture work. NOTE: changes to mute points are ignored right now
[ardour.git] / libs / ardour / mute_master.cc
1 /*
2
3     Copyright (C) 2009 Paul Davis
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #include "pbd/enumwriter.h"
22 #include "pbd/xml++.h"
23
24 #include "ardour/types.h"
25 #include "ardour/mute_master.h"
26 #include "ardour/rc_configuration.h"
27
28 #include "i18n.h"
29
30 using namespace ARDOUR;
31 using namespace std;
32
33 const MuteMaster::MutePoint MuteMaster::AllPoints = MutePoint (MuteMaster::PreFader|
34                                                                MuteMaster::PostFader|
35                                                                MuteMaster::Listen|
36                                                                MuteMaster::Main);
37
38 MuteMaster::MuteMaster (Session&, const std::string&)
39         : _mute_point (AllPoints)
40         , _self_muted (false)
41         , _muted_by_others (0)
42 {
43 }
44
45 void
46 MuteMaster::mute_at (MutePoint mp)
47 {
48         if ((_mute_point & mp) != mp) {
49                 _mute_point = MutePoint (_mute_point | mp);
50                 cerr << "Mute point set, now " << _mute_point << endl;
51                 MutePointChanged (); // EMIT SIGNAL
52         }
53 }
54
55 void
56 MuteMaster::unmute_at (MutePoint mp)
57 {
58         if ((_mute_point & mp) == mp) {
59                 _mute_point = MutePoint (_mute_point & ~mp);
60                 cerr << "Mute point unset, now " << _mute_point << endl;
61                 MutePointChanged (); // EMIT SIGNAL
62         }
63 }
64
65 void
66 MuteMaster::clear_muted_by_others ()
67 {
68         _muted_by_others = 0;
69 }
70
71 void
72 MuteMaster::mod_muted_by_others (int32_t delta)
73 {
74         if (delta < 0) {
75                 if (_muted_by_others >= (uint32_t) abs (delta)) {
76                         _muted_by_others += delta;
77                 } else {
78                         _muted_by_others = 0;
79                 }
80         } else {
81                 _muted_by_others += delta;
82         }
83 }
84
85 void
86 MuteMaster::set_solo_level (int32_t l)
87 {
88         _solo_level = l;
89 }
90
91 gain_t
92 MuteMaster::mute_gain_at (MutePoint mp) const
93 {
94         gain_t gain;
95         int32_t l = _solo_level;
96
97         if (Config->get_solo_mute_override()) {
98                 if (l == 2) { // self-soloed
99                         gain = 1.0;
100                 } else if (self_muted_at (mp)) { // self-muted 
101                         gain = Config->get_solo_mute_gain ();
102                 } else if (l == 1) { // soloed by others
103                         gain = 1.0;
104                 } else if (muted_by_others_at (mp)) { // muted by others
105                         gain = Config->get_solo_mute_gain ();
106                 } else {
107                         gain = 1.0;
108                 }
109         } else {
110                 if (self_muted_at (mp)) { // self-muted 
111                         gain = Config->get_solo_mute_gain ();
112                 } else if (l == 2) { // self-soloed
113                         gain = 1.0;
114                 } else if (muted_by_others_at (mp)) { // muted by others
115                         gain = Config->get_solo_mute_gain ();
116                 } else if (l == 1) { // soloed by others
117                         gain = 1.0;
118                 } else {
119                         gain = 1.0;
120                 }
121         }
122
123         return gain;
124 }
125
126 void
127 MuteMaster::set_mute_points (const std::string& mute_point)
128 {
129         MutePoint old = _mute_point;
130
131         _mute_point = (MutePoint) string_2_enum (mute_point, _mute_point);
132         cerr << "Mute point set from string, now " << _mute_point << endl;
133
134         if (old != _mute_point) {
135                 MutePointChanged(); /* EMIT SIGNAL */
136         }
137 }
138
139 void
140 MuteMaster::set_mute_points (MutePoint mp) 
141 {
142         if (_mute_point != mp) {
143                 _mute_point = mp;
144                 cerr << "Mute point set from mp, now " << _mute_point << endl;
145                 MutePointChanged (); /* EMIT SIGNAL */
146         }
147 }
148
149 int
150 MuteMaster::set_state (const XMLNode& node, int /*version*/)
151 {
152         const XMLProperty* prop;
153
154         if ((prop = node.property ("mute-point")) != 0) {
155                 //_mute_point = (MutePoint) string_2_enum (prop->value(), _mute_point);
156                 cerr << "Mute point set from STATE string, now " << _mute_point << endl;
157         }
158
159         if ((prop = node.property ("muted")) != 0) {
160                 _self_muted = string_is_affirmative (prop->value());
161         } else {
162                 _self_muted = (_mute_point != MutePoint (0));
163         }
164
165         if ((prop = node.property ("muted-by-others")) != 0) {
166                 if (sscanf (prop->value().c_str(), "%u", &_muted_by_others) != 1) {
167                         _muted_by_others = 0;
168                 }
169         } else {
170                 _muted_by_others = 0;
171         }
172
173         return 0;
174 }
175
176 XMLNode&
177 MuteMaster::get_state()
178 {
179         XMLNode* node = new XMLNode (X_("MuteMaster"));
180         node->add_property ("mute-point", enum_2_string (_mute_point));
181         node->add_property ("muted", (_self_muted ? X_("yes") : X_("no")));
182
183         char buf[32];
184         snprintf (buf, sizeof (buf), "%u", _muted_by_others);
185         node->add_property ("muted-by-others", buf);
186
187         return *node;
188 }