2 * Copyright (C) 2013-2018 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2015-2018 Robin Gareus <robin@gareus.org>
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.
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.
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.
20 #ifndef __libardour_port_engine_h__
21 #define __libardour_port_engine_h__
28 #include "ardour/data_type.h"
29 #include "ardour/libardour_visibility.h"
30 #include "ardour/types.h"
36 /** PortEngine is an abstract base class that defines the functionality
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.
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.
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.
61 * Ports also have latency associated with them. Each port has a playback
62 * latency and a capture latency:
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.
70 * <b>playback latency</b>: how long until the data written to the buffer of
71 * port will reach a terminal port.
74 * For more detailed questions about the PortEngine API, consult the JACK API
75 * documentation, on which this entire object is based.
78 class LIBARDOUR_API PortEngine
81 PortEngine (PortManager& pm) : manager (pm) {}
82 virtual ~PortEngine() {}
84 /** Return a private, type-free pointer to any data
85 * that might be useful to a concrete implementation
87 virtual void* private_handle() const = 0;
89 /** Opaque handle to use as reference for Ports
91 * We use void* here so that the API can be defined for any implementation.
93 * We could theoretically use a template (PortEngine\<T\>) and define
94 * PortHandle as T, but this complicates the desired inheritance
95 * pattern in which FooPortEngine handles things for the Foo API,
96 * rather than being a derivative of PortEngine\<Foo\>.
98 typedef void* PortHandle;
100 /** Return the name of this process as used by the port manager
103 virtual const std::string& my_name() const = 0;
105 /** Return the maximum size of a port name */
106 virtual uint32_t port_name_size() const = 0;
110 * @param port \ref PortHandle to operate on
111 * @param name new name to use for this port
112 * @return zero if successful, non-zero otherwise
114 virtual int set_port_name (PortHandle port, const std::string& name) = 0;
118 * @param port \ref PortHandle
119 * @return the name of the port referred to by @param port . If the port
120 * does not exist, return an empty string.
122 virtual std::string get_port_name (PortHandle port) const = 0;
126 * @param port \ref PortHandle
127 * @return the flags of the port referred to by \param port . If the port
128 * does not exist, return PortFlags (0)
130 virtual PortFlags get_port_flags (PortHandle port) const = 0;
132 /** Return the port-property value and type for a given key.
133 * (eg query a human readable port name)
135 * The API follows jack_get_property():
137 * @param key The key of the property to retrieve
138 * @param value Set to the value of the property if found
139 * @param type The type of the property if set (
140 * Type of data, either a MIME type or URI.
141 * If type is empty, the data is assumed to be a UTF-8 encoded string.
143 * @return 0 on success, -1 if the @p subject has no @p key property.
145 * for available keys, see
146 * https://github.com/jackaudio/headers/blob/master/metadata.h
147 * https://github.com/drobilla/jackey/blob/master/jackey.h
149 virtual int get_port_property (PortHandle, const std::string& key, std::string& value, std::string& type) const { return -1; }
151 /** Set the port-property value and type for a given key
153 * The API follows jack_set_property():
154 * @param key The key of the property.
155 * @param value The value of the property.
156 * @param type The type of the property.
158 * @return 0 on success, -1 on error
160 virtual int set_port_property (PortHandle, const std::string& key, const std::string& value, const std::string& type) { return -1; }
162 /** Return a reference to a port with the fullname \param name .
164 * @param name Full port-name to lookup
165 * @return PortHandle if lookup was successful, or an "empty" PortHandle (analogous to a null pointer) if no such port exists.
167 virtual PortHandle get_port_by_name (const std::string& name) const = 0;
169 /** Find the set of ports whose names, types and flags match
170 * specified values, place the names of each port into \param ports .
172 * @param port_name_pattern match by given pattern. To avoid selecting by name, pass an empty string.
173 * @param type filter by given type; pass DataType::NIL to match all types.
174 * @param flags filter by flags, pass PortFlags (0) to avoid selecting by flags.
175 * @return the count of the number found
177 virtual int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>& ports) const = 0;
179 /** Lookup data type of a port
181 * @param port \ref PortHandle of the port to lookup.
182 * @return the Ardour data type handled by the port referred to by \param port .
183 * DataType::NIL is returned if the port does not exist.
185 virtual DataType port_data_type (PortHandle port) const = 0;
187 /** Create a new port whose fullname will be the conjunction of my_name(),
188 * ":" and \param shortname . The port will handle data specified by \param type
189 * and will have the flags given by \param flags . If successful,
191 * @param shortname Name of port to create
192 * @param type type of port to create
193 * @param flags flags of the port to create
194 * @return a reference to the port, otherwise return a null pointer.
196 virtual PortHandle register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags) = 0;
198 /* Destroy the port referred to by \param port, including all resources
199 * associated with it. This will also disconnect \param port from any ports it
202 * @param port \ref PortHandle of the port to destroy
204 virtual void unregister_port (PortHandle port) = 0;
206 /* Connection management */
208 /** Ensure that data written to the port named by \param src will be
209 * readable from the port named by \param dst
211 * @param src name of source port to connect
212 * @param dst name of destination (sink) port
213 * @return zero on success, non-zero otherwise.
215 virtual int connect (const std::string& src, const std::string& dst) = 0;
217 /** Remove any existing connection between the ports named by \param src and
220 * @param src name of source port to dis-connect to disconnect from
221 * @param dst name of destination (sink) port to disconnect
222 * @return zero on success, non-zero otherwise.
224 virtual int disconnect (const std::string& src, const std::string& dst) = 0;
226 /** Ensure that data written to the port referenced by \param src will be
227 * readable from the port named by \param dst
229 * @param src \ref PortHandle of source port to connect
230 * @param dst \ref PortHandle of destination (sink) port
231 * @return zero on success, non-zero otherwise.
233 virtual int connect (PortHandle src, const std::string& dst) = 0;
235 /** Remove any existing connection between the port referenced by \param src and
236 * the port named \param dst
238 * @param src \ref PortHandle of source port to disconnect from
239 * @param dst \ref PortHandle of destination (sink) port to disconnect
240 * @return zero on success, non-zero otherwise.
242 virtual int disconnect (PortHandle src, const std::string& dst) = 0;
244 /** Remove all connections between the port referred to by \param port and
247 * @param port \ref PortHandle of port to disconnect
248 * @return zero on success, non-zero otherwise.
250 virtual int disconnect_all (PortHandle port) = 0;
252 /** Test if given \param port is connected
254 * @param port \ref PortHandle of port to test
255 * @param process_callback_safe true if this method is not called from rt-context of backend callbacks
256 * @return true if the port referred to by \param port has any connections to other ports. Return false otherwise.
258 virtual bool connected (PortHandle port, bool process_callback_safe = true) = 0;
260 /** Test port connection
262 * @param port \ref PortHandle of source port to test
263 * @param name name of destination to test
264 * @param process_callback_safe true if this method is not called from rt-context of backend callbacks
265 * @return true if the port referred to by \param port is connected to the port named by \param name . Return false otherwise.
267 virtual bool connected_to (PortHandle port, const std::string& name, bool process_callback_safe = true) = 0;
269 /** Test if given \param port is is connected to physical I/O ports.
271 * @param port \ref PortHandle of source 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 \param port has any connections
274 * to ports marked with the PortFlag IsPhysical. Return false otherwise.
276 virtual bool physically_connected (PortHandle port, bool process_callback_safe = true) = 0;
278 /** Test if given \param port is has external connections.
280 * @param port \ref PortHandle of port 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 \param port has any connections
283 * to external, not-ardour owned, ports.
285 virtual bool externally_connected (PortHandle port, bool process_callback_safe = true) {
286 /* only with JACK, provides client ports that are not physical */
287 return physically_connected (port, process_callback_safe);
290 /** Place the names of all ports connected to the port named by
291 * \param port into \param names .
293 * @param port \ref PortHandle
294 * @param names array or returned port-names
295 * @param process_callback_safe true if this method is not called from rt-context of backend callbacks
296 * @return number of connections found
298 virtual int get_connections (PortHandle port, std::vector<std::string>& names, bool process_callback_safe = true) = 0;
302 /** Retrieve a MIDI event from the data at \param port_buffer . The event
303 * number to be retrieved is given by \param event_index (a value of zero
304 * indicates that the first event in the port_buffer should be retrieved).
306 * The data associated with the event will be copied into the buffer at
307 * \param buf and the number of bytes written will be stored in \param size .
308 * The timestamp of the event (which is always relative to the start
309 * of the current process cycle, in samples) will be stored in \param timestamp .
311 * @param timestamp time in samples relative to the current cycle start
312 * @param size number of bytes read into \param buf
313 * @param buf raw MIDI data
314 * @param port_buffer the midi-port buffer
315 * @param event_index index of event to retrieve
316 * @return 0 on success, -1 otherwise
318 virtual int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t const** buf, void* port_buffer, uint32_t event_index) = 0;
320 /** Place a MIDI event consisting of \param size bytes copied from the data
321 * at \param buffer into the port buffer referred to by \param port_buffer .
322 * The MIDI event will be marked with a time given by \param timestamp .
324 * Events must be added monotonically to a port buffer. An attempt to
325 * add a non-monotonic event (e.g. out-of-order) will cause this method
326 * to return a failure status.
328 * @param port_buffer the midi-port buffer
329 * @param timestamp time in samples relative to the current cycle start
330 * @param buffer raw MIDI data to emplace
331 * @param size number of bytes of \param buffer
332 * @return zero on success, non-zero otherwise.
334 virtual int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) = 0;
336 /** Query the number of MIDI events in the data at \param port_buffer
338 * @param port_buffer the midi-port buffer
339 * @return the number of MIDI events in the data at \param port_buffer
341 virtual uint32_t get_midi_event_count (void* port_buffer) = 0;
343 /** Clear the buffer at \param port_buffer of all MIDI events.
345 * After a call to this method, an immediate, subsequent call to
346 * \ref get_midi_event_count with the same \param port_buffer argument must
349 * @param port_buffer the buffer to clear
351 virtual void midi_clear (void* port_buffer) = 0;
355 /** Return true if the implementation can offer input monitoring.
357 * Input monitoring involves the (selective) routing of incoming data
358 * to an outgoing data stream, without the data being passed to the CPU.
360 * Only certain audio hardware can provide this, and only certain audio
363 virtual bool can_monitor_input() const = 0;
365 /** Increment or decrement the number of requests to monitor the input
366 * of the hardware channel represented by the port referred to by
369 * If the number of requests rises above zero, input monitoring will
370 * be enabled (if can_monitor_input() returns true for the implementation).
372 * If the number of requests falls to zero, input monitoring will be
373 * disabled (if can_monitor_input() returns true for the implementation)
375 * @param port \ref PortHandle
376 * @param yn true to enable hardware monitoring, false to disable
377 * @return 0 on success, -1 otherwise
379 virtual int request_input_monitoring (PortHandle port, bool yn) = 0;
381 /* Force input monitoring of the hardware channel represented by the port
382 * referred to by \param port to be on or off, depending on the true/false
383 * status of \param yn. The request count is ignored when using this
384 * method, so if this is called with \param yn set to false, input monitoring will
385 * be disabled regardless of the number of requests to enable it.
387 * @param port \ref PortHandle
388 * @param yn true to enable hardware monitoring, false to disable
389 * @return 0 on success, -1 otherwise
391 virtual int ensure_input_monitoring (PortHandle port, bool yn) = 0;
393 /** Query status of hardware monitoring for given \param port
395 * @param port \ref PortHandle to test
396 * @return true if input monitoring is enabled for the hardware channel
397 * represented by the port referred to by \param port .
398 * Return false otherwise.
400 virtual bool monitoring_input (PortHandle port) = 0;
402 /* Latency management */
404 /** Set the latency range for the port referred to by \param port to
405 * \param r . The playback range will be set if \param for_playback is true,
406 * otherwise the capture range will be set.
408 * @param port \ref PortHandle to operate on
409 * @param for_playback When true, playback latency is set: How long will it be
410 * until the signal arrives at the edge of the process graph.
411 * When false the capture latency is set: ow long has it been
412 * since the signal arrived at the edge of the process graph.
413 * @param r min/max latency for given port.
415 virtual void set_latency_range (PortHandle port, bool for_playback, LatencyRange r) = 0;
417 /** Return the latency range for the port referred to by \param port .
418 * The playback range will be returned if @param for_playback is true,
419 * otherwise the capture range will be returned.
421 * @param port The PortHandle to query
422 * @param for_playback When true, playback (downstream) latency is queried,
423 * false for capture (upstream) latency.
425 virtual LatencyRange get_latency_range (PortHandle port, bool for_playback) = 0;
427 /* Discovering physical ports */
429 /** Return true if the port referred to by \param port has the IsPhysical
430 * flag set. Return false otherwise.
432 * @param port \ref PortHandle to query
434 virtual bool port_is_physical (PortHandle port) const = 0;
436 /** Store into \param names the names of all ports with the IsOutput and
437 * IsPhysical flag set, that handle data of type \param type .
439 * This can be used to discover outputs associated with hardware devices.
441 * @param type Data-type to lookup
442 * @param names return value to populate with names
444 virtual void get_physical_outputs (DataType type, std::vector<std::string>& names) = 0;
446 /** Store into @param names the names of all ports with the IsInput and
447 * IsPhysical flags set, that handle data of type @param type .
449 * This can be used to discover inputs associated with hardware devices.
451 virtual void get_physical_inputs (DataType type, std::vector<std::string>& names) = 0;
453 /** @return the total count (possibly mixed between different data types)
454 * of the number of ports with the IsPhysical and IsOutput flags set.
456 virtual ChanCount n_physical_outputs () const = 0;
458 /** @return the total count (possibly mixed between different data types)
459 * of the number of ports with the IsPhysical and IsInput flags set.
461 virtual ChanCount n_physical_inputs () const = 0;
463 /** Return the address of the memory area where data for the port can be
464 * written (if the port has the PortFlag IsOutput set) or read (if the port
465 * has the PortFlag IsInput set).
467 * The return value is untyped because buffers containing different data
468 * depending on the port type.
470 * @param port \ref PortHandle
471 * @param off memory offset
472 * @return pointer to raw memory area
474 virtual void* get_buffer (PortHandle port, pframes_t off) = 0;
476 /* MIDI ports (the ones in libmidi++) need this to be able to correctly
477 * schedule MIDI events within their buffers. It is a bit odd that we
478 * expose this here, because it is also exposed by AudioBackend, but they
479 * only have access to a PortEngine object, not an AudioBackend.
481 * Return the time according to the sample clock in use when the current
482 * buffer process cycle began.
484 * XXX to be removed after some more design cleanup.
486 virtual samplepos_t sample_time_at_cycle_start () = 0;
489 PortManager& manager;
494 #endif /* __libardour_port_engine_h__ */