2 Copyright (C) 2013 Paul Davis
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.
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.
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.
20 #ifndef __libardour_port_engine_h__
21 #define __libardour_port_engine_h__
28 #include "ardour/data_type.h"
29 #include "ardour/types.h"
35 /** PortEngine is an abstract base class that defines the functionality
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.
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.
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.
60 * Ports also have latency associated with them. Each port has a playback
61 * latency and a capture latency:
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.
69 * <b>playback latency</b>: how long until the data written to the buffer of
70 * port will reach a terminal port.
73 * For more detailed questions about the PortEngine API, consult the JACK API
74 * documentation, on which this entire object is based.
79 PortEngine (PortManager& pm) : manager (pm) {}
80 virtual ~PortEngine() {}
82 /* We use void* here so that the API can be defined for any implementation.
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>.
90 typedef void* PortHandle;
92 virtual void* private_handle() const = 0;
94 virtual const std::string& my_name() const = 0;
96 virtual int set_port_name (PortHandle, const std::string&) = 0;
97 virtual std::string get_port_name (PortHandle) const = 0;
98 virtual PortHandle* get_port_by_name (const std::string&) const = 0;
100 /* Discovering the set of ports whose names, types and flags match
104 virtual int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&) const = 0;
106 virtual DataType port_data_type (PortHandle) const = 0;
108 virtual PortHandle register_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags) = 0;
109 virtual void unregister_port (PortHandle) = 0;
111 /* Connection management */
113 virtual int connect (const std::string& src, const std::string& dst) = 0;
114 virtual int disconnect (const std::string& src, const std::string& dst) = 0;
116 virtual int connect (PortHandle, const std::string&) = 0;
117 virtual int disconnect (PortHandle, const std::string&) = 0;
118 virtual int disconnect_all (PortHandle) = 0;
120 virtual bool connected (PortHandle) = 0;
121 virtual bool connected_to (PortHandle, const std::string&) = 0;
122 virtual bool physically_connected (PortHandle) = 0;
123 virtual int get_connections (PortHandle, std::vector<std::string>&) = 0;
127 virtual int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index) = 0;
128 virtual int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) = 0;
129 virtual uint32_t get_midi_event_count (void* port_buffer) = 0;
130 virtual void midi_clear (void* port_buffer) = 0;
134 virtual bool can_monitor_input() const = 0;
135 virtual int request_input_monitoring (PortHandle, bool) = 0;
136 virtual int ensure_input_monitoring (PortHandle, bool) = 0;
137 virtual bool monitoring_input (PortHandle) = 0;
139 /* Latency management
142 virtual void set_latency_range (PortHandle, bool for_playback, LatencyRange) = 0;
143 virtual LatencyRange get_latency_range (PortHandle, bool for_playback) = 0;
145 /* Discovering physical ports */
147 virtual bool port_is_physical (PortHandle) const = 0;
148 virtual void get_physical_outputs (DataType type, std::vector<std::string>&) = 0;
149 virtual void get_physical_inputs (DataType type, std::vector<std::string>&) = 0;
150 virtual ChanCount n_physical_outputs () const = 0;
151 virtual ChanCount n_physical_inputs () const = 0;
153 /* getting the port buffer. untyped (void*) because this will return
154 * buffers containing different data depending on the port type
157 virtual void* get_buffer (PortHandle, pframes_t) = 0;
159 /* MIDI ports (the ones in libmidi++) need this to be able to correctly
160 * schedule MIDI events within their buffers. It is a bit odd that we
161 * expose this here, because it is also exposed by AudioBackend, but they
162 * only have access to a PortEngine object, not an AudioBackend.
164 * Return the time according to the sample clock in use when the current
165 * buffer process cycle began.
168 virtual pframes_t sample_time_at_cycle_start () = 0;
171 PortManager& manager;
176 #endif /* __libardour_port_engine_h__ */