1 /*
2  * Copyright (C) 2000-2016 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2005-2006 Taybin Rutkin <taybin@taybin.com>
4  * Copyright (C) 2006-2011 David Robillard <d@drobilla.net>
5  * Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
6  * Copyright (C) 2016-2017 Robin Gareus <robin@gareus.org>
7  * Copyright (C) 2018 Len Ovens <len@ovenwerks.net>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifndef __ardour_route_group_h__
25 #define __ardour_route_group_h__
26 
27 #include <list>
28 #include <set>
29 #include <string>
30 #include <stdint.h>
31 
32 #include "pbd/controllable.h"
33 #include "pbd/signals.h"
34 #include "pbd/stateful.h"
35 
36 #include "ardour/control_group.h"
37 #include "ardour/types.h"
38 #include "ardour/session_object.h"
39 
40 #include "ardour/libardour_visibility.h"
41 
42 namespace ARDOUR {
43 
44 namespace Properties {
45 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_relative;
46 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_gain;
47 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_mute;
48 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_solo;
49 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_recenable;
50 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_select;
51 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_route_active;
52 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_color;
53 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> group_monitoring;
54 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> active;
55 	LIBARDOUR_API extern PBD::PropertyDescriptor<int32_t> group_master_number;
56 	/* we use these declared in region.cc */
57 	LIBARDOUR_API extern PBD::PropertyDescriptor<bool> hidden;
58 };
59 
60 class Route;
61 class Track;
62 class AudioTrack;
63 class Session;
64 
65 /** A group identifier for routes.
66  *
67  * RouteGroups permit to define properties which are shared
68  * among all Routes that use the given identifier.
69  *
70  * A route can at most be in one group.
71  */
72 class LIBARDOUR_API RouteGroup : public SessionObject
73 {
74 public:
75 	static void make_property_quarks();
76 
77 	RouteGroup (Session& s, const std::string &n);
78 	~RouteGroup ();
79 
is_active()80 	bool is_active () const { return _active.val(); }
is_relative()81 	bool is_relative () const { return _relative.val(); }
is_hidden()82 	bool is_hidden () const { return _hidden.val(); }
is_gain()83 	bool is_gain () const { return _gain.val(); }
is_mute()84 	bool is_mute () const { return _mute.val(); }
is_solo()85 	bool is_solo () const { return _solo.val(); }
is_recenable()86 	bool is_recenable () const { return _recenable.val(); }
is_select()87 	bool is_select () const { return _select.val(); }
is_route_active()88 	bool is_route_active () const { return _route_active.val(); }
is_color()89 	bool is_color () const { return _color.val(); }
is_monitoring()90 	bool is_monitoring() const { return _monitoring.val(); }
group_master_number()91 	int32_t group_master_number() const { return _group_master_number.val(); }
subgroup_bus()92 	boost::weak_ptr<Route> subgroup_bus() const { return _subgroup_bus; }
93 
empty()94 	bool empty() const {return routes->empty();}
size()95 	size_t size() const { return routes->size();}
96 
97 	gain_t get_max_factor(gain_t factor);
98 	gain_t get_min_factor(gain_t factor);
99 
100 	void set_active (bool yn, void *src);
101 	void set_relative (bool yn, void *src);
102 	void set_hidden (bool yn, void *src);
103 
104 	void set_gain (bool yn);
105 	void set_mute (bool yn);
106 	void set_solo (bool yn);
107 	void set_recenable (bool yn);
108 	void set_select (bool yn);
109 	void set_route_active (bool yn);
110 	void set_color (bool yn);
111 	void set_monitoring (bool yn);
112 
113 	bool enabled_property (PBD::PropertyID);
114 
115 	int add (boost::shared_ptr<Route>);
116 	int remove (boost::shared_ptr<Route>);
117 
118 	template<typename Function>
foreach_route(Function f)119 	void foreach_route (Function f) {
120 		for (RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
121 			f (i->get());
122 		}
123 	}
124 
125 	/* to use these, #include "ardour/route_group_specialized.h" */
126 
127 	template<class T> void apply (void (Track::*func)(T, PBD::Controllable::GroupControlDisposition), T val, PBD::Controllable::GroupControlDisposition);
128 
129 	/* fills at_set with all members of the group that are AudioTracks */
130 
131 	void audio_track_group (std::set<boost::shared_ptr<AudioTrack> >& at_set);
132 
clear()133 	void clear () {
134 		routes->clear ();
135 		changed();
136 	}
137 
138 	bool has_subgroup() const;
139 	void make_subgroup (bool, Placement);
140 	void destroy_subgroup ();
141 
route_list()142 	boost::shared_ptr<RouteList> route_list() { return routes; }
143 
144 	/** Emitted when a route has been added to this group */
145 	PBD::Signal2<void, RouteGroup *, boost::weak_ptr<ARDOUR::Route> > RouteAdded;
146 	/** Emitted when a route has been removed from this group */
147 	PBD::Signal2<void, RouteGroup *, boost::weak_ptr<ARDOUR::Route> > RouteRemoved;
148 
149 	XMLNode& get_state ();
150 
151 	int set_state (const XMLNode&, int version);
152 
153 	void assign_master (boost::shared_ptr<VCA>);
154 	void unassign_master (boost::shared_ptr<VCA>);
155 	bool has_control_master() const;
156 	bool slaved () const;
157 
rgba()158 	uint32_t rgba () const { return _rgba; }
159 
160 	/** set route-group color and notify UI about change */
161 	void set_rgba (uint32_t);
162 
163 	/* directly set color only, used to convert old 5.x gui-object-state
164 	 * to libardour color */
migrate_rgba(uint32_t color)165 	void migrate_rgba (uint32_t color) { _rgba = color; }
166 
167 private:
168 	boost::shared_ptr<RouteList> routes;
169 	boost::shared_ptr<Route> _subgroup_bus;
170 	boost::weak_ptr<VCA> group_master;
171 
172 	PBD::Property<bool> _relative;
173 	PBD::Property<bool> _active;
174 	PBD::Property<bool> _hidden;
175 	PBD::Property<bool> _gain;
176 	PBD::Property<bool> _mute;
177 	PBD::Property<bool> _solo;
178 	PBD::Property<bool> _recenable;
179 	PBD::Property<bool> _select;
180 	PBD::Property<bool> _route_active;
181 	PBD::Property<bool> _color;
182 	PBD::Property<bool> _monitoring;
183 	PBD::Property<int32_t> _group_master_number;
184 
185 	boost::shared_ptr<ControlGroup> _solo_group;
186 	boost::shared_ptr<ControlGroup> _mute_group;
187 	boost::shared_ptr<ControlGroup> _rec_enable_group;
188 	boost::shared_ptr<ControlGroup> _gain_group;
189 	boost::shared_ptr<ControlGroup> _monitoring_group;
190 
191 	void remove_when_going_away (boost::weak_ptr<Route>);
192 	int set_state_2X (const XMLNode&, int);
193 
194 	void post_set (PBD::PropertyChange const &);
195 	void push_to_groups ();
196 
197 	uint32_t _rgba;
198 	bool _used_to_share_gain;
199 };
200 
201 } /* namespace */
202 
203 #endif /* __ardour_route_group_h__ */
204