Ardour  9.0-pre0-582-g084a23a80d
jack_audiobackend.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013-2018 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2013 Tim Mayberry <mojofunk@gmail.com>
4  * Copyright (C) 2014-2018 Robin Gareus <robin@gareus.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #ifndef __libardour_jack_audiobackend_h__
22 #define __libardour_jack_audiobackend_h__
23 
24 #include <cstdint>
25 #include <string>
26 #include <vector>
27 #include <map>
28 #include <memory>
29 #include <set>
30 
31 
32 #include "weak_libjack.h"
33 
34 #include "ardour/audio_backend.h"
35 
36 namespace ARDOUR {
37 
38 class JackConnection;
39 class JACKSession;
40 
41 class JackPort : public ProtoPort
42 {
43  public:
44  JackPort (jack_port_t* p) : jack_ptr (p) {}
45  ~JackPort() { }
46 
47  private:
48  friend class JACKAudioBackend;
49  jack_port_t* jack_ptr;
50 };
51 
53  public:
54  JACKAudioBackend (AudioEngine& e, AudioBackendInfo& info, std::shared_ptr<JackConnection>);
56 
57  /* AUDIOBACKEND API */
58 
59  std::string name() const;
60  void* private_handle() const;
61  bool is_realtime () const;
62 
63  bool is_jack () const { return true; }
64 
66  std::vector<std::string> enumerate_drivers () const;
67  int set_driver (const std::string&);
68 
69  std::vector<DeviceStatus> enumerate_devices () const;
70 
71  std::vector<float> available_sample_rates (const std::string& device) const;
72  std::vector<uint32_t> available_buffer_sizes (const std::string& device) const;
73  std::vector<uint32_t> available_period_sizes (const std::string& driver, const std::string& device) const;
74 
77 
78  int set_device_name (const std::string&);
79  int set_sample_rate (float);
80  int set_buffer_size (uint32_t);
81  int set_peridod_size (uint32_t);
82  int set_interleaved (bool yn);
85  int set_systemic_midi_input_latency (std::string const, uint32_t) { return 0; }
86  int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; }
87 
88  int reset_device ();
89 
90  std::string device_name () const;
91  float sample_rate () const;
92  uint32_t buffer_size () const;
93  uint32_t period_size () const;
94  bool interleaved () const;
95  uint32_t systemic_input_latency () const;
96  uint32_t systemic_output_latency () const;
97  uint32_t systemic_midi_input_latency (std::string const) const { return 0; }
98  uint32_t systemic_midi_output_latency (std::string const) const { return 0; }
99  std::string driver_name() const;
100 
101  std::string control_app_name () const;
103 
104  int stop ();
105  int freewheel (bool);
106 
107  float dsp_load() const;
108 
112 
114 
115  int create_process_thread (std::function<void()> func);
118  uint32_t process_thread_count ();
120 
122  void transport_stop ();
126 
127  int set_time_master (bool /*yn*/);
128  bool get_sync_offset (pframes_t& /*offset*/) const;
129 
131 
132  static bool already_configured();
133 
134  /* PORTENGINE API */
135 
136  const std::string& my_name() const;
137  uint32_t port_name_size() const;
138 
139  int set_port_name (PortHandle, const std::string&);
140  std::string get_port_name (PortHandle) const;
142  PortPtr get_port_by_name (const std::string&) const;
143  int get_port_property (PortHandle, const std::string& key, std::string& value, std::string& type) const;
144  int set_port_property (PortHandle, const std::string& key, const std::string& value, const std::string& type);
145 
146  int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&) const;
147 
149 
150  PortPtr register_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
152 
153  bool connected (PortHandle, bool process_callback_safe);
154  bool connected_to (PortHandle, const std::string&, bool process_callback_safe);
155  bool physically_connected (PortHandle, bool process_callback_safe);
156  bool externally_connected (PortHandle, bool process_callback_safe);
157  int get_connections (PortHandle, std::vector<std::string>&, bool process_callback_safe);
158  int connect (PortHandle, const std::string&);
159 
160  int disconnect (PortHandle, const std::string&);
162  int connect (const std::string& src, const std::string& dst);
163  int disconnect (const std::string& src, const std::string& dst);
164 
165  /* MIDI */
166 
167  std::vector<std::string> enumerate_midi_options () const;
168  int set_midi_option (const std::string&);
169  std::string midi_option () const;
170 
171  std::vector<DeviceStatus> enumerate_midi_devices () const {
172  return std::vector<AudioBackend::DeviceStatus> ();
173  }
174  int set_midi_device_enabled (std::string const, bool) {
175  return 0;
176  }
177  bool midi_device_enabled (std::string const) const {
178  return true;
179  }
181  return false;
182  }
183  bool can_set_period_size () const {
184  return true;
185  }
187  return true;
188  }
189 
190  int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t const** buf, void* port_buffer, uint32_t event_index);
191  int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size);
192  uint32_t get_midi_event_count (void* port_buffer);
193  void midi_clear (void* port_buffer);
194 
195  /* Monitoring */
196 
197  bool can_monitor_input() const;
201 
202  /* Latency management
203  */
204 
205  void set_latency_range (PortHandle, bool for_playback, LatencyRange);
207 
208  /* Physical ports */
209 
211  void get_physical_outputs (DataType type, std::vector<std::string>&);
212  void get_physical_inputs (DataType type, std::vector<std::string>&);
215 
216  /* Getting access to the data buffer for a port */
217 
219 
220  /* transport sync */
221 
222  bool speed_and_position (double& sp, samplepos_t& pos);
223 
224  private:
225  std::shared_ptr<JackConnection> _jack_connection;
226  bool _running;
228  std::map<DataType,size_t> _raw_buffer_sizes;
229 
230  std::vector<jack_native_thread_t> _jack_threads;
231  jack_native_thread_t _main_thread;
232 
233  static int _xrun_callback (void *arg);
234  static void* _process_thread (void *arg);
235  static int _sample_rate_callback (pframes_t nframes, void *arg);
236  static int _bufsize_callback (pframes_t nframes, void *arg);
237  static void _jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int, void*);
238  static int _jack_sync_callback (jack_transport_state_t, jack_position_t*, void *arg);
239  static void _freewheel_callback (int , void *arg);
240  static void _latency_callback (jack_latency_callback_mode_t, void*);
241  static void _session_callback (jack_session_event_t *event, void *arg);
242 
243  void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int);
244  int jack_sync_callback (jack_transport_state_t, jack_position_t*);
247  void freewheel_callback (int);
249  void jack_latency_callback (jack_latency_callback_mode_t);
250  void disconnected (const char*);
251 
254 
255  bool available() const;
256 
257  struct ThreadData {
259  std::function<void()> f;
260  size_t stacksize;
261 
262  ThreadData (JACKAudioBackend* e, std::function<void()> fp, size_t stacksz)
263  : engine (e) , f (fp) , stacksize (stacksz) {}
264  };
265 
266  void* process_thread ();
267  static void* _start_process_thread (void*);
268 
269  void setup_jack_startup_command (bool for_latency_measurement);
270 
271  /* pffooo */
272 
273  std::string _target_driver;
274  std::string _target_device;
286  std::string _target_midi_option;
287 
288  typedef std::set<std::string> DeviceList;
289  typedef std::map<std::string,DeviceList> DriverDeviceMap;
290 
292 
294 
295  /* PORTENGINE RELATED */
296 
297  static int _graph_order_callback (void *arg);
298  static void _registration_callback (jack_port_id_t, int, void *);
299  static void _connect_callback (jack_port_id_t, jack_port_id_t, int, void *);
300 
301  /* used to manage _jack_ports, specifically for ports belonging to the
302  JACK backend or other clients.
303  */
304  void jack_registration_callback (jack_port_id_t, int);
305 
306  typedef std::map<std::string,std::shared_ptr<JackPort> > JackPorts;
307  mutable SerializedRCUManager<JackPorts> _jack_ports; /* can be modified in ::get_port_by_name () */
308 
309  void connect_callback (jack_port_id_t, jack_port_id_t, int);
310 
311  ChanCount n_physical (unsigned long flags) const;
312  void get_physical (DataType type, unsigned long flags, std::vector<std::string>& phy) const;
313 
316 
317  /* Object to manage interactions with Session in a way that
318  keeps JACK out of libardour directly
319  */
320 
322 
323  mutable Glib::Threads::Mutex server_call_mutex;
324 
325  protected:
326  int _start (bool for_latency_measurement);
327 };
328 
329 } // namespace
330 
331 #endif /* __ardour_audiobackend_h__ */
AudioBackendInfo & info() const
pframes_t samples_since_cycle_start()
int disconnect(PortHandle, const std::string &)
DataType port_data_type(PortHandle) const
int set_interleaved(bool yn)
void jack_timebase_callback(jack_transport_state_t, pframes_t, jack_position_t *, int)
uint32_t buffer_size() const
static int _bufsize_callback(pframes_t nframes, void *arg)
int set_systemic_output_latency(uint32_t)
bool can_set_systemic_midi_latencies() const
int create_process_thread(std::function< void()> func)
uint32_t systemic_output_latency() const
int ensure_input_monitoring(PortHandle, bool)
int disconnect_all(PortHandle)
const std::string & my_name() const
ChanCount n_physical_inputs() const
uint32_t systemic_input_latency() const
bool port_is_physical(PortHandle) const
int midi_event_put(void *port_buffer, pframes_t timestamp, const uint8_t *buffer, size_t size)
size_t raw_buffer_size(DataType t)
PBD::ScopedConnection disconnect_connection
bool connected(PortHandle, bool process_callback_safe)
void get_physical_inputs(DataType type, std::vector< std::string > &)
void disconnected(const char *)
int set_midi_option(const std::string &)
TransportState transport_state() const
void * private_handle() const
uint32_t process_thread_count()
bool midi_device_enabled(std::string const) const
samplepos_t sample_time()
void unregister_port(PortHandle)
JACKAudioBackend(AudioEngine &e, AudioBackendInfo &info, std::shared_ptr< JackConnection >)
bool can_change_sample_rate_when_running() const
void jack_latency_callback(jack_latency_callback_mode_t)
int _start(bool for_latency_measurement)
static void * _start_process_thread(void *)
std::vector< std::string > enumerate_midi_options() const
void get_physical(DataType type, unsigned long flags, std::vector< std::string > &phy) const
int connect(const std::string &src, const std::string &dst)
static void * _process_thread(void *arg)
bool can_measure_systemic_latency() const
PBD::ScopedConnection jack_connection_connection
SerializedRCUManager< JackPorts > _jack_ports
std::map< DataType, size_t > _raw_buffer_sizes
std::string get_port_name(PortHandle) const
float sample_rate() const
static void _freewheel_callback(int, void *arg)
bool connected_to(PortHandle, const std::string &, bool process_callback_safe)
uint32_t period_size() const
jack_native_thread_t _main_thread
int set_buffer_size(uint32_t)
bool monitoring_input(PortHandle)
uint32_t port_name_size() const
int set_systemic_midi_input_latency(std::string const, uint32_t)
bool can_change_buffer_size_when_running() const
void * get_buffer(PortHandle, pframes_t)
static void _connect_callback(jack_port_id_t, jack_port_id_t, int, void *)
int get_ports(const std::string &port_name_pattern, DataType type, PortFlags flags, std::vector< std::string > &) const
bool can_monitor_input() const
void setup_jack_startup_command(bool for_latency_measurement)
std::shared_ptr< JackConnection > _jack_connection
int midi_event_get(pframes_t &timestamp, size_t &size, uint8_t const **buf, void *port_buffer, uint32_t event_index)
std::vector< jack_native_thread_t > _jack_threads
int process_callback(pframes_t nframes)
std::string driver_name() const
std::set< std::string > DeviceList
int jack_sample_rate_callback(pframes_t)
int set_device_name(const std::string &)
int get_connections(PortHandle, std::vector< std::string > &, bool process_callback_safe)
int request_input_monitoring(PortHandle, bool)
bool physically_connected(PortHandle, bool process_callback_safe)
int set_port_property(PortHandle, const std::string &key, const std::string &value, const std::string &type)
PortPtr get_port_by_name(const std::string &) const
std::vector< std::string > enumerate_drivers() const
void jack_registration_callback(jack_port_id_t, int)
int connect(PortHandle, const std::string &)
int disconnect(const std::string &src, const std::string &dst)
Glib::Threads::Mutex server_call_mutex
std::map< std::string, DeviceList > DriverDeviceMap
int set_port_name(PortHandle, const std::string &)
PortPtr register_port(const std::string &shortname, ARDOUR::DataType, ARDOUR::PortFlags)
std::map< std::string, std::shared_ptr< JackPort > > JackPorts
int set_midi_device_enabled(std::string const, bool)
PortFlags get_port_flags(PortHandle) const
void connect_callback(jack_port_id_t, jack_port_id_t, int)
LatencyRange get_latency_range(PortHandle, bool for_playback)
std::vector< DeviceStatus > enumerate_midi_devices() const
static void _latency_callback(jack_latency_callback_mode_t, void *)
int get_port_property(PortHandle, const std::string &key, std::string &value, std::string &type) const
void midi_clear(void *port_buffer)
static void _session_callback(jack_session_event_t *event, void *arg)
int set_driver(const std::string &)
static int _jack_sync_callback(jack_transport_state_t, jack_position_t *, void *arg)
ChanCount n_physical(unsigned long flags) const
int jack_sync_callback(jack_transport_state_t, jack_position_t *)
int set_systemic_input_latency(uint32_t)
int jack_bufsize_callback(pframes_t)
bool requires_driver_selection() const
static void _registration_callback(jack_port_id_t, int, void *)
std::vector< uint32_t > available_period_sizes(const std::string &driver, const std::string &device) const
bool externally_connected(PortHandle, bool process_callback_safe)
static int _graph_order_callback(void *arg)
static int _xrun_callback(void *arg)
static bool already_configured()
uint32_t systemic_midi_output_latency(std::string const) const
std::vector< float > available_sample_rates(const std::string &device) const
int set_peridod_size(uint32_t)
void get_physical_outputs(DataType type, std::vector< std::string > &)
void transport_locate(samplepos_t)
std::vector< uint32_t > available_buffer_sizes(const std::string &device) const
std::vector< DeviceStatus > enumerate_devices() const
bool speed_and_position(double &sp, samplepos_t &pos)
std::string control_app_name() const
void set_latency_range(PortHandle, bool for_playback, LatencyRange)
samplepos_t sample_time_at_cycle_start()
int set_systemic_midi_output_latency(std::string const, uint32_t)
samplepos_t transport_sample() const
uint32_t systemic_midi_input_latency(std::string const) const
uint32_t get_midi_event_count(void *port_buffer)
ChanCount n_physical_outputs() const
std::string device_name() const
std::string midi_option() const
static void _jack_timebase_callback(jack_transport_state_t, pframes_t, jack_position_t *, int, void *)
bool get_sync_offset(pframes_t &) const
static int _sample_rate_callback(pframes_t nframes, void *arg)
std::string name() const
jack_port_t * jack_ptr
JackPort(jack_port_t *p)
PortPtr const & PortHandle
Definition: port_engine.h:113
std::shared_ptr< ProtoPort > PortPtr
Definition: port_engine.h:107
uint32_t pframes_t
Temporal::samplepos_t samplepos_t
ThreadData(JACKAudioBackend *e, std::function< void()> fp, size_t stacksz)