globally change all use of "frame" to refer to audio into "sample".
[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                         if (for_playback)
112                         {
113                                 _playback_latency_range = latency_range;
114                         }
115                         else
116                         {
117                                 _capture_latency_range = latency_range;
118                         }
119                 }
120
121         private:
122                 DummyAudioBackend &_dummy_backend;
123                 std::string _name;
124                 std::string _pretty_name;
125                 const PortFlags _flags;
126                 LatencyRange _capture_latency_range;
127                 LatencyRange _playback_latency_range;
128                 std::set<DummyPort*> _connections;
129
130                 void _connect (DummyPort* , bool);
131                 void _disconnect (DummyPort* , bool);
132
133         protected:
134                 // random number generator
135                 void setup_random_number_generator ();
136                 inline float    randf ();
137                 inline uint32_t randi ();
138                 uint32_t _rseed;
139
140                 // signal generator
141                 volatile bool _gen_cycle;
142                 Glib::Threads::Mutex generator_lock;
143
144 }; // class DummyPort
145
146 class DummyAudioPort : public DummyPort {
147         public:
148                 DummyAudioPort (DummyAudioBackend &b, const std::string&, PortFlags);
149                 ~DummyAudioPort ();
150
151                 DataType type () const { return DataType::AUDIO; };
152
153                 Sample* buffer () { return _buffer; }
154                 const Sample* const_buffer () const { return _buffer; }
155                 void* get_buffer (pframes_t nframes);
156
157                 enum GeneratorType {
158                         Silence,
159                         DC05,
160                         Demolition,
161                         UniformWhiteNoise,
162                         GaussianWhiteNoise,
163                         PinkNoise,
164                         PonyNoise,
165                         SineWave,
166                         SineWaveOctaves,
167                         SquareWave,
168                         KronekerDelta,
169                         SineSweep,
170                         SineSweepSwell,
171                         SquareSweep,
172                         SquareSweepSwell,
173                         LTC,
174                         Loopback,
175                 };
176                 std::string setup_generator (GeneratorType const, float const, int, int);
177                 void fill_wavetable (const float* d, size_t n_samples) { assert(_wavetable != 0);  memcpy(_wavetable, d, n_samples * sizeof(float)); }
178                 void midi_to_wavetable (DummyMidiBuffer const * const src, size_t n_samples);
179
180         private:
181                 Sample _buffer[8192];
182
183                 // signal generator ('fake' physical inputs)
184                 void generate (const pframes_t n_samples);
185                 GeneratorType _gen_type;
186
187                 // generator buffers
188                 // pink-noise filters
189                 float _b0, _b1, _b2, _b3, _b4, _b5, _b6;
190                 // generated sinf() samples
191                 Sample * _wavetable;
192                 uint32_t _gen_period;
193                 uint32_t _gen_offset;
194                 uint32_t _gen_perio2;
195                 uint32_t _gen_count2;
196
197                 // gaussian noise generator
198                 float grandf ();
199                 bool _pass;
200                 float _rn1;
201                 // LTC generator
202                 LTCEncoder* _ltc;
203                 PBD::RingBuffer<Sample>* _ltcbuf;
204                 float _ltc_spd;
205                 float _ltc_rand;
206
207
208 }; // class DummyAudioPort
209
210 class DummyMidiPort : public DummyPort {
211         public:
212                 DummyMidiPort (DummyAudioBackend &b, const std::string&, PortFlags);
213                 ~DummyMidiPort ();
214
215                 DataType type () const { return DataType::MIDI; };
216
217                 void* get_buffer (pframes_t nframes);
218                 const DummyMidiBuffer * const_buffer () const { return &_buffer; }
219
220                 std::string setup_generator (int, float const);
221                 void set_loopback (DummyMidiBuffer const * const src);
222
223         private:
224                 DummyMidiBuffer _buffer;
225                 DummyMidiBuffer _loopback;
226
227                 // midi event generator ('fake' physical inputs)
228                 void midi_generate (const pframes_t n_samples);
229                 float   _midi_seq_spb; // samples per beat
230                 int32_t _midi_seq_time;
231                 uint32_t _midi_seq_pos;
232                 DummyMidiData::MIDISequence const * _midi_seq_dat;
233 }; // class DummyMidiPort
234
235 class DummyAudioBackend : public AudioBackend {
236         friend class DummyPort;
237         public:
238                  DummyAudioBackend (AudioEngine& e, AudioBackendInfo& info);
239                 ~DummyAudioBackend ();
240
241                 bool is_running () const { return _running; }
242
243                 /* AUDIOBACKEND API */
244
245                 std::string name () const;
246                 bool is_realtime () const;
247
248                 bool requires_driver_selection() const { return true; }
249                 std::string driver_name () const;
250                 std::vector<std::string> enumerate_drivers () const;
251                 int set_driver (const std::string&);
252
253                 std::vector<DeviceStatus> enumerate_devices () const;
254                 std::vector<float> available_sample_rates (const std::string& device) const;
255                 std::vector<uint32_t> available_buffer_sizes (const std::string& device) const;
256                 uint32_t available_input_channel_count (const std::string& device) const;
257                 uint32_t available_output_channel_count (const std::string& device) const;
258
259                 bool can_change_sample_rate_when_running () const;
260                 bool can_change_buffer_size_when_running () const;
261
262                 int set_device_name (const std::string&);
263                 int set_sample_rate (float);
264                 int set_buffer_size (uint32_t);
265                 int set_interleaved (bool yn);
266                 int set_input_channels (uint32_t);
267                 int set_output_channels (uint32_t);
268                 int set_systemic_input_latency (uint32_t);
269                 int set_systemic_output_latency (uint32_t);
270                 int set_systemic_midi_input_latency (std::string const, uint32_t) { return 0; }
271                 int set_systemic_midi_output_latency (std::string const, uint32_t) { return 0; }
272
273                 int reset_device () { return 0; };
274
275                 /* Retrieving parameters */
276                 std::string  device_name () const;
277                 float        sample_rate () const;
278                 uint32_t     buffer_size () const;
279                 bool         interleaved () const;
280                 uint32_t     input_channels () const;
281                 uint32_t     output_channels () const;
282                 uint32_t     systemic_input_latency () const;
283                 uint32_t     systemic_output_latency () const;
284                 uint32_t     systemic_midi_input_latency (std::string const) const { return 0; }
285                 uint32_t     systemic_midi_output_latency (std::string const) const { return 0; }
286
287                 /* External control app */
288                 std::string control_app_name () const { return std::string (); }
289                 void launch_control_app () {}
290
291                 /* MIDI */
292                 std::vector<std::string> enumerate_midi_options () const;
293                 int set_midi_option (const std::string&);
294                 std::string midi_option () const;
295
296                 std::vector<DeviceStatus> enumerate_midi_devices () const {
297                         return std::vector<AudioBackend::DeviceStatus> ();
298                 }
299                 int set_midi_device_enabled (std::string const, bool) {
300                         return 0;
301                 }
302                 bool midi_device_enabled (std::string const) const {
303                         return true;
304                 }
305                 bool can_set_systemic_midi_latencies () const {
306                         return false;
307                 }
308
309                 /* State Control */
310         protected:
311                 int _start (bool for_latency_measurement);
312         public:
313                 int stop ();
314                 int freewheel (bool);
315                 float dsp_load () const;
316                 size_t raw_buffer_size (DataType t);
317
318                 /* Process time */
319                 samplepos_t sample_time ();
320                 samplepos_t sample_time_at_cycle_start ();
321                 pframes_t samples_since_cycle_start ();
322
323                 int create_process_thread (boost::function<void()> func);
324                 int join_process_threads ();
325                 bool in_process_thread ();
326                 uint32_t process_thread_count ();
327
328                 void update_latencies ();
329
330                 /* PORTENGINE API */
331
332                 void* private_handle () const;
333                 const std::string& my_name () const;
334                 bool available () const;
335                 uint32_t port_name_size () const;
336
337                 int         set_port_name (PortHandle, const std::string&);
338                 std::string get_port_name (PortHandle) const;
339                 PortHandle  get_port_by_name (const std::string&) const;
340
341                 int get_port_property (PortHandle, const std::string& key, std::string& value, std::string& type) const;
342                 int set_port_property (PortHandle, const std::string& key, const std::string& value, const std::string& type);
343
344                 int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&) const;
345
346                 DataType port_data_type (PortHandle) const;
347
348                 PortHandle register_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
349                 void unregister_port (PortHandle);
350
351                 int  connect (const std::string& src, const std::string& dst);
352                 int  disconnect (const std::string& src, const std::string& dst);
353                 int  connect (PortHandle, const std::string&);
354                 int  disconnect (PortHandle, const std::string&);
355                 int  disconnect_all (PortHandle);
356
357                 bool connected (PortHandle, bool process_callback_safe);
358                 bool connected_to (PortHandle, const std::string&, bool process_callback_safe);
359                 bool physically_connected (PortHandle, bool process_callback_safe);
360                 int  get_connections (PortHandle, std::vector<std::string>&, bool process_callback_safe);
361
362                 /* MIDI */
363                 int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t const** buf, void* port_buffer, uint32_t event_index);
364                 int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size);
365                 uint32_t get_midi_event_count (void* port_buffer);
366                 void     midi_clear (void* port_buffer);
367
368                 /* Monitoring */
369
370                 bool can_monitor_input () const;
371                 int  request_input_monitoring (PortHandle, bool);
372                 int  ensure_input_monitoring (PortHandle, bool);
373                 bool monitoring_input (PortHandle);
374
375                 /* Latency management */
376
377                 void         set_latency_range (PortHandle, bool for_playback, LatencyRange);
378                 LatencyRange get_latency_range (PortHandle, bool for_playback);
379
380                 /* Discovering physical ports */
381
382                 bool      port_is_physical (PortHandle) const;
383                 void      get_physical_outputs (DataType type, std::vector<std::string>&);
384                 void      get_physical_inputs (DataType type, std::vector<std::string>&);
385                 ChanCount n_physical_outputs () const;
386                 ChanCount n_physical_inputs () const;
387
388                 /* Getting access to the data buffer for a port */
389
390                 void* get_buffer (PortHandle, pframes_t);
391
392                 void* main_process_thread ();
393
394                 static size_t max_buffer_size() {return _max_buffer_size;}
395
396         private:
397                 enum MidiPortMode {
398                         MidiNoEvents,
399                         MidiGenerator,
400                         MidiLoopback,
401                         MidiToAudio,
402                 };
403
404                 struct DriverSpeed {
405                         std::string name;
406                         float speedup;
407                         DriverSpeed (const std::string& n, float s) : name (n), speedup (s) {}
408                 };
409
410                 std::string _instance_name;
411                 static std::vector<std::string> _midi_options;
412                 static std::vector<AudioBackend::DeviceStatus> _device_status;
413                 static std::vector<DummyAudioBackend::DriverSpeed> _driver_speed;
414
415                 bool  _running;
416                 bool  _freewheel;
417                 bool  _freewheeling;
418                 float _speedup;
419
420                 std::string _device;
421
422                 float  _samplerate;
423                 size_t _samples_per_period;
424                 float  _dsp_load;
425                 DSPLoadCalculator _dsp_load_calc;
426                 static size_t _max_buffer_size;
427
428                 uint32_t _n_inputs;
429                 uint32_t _n_outputs;
430
431                 uint32_t _n_midi_inputs;
432                 uint32_t _n_midi_outputs;
433                 MidiPortMode _midi_mode;
434
435                 uint32_t _systemic_input_latency;
436                 uint32_t _systemic_output_latency;
437
438                 samplecnt_t _processed_samples;
439
440                 pthread_t _main_thread;
441
442                 /* process threads */
443                 static void* dummy_process_thread (void *);
444                 std::vector<pthread_t> _threads;
445
446                 struct ThreadData {
447                         DummyAudioBackend* engine;
448                         boost::function<void ()> f;
449                         size_t stacksize;
450
451                         ThreadData (DummyAudioBackend* e, boost::function<void ()> fp, size_t stacksz)
452                                 : engine (e) , f (fp) , stacksize (stacksz) {}
453                 };
454
455                 /* port engine */
456                 PortHandle add_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags);
457                 int register_system_ports ();
458                 void unregister_ports (bool system_only = false);
459
460                 std::vector<DummyAudioPort *> _system_inputs;
461                 std::vector<DummyAudioPort *> _system_outputs;
462                 std::vector<DummyMidiPort *> _system_midi_in;
463                 std::vector<DummyMidiPort *> _system_midi_out;
464
465                 struct SortByPortName
466                 {
467                         bool operator ()(const DummyPort* lhs, const DummyPort* rhs) const
468                         {
469                                 return PBD::naturally_less (lhs->name ().c_str (), rhs->name ().c_str ());
470                         }
471                 };
472
473                 typedef std::map<std::string, DummyPort *> PortMap; // fast lookup in _ports
474                 typedef std::set<DummyPort *, SortByPortName> PortIndex; // fast lookup in _ports
475                 PortMap _portmap;
476                 PortIndex _ports;
477
478                 struct PortConnectData {
479                         std::string a;
480                         std::string b;
481                         bool c;
482
483                         PortConnectData (const std::string& a, const std::string& b, bool c)
484                                 : a (a) , b (b) , c (c) {}
485                 };
486
487                 std::vector<PortConnectData *> _port_connection_queue;
488                 pthread_mutex_t _port_callback_mutex;
489                 bool _port_change_flag;
490
491                 void port_connect_callback (const std::string& a, const std::string& b, bool conn) {
492                         pthread_mutex_lock (&_port_callback_mutex);
493                         _port_connection_queue.push_back(new PortConnectData(a, b, conn));
494                         pthread_mutex_unlock (&_port_callback_mutex);
495                 }
496
497                 void port_connect_add_remove_callback () {
498                         pthread_mutex_lock (&_port_callback_mutex);
499                         _port_change_flag = true;
500                         pthread_mutex_unlock (&_port_callback_mutex);
501                 }
502
503                 bool valid_port (PortHandle port) const {
504                         return std::find (_ports.begin(), _ports.end(), static_cast<DummyPort*>(port)) != _ports.end ();
505                 }
506
507                 DummyPort* find_port (const std::string& port_name) const {
508                         PortMap::const_iterator it = _portmap.find (port_name);
509                         if (it == _portmap.end()) {
510                                 return NULL;
511                         }
512                         return (*it).second;
513                 }
514
515 }; // class DummyAudioBackend
516
517 } // namespace
518
519 #endif /* __libbackend_dummy_audiobackend_h__ */