add new API for retrieving port flags from backend
[ardour.git] / libs / ardour / ardour / port_engine.h
1 /*
2     Copyright (C) 2013 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
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 PortEngine
79 {
80 public:
81         PortEngine (PortManager& pm) : manager (pm) {}
82         virtual ~PortEngine() {}
83
84         /** Return a private, type-free pointer to any data
85          * that might be useful to a concrete implementation
86          */
87         virtual void* private_handle() const = 0;
88
89         /* We use void* here so that the API can be defined for any implementation.
90          *
91          * We could theoretically use a template (PortEngine<T>) and define
92          * PortHandle as T, but this complicates the desired inheritance
93          * pattern in which FooPortEngine handles things for the Foo API,
94          * rather than being a derivative of PortEngine<Foo>.
95          */
96
97         typedef void* PortHandle;
98
99         /** Return the name of this process as used by the port manager
100          * when naming ports.
101          */
102         virtual const std::string& my_name() const = 0;
103
104         /** Return true if the underlying mechanism/API is still available
105          * for us to utilize. return false if some or all of the AudioBackend
106          * API can no longer be effectively used.
107          */
108         virtual bool available() const = 0;
109
110         /** Return the maximum size of a port name
111         */
112         virtual uint32_t port_name_size() const = 0;
113
114         /** Returns zero if the port referred to by @param port was set to @param
115          * name. Return non-zero otherwise.
116          */
117         virtual int         set_port_name (PortHandle port, const std::string& name) = 0;
118         /** Return the name of the port referred to by @param port. If the port
119          * does not exist, return an empty string.
120          */
121         virtual std::string get_port_name (PortHandle) const = 0;
122
123         /** Return the flags of the port referred to by @param port. If the port
124          * does not exist, return an empty string.
125          */
126         virtual PortFlags get_port_flags (PortHandle) const = 0;
127
128         /** Return the port-property value and type for a given key.
129          * (eg query a human readable port name)
130          *
131          * The API follows jack_get_property():
132          *
133          * @param key The key of the property to retrieve
134          * @param value Set to the value of the property if found
135          * @param type The type of the property if set (
136          *             Type of data, either a MIME type or URI.
137          *             If type is empty, the data is assumed to be a UTF-8 encoded string.
138          *
139          * @return 0 on success, -1 if the @p subject has no @p key property.
140          *
141          * for available keys, see
142          * https://github.com/jackaudio/headers/blob/master/metadata.h
143          * https://github.com/drobilla/jackey/blob/master/jackey.h
144          */
145         virtual int get_port_property (PortHandle, const std::string& key, std::string& value, std::string& type) const { return -1; }
146
147         /** Set the port-property value and type for a given key
148          *
149          * The API follows jack_set_property():
150          * @param key The key of the property.
151          * @param value The value of the property.
152          * @param type The type of the property.
153          *
154          * @return 0 on success, -1 on error
155          */
156         virtual int set_port_property (PortHandle, const std::string& key, const std::string& value, const std::string& type) { return -1; }
157
158         /** Return a reference to a port with the fullname @param name. Return
159          * an "empty" PortHandle (analogous to a null pointer) if no such port exists.
160          */
161         virtual PortHandle get_port_by_name (const std::string&) const = 0;
162
163         /** Find the set of ports whose names, types and flags match
164          * specified values, place the names of each port into @param ports,
165          * and return the count of the number found.
166          *
167          * To avoid selecting by name, pass an empty string for @param
168          * port_name_pattern.
169          *
170          * To avoid selecting by type, pass DataType::NIL as @param type.
171          *
172          * To avoid selecting by flags, pass PortFlags (0) as @param flags.
173          */
174         virtual int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>& ports) const = 0;
175
176         /** Return the Ardour data type handled by the port referred to by @param
177          * port. Returns DataType::NIL if the port does not exist.
178          */
179         virtual DataType port_data_type (PortHandle port) const = 0;
180
181         /** Create a new port whose fullname will be the conjuction of my_name(),
182          * ":" and @param shortname. The port will handle data specified by @param
183          * type and will have the flags given by @param flags. If successfull,
184          * return a reference to the port, otherwise return a null pointer.
185          */
186         virtual PortHandle register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags) = 0;
187
188         /* Destroy the port referred to by @param port, including all resources
189          * associated with it. This will also disconnect @param port from any ports it
190          * is connected to.
191          */
192         virtual void       unregister_port (PortHandle) = 0;
193
194         /* Connection management */
195
196         /** Ensure that data written to the port named by @param src will be
197          * readable from the port named by @param dst. Return zero on success,
198          * non-zero otherwise.
199          */
200         virtual int   connect (const std::string& src, const std::string& dst) = 0;
201
202         /** Remove any existing connection between the ports named by @param src and
203          * @param dst. Return zero on success, non-zero otherwise.
204          */
205         virtual int   disconnect (const std::string& src, const std::string& dst) = 0;
206
207
208         /** Ensure that data written to the port referenced by @param portwill be
209          * readable from the port named by @param dst. Return zero on success,
210          * non-zero otherwise.
211          */
212         virtual int   connect (PortHandle src, const std::string& dst) = 0;
213         /** Remove any existing connection between the port referenced by @param src and
214          * the port named @param dst. Return zero on success, non-zero otherwise.
215          */
216         virtual int   disconnect (PortHandle src, const std::string& dst) = 0;
217
218         /** Remove all connections between the port referred to by @param port and
219          * any other ports. Return zero on success, non-zero otherwise.
220          */
221         virtual int   disconnect_all (PortHandle port) = 0;
222
223         /** Return true if the port referred to by @param port has any connections
224          * to other ports. Return false otherwise.
225          */
226         virtual bool  connected (PortHandle port, bool process_callback_safe = true) = 0;
227         /** Return true if the port referred to by @param port is connected to
228          * the port named by @param name. Return false otherwise.
229          */
230         virtual bool  connected_to (PortHandle, const std::string& name, bool process_callback_safe = true) = 0;
231
232         /** Return true if the port referred to by @param port has any connections
233          * to ports marked with the PortFlag IsPhysical. Return false otherwise.
234          */
235         virtual bool  physically_connected (PortHandle port, bool process_callback_safe = true) = 0;
236
237         /** Return true if the port referred to by @param port has any connections
238          * to external, not-ardour owned, ports.
239          */
240         virtual bool  externally_connected (PortHandle port, bool process_callback_safe = true) {
241                 /* only with JACK, provides client ports that are not physical */
242                 return physically_connected (port, process_callback_safe);
243         }
244
245         /** Place the names of all ports connected to the port named by @param
246          * ports into @param names, and return the number of connections.
247          */
248         virtual int   get_connections (PortHandle port, std::vector<std::string>& names, bool process_callback_safe = true) = 0;
249
250         /* MIDI */
251
252         /** Retrieve a MIDI event from the data at @param port_buffer. The event
253                 number to be retrieved is given by @param event_index (a value of zero
254                 indicates that the first event in the port_buffer should be retrieved).
255          *
256          * The data associated with the event will be copied into the buffer at
257          * @param buf and the number of bytes written will be stored in @param
258          * size. The timestamp of the event (which is always relative to the start
259          * of the current process cycle, in samples) will be stored in @param
260          * timestamp
261          */
262         virtual int      midi_event_get (pframes_t& timestamp, size_t& size, uint8_t const** buf, void* port_buffer, uint32_t event_index) = 0;
263
264         /** Place a MIDI event consisting of @param size bytes copied from the data
265          * at @param buf into the port buffer referred to by @param
266          * port_buffer. The MIDI event will be marked with a time given by @param
267          * timestamp. Return zero on success, non-zero otherwise.
268          *
269          * Events  must be added monotonically to a port buffer. An attempt to
270          * add a non-monotonic event (e.g. out-of-order) will cause this method
271          * to return a failure status.
272          */
273         virtual int      midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) = 0;
274
275         /** Return the number of MIDI events in the data at @param port_buffer
276         */
277         virtual uint32_t get_midi_event_count (void* port_buffer) = 0;
278
279         /** Clear the buffer at @param port_buffer of all MIDI events.
280          *
281          * After a call to this method, an immediate, subsequent call to
282          * get_midi_event_count() with the same @param port_buffer argument must
283          * return zero.
284          */
285         virtual void     midi_clear (void* port_buffer) = 0;
286
287         /* Monitoring */
288
289         /** Return true if the implementation can offer input monitoring.
290          *
291          * Input monitoring involves the (selective) routing of incoming data
292          * to an outgoing data stream, without the data being passed to the CPU.
293          *
294          * Only certain audio hardware can provide this, and only certain audio
295          * APIs can offer it.
296          */
297         virtual bool  can_monitor_input() const = 0;
298         /** Increment or decrement the number of requests to monitor the input
299          * of the hardware channel represented by the port referred to by @param
300          * port.
301          *
302          * If the number of requests rises above zero, input monitoring will
303          * be enabled (if can_monitor_input() returns true for the implementation).
304          *
305          * If the number of requests falls to zero, input monitoring will be
306          * disabled (if can_monitor_input() returns true for the implementation)
307          */
308         virtual int   request_input_monitoring (PortHandle port, bool yn) = 0;
309         /* Force input monitoring of the hardware channel represented by the port
310          * referred to by @param port to be on or off, depending on the true/false
311          * status of @param yn. The request count is ignored when using this
312          * method, so if this is called with yn set to false, input monitoring will
313          * be disabled regardless of the number of requests to enable it.
314          */
315         virtual int   ensure_input_monitoring (PortHandle port, bool yn) = 0;
316         /** Return true if input monitoring is enabled for the hardware channel
317          * represented by the port referred to by @param port. Return false
318          * otherwise.
319          */
320         virtual bool  monitoring_input (PortHandle port) = 0;
321
322         /* Latency management */
323
324         /** Set the latency range for the port referred to by @param port to @param
325          * r. The playback range will be set if @param for_playback is true,
326          * otherwise the capture range will be set.
327          */
328         virtual void          set_latency_range (PortHandle port, bool for_playback, LatencyRange r) = 0;
329         /** Return the latency range for the port referred to by @param port.
330          * The playback range will be returned if @param for_playback is true,
331          * otherwise the capture range will be returned.
332          */
333         virtual LatencyRange  get_latency_range (PortHandle port, bool for_playback) = 0;
334
335         /* Discovering physical ports */
336
337         /** Return true if the port referred to by @param port has the IsPhysical
338          * flag set. Return false otherwise.
339          */
340         virtual bool      port_is_physical (PortHandle port) const = 0;
341
342         /** Store into @param names the names of all ports with the IsOutput and
343          * IsPhysical flag set, that handle data of type @param type.
344          *
345          * This can be used to discover outputs associated with hardware devices.
346          */
347         virtual void      get_physical_outputs (DataType type, std::vector<std::string>& names) = 0;
348         /** Store into @param names the names of all ports with the IsInput and
349          * IsPhysical flags set, that handle data of type @param type.
350          *
351          * This can be used to discover inputs associated with hardware devices.
352          */
353         virtual void      get_physical_inputs (DataType type, std::vector<std::string>& names) = 0;
354         /** Return the total count (possibly mixed between different data types)
355          * of the number of ports with the IsPhysical and IsOutput flags set.
356          */
357         virtual ChanCount n_physical_outputs () const = 0;
358         /** Return the total count (possibly mixed between different data types)
359          * of the number of ports with the IsPhysical and IsInput flags set.
360          */
361         virtual ChanCount n_physical_inputs () const = 0;
362
363         /** Return the address of the memory area where data for the port can be
364          * written (if the port has the PortFlag IsOutput set) or read (if the port
365          * has the PortFlag IsInput set).
366          *
367          * The return value is untyped because buffers containing different data
368          * depending on the port type.
369          */
370         virtual void* get_buffer (PortHandle, pframes_t) = 0;
371
372         /* MIDI ports (the ones in libmidi++) need this to be able to correctly
373          * schedule MIDI events within their buffers. It is a bit odd that we
374          * expose this here, because it is also exposed by AudioBackend, but they
375          * only have access to a PortEngine object, not an AudioBackend.
376          *
377          * Return the time according to the sample clock in use when the current
378          * buffer process cycle began.
379          *
380          * XXX to be removed after some more design cleanup.
381          */
382         virtual samplepos_t sample_time_at_cycle_start () = 0;
383
384 protected:
385         PortManager& manager;
386 };
387
388 } // namespace
389
390 #endif /* __libardour_port_engine_h__ */