1 /*
2  * Copyright (C) 2013-2018 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2015-2018 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef __libardour_port_engine_h__
21 #define __libardour_port_engine_h__
22 
23 #include <vector>
24 #include <string>
25 
26 #include <stdint.h>
27 
28 #include "ardour/data_type.h"
29 #include "ardour/libardour_visibility.h"
30 #include "ardour/types.h"
31 
32 namespace ARDOUR {
33 
34 class PortManager;
35 
36 /** PortEngine is an abstract base class that defines the functionality
37  * required by Ardour.
38  *
39  * A Port is basically an endpoint for a datastream (which can either be
40  * continuous, like audio, or event-based, like MIDI). Ports have buffers
41  * associated with them into which data can be written (if they are output
42  * ports) and from which data can be read (if they input ports). Ports can be
43  * connected together so that data written to an output port can be read from
44  * an input port. These connections can be 1:1, 1:N OR N:1.
45  *
46  * Ports may be associated with software only, or with hardware.  Hardware
47  * related ports are often referred to as physical, and correspond to some
48  * relevant physical entity on a hardware device, such as an audio jack or a
49  * MIDI connector. Physical ports may be potentially asked to monitor their
50  * inputs, though some implementations may not support this.
51  *
52  * Most physical ports will also be considered "terminal", which means that
53  * data delivered there or read from there will go to or comes from a system
54  * outside of the PortEngine implementation's control (e.g. the analog domain
55  * for audio, or external MIDI devices for MIDI). Non-physical ports can also
56  * be considered "terminal". For example, the output port of a software
57  * synthesizer is a terminal port, because the data contained in its buffer
58  * does not and cannot be considered to come from any other port - it is
59  * synthesized by its owner.
60  *
61  * Ports also have latency associated with them. Each port has a playback
62  * latency and a capture latency:
63  *
64  * <b>capture latency</b>: how long since the data read from the buffer of a
65  *                  port arrived at at a terminal port.  The data will have
66  *                  come from the "outside world" if the terminal port is also
67  *                  physical, or will have been synthesized by the entity that
68  *                  owns the terminal port.
69  *
70  * <b>playback latency</b>: how long until the data written to the buffer of
71  *                   port will reach a terminal port.
72  *
73  *
74  * For more detailed questions about the PortEngine API, consult the JACK API
75  * documentation, on which this entire object is based.
76  */
77 
78 class LIBARDOUR_API ProtoPort {
79   public:
ProtoPort()80 	ProtoPort() {}
~ProtoPort()81 	virtual ~ProtoPort () {}
82 };
83 
84 class LIBARDOUR_API PortEngine
85 {
86 public:
PortEngine(PortManager & pm)87 	PortEngine (PortManager& pm) : manager (pm) {}
~PortEngine()88 	virtual ~PortEngine() {}
89 
90 	/** Return a private, type-free pointer to any data
91 	 * that might be useful to a concrete implementation
92 	 */
93 	virtual void* private_handle() const = 0;
94 
95 	/** Opaque handle to use as reference for Ports
96 	 *
97 	 * The handle needs to be lifetime managed (i.e. a shared_ptr type)
98 	 * in order to allow RCU to provide lock-free cross-thread operations
99 	 * on ports and ports containers.
100 	 *
101 	 * We could theoretically use a template (PortEngine\<T\>) and define
102 	 * PortHandle as T, but this complicates the desired inheritance
103 	 * pattern in which FooPortEngine handles things for the Foo API,
104 	 * rather than being a derivative of PortEngine\<Foo\>.
105 	 *
106 	 * We use this to declare return values and members of structures.
107 	 */
108 	typedef boost::shared_ptr<ProtoPort> PortPtr;
109 
110 	/* We use this to declare arguments to methods/functions, in order to
111 	 * avoid copying shared_ptr<ProtoPort> every time (a practice we use in
112 	 * other contexts where we pass shared_ptr<T>).
113 	 */
114 	typedef PortPtr const & PortHandle;
115 
116 	/** Return the name of this process as used by the port manager
117 	 * when naming ports.
118 	 */
119 	virtual const std::string& my_name() const = 0;
120 
121 	/** Return the maximum size of a port name */
122 	virtual uint32_t port_name_size() const = 0;
123 
124 	/** Set/rename port
125 	 *
126 	 * @param port \ref PortHandle to operate on
127 	 * @param name new name to use for this port
128 	 * @return zero if successful, non-zero otherwise
129 	 */
130 	virtual int         set_port_name (PortHandle port, const std::string& name) = 0;
131 
132 	/** Query port name
133 	 *
134 	 * @param port \ref PortHandle
135 	 * @return the name of the port referred to by @param port . If the port
136 	 *         does not exist, return an empty string.
137 	 */
138 	virtual std::string get_port_name (PortHandle port) const = 0;
139 
140 	/** Query port-flags
141 	 *
142 	 * @param port \ref PortHandle
143 	 * @return the flags of the port referred to by \p port . If the port
144 	 *         does not exist, return PortFlags (0)
145 	 */
146 	virtual PortFlags get_port_flags (PortHandle port) const = 0;
147 
148 	/** Return the port-property value and type for a given key.
149 	 * (eg query a human readable port name)
150 	 *
151 	 * The API follows jack_get_property():
152 	 *
153 	 * @param key The key of the property to retrieve
154 	 * @param value Set to the value of the property if found
155 	 * @param type The type of the property if set (
156 	 *             Type of data, either a MIME type or URI.
157 	 *             If type is empty, the data is assumed to be a UTF-8 encoded string.
158 	 *
159 	 * @return 0 on success, -1 if the @p subject has no @p key property.
160 	 *
161 	 * for available keys, see
162 	 * https://github.com/jackaudio/headers/blob/master/metadata.h
163 	 * https://github.com/drobilla/jackey/blob/master/jackey.h
164 	 */
get_port_property(PortHandle,const std::string & key,std::string & value,std::string & type)165 	virtual int get_port_property (PortHandle, const std::string& key, std::string& value, std::string& type) const { return -1; }
166 
167 	/** Set the port-property value and type for a given key
168 	 *
169 	 * The API follows jack_set_property():
170 	 * @param key The key of the property.
171 	 * @param value The value of the property.
172 	 * @param type The type of the property.
173 	 *
174 	 * @return 0 on success, -1 on error
175 	 */
set_port_property(PortHandle,const std::string & key,const std::string & value,const std::string & type)176 	virtual int set_port_property (PortHandle, const std::string& key, const std::string& value, const std::string& type) { return -1; }
177 
178 	/** Return a reference to a port with the fullname \p name .
179 	 *
180 	 * @param name Full port-name to lookup
181 	 * @return PortHandle if lookup was successful, or an "empty" PortHandle (analogous to a null pointer) if no such port exists.
182 	 */
183 	virtual PortPtr get_port_by_name (const std::string& name) const = 0;
184 
185 	/** Find the set of ports whose names, types and flags match
186 	 * specified values, place the names of each port into \p ports .
187 	 *
188 	 * @param port_name_pattern match by given pattern. To avoid selecting by name, pass an empty string.
189 	 * @param type filter by given type; pass DataType::NIL to match all types.
190 	 * @param flags filter by flags, pass PortFlags (0) to avoid selecting by flags.
191 	 * @param ports array filled with matching port-names
192 	 * @return the count of the number found
193 	 */
194 	virtual int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>& ports) const = 0;
195 
196 	/** Lookup data type of a port
197 	 *
198 	 * @param port \ref PortHandle of the port to lookup.
199 	 * @return the Ardour data type handled by the port referred to by \p port .
200 	 *         DataType::NIL is returned if the port does not exist.
201 	 */
202 	virtual DataType port_data_type (PortHandle port) const = 0;
203 
204 	/** Create a new port whose fullname will be the conjunction of my_name(),
205 	 * ":" and \p shortname . The port will handle data specified by \p type
206 	 * and will have the flags given by \p flags . If successful,
207 	 *
208 	 * @param shortname Name of port to create
209 	 * @param type type of port to create
210 	 * @param flags flags of the port to create
211 	 * @return a reference to the port, otherwise return a null pointer.
212 	 */
213 	virtual PortPtr register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags) = 0;
214 
215 	/* Destroy the port referred to by \p port, including all resources
216 	 * associated with it. This will also disconnect \p port from any ports it
217 	 * is connected to.
218 	 *
219 	 * @param port \ref PortHandle of the port to destroy
220 	 */
221 	virtual void    unregister_port (PortHandle port) = 0;
222 
223 	/* Connection management */
224 
225 	/** Ensure that data written to the port named by \p src will be
226 	 * readable from the port named by \p dst
227 	 *
228 	 * @param src name of source port to connect
229 	 * @param dst name of destination (sink) port
230 	 * @return zero on success, non-zero otherwise.
231 	 */
232 	virtual int   connect (const std::string& src, const std::string& dst) = 0;
233 
234 	/** Remove any existing connection between the ports named by \p src and
235 	 * \p dst
236 	 *
237 	 * @param src name of source port to dis-connect to disconnect from
238 	 * @param dst name of destination (sink) port to disconnect
239 	 * @return zero on success, non-zero otherwise.
240 	 */
241 	virtual int   disconnect (const std::string& src, const std::string& dst) = 0;
242 
243 	/** Ensure that data written to the port referenced by \p src will be
244 	 * readable from the port named by \p dst
245 	 *
246 	 * @param src \ref PortHandle of source port to connect
247 	 * @param dst \ref PortHandle of destination (sink) port
248 	 * @return zero on success, non-zero otherwise.
249 	 */
250 	virtual int   connect (PortHandle src, const std::string& dst) = 0;
251 
252 	/** Remove any existing connection between the port referenced by \p src and
253 	 * the port named \p dst
254 	 *
255 	 * @param src \ref PortHandle of source port to disconnect from
256 	 * @param dst \ref PortHandle of destination (sink) port to disconnect
257 	 * @return zero on success, non-zero otherwise.
258 	 */
259 	virtual int   disconnect (PortHandle src, const std::string& dst) = 0;
260 
261 	/** Remove all connections between the port referred to by \p port and
262 	 * any other ports.
263 	 *
264 	 * @param port \ref PortHandle of port to disconnect
265 	 * @return zero on success, non-zero otherwise.
266 	 */
267 	virtual int   disconnect_all (PortHandle port) = 0;
268 
269 	/** Test if given \p port is connected
270 	 *
271 	 * @param port \ref PortHandle of port to test
272 	 * @param process_callback_safe true if this method is not called from rt-context of backend callbacks
273 	 * @return true if the port referred to by \p port has any connections to other ports. Return false otherwise.
274 	 */
275 	virtual bool  connected (PortHandle port, bool process_callback_safe = true) = 0;
276 
277 	/** Test port connection
278 	 *
279 	 * @param port \ref PortHandle of source port to test
280 	 * @param name name of destination to test
281 	 * @param process_callback_safe true if this method is not called from rt-context of backend callbacks
282 	 * @return true if the port referred to by \p port is connected to the port named by \p name . Return false otherwise.
283 	 */
284 	virtual bool  connected_to (PortHandle port, const std::string& name, bool process_callback_safe = true) = 0;
285 
286 	/** Test if given \p port is is connected to physical I/O ports.
287 	 *
288 	 * @param port \ref PortHandle of source port to test
289 	 * @param process_callback_safe true if this method is not called from rt-context of backend callbacks
290 	 * @return true if the port referred to by \p port has any connections
291 	 *         to ports marked with the PortFlag IsPhysical. Return false otherwise.
292 	 */
293 	virtual bool  physically_connected (PortHandle port, bool process_callback_safe = true) = 0;
294 
295 	/** Test if given \p port is has external connections.
296 	 *
297 	 * @param port \ref PortHandle of port to test
298 	 * @param process_callback_safe true if this method is not called from rt-context of backend callbacks
299 	 * @return true if the port referred to by \p port has any connections
300 	 *         to external, not-ardour owned, ports.
301 	 */
302 	virtual bool  externally_connected (PortHandle port, bool process_callback_safe = true) {
303 		/* only with JACK, provides client ports that are not physical */
304 		return physically_connected (port, process_callback_safe);
305 	}
306 
307 	/** Place the names of all ports connected to the port named by
308 	 * \p port into \p names .
309 	 *
310 	 * @param port \ref PortHandle
311 	 * @param names array or returned port-names
312 	 * @param process_callback_safe true if this method is not called from rt-context of backend callbacks
313 	 * @return number of connections found
314 	 */
315 	virtual int   get_connections (PortHandle port, std::vector<std::string>& names, bool process_callback_safe = true) = 0;
316 
317 	/* MIDI */
318 
319 	/** Retrieve a MIDI event from the data at \p port_buffer . The event
320 	 * number to be retrieved is given by \p event_index (a value of zero
321 	 * indicates that the first event in the port_buffer should be retrieved).
322 	 *
323 	 * The data associated with the event will be copied into the buffer at
324 	 * \p buf and the number of bytes written will be stored in \p size .
325 	 * The timestamp of the event (which is always relative to the start
326 	 * of the current process cycle, in samples) will be stored in \p timestamp .
327 	 *
328 	 * @param timestamp time in samples relative to the current cycle start
329 	 * @param size number of bytes read into \p buf
330 	 * @param buf raw MIDI data
331 	 * @param port_buffer the midi-port buffer
332 	 * @param event_index index of event to retrieve
333 	 * @return 0 on success, -1 otherwise
334 	 */
335 	virtual int      midi_event_get (pframes_t& timestamp, size_t& size, uint8_t const** buf, void* port_buffer, uint32_t event_index) = 0;
336 
337 	/** Place a MIDI event consisting of \p size bytes copied from the data
338 	 * at \p buffer into the port buffer referred to by \p port_buffer .
339 	 * The MIDI event will be marked with a time given by \p timestamp .
340 	 *
341 	 * Events  must be added monotonically to a port buffer. An attempt to
342 	 * add a non-monotonic event (e.g. out-of-order) will cause this method
343 	 * to return a failure status.
344 	 *
345 	 * @param port_buffer the midi-port buffer
346 	 * @param timestamp time in samples relative to the current cycle start
347 	 * @param buffer raw MIDI data to emplace
348 	 * @param size number of bytes of \p buffer
349 	 * @return zero on success, non-zero otherwise.
350 	 */
351 	virtual int      midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) = 0;
352 
353 	/** Query the number of MIDI events in the data at \p port_buffer
354 	 *
355 	 * @param port_buffer the midi-port buffer
356 	 * @return the number of MIDI events in the data at \p port_buffer
357 	*/
358 	virtual uint32_t get_midi_event_count (void* port_buffer) = 0;
359 
360 	/** Clear the buffer at \p port_buffer of all MIDI events.
361 	 *
362 	 * After a call to this method, an immediate, subsequent call to
363 	 * \ref get_midi_event_count with the same \p port_buffer argument must
364 	 * return zero.
365 	 *
366 	 * @param port_buffer the buffer to clear
367 	 */
368 	virtual void     midi_clear (void* port_buffer) = 0;
369 
370 	/* Monitoring */
371 
372 	/** Return true if the implementation can offer input monitoring.
373 	 *
374 	 * Input monitoring involves the (selective) routing of incoming data
375 	 * to an outgoing data stream, without the data being passed to the CPU.
376 	 *
377 	 * Only certain audio hardware can provide this, and only certain audio
378 	 * APIs can offer it.
379 	 */
380 	virtual bool  can_monitor_input() const = 0;
381 
382 	/** Increment or decrement the number of requests to monitor the input
383 	 * of the hardware channel represented by the port referred to by
384 	 * \p port .
385 	 *
386 	 * If the number of requests rises above zero, input monitoring will
387 	 * be enabled (if can_monitor_input() returns true for the implementation).
388 	 *
389 	 * If the number of requests falls to zero, input monitoring will be
390 	 * disabled (if can_monitor_input() returns true for the implementation)
391 	 *
392 	 * @param port \ref PortHandle
393 	 * @param yn true to enable hardware monitoring, false to disable
394 	 * @return 0 on success, -1 otherwise
395 	 */
396 	virtual int   request_input_monitoring (PortHandle port, bool yn) = 0;
397 
398 	/* Force input monitoring of the hardware channel represented by the port
399 	 * referred to by \p port to be on or off, depending on the true/false
400 	 * status of \p yn. The request count is ignored when using this
401 	 * method, so if this is called with \p yn set to false, input monitoring will
402 	 * be disabled regardless of the number of requests to enable it.
403 	 *
404 	 * @param port \ref PortHandle
405 	 * @param yn true to enable hardware monitoring, false to disable
406 	 * @return 0 on success, -1 otherwise
407 	 */
408 	virtual int   ensure_input_monitoring (PortHandle port, bool yn) = 0;
409 
410 	/** Query status of hardware monitoring for given \p port
411 	 *
412 	 * @param port \ref PortHandle to test
413 	 * @return true if input monitoring is enabled for the hardware channel
414 	 *         represented by the port referred to by \p port .
415 	 *         Return false otherwise.
416 	 */
417 	virtual bool  monitoring_input (PortHandle port) = 0;
418 
419 	/* Latency management */
420 
421 	/** Set the latency range for the port referred to by \p port to
422 	 * \p r . The playback range will be set if \p for_playback is true,
423 	 * otherwise the capture range will be set.
424 	 *
425 	 * @param port \ref PortHandle to operate on
426 	 * @param for_playback When true, playback latency is set: How long will it be
427 	 *                     until the signal arrives at the edge of the process graph.
428 	 *                     When false the capture latency is set: ow long has it been
429 	 *                     since the signal arrived at the edge of the process graph.
430 	 * @param r min/max latency for given port.
431 	 */
432 	virtual void          set_latency_range (PortHandle port, bool for_playback, LatencyRange r) = 0;
433 
434 	/** Return the latency range for the port referred to by \p port .
435 	 * The playback range will be returned if @param for_playback is true,
436 	 * otherwise the capture range will be returned.
437 	 *
438 	 * @param port The PortHandle to query
439 	 * @param for_playback When true, playback (downstream) latency is queried,
440 	 *                     false for capture (upstream) latency.
441 	 */
442 	virtual LatencyRange  get_latency_range (PortHandle port, bool for_playback) = 0;
443 
444 	/* Discovering physical ports */
445 
446 	/** Return true if the port referred to by \p port has the IsPhysical
447 	 * flag set. Return false otherwise.
448 	 *
449 	 * @param port \ref PortHandle to query
450 	 */
451 	virtual bool      port_is_physical (PortHandle port) const = 0;
452 
453 	/** Store into \p names the names of all ports with the IsOutput and
454 	 * IsPhysical flag set, that handle data of type \p type .
455 	 *
456 	 * This can be used to discover outputs associated with hardware devices.
457 	 *
458 	 * @param type Data-type to lookup
459 	 * @param names return value to populate with names
460 	 */
461 	virtual void      get_physical_outputs (DataType type, std::vector<std::string>& names) = 0;
462 
463 	/** Store into @param names the names of all ports with the IsInput and
464 	 * IsPhysical flags set, that handle data of type @param type .
465 	 *
466 	 * This can be used to discover inputs associated with hardware devices.
467 	 */
468 	virtual void      get_physical_inputs (DataType type, std::vector<std::string>& names) = 0;
469 
470 	/** @return the total count (possibly mixed between different data types)
471 	 * of the number of ports with the IsPhysical and IsOutput flags set.
472 	 */
473 	virtual ChanCount n_physical_outputs () const = 0;
474 
475 	/** @return the total count (possibly mixed between different data types)
476 	 * of the number of ports with the IsPhysical and IsInput flags set.
477 	 */
478 	virtual ChanCount n_physical_inputs () const = 0;
479 
480 	/** Return the address of the memory area where data for the port can be
481 	 * written (if the port has the PortFlag IsOutput set) or read (if the port
482 	 * has the PortFlag IsInput set).
483 	 *
484 	 * The return value is untyped because buffers containing different data
485 	 * depending on the port type.
486 	 *
487 	 * @param port \ref PortHandle
488 	 * @param off memory offset
489 	 * @return pointer to raw memory area
490 	 */
491 	virtual void* get_buffer (PortHandle port, pframes_t off) = 0;
492 
493 	/* MIDI ports (the ones in libmidi++) need this to be able to correctly
494 	 * schedule MIDI events within their buffers. It is a bit odd that we
495 	 * expose this here, because it is also exposed by AudioBackend, but they
496 	 * only have access to a PortEngine object, not an AudioBackend.
497 	 *
498 	 * Return the time according to the sample clock in use when the current
499 	 * buffer process cycle began.
500 	 *
501 	 * XXX to be removed after some more design cleanup.
502 	 */
503 	virtual samplepos_t sample_time_at_cycle_start () = 0;
504 
505 protected:
506 	PortManager& manager;
507 };
508 
509 } // namespace
510 
511 #endif /* __libardour_port_engine_h__ */
512