Add weak linked symbol for "jack_port_is_mine"
[ardour.git] / libs / backends / dummy / dummy_audiobackend.h
1 /*
2  * Copyright (C) 2014 Robin Gareus <robin@gareus.org>
3  * Copyright (C) 2013 Paul Davis
4  *
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.
9  *
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.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #ifndef __libbackend_dummy_audiobackend_h__
21 #define __libbackend_dummy_audiobackend_h__
22
23 #include <string>
24 #include <vector>
25 #include <map>
26 #include <set>
27
28 #include <stdint.h>
29 #include <pthread.h>
30
31 #include <ltc.h>
32
33 #include <boost/shared_ptr.hpp>
34
35 #include "pbd/natsort.h"
36 #include "pbd/ringbuffer.h"
37 #include "ardour/types.h"
38 #include "ardour/audio_backend.h"
39 #include "ardour/dsp_load_calculator.h"
40
41 namespace ARDOUR {
42
43 class DummyAudioBackend;
44
45 namespace DummyMidiData {
46         typedef struct _MIDISequence {
47                 float   beat_time;
48                 uint8_t size;
49                 uint8_t event[10];
50         } MIDISequence;
51 };
52
53
54 class DummyMidiEvent {
55         public:
56                 DummyMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size);
57                 DummyMidiEvent (const DummyMidiEvent& other);
58                 ~DummyMidiEvent ();
59                 size_t size () const { return _size; };
60                 pframes_t timestamp () const { return _timestamp; };
61                 const unsigned char* const_data () const { return _data; };
62                 unsigned char* data () { return _data; };
63                 bool operator< (const DummyMidiEvent &other) const { return timestamp () < other.timestamp (); };
64         private:
65                 size_t _size;
66                 pframes_t _timestamp;
67                 uint8_t *_data;
68 };
69
70 typedef std::vector<boost::shared_ptr<DummyMidiEvent> > DummyMidiBuffer;
71
72 class DummyPort {
73         protected:
74                 DummyPort (DummyAudioBackend &b, const std::string&, PortFlags);
75         public:
76                 virtual ~DummyPort ();
77
78                 const std::string& name () const { return _name; }
79                 const std::string& pretty_name () const { return _pretty_name; }
80                 PortFlags flags () const { return _flags; }
81
82                 int set_name (const std::string &name) { _name = name; return 0; }
83                 int set_pretty_name (const std::string &name) { _pretty_name = name; return 0; }
84
85                 virtual DataType type () const = 0;
86
87                 bool is_input ()     const { return flags () & IsInput; }
88                 bool is_output ()    const { return flags () & IsOutput; }
89                 bool is_physical ()  const { return flags () & IsPhysical; }
90                 bool is_terminal ()  const { return flags () & IsTerminal; }
91                 bool is_connected () const { return _connections.size () != 0; }
92                 bool is_connected (const DummyPort *port) const;
93                 bool is_physically_connected () const;
94
95                 const std::set<DummyPort *>& get_connections () const { return _connections; }
96
97                 int connect (DummyPort *port);
98                 int disconnect (DummyPort *port);
99                 void disconnect_all ();
100
101                 virtual void* get_buffer (pframes_t nframes) = 0;
102                 void next_period () { _gen_cycle = false; }
103
104                 const LatencyRange latency_range (bool for_playback) const
105                 {
106                         return for_playback ? _playback_latency_range : _capture_latency_range;
107                 }
108
109                 void set_latency_range (const LatencyRange &latency_range, bool for_playback);
110
111                 void update_connected_latency (bool for_playback);
112
113         private:
114                 DummyAudioBackend &_dummy_backend;
115                 std::string _name;
116                 std::string _pretty_name;
117                 const PortFlags _flags;
118                 LatencyRange _capture_latency_range;
119                 LatencyRange _playback_latency_range;
120                 std::set<DummyPort*> _connections;
121
122                 void _connect (DummyPort* , bool);
123                 void _disconnect (DummyPort* , bool);
124
125         protected:
126                 // random number generator
127                 void setup_random_number_generator ();
128                 inline float    randf ();
129                 inline uint32_t randi ();
130                 uint32_t _rseed;
131
132                 // signal generator
133                 volatile bool _gen_cycle;
134                 Glib::Threads::Mutex generator_lock;
135
136 }; // class DummyPort
137
138 class DummyAudioPort : public DummyPort {
139         public:
140                 DummyAudioPort (DummyAudioBackend &b, const std::string&, PortFlags);
141                 ~DummyAudioPort ();
142
143                 DataType type () const { return DataType::AUDIO; };
144
145                 Sample* buffer () { return _buffer; }
146                 const Sample* const_buffer () const { return _buffer; }
147                 void* get_buffer (pframes_t nframes);
148
149                 enum GeneratorType {
150                         Silence,
151                         DC05,
152                         Demolition,
153                         UniformWhiteNoise,
154                         GaussianWhiteNoise,
155                         PinkNoise,
156                         PonyNoise,
157                         SineWave,
158                         SineWaveOctaves,
159                         SquareWave,
160                         KronekerDelta,
161                         SineSweep,
162                         SineSweepSwell,
163                         SquareSweep,
164                         SquareSweepSwell,
165                         LTC,
166                         Loopback,
167                 };
168                 std::string setup_generator (GeneratorType const, float const, int, int);
169                 void fill_wavetable (const float* d, size_t n_samples) { assert(_wavetable != 0);  memcpy(_wavetable, d, n_samples * sizeof(float)); }
170                 void midi_to_wavetable (DummyMidiBuffer const * const src, size_t n_samples);
171
172         private:
173                 Sample _buffer[8192];
174
175                 // signal generator ('fake' physical inputs)
176                 void generate (const pframes_t n_samples);
177                 GeneratorType _gen_type;
178
179                 // generator buffers
180                 // pink-noise filters
181                 float _b0, _b1, _b2, _b3, _b4, _b5, _b6;
182                 // generated sinf() samples
183                 Sample * _wavetable;
184                 uint32_t _gen_period;
185                 uint32_t _gen_offset;
186                 uint32_t _gen_perio2;
187                 uint32_t _gen_count2;
188
189                 // gaussian noise generator
190                 float grandf ();
191                 bool _pass;
192                 float _rn1;
193                 // LTC generator
194                 LTCEncoder* _ltc;
195                 PBD::RingBuffer<Sample>* _ltcbuf;
196                 float _ltc_spd;
197                 float _ltc_rand;
198
199
200 }; // class DummyAudioPort
201
202 class DummyMidiPort : public DummyPort {
203         public:
204                 DummyMidiPort (DummyAudioBackend &b, const std::string&, PortFlags);
205                 ~DummyMidiPort ();
206
207                 DataType type () const { return DataType::MIDI; };
208
209                 void* get_buffer (pframes_t nframes);
210                 const DummyMidiBuffer * const_buffer () const { return &_buffer; }
211
212                 std::string setup_generator (int, float const);
213                 void set_loopback (DummyMidiBuffer const * const src);
214
215         private:
216                 DummyMidiBuffer _buffer;
217                 DummyMidiBuffer _loopback;
218
219                 // midi event generator ('fake' physical inputs)
220                 void midi_generate (const pframes_t n_samples);
221                 float   _midi_seq_spb; // samples per beat
222                 int32_t _midi_seq_time;
223                 uint32_t _midi_seq_pos;
224                 DummyMidiData::MIDISequence const * _midi_seq_dat;
225 }; // class DummyMidiPort
226
227 class DummyAudioBackend : public AudioBackend {
228         friend class DummyPort;
229         public:
230                  DummyAudioBackend (AudioEngine& e, AudioBackendInfo& info);
231                 ~DummyAudioBackend ();
232
233                 bool is_running () const { return _running; }
234
235                 /* AUDIOBACKEND API */
236
237                 std::string name () const;
238                 bool is_realtime () const;
239
240                 bool requires_driver_selection() const { return true; }
241                 std::string driver_name () const;
242                 std::vector<std::string> enumerate_drivers () const;
243                 int set_driver (const std::string&);
244
245                 std::vector<DeviceStatus> enumerate_devices () const;
246                 std::vector<float> available_sample_rates (const std::string& device) const;
247                 std::vector<uint32_t> available_buffer_sizes (const std::string& device) const;
248                 uint32_t available_input_channel_count (const std::string& device) const;
249                 uint32_t available_output_channel_count (const std::string& device) const;
250
251                 bool can_change_sample_rate_when_running () const;
252                 bool can_change_buffer_size_when_running () const;
253
254                 int set_device_name (const std::string&);
255                 int set_sample_rate (float);
256                 int set_buffer_size (uint32_t);
257                 int set_interleaved (bool yn);
258                 int set_input_channels (uint32_t);
259                 int set_output_channels (uint32_t);
260                 int set_systemic_input_latency (uint32_t);
261                 int set_systemic_output_latency (uint32_t);
262                 int set_systemic_midi_input_latency (std::string const, uint32_t) { return 0; }
263                 int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; }
264
265                 int reset_device () { return 0; };
266
267                 /* Retrieving parameters */
268                 std::string  device_name () const;
269                 float        sample_rate () const;
270                 uint32_t     buffer_size () const;
271                 bool         interleaved () const;
272                 uint32_t     input_channels () const;
273                 uint32_t     output_channels () const;
274                 uint32_t     systemic_input_latency () const;
275                 uint32_t     systemic_output_latency () const;
276                 uint32_t     systemic_midi_input_latency (std::string const) const { return 0; }
277                 uint32_t     systemic_midi_output_latency (std::string const) const { return 0; }
278
279                 /* External control app */
280                 std::string control_app_name () const { return std::string (); }
281                 void launch_control_app () {}
282
283                 /* MIDI */
284                 std::vector<std::string> enumerate_midi_options () const;
285                 int set_midi_option (const std::string&);
286                 std::string midi_option () const;
287
288                 std::vector<DeviceStatus> enumerate_midi_devices () const {
289                         return std::vector<AudioBackend::DeviceStatus> ();
290                 }
291                 int set_midi_device_enabled (std::string const, bool) {
292                         return 0;
293                 }
294                 bool midi_device_enabled (std::string const) const {
295                         return true;
296                 }
297                 bool can_set_systemic_midi_latencies () const {
298                         return false;
299                 }
300
301                 /* State Control */
302         protected:
303                 int _start (bool for_latency_measurement);
304         public:
305                 int stop ();
306                 int freewheel (bool);
307                 float dsp_load () const;
308                 size_t raw_buffer_size (DataType t);
309
310                 /* Process time */
311                 samplepos_t sample_time ();
312                 samplepos_t sample_time_at_cycle_start ();
313                 pframes_t samples_since_cycle_start ();
314
315                 int create_process_thread (boost::function<void()> func);
316                 int join_process_threads ();
317                 bool in_process_thread ();
318                 uint32_t process_thread_count ();
319
320                 void update_latencies ();
321
322                 /* PORTENGINE API */
323
324                 void* private_handle () const;
325                 const std::string& my_name () const;
326                 bool available () const;
327                 uint32_t port_name_size () const;
328
329                 int         set_port_name (PortHandle, const std::string&);
330                 std::string get_port_name (PortHandle) const;
331                 PortHandle  get_port_by_name (const std::string&) const;
332
333                 int get_port_property (PortHandle, const std::string& key, std::string& value, std::string& type) const;
334                 int set_port_property (PortHandle, const std::string& key, const std::string& value, const std::string& type);
335
336                 int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&) const;
337
338                 DataType port_data_type (PortHandle) const;
339
340                 PortHandle register_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
341                 void unregister_port (PortHandle);
342
343                 int  connect (const std::string& src, const std::string& dst);
344                 int  disconnect (const std::string& src, const std::string& dst);
345                 int  connect (PortHandle, const std::string&);
346                 int  disconnect (PortHandle, const std::string&);
347                 int  disconnect_all (PortHandle);
348
349                 bool connected (PortHandle, bool process_callback_safe);
350                 bool connected_to (PortHandle, const std::string&, bool process_callback_safe);
351                 bool physically_connected (PortHandle, bool process_callback_safe);
352                 int  get_connections (PortHandle, std::vector<std::string>&, bool process_callback_safe);
353
354                 /* MIDI */
355                 int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t const** buf, void* port_buffer, uint32_t event_index);
356                 int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size);
357                 uint32_t get_midi_event_count (void* port_buffer);
358                 void     midi_clear (void* port_buffer);
359
360                 /* Monitoring */
361
362                 bool can_monitor_input () const;
363                 int  request_input_monitoring (PortHandle, bool);
364                 int  ensure_input_monitoring (PortHandle, bool);
365                 bool monitoring_input (PortHandle);
366
367                 /* Latency management */
368
369                 void         set_latency_range (PortHandle, bool for_playback, LatencyRange);
370                 LatencyRange get_latency_range (PortHandle, bool for_playback);
371
372                 /* Discovering physical ports */
373
374                 bool      port_is_physical (PortHandle) const;
375                 void      get_physical_outputs (DataType type, std::vector<std::string>&);
376                 void      get_physical_inputs (DataType type, std::vector<std::string>&);
377                 ChanCount n_physical_outputs () const;
378                 ChanCount n_physical_inputs () const;
379
380                 /* Getting access to the data buffer for a port */
381
382                 void* get_buffer (PortHandle, pframes_t);
383
384                 void* main_process_thread ();
385
386                 static size_t max_buffer_size() {return _max_buffer_size;}
387
388         private:
389                 enum MidiPortMode {
390                         MidiNoEvents,
391                         MidiGenerator,
392                         MidiLoopback,
393                         MidiToAudio,
394                 };
395
396                 struct DriverSpeed {
397                         std::string name;
398                         float speedup;
399                         DriverSpeed (const std::string& n, float s) : name (n), speedup (s) {}
400                 };
401
402                 std::string _instance_name;
403                 static std::vector<std::string> _midi_options;
404                 static std::vector<AudioBackend::DeviceStatus> _device_status;
405                 static std::vector<DummyAudioBackend::DriverSpeed> _driver_speed;
406
407                 bool  _running;
408                 bool  _freewheel;
409                 bool  _freewheeling;
410                 float _speedup;
411
412                 std::string _device;
413
414                 float  _samplerate;
415                 size_t _samples_per_period;
416                 float  _dsp_load;
417                 DSPLoadCalculator _dsp_load_calc;
418                 static size_t _max_buffer_size;
419
420                 uint32_t _n_inputs;
421                 uint32_t _n_outputs;
422
423                 uint32_t _n_midi_inputs;
424                 uint32_t _n_midi_outputs;
425                 MidiPortMode _midi_mode;
426
427                 uint32_t _systemic_input_latency;
428                 uint32_t _systemic_output_latency;
429
430                 samplecnt_t _processed_samples;
431
432                 pthread_t _main_thread;
433
434                 /* process threads */
435                 static void* dummy_process_thread (void *);
436                 std::vector<pthread_t> _threads;
437
438                 struct ThreadData {
439                         DummyAudioBackend* engine;
440                         boost::function<void ()> f;
441                         size_t stacksize;
442
443                         ThreadData (DummyAudioBackend* e, boost::function<void ()> fp, size_t stacksz)
444                                 : engine (e) , f (fp) , stacksize (stacksz) {}
445                 };
446
447                 /* port engine */
448                 PortHandle add_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
449                 int register_system_ports ();
450                 void unregister_ports (bool system_only = false);
451                 void update_system_port_latecies ();
452
453                 std::vector<DummyAudioPort *> _system_inputs;
454                 std::vector<DummyAudioPort *> _system_outputs;
455                 std::vector<DummyMidiPort *> _system_midi_in;
456                 std::vector<DummyMidiPort *> _system_midi_out;
457
458                 struct SortByPortName
459                 {
460                         bool operator ()(const DummyPort* lhs, const DummyPort* rhs) const
461                         {
462                                 return PBD::naturally_less (lhs->name ().c_str (), rhs->name ().c_str ());
463                         }
464                 };
465
466                 typedef std::map<std::string, DummyPort *> PortMap; // fast lookup in _ports
467                 typedef std::set<DummyPort *, SortByPortName> PortIndex; // fast lookup in _ports
468                 PortMap _portmap;
469                 PortIndex _ports;
470
471                 struct PortConnectData {
472                         std::string a;
473                         std::string b;
474                         bool c;
475
476                         PortConnectData (const std::string& a, const std::string& b, bool c)
477                                 : a (a) , b (b) , c (c) {}
478                 };
479
480                 std::vector<PortConnectData *> _port_connection_queue;
481                 pthread_mutex_t _port_callback_mutex;
482                 bool _port_change_flag;
483
484                 void port_connect_callback (const std::string& a, const std::string& b, bool conn) {
485                         pthread_mutex_lock (&_port_callback_mutex);
486                         _port_connection_queue.push_back(new PortConnectData(a, b, conn));
487                         pthread_mutex_unlock (&_port_callback_mutex);
488                 }
489
490                 void port_connect_add_remove_callback () {
491                         pthread_mutex_lock (&_port_callback_mutex);
492                         _port_change_flag = true;
493                         pthread_mutex_unlock (&_port_callback_mutex);
494                 }
495
496                 bool valid_port (PortHandle port) const {
497                         return std::find (_ports.begin(), _ports.end(), static_cast<DummyPort*>(port)) != _ports.end ();
498                 }
499
500                 DummyPort* find_port (const std::string& port_name) const {
501                         PortMap::const_iterator it = _portmap.find (port_name);
502                         if (it == _portmap.end()) {
503                                 return NULL;
504                         }
505                         return (*it).second;
506                 }
507
508 }; // class DummyAudioBackend
509
510 } // namespace
511
512 #endif /* __libbackend_dummy_audiobackend_h__ */