fix merge issues with master
[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/types.h"
30
31 namespace ARDOUR {
32
33 class PortManager;
34
35 /** PortEngine is an abstract base class that defines the functionality
36  * required by Ardour. 
37  * 
38  * A Port is basically an endpoint for a datastream (which can either be
39  * continuous, like audio, or event-based, like MIDI). Ports have buffers
40  * associated with them into which data can be written (if they are output
41  * ports) and from which data can be read (if they input ports). Ports can be
42  * connected together so that data written to an output port can be read from
43  * an input port. These connections can be 1:1, 1:N OR N:1. 
44  *
45  * Ports may be associated with software only, or with hardware.  Hardware
46  * related ports are often referred to as physical, and correspond to some
47  * relevant physical entity on a hardware device, such as an audio jack or a
48  * MIDI connector. Physical ports may be potentially asked to monitor their
49  * inputs, though some implementations may not support this.
50  *
51  * Most physical ports will also be considered "terminal", which means that
52  * data delivered there or read from there will go to or comes from a system
53  * outside of the PortEngine implementation's control (e.g. the analog domain
54  * for audio, or external MIDI devices for MIDI). Non-physical ports can also
55  * be considered "terminal". For example, the output port of a software
56  * synthesizer is a terminal port, because the data contained in its buffer
57  * does not and cannot be considered to come from any other port - it is
58  * synthesized by its owner.
59  *
60  * Ports also have latency associated with them. Each port has a playback
61  * latency and a capture latency:
62  *
63  * <b>capture latency</b>: how long since the data read from the buffer of a
64  *                  port arrived at at a terminal port.  The data will have
65  *                  come from the "outside world" if the terminal port is also
66  *                  physical, or will have been synthesized by the entity that
67  *                  owns the terminal port.
68  *                  
69  * <b>playback latency</b>: how long until the data written to the buffer of
70  *                   port will reach a terminal port.
71  *
72  *
73  * For more detailed questions about the PortEngine API, consult the JACK API
74  * documentation, on which this entire object is based.
75  */
76
77 class PortEngine {
78   public:
79     PortEngine (PortManager& pm) : manager (pm) {}
80     virtual ~PortEngine() {}
81     
82     /* We use void* here so that the API can be defined for any implementation.
83      * 
84      * We could theoretically use a template (PortEngine<T>) and define
85      * PortHandle as T, but this complicates the desired inheritance
86      * pattern in which FooPortEngine handles things for the Foo API,
87      * rather than being a derivative of PortEngine<Foo>.
88     */
89        
90     typedef void* PortHandle;
91
92     /** Return a typeless pointer to an object that may be of interest
93      * that understands the internals of a particular PortEngine
94      * implementation.
95      *
96      * XXX the existence of this method is a band-aid over some design
97      * issues and will it will be removed in the future
98      */
99     virtual void* private_handle() const = 0;
100
101     virtual bool connected() const = 0;
102
103     /** Return the name of this process as used by the port manager
104      * when naming ports.
105      */
106     virtual const std::string& my_name() const = 0;
107
108     /** Return the maximum size of a port name 
109      */
110     virtual uint32_t port_name_size() const = 0;
111
112     /** Returns zero if the port referred to by @param port was set to @param
113      * name. Return non-zero otherwise.
114      */
115     virtual int         set_port_name (PortHandle port, const std::string& name) = 0;
116     /** Return the name of the port referred to by @param port. If the port
117      * does not exist, return an empty string.
118      */
119     virtual std::string get_port_name (PortHandle) const = 0;
120     /** Return a reference to a port with the fullname @param name. Return
121      * a null pointer if no such port exists.
122      */
123     virtual PortHandle* get_port_by_name (const std::string&) const = 0;
124
125     /** Find the set of ports whose names, types and flags match
126      * specified values, place the names of each port into @param ports,
127      * and return the count of the number found.
128      *
129      * To avoid selecting by name, pass an empty string for @param
130      * port_name_pattern.
131      * 
132      * To avoid selecting by type, pass DataType::NIL as @param type.
133      * 
134      * To avoid selecting by flags, pass PortFlags (0) as @param flags.
135      */
136     virtual int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>& ports) const = 0;
137
138     /** Return the Ardour data type handled by the port referred to by @param
139      * port. Returns DataType::NIL if the port does not exist.
140      */
141     virtual DataType port_data_type (PortHandle port) const = 0;
142
143     /** Create a new port whose fullname will be the conjuction of my_name(),
144      * ":" and @param shortname. The port will handle data specified by @param
145      * type and will have the flags given by @param flags. If successfull,
146      * return a reference to the port, otherwise return a null pointer.
147     */
148     virtual PortHandle register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags) = 0;
149
150     /* Destroy the port referred to by @param port, including all resources
151      * associated with it. This will also disconnect @param port from any ports it
152      * is connected to.
153      */
154     virtual void       unregister_port (PortHandle) = 0;
155     
156     /* Connection management */
157
158     /** Ensure that data written to the port named by @param src will be
159      * readable from the port named by @param dst. Return zero on success,
160      * non-zero otherwise.
161     */
162     virtual int   connect (const std::string& src, const std::string& dst) = 0;
163
164     /** Remove any existing connection between the ports named by @param src and 
165      * @param dst. Return zero on success, non-zero otherwise.
166      */
167     virtual int   disconnect (const std::string& src, const std::string& dst) = 0;
168     
169     
170     /** Ensure that data written to the port referenced by @param portwill be
171      * readable from the port named by @param dst. Return zero on success,
172      * non-zero otherwise.
173     */
174     virtual int   connect (PortHandle src, const std::string& dst) = 0;
175     /** Remove any existing connection between the port referenced by @param src and 
176      * the port named @param dst. Return zero on success, non-zero otherwise.
177      */ 
178     virtual int   disconnect (PortHandle src, const std::string& dst) = 0;
179
180     /** Remove all connections between the port referred to by @param port and
181      * any other ports. Return zero on success, non-zero otherwise.
182      */
183     virtual int   disconnect_all (PortHandle port) = 0;
184
185     /** Return true if the port referred to by @param port has any connections
186      * to other ports. Return false otherwise.
187      */
188     virtual bool  connected (PortHandle port) = 0;
189     /** Return true if the port referred to by @param port is connected to
190      * the port named by @param name. Return false otherwise.
191      */
192     virtual bool  connected_to (PortHandle, const std::string& name) = 0;
193
194     /** Return true if the port referred to by @param port has any connections
195      * to ports marked with the PortFlag IsPhysical. Return false otherwise.
196      */
197     virtual bool  physically_connected (PortHandle port) = 0;
198
199     /** Place the names of all ports connected to the port named by @param
200      * ports into @param names, and return the number of connections.
201      */
202     virtual int   get_connections (PortHandle port, std::vector<std::string>& names) = 0;
203
204     /* MIDI */
205
206     /** Retrieve a MIDI event from the data at @param port_buffer. The event
207     number to be retrieved is given by @param event_index (a value of zero
208     indicates that the first event in the port_buffer should be retrieved).
209     * 
210     * The data associated with the event will be copied into the buffer at
211     * @param buf and the number of bytes written will be stored in @param
212     * size. The timestamp of the event (which is always relative to the start 
213     * of the current process cycle, in samples) will be stored in @param
214     * timestamp
215     */
216     virtual int      midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index) = 0;
217
218     /** Place a MIDI event consisting of @param size bytes copied from the data
219      * at @param buf into the port buffer referred to by @param
220      * port_buffer. The MIDI event will be marked with a time given by @param
221      * timestamp. Return zero on success, non-zero otherwise.
222      *
223      * Events  must be added monotonically to a port buffer. An attempt to 
224      * add a non-monotonic event (e.g. out-of-order) will cause this method
225      * to return a failure status.
226      */
227     virtual int      midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) = 0;
228
229     /** Return the number of MIDI events in the data at @param port_buffer
230      */
231     virtual uint32_t get_midi_event_count (void* port_buffer) = 0;
232
233     /** Clear the buffer at @param port_buffer of all MIDI events.
234      *
235      * After a call to this method, an immediate, subsequent call to
236      * get_midi_event_count() with the same @param port_buffer argument must
237      * return zero.
238     */
239     virtual void     midi_clear (void* port_buffer) = 0;
240
241     /* Monitoring */
242
243     /** Return true if the implementation can offer input monitoring.
244      *
245      * Input monitoring involves the (selective) routing of incoming data
246      * to an outgoing data stream, without the data being passed to the CPU.
247      *
248      * Only certain audio hardware can provide this, and only certain audio
249      * APIs can offer it.
250      */
251     virtual bool  can_monitor_input() const = 0;
252     /** Increment or decrement the number of requests to monitor the input 
253      * of the hardware channel represented by the port referred to by @param
254      * port.
255      *
256      * If the number of requests rises above zero, input monitoring will
257      * be enabled (if can_monitor_input() returns true for the implementation).
258      * 
259      * If the number of requests falls to zero, input monitoring will be
260      * disabled (if can_monitor_input() returns true for the implementation)
261      */
262     virtual int   request_input_monitoring (PortHandle port, bool yn) = 0;
263     /* Force input monitoring of the hardware channel represented by the port
264      * referred to by @param port to be on or off, depending on the true/false
265      * status of @param yn. The request count is ignored when using this
266      * method, so if this is called with yn set to false, input monitoring will
267      * be disabled regardless of the number of requests to enable it.
268     */
269     virtual int   ensure_input_monitoring (PortHandle port, bool yn) = 0;
270     /** Return true if input monitoring is enabled for the hardware channel
271      * represented by the port referred to by @param port. Return false
272      * otherwise.
273      */
274     virtual bool  monitoring_input (PortHandle port) = 0;
275
276     /* Latency management
277      */
278     
279     /** Set the latency range for the port referred to by @param port to @param
280      * r. The playback range will be set if @param for_playback is true,
281      * otherwise the capture range will be set.
282      */
283     virtual void          set_latency_range (PortHandle port, bool for_playback, LatencyRange r) = 0;
284     /** Return the latency range for the port referred to by @param port.
285      * The playback range will be returned if @param for_playback is true,
286      * otherwise the capture range will be returned.
287      */
288     virtual LatencyRange  get_latency_range (PortHandle port, bool for_playback) = 0;
289
290     /* Discovering physical ports */
291
292     /** Return true if the port referred to by @param port has the IsPhysical
293      * flag set. Return false otherwise.
294      */
295     virtual bool      port_is_physical (PortHandle port) const = 0;
296
297     /** Store into @param names the names of all ports with the IsOutput and
298      * IsPhysical flag set, that handle data of type @param type.
299      *
300      * This can be used to discover outputs associated with hardware devices.
301      */
302     virtual void      get_physical_outputs (DataType type, std::vector<std::string>& names) = 0;
303     /** Store into @param names the names of all ports with the IsInput and
304      * IsPhysical flags set, that handle data of type @param type.
305      *
306      * This can be used to discover inputs associated with hardware devices.
307      */
308     virtual void      get_physical_inputs (DataType type, std::vector<std::string>& names) = 0;
309     /** Return the total count (possibly mixed between different data types)
310         of the number of ports with the IsPhysical and IsOutput flags set.
311     */
312     virtual ChanCount n_physical_outputs () const = 0;
313     /** Return the total count (possibly mixed between different data types)
314         of the number of ports with the IsPhysical and IsInput flags set.
315     */
316     virtual ChanCount n_physical_inputs () const = 0;
317
318     /** Return the address of the memory area where data for the port can be
319      * written (if the port has the PortFlag IsOutput set) or read (if the port
320      * has the PortFlag IsInput set).
321      *
322      * The return value is untyped because buffers containing different data
323      * depending on the port type.
324      */
325     virtual void* get_buffer (PortHandle, pframes_t) = 0;
326
327     /* MIDI ports (the ones in libmidi++) need this to be able to correctly
328      * schedule MIDI events within their buffers. It is a bit odd that we
329      * expose this here, because it is also exposed by AudioBackend, but they
330      * only have access to a PortEngine object, not an AudioBackend.
331      * 
332      * Return the time according to the sample clock in use when the current 
333      * buffer process cycle began. 
334      *
335      * XXX to be removed after some more design cleanup. 
336      */
337     virtual pframes_t sample_time_at_cycle_start () = 0;
338
339   protected:
340     PortManager& manager;
341 };
342
343 }
344
345 #endif /* __libardour_port_engine_h__ */