1 /*
2  * Copyright (C) 2006-2011 David Robillard <d@drobilla.net>
3  * Copyright (C) 2006-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2007-2011 Carl Hetherington <carl@carlh.net>
5  * Copyright (C) 2016-2019 Robin Gareus <robin@gareus.org>
6  * Copyright (C) 2017 Julien "_FrnchFrgg_" RIVAUD <frnchfrgg@free.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #ifndef __ardour_io_h__
24 #define __ardour_io_h__
25 
26 #include <string>
27 #include <vector>
28 #include <cmath>
29 
30 #include <glibmm/threads.h>
31 
32 #include "pbd/fastlog.h"
33 #include "pbd/undo.h"
34 #include "pbd/statefuldestructible.h"
35 #include "pbd/controllable.h"
36 #include "pbd/enum_convert.h"
37 
38 #include "ardour/ardour.h"
39 #include "ardour/automation_control.h"
40 #include "ardour/bundle.h"
41 #include "ardour/chan_count.h"
42 #include "ardour/data_type.h"
43 #include "ardour/latent.h"
44 #include "ardour/port_set.h"
45 #include "ardour/session_object.h"
46 #include "ardour/libardour_visibility.h"
47 #include "ardour/types.h"
48 #include "ardour/utils.h"
49 #include "ardour/buffer_set.h"
50 
51 class XMLNode;
52 
53 namespace ARDOUR {
54 
55 class Amp;
56 class AudioEngine;
57 class AudioPort;
58 class Bundle;
59 class MidiPort;
60 class PeakMeter;
61 class Port;
62 class Processor;
63 class Session;
64 class UserBundle;
65 
66 /** A collection of ports (all input or all output) with connections.
67  *
68  * An IO can contain ports of varying types, making routes/inserts/etc with
69  * varied combinations of types (eg MIDI and audio) possible.
70  */
71 class LIBARDOUR_API IO : public SessionObject
72 {
73 public:
74 	static const std::string state_node_name;
75 
76 	enum Direction {
77 		Input,
78 		Output
79 	};
80 
81 	IO (Session&, const std::string& name, Direction, DataType default_type = DataType::AUDIO, bool sendish = false);
82 	IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO, bool sendish = false);
83 
84 	virtual ~IO();
85 
direction()86 	Direction direction() const { return _direction; }
87 
default_type()88 	DataType default_type() const         { return _default_type; }
set_default_type(DataType t)89 	void     set_default_type(DataType t) { _default_type = t; }
90 
active()91 	bool active() const { return _active; }
set_active(bool yn)92 	void set_active(bool yn) { _active = yn; }
93 
94 	bool set_name (const std::string& str);
95 	void set_pretty_name (const std::string& str);
pretty_name()96 	std::string pretty_name () const { return _pretty_name_prefix; }
97 
98 	virtual void silence (samplecnt_t);
99 
100 	int ensure_io (ChanCount cnt, bool clear, void *src);
101 
102 	int connect_ports_to_bundle (boost::shared_ptr<Bundle>, bool exclusive, void *);
103 	int connect_ports_to_bundle (boost::shared_ptr<Bundle>, bool, bool, void *);
104 	int disconnect_ports_from_bundle (boost::shared_ptr<Bundle>, void *);
105 
106 	BundleList bundles_connected ();
107 
bundle()108 	boost::shared_ptr<Bundle> bundle () { return _bundle; }
109 
110 	bool can_add_port (DataType) const;
111 
112 	int add_port (std::string connection, void *src, DataType type = DataType::NIL);
113 	int remove_port (boost::shared_ptr<Port>, void *src);
114 	int connect (boost::shared_ptr<Port> our_port, std::string other_port, void *src);
115 	int disconnect (boost::shared_ptr<Port> our_port, std::string other_port, void *src);
116 	int disconnect (void *src);
117 	bool connected_to (boost::shared_ptr<const IO>) const;
118 	bool connected_to (const std::string&) const;
119 	bool connected () const;
120 	bool physically_connected () const;
121 
122 	samplecnt_t latency () const;
123 	samplecnt_t connected_latency (bool for_playback) const;
124 
125 	void set_private_port_latencies (samplecnt_t value, bool playback);
126 	void set_public_port_latencies (samplecnt_t value, bool playback) const;
127 
ports()128 	PortSet& ports() { return _ports; }
ports()129 	const PortSet& ports() const { return _ports; }
130 
131 	bool has_port (boost::shared_ptr<Port>) const;
132 
nth(uint32_t n)133 	boost::shared_ptr<Port> nth (uint32_t n) const {
134 		if (n < _ports.num_ports()) {
135 			return _ports.port(n);
136 		} else {
137 			return boost::shared_ptr<Port> ();
138 		}
139 	}
140 
141 	boost::shared_ptr<Port> port_by_name (const std::string& str) const;
142 
143 	boost::shared_ptr<AudioPort> audio(uint32_t n) const;
144 	boost::shared_ptr<MidiPort>  midi(uint32_t n) const;
145 
n_ports()146 	const ChanCount& n_ports ()  const { return _ports.count(); }
147 
148 	/* The process lock will be held on emission of this signal if
149 	 * IOChange contains ConfigurationChanged.  In other cases,
150 	 * the process lock status is undefined.
151 	 */
152 	PBD::Signal2<void, IOChange, void *> changed;
153 
154 	XMLNode& get_state (void);
155 
156 	int set_state (const XMLNode&, int version);
157 	int set_state_2X (const XMLNode&, int, bool);
158 	static void prepare_for_reset (XMLNode&, const std::string&);
159 
160 	class BoolCombiner {
161 	public:
162 
163 		typedef bool result_type;
164 
165 		template <typename Iter>
operator()166 		result_type operator() (Iter first, Iter last) const {
167 			bool r = false;
168 			while (first != last) {
169 				if (*first) {
170 					r = true;
171 				}
172 				++first;
173 			}
174 
175 			return r;
176 		}
177 	};
178 
179 	/** Emitted when the port count is about to change.  Objects
180 	 *  can attach to this, and return `true' if they want to prevent
181 	 *  the change from happening.
182 	 */
183 	PBD::Signal1<bool, ChanCount, BoolCombiner> PortCountChanging;
184 
185 	static int disable_connecting ();
186 	static int enable_connecting ();
187 
188 	static PBD::Signal1<void, ChanCount> PortCountChanged; // emitted when the number of ports changes
189 
190 	static std::string name_from_state (const XMLNode&);
191 	static void set_name_in_state (XMLNode&, const std::string&);
192 
193 	/* we have to defer/order port connection. this is how we do it.
194 	*/
195 
196 	static PBD::Signal0<int> ConnectingLegal;
197 	static bool              connecting_legal;
198 
199 	XMLNode *pending_state_node;
200 	int pending_state_node_version;
201 	bool pending_state_node_in;
202 
203 	/* three utility functions - this just seems to be simplest place to put them */
204 
205 	void collect_input (BufferSet& bufs, pframes_t nframes, ChanCount offset);
206 	void copy_to_outputs (BufferSet& bufs, DataType type, pframes_t nframes, samplecnt_t offset);
207 
208 	/* AudioTrack::deprecated_use_diskstream_connections() needs these */
209 
210 	int set_ports (const std::string& str);
211 
212 protected:
213 	virtual XMLNode& state ();
214 
215 	Direction _direction;
216 	DataType _default_type;
217 	bool     _active;
218 	bool     _sendish;
219 
220 private:
221 	mutable Glib::Threads::Mutex io_lock;
222 	PortSet   _ports;
223 
224 	int connecting_became_legal ();
225 	PBD::ScopedConnection connection_legal_c;
226 
227 	void reestablish_port_subscriptions ();
228 	PBD::ScopedConnectionList _port_connections;
229 
230 	boost::shared_ptr<Bundle> _bundle; ///< a bundle representing our ports
231 
232 	struct UserBundleInfo {
233 		UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b);
234 		boost::shared_ptr<UserBundle> bundle;
235 		PBD::ScopedConnection changed;
236 	};
237 
238 	static int parse_io_string (const std::string&, std::vector<std::string>& chns);
239 	static int parse_gain_string (const std::string&, std::vector<std::string>& chns);
240 
241 	int ensure_ports (ChanCount, bool clear, void *src);
242 
243 	void bundle_changed (Bundle::Change);
244 
245 	int get_port_counts (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c);
246 	int get_port_counts_2X (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c);
247 	int create_ports (const XMLNode&, int version);
248 	int make_connections (const XMLNode&, int, bool);
249 	int make_connections_2X (const XMLNode &, int, bool);
250 
251 	boost::shared_ptr<Bundle> find_possible_bundle (const std::string &desired_name);
252 
253 	int ensure_ports_locked (ChanCount, bool clear, bool& changed);
254 
255 	std::string build_legal_port_name (DataType type);
256 	int32_t find_port_hole (const char* base);
257 
258 	void setup_bundle ();
259 	std::string bundle_channel_name (uint32_t, uint32_t, DataType) const;
260 
261 	void apply_pretty_name ();
262 	std::string _pretty_name_prefix;
263 	BufferSet _buffers;
264 	void connection_change (boost::shared_ptr<ARDOUR::Port>, boost::shared_ptr<ARDOUR::Port>);
265 };
266 
267 } // namespace ARDOUR
268 
269 namespace PBD {
270 	DEFINE_ENUM_CONVERT (ARDOUR::IO::Direction)
271 }
272 
273 #endif /*__ardour_io_h__ */
274