finish use of EnumWriter for saving flags etc. throughout the session file
[ardour.git] / libs / ardour / route_group.cc
1 /*
2     Copyright (C) 2000-2002 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #define __STDC_FORMAT_MACROS
22 #include <inttypes.h>
23
24 #include <algorithm>
25
26 #include <sigc++/bind.h>
27
28 #include <pbd/error.h>
29 #include <pbd/enumwriter.h>
30
31 #include <ardour/route_group.h>
32 #include <ardour/audio_track.h>
33 #include <ardour/audio_diskstream.h>
34 #include <ardour/configuration.h>
35
36 using namespace ARDOUR;
37 using namespace sigc;
38 using namespace std;
39
40 RouteGroup::RouteGroup (Session& s, const string &n, Flag f)
41         : _session (s), _name (n), _flags (f) 
42 {
43 }
44
45 void
46 RouteGroup::set_name (string str)
47 {
48         _name = str;
49         _session.set_dirty ();
50         FlagsChanged (0); /* EMIT SIGNAL */
51 }
52
53 int
54 RouteGroup::add (Route *r)
55 {
56         routes.push_back (r);
57         r->GoingAway.connect (sigc::bind (mem_fun (*this, &RouteGroup::remove_when_going_away), r));
58         _session.set_dirty ();
59         changed (); /* EMIT SIGNAL */
60         return 0;
61 }
62
63 void
64 RouteGroup::remove_when_going_away (Route *r)
65 {
66         remove (r);
67 }
68     
69 int
70 RouteGroup::remove (Route *r) 
71 {
72         list<Route *>::iterator i;
73
74         if ((i = find (routes.begin(), routes.end(), r)) != routes.end()) {
75                 routes.erase (i);
76                 _session.set_dirty ();
77                 changed (); /* EMIT SIGNAL */
78                 return 0;
79         }
80         return -1;
81 }
82
83
84 gain_t
85 RouteGroup::get_min_factor(gain_t factor)
86 {
87         gain_t g;
88         
89         for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
90                 g = (*i)->gain();
91
92                 if ( (g+g*factor) >= 0.0f)
93                         continue;
94
95                 if ( g <= 0.0000003f )
96                         return 0.0f;
97                 
98                 factor = 0.0000003f/g - 1.0f;
99         }       
100         return factor;
101 }
102
103 gain_t
104 RouteGroup::get_max_factor(gain_t factor)
105 {
106         gain_t g;
107         
108         for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
109                 g = (*i)->gain();
110                 
111                 // if the current factor woulnd't raise this route above maximum
112                 if ( (g+g*factor) <= 1.99526231f) 
113                         continue;
114                 
115                 // if route gain is already at peak, return 0.0f factor
116             if (g>=1.99526231f)
117                         return 0.0f;
118
119                 // factor is calculated so that it would raise current route to max
120                 factor = 1.99526231f/g - 1.0f;
121         }
122
123         return factor;
124 }
125
126 XMLNode&
127 RouteGroup::get_state (void)
128 {
129         XMLNode *node = new XMLNode ("RouteGroup");
130         node->add_property ("name", _name);
131         node->add_property ("flags", enum_2_string (_flags));
132         return *node;
133 }
134
135 int 
136 RouteGroup::set_state (const XMLNode& node)
137 {
138         const XMLProperty *prop;
139
140         if ((prop = node.property ("name")) != 0) {
141                 _name = prop->value();
142         }
143
144         if ((prop = node.property ("flags")) != 0) {
145                 _flags = Flag (string_2_enum (prop->value(), _flags));
146         }
147
148         return 0;
149 }
150
151 void
152 RouteGroup::set_active (bool yn, void *src)
153
154 {
155         if (is_active() == yn) {
156                 return;
157         }
158         if (yn) {
159                 _flags = Flag (_flags | Active);
160         } else {
161                 _flags = Flag (_flags & ~Active);
162         }
163         _session.set_dirty ();
164         FlagsChanged (src); /* EMIT SIGNAL */
165 }
166
167 void
168 RouteGroup::set_relative (bool yn, void *src)
169
170 {
171         if (is_relative() == yn) {
172                 return;
173         }
174         if (yn) {
175                 _flags = Flag (_flags | Relative);
176         } else {
177                 _flags = Flag (_flags & ~Relative);
178         }
179         _session.set_dirty ();
180         FlagsChanged (src); /* EMIT SIGNAL */
181 }
182
183 void
184 RouteGroup::set_hidden (bool yn, void *src)
185
186 {
187         if (is_hidden() == yn) {
188                 return;
189         }
190         if (yn) {
191                 _flags = Flag (_flags | Hidden);
192                 if (Config->get_hiding_groups_deactivates_groups()) {
193                         _flags = Flag (_flags & ~Active);
194                 }
195         } else {
196                 _flags = Flag (_flags & ~Hidden);
197                 if (Config->get_hiding_groups_deactivates_groups()) {
198                         _flags = Flag (_flags | Active);
199                 }
200         }
201         _session.set_dirty ();
202         FlagsChanged (src); /* EMIT SIGNAL */
203 }
204
205 void
206 RouteGroup::audio_track_group (set<AudioTrack*>& ats) 
207 {       
208         for (list<Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
209                 AudioTrack* at = dynamic_cast<AudioTrack*>(*i);
210                 if (at) {
211                         ats.insert (at);
212                 }
213         }
214 }
215