Add mising 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 */
19
20 #define __STDC_FORMAT_MACROS
21 #include <inttypes.h>
22
23 #include <algorithm>
24
25 #include <sigc++/bind.h>
26
27 #include "pbd/error.h"
28 #include "pbd/enumwriter.h"
29
30 #include "ardour/route_group.h"
31 #include "ardour/audio_track.h"
32 #include "ardour/audio_diskstream.h"
33 #include "ardour/configuration.h"
34 #include "ardour/session.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         if (is_active() == yn) {
155                 return;
156         }
157         if (yn) {
158                 _flags = Flag (_flags | Active);
159         } else {
160                 _flags = Flag (_flags & ~Active);
161         }
162         _session.set_dirty ();
163         FlagsChanged (src); /* EMIT SIGNAL */
164 }
165
166 void
167 RouteGroup::set_relative (bool yn, void *src)
168
169 {
170         if (is_relative() == yn) {
171                 return;
172         }
173         if (yn) {
174                 _flags = Flag (_flags | Relative);
175         } else {
176                 _flags = Flag (_flags & ~Relative);
177         }
178         _session.set_dirty ();
179         FlagsChanged (src); /* EMIT SIGNAL */
180 }
181
182 void
183 RouteGroup::set_hidden (bool yn, void *src)
184
185 {
186         if (is_hidden() == yn) {
187                 return;
188         }
189         if (yn) {
190                 _flags = Flag (_flags | Hidden);
191                 if (Config->get_hiding_groups_deactivates_groups()) {
192                         _flags = Flag (_flags & ~Active);
193                 }
194         } else {
195                 _flags = Flag (_flags & ~Hidden);
196                 if (Config->get_hiding_groups_deactivates_groups()) {
197                         _flags = Flag (_flags | Active);
198                 }
199         }
200         _session.set_dirty ();
201         FlagsChanged (src); /* EMIT SIGNAL */
202 }
203
204 void
205 RouteGroup::audio_track_group (set<AudioTrack*>& ats) 
206 {       
207         for (list<Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
208                 AudioTrack* at = dynamic_cast<AudioTrack*>(*i);
209                 if (at) {
210                         ats.insert (at);
211                 }
212         }
213 }
214