perhaps, just possibly, a working solo model. needs to be fixed so that connections...
[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/session.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& s, const std::string&)
39         : SessionHandleRef (s) 
40         , _mute_point (AllPoints)
41         , _self_muted (false)
42         , _muted_by_others (0)
43 {
44 }
45
46 void
47 MuteMaster::mute_at (MutePoint mp)
48 {
49         if ((_mute_point & mp) != mp) {
50                 _mute_point = MutePoint (_mute_point | mp);
51                 cerr << "Mute point set, now " << _mute_point << endl;
52                 MutePointChanged (); // EMIT SIGNAL
53         }
54 }
55
56 void
57 MuteMaster::unmute_at (MutePoint mp)
58 {
59         if ((_mute_point & mp) == mp) {
60                 _mute_point = MutePoint (_mute_point & ~mp);
61                 cerr << "Mute point unset, now " << _mute_point << endl;
62                 MutePointChanged (); // EMIT SIGNAL
63         }
64 }
65
66 void
67 MuteMaster::clear_muted_by_others ()
68 {
69         _muted_by_others = 0;
70 }
71
72 void
73 MuteMaster::mod_muted_by_others (int32_t delta)
74 {
75         if (delta < 0) {
76                 if (_muted_by_others >= (uint32_t) abs (delta)) {
77                         _muted_by_others += delta;
78                 } else {
79                         _muted_by_others = 0;
80                 }
81         } else {
82                 _muted_by_others += delta;
83         }
84 }
85
86 void
87 MuteMaster::set_solo_level (SoloLevel l)
88 {
89         _solo_level = l;
90 }
91
92 gain_t
93 MuteMaster::mute_gain_at (MutePoint mp) const
94 {
95         gain_t gain;
96         const SoloLevel l = _solo_level;
97
98         // cerr << "solo level = " << _solo_level << " selfmuted " <<  self_muted_at (mp) << " omute " << muted_by_others_at (mp) << endl;
99         
100         if (Config->get_solo_mute_override()) {
101                 if ((l == SelfSoloed) || (l == DownstreamSoloed)) { 
102                         gain = 1.0;
103                 } else if (self_muted_at (mp)) { // self-muted 
104                         gain = Config->get_solo_mute_gain ();
105                 } else if (l == UpstreamSoloed) {
106                         gain = 1.0;
107                 } else if (muted_by_others_at (mp)) { // muted by others
108                         gain = Config->get_solo_mute_gain ();
109                 } else {
110                         gain = 1.0;
111                 }
112         } else {
113                 if (self_muted_at (mp)) { // self-muted 
114                         gain = Config->get_solo_mute_gain ();
115                 } else if ((l == SelfSoloed) || (l == DownstreamSoloed)) {
116                         gain = 1.0;
117                 } else if (muted_by_others_at (mp)) { // muted by others
118                         gain = Config->get_solo_mute_gain ();
119                 } else if (l == UpstreamSoloed) { // soloed by others
120                         gain = 1.0;
121                 } else {
122                         gain = 1.0;
123                 }
124         }
125
126         // cerr << "\tgain = " << gain << endl;
127         
128         return gain;
129 }
130
131 void
132 MuteMaster::set_mute_points (const std::string& mute_point)
133 {
134         MutePoint old = _mute_point;
135
136         _mute_point = (MutePoint) string_2_enum (mute_point, _mute_point);
137         cerr << "Mute point set from string, now " << _mute_point << endl;
138         
139         if (old != _mute_point) {
140                 MutePointChanged(); /* EMIT SIGNAL */
141         }
142 }
143
144 void
145 MuteMaster::set_mute_points (MutePoint mp) 
146 {
147         if (_mute_point != mp) {
148                 _mute_point = mp;
149                 cerr << "Mute point set from mp, now " << _mute_point << endl;
150                 MutePointChanged (); /* EMIT SIGNAL */
151         }
152 }
153
154 int
155 MuteMaster::set_state (const XMLNode& node, int /*version*/)
156 {
157         const XMLProperty* prop;
158
159         if ((prop = node.property ("mute-point")) != 0) {
160                 _mute_point = (MutePoint) string_2_enum (prop->value(), _mute_point);
161                 cerr << "Mute point set from STATE string, now " << _mute_point << endl;
162         }
163
164         if ((prop = node.property ("muted")) != 0) {
165                 _self_muted = string_is_affirmative (prop->value());
166         } else {
167                 _self_muted = (_mute_point != MutePoint (0));
168         }
169
170         if ((prop = node.property ("muted-by-others")) != 0) {
171                 if (sscanf (prop->value().c_str(), "%u", &_muted_by_others) != 1) {
172                         _muted_by_others = 0;
173                 }
174         } else {
175                 _muted_by_others = 0;
176         }
177
178         return 0;
179 }
180
181 XMLNode&
182 MuteMaster::get_state()
183 {
184         XMLNode* node = new XMLNode (X_("MuteMaster"));
185         node->add_property ("mute-point", enum_2_string (_mute_point));
186         node->add_property ("muted", (_self_muted ? X_("yes") : X_("no")));
187
188         char buf[32];
189         snprintf (buf, sizeof (buf), "%u", _muted_by_others);
190         node->add_property ("muted-by-others", buf);
191
192         return *node;
193 }