1 /*
2  * Copyright (C) 2006-2011 David Robillard <d@drobilla.net>
3  * Copyright (C) 2006-2018 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
5  * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #ifndef __ardour_port_h__
23 #define __ardour_port_h__
24 
25 #ifdef WAF_BUILD
26 #include "libardour-config.h"
27 #endif
28 
29 #include <set>
30 #include <string>
31 #include <vector>
32 #include <boost/utility.hpp>
33 #include "pbd/signals.h"
34 
35 #include "ardour/data_type.h"
36 #include "ardour/port_engine.h"
37 #include "ardour/libardour_visibility.h"
38 #include "ardour/types.h"
39 
40 namespace ARDOUR {
41 
42 class AudioEngine;
43 class Buffer;
44 
45 class LIBARDOUR_API Port : public boost::noncopyable
46 {
47 public:
48 	virtual ~Port ();
49 
set_connecting_blocked(bool yn)50 	static void set_connecting_blocked( bool yn ) {
51 		_connecting_blocked = yn;
52 	}
connecting_blocked()53 	static bool connecting_blocked() {
54 		return _connecting_blocked;
55 	}
56 
57 	/** @return Port short name */
name()58 	std::string name () const {
59 		return _name;
60 	}
61 
62 	/** @return Port human readable name */
63 	std::string pretty_name (bool fallback_to_name = false) const;
64 	bool set_pretty_name (const std::string&);
65 
66 	int set_name (std::string const &);
67 
68 	/** @return flags */
flags()69 	PortFlags flags () const {
70 		return _flags;
71 	}
72 
73 	/** @return true if this Port receives input, otherwise false */
receives_input()74 	bool receives_input () const {
75 		return _flags & IsInput;
76 	}
77 
78 	/** @return true if this Port sends output, otherwise false */
sends_output()79 	bool sends_output () const {
80 		return _flags & IsOutput;
81 	}
82 
83 	bool connected () const;
84 	int disconnect_all ();
85 	int get_connections (std::vector<std::string> &) const;
86 
87 	/* connection by name */
88 	bool connected_to (std::string const &) const;
89 	int connect (std::string const &);
90 	int disconnect (std::string const &);
91 
92 	/* connection by Port* */
93 	bool connected_to (Port *) const;
94 	virtual int connect (Port *);
95 	int disconnect (Port *);
96 
97 	void request_input_monitoring (bool);
98 	void ensure_input_monitoring (bool);
99 	bool monitoring_input () const;
100 	int reestablish ();
101 	int reconnect ();
102 
last_monitor()103 	bool last_monitor() const { return _last_monitor; }
set_last_monitor(bool yn)104 	void set_last_monitor (bool yn) { _last_monitor = yn; }
105 
port_handle()106 	PortEngine::PortHandle port_handle() { return _port_handle; }
107 
108 	void get_connected_latency_range (LatencyRange& range, bool playback) const;
109 
110 	void set_private_latency_range (LatencyRange& range, bool playback);
111 	const LatencyRange&  private_latency_range (bool playback) const;
112 
113 	void set_public_latency_range (LatencyRange const& range, bool playback) const;
114 	LatencyRange public_latency_range (bool playback) const;
115 
116 	virtual void reset ();
117 
118 	virtual DataType type () const = 0;
119 	virtual void cycle_start (pframes_t);
120 	virtual void cycle_end (pframes_t) = 0;
121 	virtual void cycle_split () = 0;
122 	virtual Buffer& get_buffer (pframes_t nframes) = 0;
flush_buffers(pframes_t)123 	virtual void flush_buffers (pframes_t /*nframes*/) {}
transport_stopped()124 	virtual void transport_stopped () {}
realtime_locate(bool for_loop_end)125 	virtual void realtime_locate (bool for_loop_end) {}
set_buffer_size(pframes_t)126 	virtual void set_buffer_size (pframes_t) {}
127 
128 	bool physically_connected () const;
externally_connected()129 	uint32_t externally_connected () const { return _externally_connected; }
130 
increment_external_connections()131 	void increment_external_connections() { _externally_connected++; }
decrement_external_connections()132 	void decrement_external_connections() { if (_externally_connected) _externally_connected--; }
133 
134 	PBD::Signal1<void,bool> MonitorInputChanged;
135 	PBD::Signal3<void,boost::shared_ptr<Port>,boost::shared_ptr<Port>, bool > ConnectedOrDisconnected;
136 
137 	static PBD::Signal0<void> PortDrop;
138 	static PBD::Signal0<void> PortSignalDrop;
139 
140 	static void set_speed_ratio (double s);
141 	static void set_cycle_samplecnt (pframes_t n);
142 
port_offset()143 	static samplecnt_t port_offset() { return _global_port_buffer_offset; }
set_global_port_buffer_offset(pframes_t off)144 	static void set_global_port_buffer_offset (pframes_t off) {
145 		_global_port_buffer_offset = off;
146 	}
increment_global_port_buffer_offset(pframes_t n)147 	static void increment_global_port_buffer_offset (pframes_t n) {
148 		_global_port_buffer_offset += n;
149 	}
150 
151 	virtual XMLNode& get_state (void) const;
152 	virtual int set_state (const XMLNode&, int version);
153 
154 	static std::string state_node_name;
155 
cycle_nframes()156 	static pframes_t cycle_nframes () { return _cycle_nframes; }
speed_ratio()157 	static double speed_ratio () { return _speed_ratio; }
resampler_quality()158 	static uint32_t resampler_quality () { return _resampler_quality; }
159 
160 protected:
161 
162 	Port (std::string const &, DataType, PortFlags);
163 
164 	PortEngine::PortPtr _port_handle;
165 
166 	static bool       _connecting_blocked;
167 	static pframes_t  _cycle_nframes; /* access only from process() tree */
168 
169 	static pframes_t  _global_port_buffer_offset; /* access only from process() tree */
170 
171 	LatencyRange _private_playback_latency;
172 	LatencyRange _private_capture_latency;
173 
174 	static double _speed_ratio;
175 	static const uint32_t _resampler_quality; /* also latency of the resampler */
176 
177 private:
178 	std::string _name;  ///< port short name
179 	PortFlags   _flags; ///< flags
180 	bool        _last_monitor;
181 	uint32_t    _externally_connected;
182 
183 	/** ports that we are connected to, kept so that we can
184 	    reconnect to the backend when required
185 	*/
186 	std::set<std::string> _connections;
187 
188 	void port_connected_or_disconnected (boost::weak_ptr<Port>, boost::weak_ptr<Port>, bool);
189 	void signal_drop ();
190 	void session_global_drop ();
191 	void drop ();
192 	PBD::ScopedConnectionList drop_connection;
193 	PBD::ScopedConnection engine_connection;
194 };
195 
196 }
197 
198 #endif /* __ardour_port_h__ */
199