d1b28fa560b39fa23aeb5781f570901337aa5ecf
[ardour.git] / libs / backends / alsa / alsa_audiobackend.cc
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 #include <regex.h>
21 #include <sys/mman.h>
22 #include <sys/time.h>
23
24 #include <glibmm.h>
25
26 #include "alsa_audiobackend.h"
27 #include "rt_thread.h"
28
29 #include "pbd/compose.h"
30 #include "pbd/error.h"
31 #include "pbd/file_utils.h"
32 #include "ardour/filesystem_paths.h"
33 #include "ardour/port_manager.h"
34 #include "ardouralsautil/devicelist.h"
35 #include "i18n.h"
36
37 using namespace ARDOUR;
38
39 static std::string s_instance_name;
40 size_t AlsaAudioBackend::_max_buffer_size = 8192;
41 std::vector<std::string> AlsaAudioBackend::_midi_options;
42 std::vector<AudioBackend::DeviceStatus> AlsaAudioBackend::_audio_device_status;
43 std::vector<AudioBackend::DeviceStatus> AlsaAudioBackend::_midi_device_status;
44
45 AlsaAudioBackend::AlsaAudioBackend (AudioEngine& e, AudioBackendInfo& info)
46         : AudioBackend (e, info)
47         , _pcmi (0)
48         , _run (false)
49         , _active (false)
50         , _freewheel (false)
51         , _freewheeling (false)
52         , _measure_latency (false)
53         , _audio_device("")
54         , _midi_driver_option(_("None"))
55         , _device_reservation(0)
56         , _samplerate (48000)
57         , _samples_per_period (1024)
58         , _periods_per_cycle (2)
59         , _n_inputs (0)
60         , _n_outputs (0)
61         , _systemic_audio_input_latency (0)
62         , _systemic_audio_output_latency (0)
63         , _dsp_load (0)
64         , _processed_samples (0)
65         , _port_change_flag (false)
66 {
67         _instance_name = s_instance_name;
68         pthread_mutex_init (&_port_callback_mutex, 0);
69 }
70
71 AlsaAudioBackend::~AlsaAudioBackend ()
72 {
73         pthread_mutex_destroy (&_port_callback_mutex);
74 }
75
76 /* AUDIOBACKEND API */
77
78 std::string
79 AlsaAudioBackend::name () const
80 {
81         return X_("ALSA");
82 }
83
84 bool
85 AlsaAudioBackend::is_realtime () const
86 {
87         return true;
88 }
89
90 std::vector<AudioBackend::DeviceStatus>
91 AlsaAudioBackend::enumerate_devices () const
92 {
93         _audio_device_status.clear();
94         std::map<std::string, std::string> devices;
95         get_alsa_audio_device_names(devices);
96         for (std::map<std::string, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
97                 if (_audio_device == "") _audio_device = i->first;
98                 _audio_device_status.push_back (DeviceStatus (i->first, true));
99         }
100         return _audio_device_status;
101 }
102
103 void
104 AlsaAudioBackend::reservation_stdout (std::string d, size_t /* s */)
105 {
106   if (d.substr(0, 19) == "Acquired audio-card") {
107                 _reservation_succeeded = true;
108         }
109 }
110
111 void
112 AlsaAudioBackend::release_device()
113 {
114         _reservation_connection.drop_connections();
115         ARDOUR::SystemExec * tmp = _device_reservation;
116         _device_reservation = 0;
117         delete tmp;
118 }
119
120 bool
121 AlsaAudioBackend::acquire_device(const char* device_name)
122 {
123         /* This is  quick hack, ideally we'll link against libdbus and implement a dbus-listener
124          * that owns the device. here we try to get away by just requesting it and then block it...
125          * (pulseaudio periodically checks anyway)
126          *
127          * dbus-send --session --print-reply --type=method_call --dest=org.freedesktop.ReserveDevice1.Audio2 /org/freedesktop/ReserveDevice1/Audio2 org.freedesktop.ReserveDevice1.RequestRelease int32:4
128          * -> should not return  'boolean false'
129          */
130         int device_number = card_to_num(device_name);
131         if (device_number < 0) return false;
132
133         assert(_device_reservation == 0);
134         _reservation_succeeded = false;
135
136         std::string request_device_exe;
137         if (!PBD::find_file (
138                                 PBD::Searchpath(Glib::build_filename(ARDOUR::ardour_dll_directory(), "ardouralsautil")
139                                         + G_SEARCHPATH_SEPARATOR_S + ARDOUR::ardour_dll_directory()),
140                                 "ardour-request-device", request_device_exe))
141         {
142                 PBD::warning << "ardour-request-device binary was not found..'" << endmsg;
143                 return false;
144         }
145         else
146         {
147                 char **argp;
148                 char tmp[128];
149                 argp=(char**) calloc(5,sizeof(char*));
150                 argp[0] = strdup(request_device_exe.c_str());
151                 argp[1] = strdup("-P");
152                 snprintf(tmp, sizeof(tmp), "%d", getpid());
153                 argp[2] = strdup(tmp);
154                 snprintf(tmp, sizeof(tmp), "Audio%d", device_number);
155                 argp[3] = strdup(tmp);
156                 argp[4] = 0;
157
158                 _device_reservation = new ARDOUR::SystemExec(request_device_exe, argp);
159                 _device_reservation->ReadStdout.connect_same_thread (_reservation_connection, boost::bind (&AlsaAudioBackend::reservation_stdout, this, _1 ,_2));
160                 _device_reservation->Terminated.connect_same_thread (_reservation_connection, boost::bind (&AlsaAudioBackend::release_device, this));
161                 if (_device_reservation->start(0)) {
162                         PBD::warning << _("AlsaAudioBackend: Device Request failed.") << endmsg;
163                         release_device();
164                         return false;
165                 }
166         }
167         // wait to check if reservation suceeded.
168         int timeout = 500; // 5 sec
169         while (_device_reservation && !_reservation_succeeded && --timeout > 0) {
170                 Glib::usleep(10000);
171         }
172         if (timeout == 0 || !_reservation_succeeded) {
173                 PBD::warning << _("AlsaAudioBackend: Device Reservation failed.") << endmsg;
174                 release_device();
175                 return false;
176         }
177         return true;
178 }
179
180 std::vector<float>
181 AlsaAudioBackend::available_sample_rates (const std::string&) const
182 {
183         std::vector<float> sr;
184         sr.push_back (8000.0);
185         sr.push_back (22050.0);
186         sr.push_back (24000.0);
187         sr.push_back (44100.0);
188         sr.push_back (48000.0);
189         sr.push_back (88200.0);
190         sr.push_back (96000.0);
191         sr.push_back (176400.0);
192         sr.push_back (192000.0);
193         return sr;
194 }
195
196 std::vector<uint32_t>
197 AlsaAudioBackend::available_buffer_sizes (const std::string&) const
198 {
199         std::vector<uint32_t> bs;
200         bs.push_back (32);
201         bs.push_back (64);
202         bs.push_back (128);
203         bs.push_back (256);
204         bs.push_back (512);
205         bs.push_back (1024);
206         bs.push_back (2048);
207         bs.push_back (4096);
208         bs.push_back (8192);
209         return bs;
210 }
211
212 uint32_t
213 AlsaAudioBackend::available_input_channel_count (const std::string&) const
214 {
215         return 128; // TODO query current device
216 }
217
218 uint32_t
219 AlsaAudioBackend::available_output_channel_count (const std::string&) const
220 {
221         return 128; // TODO query current device
222 }
223
224 bool
225 AlsaAudioBackend::can_change_sample_rate_when_running () const
226 {
227         return false;
228 }
229
230 bool
231 AlsaAudioBackend::can_change_buffer_size_when_running () const
232 {
233         return false;
234 }
235
236 int
237 AlsaAudioBackend::set_device_name (const std::string& d)
238 {
239         _audio_device = d;
240         return 0;
241 }
242
243 int
244 AlsaAudioBackend::set_sample_rate (float sr)
245 {
246         if (sr <= 0) { return -1; }
247         _samplerate = sr;
248         engine.sample_rate_change (sr);
249         return 0;
250 }
251
252 int
253 AlsaAudioBackend::set_buffer_size (uint32_t bs)
254 {
255         if (bs <= 0 || bs >= _max_buffer_size) {
256                 return -1;
257         }
258         _samples_per_period = bs;
259         engine.buffer_size_change (bs);
260         return 0;
261 }
262
263 int
264 AlsaAudioBackend::set_interleaved (bool yn)
265 {
266         if (!yn) { return 0; }
267         return -1;
268 }
269
270 int
271 AlsaAudioBackend::set_input_channels (uint32_t cc)
272 {
273         _n_inputs = cc;
274         return 0;
275 }
276
277 int
278 AlsaAudioBackend::set_output_channels (uint32_t cc)
279 {
280         _n_outputs = cc;
281         return 0;
282 }
283
284 int
285 AlsaAudioBackend::set_systemic_input_latency (uint32_t sl)
286 {
287         _systemic_audio_input_latency = sl;
288         return 0;
289 }
290
291 int
292 AlsaAudioBackend::set_systemic_output_latency (uint32_t sl)
293 {
294         _systemic_audio_output_latency = sl;
295         return 0;
296 }
297
298 int
299 AlsaAudioBackend::set_systemic_midi_input_latency (std::string const device, uint32_t sl)
300 {
301         struct AlsaMidiDeviceInfo * nfo = midi_device_info(device);
302         if (!nfo) return -1;
303         nfo->systemic_input_latency = sl;
304         return 0;
305 }
306
307 int
308 AlsaAudioBackend::set_systemic_midi_output_latency (std::string const device, uint32_t sl)
309 {
310         struct AlsaMidiDeviceInfo * nfo = midi_device_info(device);
311         if (!nfo) return -1;
312         nfo->systemic_output_latency = sl;
313         return 0;
314 }
315
316 /* Retrieving parameters */
317 std::string
318 AlsaAudioBackend::device_name () const
319 {
320         return _audio_device;
321 }
322
323 float
324 AlsaAudioBackend::sample_rate () const
325 {
326         return _samplerate;
327 }
328
329 uint32_t
330 AlsaAudioBackend::buffer_size () const
331 {
332         return _samples_per_period;
333 }
334
335 bool
336 AlsaAudioBackend::interleaved () const
337 {
338         return false;
339 }
340
341 uint32_t
342 AlsaAudioBackend::input_channels () const
343 {
344         return _n_inputs;
345 }
346
347 uint32_t
348 AlsaAudioBackend::output_channels () const
349 {
350         return _n_outputs;
351 }
352
353 uint32_t
354 AlsaAudioBackend::systemic_input_latency () const
355 {
356         return _systemic_audio_input_latency;
357 }
358
359 uint32_t
360 AlsaAudioBackend::systemic_output_latency () const
361 {
362         return _systemic_audio_output_latency;
363 }
364
365 uint32_t
366 AlsaAudioBackend::systemic_midi_input_latency (std::string const device) const
367 {
368         struct AlsaMidiDeviceInfo * nfo = midi_device_info(device);
369         if (!nfo) return 0;
370         return nfo->systemic_input_latency;
371 }
372
373 uint32_t
374 AlsaAudioBackend::systemic_midi_output_latency (std::string const device) const
375 {
376         struct AlsaMidiDeviceInfo * nfo = midi_device_info(device);
377         if (!nfo) return 0;
378         return nfo->systemic_output_latency;
379 }
380
381 /* MIDI */
382 struct AlsaAudioBackend::AlsaMidiDeviceInfo *
383 AlsaAudioBackend::midi_device_info(std::string const name) const {
384         for (std::map<std::string, struct AlsaMidiDeviceInfo*>::const_iterator i = _midi_devices.begin (); i != _midi_devices.end(); ++i) {
385                 if (i->first == name) {
386                         return (i->second);
387                 }
388         }
389
390         assert(_midi_driver_option != _("None"));
391
392         std::map<std::string, std::string> devices;
393         if (_midi_driver_option == _("ALSA raw devices")) {
394                 get_alsa_rawmidi_device_names(devices);
395         } else {
396                 get_alsa_sequencer_names (devices);
397         }
398
399         for (std::map<std::string, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
400                 if (i->first == name) {
401                         _midi_devices[name] = new AlsaMidiDeviceInfo();
402                         return _midi_devices[name];
403                 }
404         }
405         return 0;
406 }
407
408 std::vector<std::string>
409 AlsaAudioBackend::enumerate_midi_options () const
410 {
411         if (_midi_options.empty()) {
412                 _midi_options.push_back (_("ALSA raw devices"));
413                 _midi_options.push_back (_("ALSA sequencer"));
414                 _midi_options.push_back (_("None"));
415         }
416         return _midi_options;
417 }
418
419 std::vector<AudioBackend::DeviceStatus>
420 AlsaAudioBackend::enumerate_midi_devices () const
421 {
422         _midi_device_status.clear();
423         std::map<std::string, std::string> devices;
424
425         if (_midi_driver_option == _("ALSA raw devices")) {
426                 get_alsa_rawmidi_device_names (devices);
427         }
428         else if (_midi_driver_option == _("ALSA sequencer")) {
429                 get_alsa_sequencer_names (devices);
430         }
431
432         for (std::map<std::string, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
433                 _midi_device_status.push_back (DeviceStatus (i->first, true));
434         }
435         return _midi_device_status;
436 }
437
438 int
439 AlsaAudioBackend::set_midi_option (const std::string& opt)
440 {
441         if (opt != _("None") && opt != _("ALSA raw devices") && opt != _("ALSA sequencer")) {
442                 return -1;
443         }
444         _midi_driver_option = opt;
445         return 0;
446 }
447
448 std::string
449 AlsaAudioBackend::midi_option () const
450 {
451         return _midi_driver_option;
452 }
453
454 int
455 AlsaAudioBackend::set_midi_device_enabled (std::string const device, bool enable)
456 {
457         struct AlsaMidiDeviceInfo * nfo = midi_device_info(device);
458         if (!nfo) return -1;
459         nfo->enabled = enable;
460         return 0;
461 }
462
463 bool
464 AlsaAudioBackend::midi_device_enabled (std::string const device) const
465 {
466         struct AlsaMidiDeviceInfo * nfo = midi_device_info(device);
467         if (!nfo) return false;
468         return nfo->enabled;
469 }
470
471 /* State Control */
472
473 static void * pthread_process (void *arg)
474 {
475         AlsaAudioBackend *d = static_cast<AlsaAudioBackend *>(arg);
476         d->main_process_thread ();
477         pthread_exit (0);
478         return 0;
479 }
480
481 int
482 AlsaAudioBackend::_start (bool for_latency_measurement)
483 {
484         if (!_active && _run) {
485                 // recover from 'halted', reap threads
486                 stop();
487         }
488
489         if (_active || _run) {
490                 PBD::error << _("AlsaAudioBackend: already active.") << endmsg;
491                 return -1;
492         }
493
494         if (_ports.size()) {
495                 PBD::warning << _("AlsaAudioBackend: recovering from unclean shutdown, port registry is not empty.") << endmsg;
496                 _system_inputs.clear();
497                 _system_outputs.clear();
498                 _system_midi_in.clear();
499                 _system_midi_out.clear();
500                 _ports.clear();
501         }
502
503         release_device();
504
505         assert(_rmidi_in.size() == 0);
506         assert(_rmidi_out.size() == 0);
507         assert(_pcmi == 0);
508
509         std::string alsa_device;
510         std::map<std::string, std::string> devices;
511         get_alsa_audio_device_names(devices);
512         for (std::map<std::string, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
513                 if (i->first == _audio_device) {
514                         alsa_device = i->second;
515                         break;
516                 }
517         }
518
519         acquire_device(alsa_device.c_str());
520         _pcmi = new Alsa_pcmi (alsa_device.c_str(), alsa_device.c_str(), 0, _samplerate, _samples_per_period, _periods_per_cycle, 0);
521         switch (_pcmi->state ()) {
522                 case 0: /* OK */ break;
523                 case -1: PBD::error << _("AlsaAudioBackend: failed to open device.") << endmsg; break;
524                 case -2: PBD::error << _("AlsaAudioBackend: failed to allocate parameters.") << endmsg; break;
525                 case -3: PBD::error << _("AlsaAudioBackend: cannot set requested sample rate.") << endmsg; break;
526                 case -4: PBD::error << _("AlsaAudioBackend: cannot set requested period size.") << endmsg; break;
527                 case -5: PBD::error << _("AlsaAudioBackend: cannot set requested number of periods.") << endmsg; break;
528                 case -6: PBD::error << _("AlsaAudioBackend: unsupported sample format.") << endmsg; break;
529                 default: PBD::error << _("AlsaAudioBackend: initialization failed.") << endmsg; break;
530         }
531         if (_pcmi->state ()) {
532                 delete _pcmi; _pcmi = 0;
533                 release_device();
534                 return -1;
535         }
536
537 #ifndef NDEBUG
538         _pcmi->printinfo ();
539 #endif
540
541         if (_n_outputs != _pcmi->nplay ()) {
542                 if (_n_outputs == 0) {
543                  _n_outputs = _pcmi->nplay ();
544                 } else {
545                  _n_outputs = std::min (_n_outputs, _pcmi->nplay ());
546                 }
547                 PBD::warning << _("AlsaAudioBackend: adjusted output channel count to match device.") << endmsg;
548         }
549
550         if (_n_inputs != _pcmi->ncapt ()) {
551                 if (_n_inputs == 0) {
552                  _n_inputs = _pcmi->ncapt ();
553                 } else {
554                  _n_inputs = std::min (_n_inputs, _pcmi->ncapt ());
555                 }
556                 PBD::warning << _("AlsaAudioBackend: adjusted input channel count to match device.") << endmsg;
557         }
558
559         if (_pcmi->fsize() != _samples_per_period) {
560                 _samples_per_period = _pcmi->fsize();
561                 PBD::warning << _("AlsaAudioBackend: samples per period does not match.") << endmsg;
562         }
563
564         if (_pcmi->fsamp() != _samplerate) {
565                 _samplerate = _pcmi->fsamp();
566                 engine.sample_rate_change (_samplerate);
567                 PBD::warning << _("AlsaAudioBackend: sample rate does not match.") << endmsg;
568         }
569
570         _measure_latency = for_latency_measurement;
571
572         register_system_midi_ports();
573
574         if (register_system_audio_ports()) {
575                 PBD::error << _("AlsaAudioBackend: failed to register system ports.") << endmsg;
576                 delete _pcmi; _pcmi = 0;
577                 release_device();
578                 return -1;
579         }
580
581         engine.sample_rate_change (_samplerate);
582         engine.buffer_size_change (_samples_per_period);
583
584         if (engine.reestablish_ports ()) {
585                 PBD::error << _("AlsaAudioBackend: Could not re-establish ports.") << endmsg;
586                 delete _pcmi; _pcmi = 0;
587                 release_device();
588                 return -1;
589         }
590
591         engine.reconnect_ports ();
592         _run = true;
593         _port_change_flag = false;
594
595         if (_realtime_pthread_create (SCHED_FIFO, -20, 100000,
596                                 &_main_thread, pthread_process, this))
597         {
598                 if (pthread_create (&_main_thread, NULL, pthread_process, this))
599                 {
600                         PBD::error << _("AlsaAudioBackend: failed to create process thread.") << endmsg;
601                         delete _pcmi; _pcmi = 0;
602                         release_device();
603                         _run = false;
604                         return -1;
605                 } else {
606                         PBD::warning << _("AlsaAudioBackend: cannot acquire realtime permissions.") << endmsg;
607                 }
608         }
609
610         int timeout = 5000;
611         while (!_active && --timeout > 0) { Glib::usleep (1000); }
612
613         if (timeout == 0 || !_active) {
614                 PBD::error << _("AlsaAudioBackend: failed to start process thread.") << endmsg;
615                 delete _pcmi; _pcmi = 0;
616                 release_device();
617                 _run = false;
618                 return -1;
619         }
620
621         return 0;
622 }
623
624 int
625 AlsaAudioBackend::stop ()
626 {
627         void *status;
628         if (!_run) {
629                 return 0;
630         }
631
632         _run = false;
633         if (pthread_join (_main_thread, &status)) {
634                 PBD::error << _("AlsaAudioBackend: failed to terminate.") << endmsg;
635                 return -1;
636         }
637
638         while (!_rmidi_out.empty ()) {
639                 AlsaMidiIO *m = _rmidi_out.back ();
640                 m->stop();
641                 _rmidi_out.pop_back ();
642                 delete m;
643         }
644         while (!_rmidi_in.empty ()) {
645                 AlsaMidiIO *m = _rmidi_in.back ();
646                 m->stop();
647                 _rmidi_in.pop_back ();
648                 delete m;
649         }
650
651         unregister_ports();
652         delete _pcmi; _pcmi = 0;
653         release_device();
654
655         return (_active == false) ? 0 : -1;
656 }
657
658 int
659 AlsaAudioBackend::freewheel (bool onoff)
660 {
661         _freewheeling = onoff;
662         return 0;
663 }
664
665 float
666 AlsaAudioBackend::dsp_load () const
667 {
668         return 100.f * _dsp_load;
669 }
670
671 size_t
672 AlsaAudioBackend::raw_buffer_size (DataType t)
673 {
674         switch (t) {
675                 case DataType::AUDIO:
676                         return _samples_per_period * sizeof(Sample);
677                 case DataType::MIDI:
678                         return _max_buffer_size; // XXX not really limited
679         }
680         return 0;
681 }
682
683 /* Process time */
684 pframes_t
685 AlsaAudioBackend::sample_time ()
686 {
687         return _processed_samples;
688 }
689
690 pframes_t
691 AlsaAudioBackend::sample_time_at_cycle_start ()
692 {
693         return _processed_samples;
694 }
695
696 pframes_t
697 AlsaAudioBackend::samples_since_cycle_start ()
698 {
699         return 0;
700 }
701
702
703 void *
704 AlsaAudioBackend::alsa_process_thread (void *arg)
705 {
706         ThreadData* td = reinterpret_cast<ThreadData*> (arg);
707         boost::function<void ()> f = td->f;
708         delete td;
709         f ();
710         return 0;
711 }
712
713 int
714 AlsaAudioBackend::create_process_thread (boost::function<void()> func)
715 {
716         pthread_t thread_id;
717         pthread_attr_t attr;
718         size_t stacksize = 100000;
719
720         ThreadData* td = new ThreadData (this, func, stacksize);
721
722         if (_realtime_pthread_create (SCHED_FIFO, -21, stacksize,
723                                 &thread_id, alsa_process_thread, td)) {
724                 pthread_attr_init (&attr);
725                 pthread_attr_setstacksize (&attr, stacksize);
726                 if (pthread_create (&thread_id, &attr, alsa_process_thread, td)) {
727                         PBD::error << _("AudioEngine: cannot create process thread.") << endmsg;
728                         pthread_attr_destroy (&attr);
729                         return -1;
730                 }
731                 pthread_attr_destroy (&attr);
732         }
733
734         _threads.push_back (thread_id);
735         return 0;
736 }
737
738 int
739 AlsaAudioBackend::join_process_threads ()
740 {
741         int rv = 0;
742
743         for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
744         {
745                 void *status;
746                 if (pthread_join (*i, &status)) {
747                         PBD::error << _("AudioEngine: cannot terminate process thread.") << endmsg;
748                         rv -= 1;
749                 }
750         }
751         _threads.clear ();
752         return rv;
753 }
754
755 bool
756 AlsaAudioBackend::in_process_thread ()
757 {
758         if (pthread_equal (_main_thread, pthread_self()) != 0) {
759                 return true;
760         }
761
762         for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
763         {
764                 if (pthread_equal (*i, pthread_self ()) != 0) {
765                         return true;
766                 }
767         }
768         return false;
769 }
770
771 uint32_t
772 AlsaAudioBackend::process_thread_count ()
773 {
774         return _threads.size ();
775 }
776
777 void
778 AlsaAudioBackend::update_latencies ()
779 {
780         // trigger latency callback in RT thread (locked graph)
781         port_connect_add_remove_callback();
782 }
783
784 /* PORTENGINE API */
785
786 void*
787 AlsaAudioBackend::private_handle () const
788 {
789         return NULL;
790 }
791
792 const std::string&
793 AlsaAudioBackend::my_name () const
794 {
795         return _instance_name;
796 }
797
798 bool
799 AlsaAudioBackend::available () const
800 {
801         return _run && _active;
802 }
803
804 uint32_t
805 AlsaAudioBackend::port_name_size () const
806 {
807         return 256;
808 }
809
810 int
811 AlsaAudioBackend::set_port_name (PortEngine::PortHandle port, const std::string& name)
812 {
813         if (!valid_port (port)) {
814                 PBD::error << _("AlsaBackend::set_port_name: Invalid Port(s)") << endmsg;
815                 return -1;
816         }
817         return static_cast<AlsaPort*>(port)->set_name (_instance_name + ":" + name);
818 }
819
820 std::string
821 AlsaAudioBackend::get_port_name (PortEngine::PortHandle port) const
822 {
823         if (!valid_port (port)) {
824                 PBD::error << _("AlsaBackend::get_port_name: Invalid Port(s)") << endmsg;
825                 return std::string ();
826         }
827         return static_cast<AlsaPort*>(port)->name ();
828 }
829
830 PortEngine::PortHandle
831 AlsaAudioBackend::get_port_by_name (const std::string& name) const
832 {
833         PortHandle port = (PortHandle) find_port (name);
834         return port;
835 }
836
837 int
838 AlsaAudioBackend::get_ports (
839                 const std::string& port_name_pattern,
840                 DataType type, PortFlags flags,
841                 std::vector<std::string>& port_names) const
842 {
843         int rv = 0;
844         regex_t port_regex;
845         bool use_regexp = false;
846         if (port_name_pattern.size () > 0) {
847                 if (!regcomp (&port_regex, port_name_pattern.c_str (), REG_EXTENDED|REG_NOSUB)) {
848                         use_regexp = true;
849                 }
850         }
851         for (size_t i = 0; i < _ports.size (); ++i) {
852                 AlsaPort* port = _ports[i];
853                 if ((port->type () == type) && (port->flags () & flags)) {
854                         if (!use_regexp || !regexec (&port_regex, port->name ().c_str (), 0, NULL, 0)) {
855                                 port_names.push_back (port->name ());
856                                 ++rv;
857                         }
858                 }
859         }
860         if (use_regexp) {
861                 regfree (&port_regex);
862         }
863         return rv;
864 }
865
866 DataType
867 AlsaAudioBackend::port_data_type (PortEngine::PortHandle port) const
868 {
869         if (!valid_port (port)) {
870                 return DataType::NIL;
871         }
872         return static_cast<AlsaPort*>(port)->type ();
873 }
874
875 PortEngine::PortHandle
876 AlsaAudioBackend::register_port (
877                 const std::string& name,
878                 ARDOUR::DataType type,
879                 ARDOUR::PortFlags flags)
880 {
881         if (name.size () == 0) { return 0; }
882         if (flags & IsPhysical) { return 0; }
883         return add_port (_instance_name + ":" + name, type, flags);
884 }
885
886 PortEngine::PortHandle
887 AlsaAudioBackend::add_port (
888                 const std::string& name,
889                 ARDOUR::DataType type,
890                 ARDOUR::PortFlags flags)
891 {
892         assert(name.size ());
893         if (find_port (name)) {
894                 PBD::error << _("AlsaBackend::register_port: Port already exists:")
895                                 << " (" << name << ")" << endmsg;
896                 return 0;
897         }
898         AlsaPort* port = NULL;
899         switch (type) {
900                 case DataType::AUDIO:
901                         port = new AlsaAudioPort (*this, name, flags);
902                         break;
903                 case DataType::MIDI:
904                         port = new AlsaMidiPort (*this, name, flags);
905                         break;
906                 default:
907                         PBD::error << _("AlsaBackend::register_port: Invalid Data Type.") << endmsg;
908                         return 0;
909         }
910
911         _ports.push_back (port);
912
913         return port;
914 }
915
916 void
917 AlsaAudioBackend::unregister_port (PortEngine::PortHandle port_handle)
918 {
919         if (!_run) {
920                 return;
921         }
922         AlsaPort* port = static_cast<AlsaPort*>(port_handle);
923         std::vector<AlsaPort*>::iterator i = std::find (_ports.begin (), _ports.end (), static_cast<AlsaPort*>(port_handle));
924         if (i == _ports.end ()) {
925                 PBD::error << _("AlsaBackend::unregister_port: Failed to find port") << endmsg;
926                 return;
927         }
928         disconnect_all(port_handle);
929         _ports.erase (i);
930         delete port;
931 }
932
933 int
934 AlsaAudioBackend::register_system_audio_ports()
935 {
936         LatencyRange lr;
937
938         const int a_ins = _n_inputs > 0 ? _n_inputs : 2;
939         const int a_out = _n_outputs > 0 ? _n_outputs : 2;
940
941         /* audio ports */
942         lr.min = lr.max = _samples_per_period + (_measure_latency ? 0 : _systemic_audio_input_latency);
943         for (int i = 1; i <= a_ins; ++i) {
944                 char tmp[64];
945                 snprintf(tmp, sizeof(tmp), "system:capture_%d", i);
946                 PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsOutput | IsPhysical | IsTerminal));
947                 if (!p) return -1;
948                 set_latency_range (p, false, lr);
949                 _system_inputs.push_back(static_cast<AlsaPort*>(p));
950         }
951
952         lr.min = lr.max = _samples_per_period + (_measure_latency ? 0 : _systemic_audio_output_latency);
953         for (int i = 1; i <= a_out; ++i) {
954                 char tmp[64];
955                 snprintf(tmp, sizeof(tmp), "system:playback_%d", i);
956                 PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
957                 if (!p) return -1;
958                 set_latency_range (p, true, lr);
959                 _system_outputs.push_back(static_cast<AlsaPort*>(p));
960         }
961         return 0;
962 }
963
964 int
965 AlsaAudioBackend::register_system_midi_ports()
966 {
967         std::map<std::string, std::string> devices;
968         int midi_ins = 0;
969         int midi_outs = 0;
970
971         if (_midi_driver_option == _("None")) {
972                 return 0;
973         } else if (_midi_driver_option == _("ALSA raw devices")) {
974                 get_alsa_rawmidi_device_names(devices);
975         } else {
976                 get_alsa_sequencer_names (devices);
977         }
978
979         for (std::map<std::string, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
980                 struct AlsaMidiDeviceInfo * nfo = midi_device_info(i->first);
981                 if (!nfo) continue;
982                 if (!nfo->enabled) continue;
983
984                 AlsaMidiOut *mout;
985                 if (_midi_driver_option == _("ALSA raw devices")) {
986                         mout = new AlsaRawMidiOut (i->second.c_str());
987                 } else {
988                         mout = new AlsaSeqMidiOut (i->second.c_str());
989                 }
990
991                 if (mout->state ()) {
992                         PBD::warning << string_compose (
993                                         _("AlsaMidiOut: failed to open midi device '%1'."), i->second)
994                                 << endmsg;
995                         delete mout;
996                 } else {
997                         mout->setup_timing(_samples_per_period, _samplerate);
998                         mout->sync_time (g_get_monotonic_time());
999                         if (mout->start ()) {
1000                                 PBD::warning << string_compose (
1001                                                 _("AlsaMidiOut: failed to start midi device '%1'."), i->second)
1002                                         << endmsg;
1003                                 delete mout;
1004                         } else {
1005                                 char tmp[64];
1006                                 snprintf(tmp, sizeof(tmp), "system:midi_playback_%d", ++midi_ins);
1007                                 PortHandle p = add_port(std::string(tmp), DataType::MIDI, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
1008                                 if (!p) {
1009                                         mout->stop();
1010                                         delete mout;
1011                                 }
1012                                 LatencyRange lr;
1013                                 lr.min = lr.max = _samples_per_period + (_measure_latency ? 0 : nfo->systemic_output_latency);
1014                                 set_latency_range (p, false, lr);
1015                                 static_cast<AlsaMidiPort*>(p)->set_n_periods(2);
1016                                 _system_midi_out.push_back(static_cast<AlsaPort*>(p));
1017                                 _rmidi_out.push_back (mout);
1018                         }
1019                 }
1020
1021                 AlsaMidiIn *midin;
1022                 if (_midi_driver_option == _("ALSA raw devices")) {
1023                         midin = new AlsaRawMidiIn (i->second.c_str());
1024                 } else {
1025                         midin = new AlsaSeqMidiIn (i->second.c_str());
1026                 }
1027
1028                 if (midin->state ()) {
1029                         PBD::warning << string_compose (
1030                                         _("AlsaMidiIn: failed to open midi device '%1'."), i->second)
1031                                 << endmsg;
1032                         delete midin;
1033                 } else {
1034                         midin->setup_timing(_samples_per_period, _samplerate);
1035                         midin->sync_time (g_get_monotonic_time());
1036                         if (midin->start ()) {
1037                                 PBD::warning << string_compose (
1038                                                 _("AlsaMidiIn: failed to start midi device '%1'."), i->second)
1039                                         << endmsg;
1040                                 delete midin;
1041                         } else {
1042                                 char tmp[64];
1043                                 snprintf(tmp, sizeof(tmp), "system:midi_capture_%d", ++midi_outs);
1044                                 PortHandle p = add_port(std::string(tmp), DataType::MIDI, static_cast<PortFlags>(IsOutput | IsPhysical | IsTerminal));
1045                                 if (!p) {
1046                                         midin->stop();
1047                                         delete midin;
1048                                         continue;
1049                                 }
1050                                 LatencyRange lr;
1051                                 lr.min = lr.max = _samples_per_period + (_measure_latency ? 0 : nfo->systemic_input_latency);
1052                                 set_latency_range (p, false, lr);
1053                                 _system_midi_in.push_back(static_cast<AlsaPort*>(p));
1054                                 _rmidi_in.push_back (midin);
1055                         }
1056                 }
1057         }
1058         return 0;
1059 }
1060
1061 void
1062 AlsaAudioBackend::unregister_ports (bool system_only)
1063 {
1064         size_t i = 0;
1065         _system_inputs.clear();
1066         _system_outputs.clear();
1067         _system_midi_in.clear();
1068         _system_midi_out.clear();
1069         while (i <  _ports.size ()) {
1070                 AlsaPort* port = _ports[i];
1071                 if (! system_only || (port->is_physical () && port->is_terminal ())) {
1072                         port->disconnect_all ();
1073                         delete port;
1074                         _ports.erase (_ports.begin() + i);
1075                 } else {
1076                         ++i;
1077                 }
1078         }
1079 }
1080
1081 int
1082 AlsaAudioBackend::connect (const std::string& src, const std::string& dst)
1083 {
1084         AlsaPort* src_port = find_port (src);
1085         AlsaPort* dst_port = find_port (dst);
1086
1087         if (!src_port) {
1088                 PBD::error << _("AlsaBackend::connect: Invalid Source port:")
1089                                 << " (" << src <<")" << endmsg;
1090                 return -1;
1091         }
1092         if (!dst_port) {
1093                 PBD::error << _("AlsaBackend::connect: Invalid Destination port:")
1094                         << " (" << dst <<")" << endmsg;
1095                 return -1;
1096         }
1097         return src_port->connect (dst_port);
1098 }
1099
1100 int
1101 AlsaAudioBackend::disconnect (const std::string& src, const std::string& dst)
1102 {
1103         AlsaPort* src_port = find_port (src);
1104         AlsaPort* dst_port = find_port (dst);
1105
1106         if (!src_port || !dst_port) {
1107                 PBD::error << _("AlsaBackend::disconnect: Invalid Port(s)") << endmsg;
1108                 return -1;
1109         }
1110         return src_port->disconnect (dst_port);
1111 }
1112
1113 int
1114 AlsaAudioBackend::connect (PortEngine::PortHandle src, const std::string& dst)
1115 {
1116         AlsaPort* dst_port = find_port (dst);
1117         if (!valid_port (src)) {
1118                 PBD::error << _("AlsaBackend::connect: Invalid Source Port Handle") << endmsg;
1119                 return -1;
1120         }
1121         if (!dst_port) {
1122                 PBD::error << _("AlsaBackend::connect: Invalid Destination Port")
1123                         << " (" << dst << ")" << endmsg;
1124                 return -1;
1125         }
1126         return static_cast<AlsaPort*>(src)->connect (dst_port);
1127 }
1128
1129 int
1130 AlsaAudioBackend::disconnect (PortEngine::PortHandle src, const std::string& dst)
1131 {
1132         AlsaPort* dst_port = find_port (dst);
1133         if (!valid_port (src) || !dst_port) {
1134                 PBD::error << _("AlsaBackend::disconnect: Invalid Port(s)") << endmsg;
1135                 return -1;
1136         }
1137         return static_cast<AlsaPort*>(src)->disconnect (dst_port);
1138 }
1139
1140 int
1141 AlsaAudioBackend::disconnect_all (PortEngine::PortHandle port)
1142 {
1143         if (!valid_port (port)) {
1144                 PBD::error << _("AlsaBackend::disconnect_all: Invalid Port") << endmsg;
1145                 return -1;
1146         }
1147         static_cast<AlsaPort*>(port)->disconnect_all ();
1148         return 0;
1149 }
1150
1151 bool
1152 AlsaAudioBackend::connected (PortEngine::PortHandle port, bool /* process_callback_safe*/)
1153 {
1154         if (!valid_port (port)) {
1155                 PBD::error << _("AlsaBackend::disconnect_all: Invalid Port") << endmsg;
1156                 return false;
1157         }
1158         return static_cast<AlsaPort*>(port)->is_connected ();
1159 }
1160
1161 bool
1162 AlsaAudioBackend::connected_to (PortEngine::PortHandle src, const std::string& dst, bool /*process_callback_safe*/)
1163 {
1164         AlsaPort* dst_port = find_port (dst);
1165         if (!valid_port (src) || !dst_port) {
1166                 PBD::error << _("AlsaBackend::connected_to: Invalid Port") << endmsg;
1167                 return false;
1168         }
1169         return static_cast<AlsaPort*>(src)->is_connected (dst_port);
1170 }
1171
1172 bool
1173 AlsaAudioBackend::physically_connected (PortEngine::PortHandle port, bool /*process_callback_safe*/)
1174 {
1175         if (!valid_port (port)) {
1176                 PBD::error << _("AlsaBackend::physically_connected: Invalid Port") << endmsg;
1177                 return false;
1178         }
1179         return static_cast<AlsaPort*>(port)->is_physically_connected ();
1180 }
1181
1182 int
1183 AlsaAudioBackend::get_connections (PortEngine::PortHandle port, std::vector<std::string>& names, bool /*process_callback_safe*/)
1184 {
1185         if (!valid_port (port)) {
1186                 PBD::error << _("AlsaBackend::get_connections: Invalid Port") << endmsg;
1187                 return -1;
1188         }
1189
1190         assert (0 == names.size ());
1191
1192         const std::vector<AlsaPort*>& connected_ports = static_cast<AlsaPort*>(port)->get_connections ();
1193
1194         for (std::vector<AlsaPort*>::const_iterator i = connected_ports.begin (); i != connected_ports.end (); ++i) {
1195                 names.push_back ((*i)->name ());
1196         }
1197
1198         return (int)names.size ();
1199 }
1200
1201 /* MIDI */
1202 int
1203 AlsaAudioBackend::midi_event_get (
1204                 pframes_t& timestamp,
1205                 size_t& size, uint8_t** buf, void* port_buffer,
1206                 uint32_t event_index)
1207 {
1208         assert (buf && port_buffer);
1209         AlsaMidiBuffer& source = * static_cast<AlsaMidiBuffer*>(port_buffer);
1210         if (event_index >= source.size ()) {
1211                 return -1;
1212         }
1213         AlsaMidiEvent * const event = source[event_index].get ();
1214
1215         timestamp = event->timestamp ();
1216         size = event->size ();
1217         *buf = event->data ();
1218         return 0;
1219 }
1220
1221 int
1222 AlsaAudioBackend::midi_event_put (
1223                 void* port_buffer,
1224                 pframes_t timestamp,
1225                 const uint8_t* buffer, size_t size)
1226 {
1227         assert (buffer && port_buffer);
1228         AlsaMidiBuffer& dst = * static_cast<AlsaMidiBuffer*>(port_buffer);
1229         if (dst.size () && (pframes_t)dst.back ()->timestamp () > timestamp) {
1230                 fprintf (stderr, "AlsaMidiBuffer: it's too late for this event. %d > %d\n",
1231                                 (pframes_t)dst.back ()->timestamp (), timestamp);
1232                 return -1;
1233         }
1234         dst.push_back (boost::shared_ptr<AlsaMidiEvent>(new AlsaMidiEvent (timestamp, buffer, size)));
1235         return 0;
1236 }
1237
1238 uint32_t
1239 AlsaAudioBackend::get_midi_event_count (void* port_buffer)
1240 {
1241         assert (port_buffer);
1242         return static_cast<AlsaMidiBuffer*>(port_buffer)->size ();
1243 }
1244
1245 void
1246 AlsaAudioBackend::midi_clear (void* port_buffer)
1247 {
1248         assert (port_buffer);
1249         AlsaMidiBuffer * buf = static_cast<AlsaMidiBuffer*>(port_buffer);
1250         assert (buf);
1251         buf->clear ();
1252 }
1253
1254 /* Monitoring */
1255
1256 bool
1257 AlsaAudioBackend::can_monitor_input () const
1258 {
1259         return false;
1260 }
1261
1262 int
1263 AlsaAudioBackend::request_input_monitoring (PortEngine::PortHandle, bool)
1264 {
1265         return -1;
1266 }
1267
1268 int
1269 AlsaAudioBackend::ensure_input_monitoring (PortEngine::PortHandle, bool)
1270 {
1271         return -1;
1272 }
1273
1274 bool
1275 AlsaAudioBackend::monitoring_input (PortEngine::PortHandle)
1276 {
1277         return false;
1278 }
1279
1280 /* Latency management */
1281
1282 void
1283 AlsaAudioBackend::set_latency_range (PortEngine::PortHandle port, bool for_playback, LatencyRange latency_range)
1284 {
1285         if (!valid_port (port)) {
1286                 PBD::error << _("AlsaPort::set_latency_range (): invalid port.") << endmsg;
1287         }
1288         static_cast<AlsaPort*>(port)->set_latency_range (latency_range, for_playback);
1289 }
1290
1291 LatencyRange
1292 AlsaAudioBackend::get_latency_range (PortEngine::PortHandle port, bool for_playback)
1293 {
1294         if (!valid_port (port)) {
1295                 PBD::error << _("AlsaPort::get_latency_range (): invalid port.") << endmsg;
1296                 LatencyRange r;
1297                 r.min = 0;
1298                 r.max = 0;
1299                 return r;
1300         }
1301         return static_cast<AlsaPort*>(port)->latency_range (for_playback);
1302 }
1303
1304 /* Discovering physical ports */
1305
1306 bool
1307 AlsaAudioBackend::port_is_physical (PortEngine::PortHandle port) const
1308 {
1309         if (!valid_port (port)) {
1310                 PBD::error << _("AlsaPort::port_is_physical (): invalid port.") << endmsg;
1311                 return false;
1312         }
1313         return static_cast<AlsaPort*>(port)->is_physical ();
1314 }
1315
1316 void
1317 AlsaAudioBackend::get_physical_outputs (DataType type, std::vector<std::string>& port_names)
1318 {
1319         for (size_t i = 0; i < _ports.size (); ++i) {
1320                 AlsaPort* port = _ports[i];
1321                 if ((port->type () == type) && port->is_input () && port->is_physical ()) {
1322                         port_names.push_back (port->name ());
1323                 }
1324         }
1325 }
1326
1327 void
1328 AlsaAudioBackend::get_physical_inputs (DataType type, std::vector<std::string>& port_names)
1329 {
1330         for (size_t i = 0; i < _ports.size (); ++i) {
1331                 AlsaPort* port = _ports[i];
1332                 if ((port->type () == type) && port->is_output () && port->is_physical ()) {
1333                         port_names.push_back (port->name ());
1334                 }
1335         }
1336 }
1337
1338 ChanCount
1339 AlsaAudioBackend::n_physical_outputs () const
1340 {
1341         int n_midi = 0;
1342         int n_audio = 0;
1343         for (size_t i = 0; i < _ports.size (); ++i) {
1344                 AlsaPort* port = _ports[i];
1345                 if (port->is_output () && port->is_physical ()) {
1346                         switch (port->type ()) {
1347                                 case DataType::AUDIO: ++n_audio; break;
1348                                 case DataType::MIDI: ++n_midi; break;
1349                                 default: break;
1350                         }
1351                 }
1352         }
1353         ChanCount cc;
1354         cc.set (DataType::AUDIO, n_audio);
1355         cc.set (DataType::MIDI, n_midi);
1356         return cc;
1357 }
1358
1359 ChanCount
1360 AlsaAudioBackend::n_physical_inputs () const
1361 {
1362         int n_midi = 0;
1363         int n_audio = 0;
1364         for (size_t i = 0; i < _ports.size (); ++i) {
1365                 AlsaPort* port = _ports[i];
1366                 if (port->is_input () && port->is_physical ()) {
1367                         switch (port->type ()) {
1368                                 case DataType::AUDIO: ++n_audio; break;
1369                                 case DataType::MIDI: ++n_midi; break;
1370                                 default: break;
1371                         }
1372                 }
1373         }
1374         ChanCount cc;
1375         cc.set (DataType::AUDIO, n_audio);
1376         cc.set (DataType::MIDI, n_midi);
1377         return cc;
1378 }
1379
1380 /* Getting access to the data buffer for a port */
1381
1382 void*
1383 AlsaAudioBackend::get_buffer (PortEngine::PortHandle port, pframes_t nframes)
1384 {
1385         assert (port);
1386         assert (valid_port (port));
1387         return static_cast<AlsaPort*>(port)->get_buffer (nframes);
1388 }
1389
1390 /* Engine Process */
1391 void *
1392 AlsaAudioBackend::main_process_thread ()
1393 {
1394         AudioEngine::thread_init_callback (this);
1395         _active = true;
1396         _processed_samples = 0;
1397
1398         uint64_t clock1, clock2;
1399         _pcmi->pcm_start ();
1400         int no_proc_errors = 0;
1401         const int bailout = 2 * _samplerate / _samples_per_period;
1402         const int64_t nomial_time = 1e6 * _samples_per_period / _samplerate;
1403
1404         manager.registration_callback();
1405         manager.graph_order_callback();
1406
1407         while (_run) {
1408                 long nr;
1409                 bool xrun = false;
1410
1411                 if (_freewheeling != _freewheel) {
1412                         _freewheel = _freewheeling;
1413                         engine.freewheel_callback (_freewheel);
1414                 }
1415
1416                 if (!_freewheel) {
1417                         nr = _pcmi->pcm_wait ();
1418
1419                         if (_pcmi->state () > 0) {
1420                                 ++no_proc_errors;
1421                                 xrun = true;
1422                         }
1423                         if (_pcmi->state () < 0) {
1424                                 PBD::error << _("AlsaAudioBackend: I/O error. Audio Process Terminated.") << endmsg;
1425                                 break;
1426                         }
1427                         if (no_proc_errors > bailout) {
1428                                 PBD::error
1429                                         << string_compose (
1430                                                         _("AlsaAudioBackend: Audio Process Terminated after %1 consecutive x-runs."),
1431                                                         no_proc_errors)
1432                                         << endmsg;
1433                                 break;
1434                         }
1435
1436                         while (nr >= (long)_samples_per_period && _freewheeling == _freewheel) {
1437                                 uint32_t i = 0;
1438                                 clock1 = g_get_monotonic_time();
1439                                 no_proc_errors = 0;
1440
1441                                 _pcmi->capt_init (_samples_per_period);
1442                                 for (std::vector<AlsaPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it, ++i) {
1443                                         _pcmi->capt_chan (i, (float*)((*it)->get_buffer(_samples_per_period)), _samples_per_period);
1444                                 }
1445                                 _pcmi->capt_done (_samples_per_period);
1446
1447                                 /* de-queue incoming midi*/
1448                                 i = 0;
1449                                 for (std::vector<AlsaPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it, ++i) {
1450                                         assert (_rmidi_in.size() > i);
1451                                         AlsaMidiIn *rm = _rmidi_in.at(i);
1452                                         void *bptr = (*it)->get_buffer(0);
1453                                         pframes_t time;
1454                                         uint8_t data[64]; // match MaxAlsaEventSize in alsa_rawmidi.cc
1455                                         size_t size = sizeof(data);
1456                                         midi_clear(bptr);
1457                                         while (rm->recv_event (time, data, size)) {
1458                                                 midi_event_put(bptr, time, data, size);
1459                                                 size = sizeof(data);
1460                                         }
1461                                         rm->sync_time (clock1);
1462                                 }
1463
1464                                 for (std::vector<AlsaPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it) {
1465                                         memset ((*it)->get_buffer (_samples_per_period), 0, _samples_per_period * sizeof (Sample));
1466                                 }
1467
1468                                 if (engine.process_callback (_samples_per_period)) {
1469                                         _pcmi->pcm_stop ();
1470                                         _active = false;
1471                                         return 0;
1472                                 }
1473
1474                                 for (std::vector<AlsaPort*>::iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) {
1475                                         static_cast<AlsaMidiPort*>(*it)->next_period();
1476                                 }
1477
1478                                 /* queue outgoing midi */
1479                                 i = 0;
1480                                 for (std::vector<AlsaPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it, ++i) {
1481                                         assert (_rmidi_out.size() > i);
1482                                         const AlsaMidiBuffer * src = static_cast<const AlsaMidiPort*>(*it)->const_buffer();
1483                                         AlsaMidiOut *rm = _rmidi_out.at(i);
1484                                         rm->sync_time (clock1);
1485                                         for (AlsaMidiBuffer::const_iterator mit = src->begin (); mit != src->end (); ++mit) {
1486                                                 rm->send_event ((*mit)->timestamp(), (*mit)->data(), (*mit)->size());
1487                                         }
1488                                 }
1489
1490                                 /* write back audio */
1491                                 i = 0;
1492                                 _pcmi->play_init (_samples_per_period);
1493                                 for (std::vector<AlsaPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it, ++i) {
1494                                         _pcmi->play_chan (i, (const float*)(*it)->get_buffer (_samples_per_period), _samples_per_period);
1495                                 }
1496                                 for (; i < _pcmi->nplay (); ++i) {
1497                                         _pcmi->clear_chan (i, _samples_per_period);
1498                                 }
1499                                 _pcmi->play_done (_samples_per_period);
1500                                 nr -= _samples_per_period;
1501                                 _processed_samples += _samples_per_period;
1502
1503                                 /* calculate DSP load */
1504                                 clock2 = g_get_monotonic_time();
1505                                 const int64_t elapsed_time = clock2 - clock1;
1506                                 _dsp_load = elapsed_time / (float) nomial_time;
1507                         }
1508
1509                         if (xrun && (_pcmi->capt_xrun() > 0 || _pcmi->play_xrun() > 0)) {
1510                                 engine.Xrun ();
1511 #if 0
1512                                 fprintf(stderr, "ALSA x-run read: %.2f ms, write: %.2f ms\n",
1513                                                 _pcmi->capt_xrun() * 1000.0, _pcmi->play_xrun() * 1000.0);
1514 #endif
1515                         }
1516                 } else {
1517                         // Freewheelin'
1518
1519                         // zero audio input buffers
1520                         for (std::vector<AlsaPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) {
1521                                 memset ((*it)->get_buffer (_samples_per_period), 0, _samples_per_period * sizeof (Sample));
1522                         }
1523
1524                         clock1 = g_get_monotonic_time();
1525                         uint32_t i = 0;
1526                         for (std::vector<AlsaPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it, ++i) {
1527                                 static_cast<AlsaMidiBuffer*>((*it)->get_buffer(0))->clear ();
1528                                 AlsaMidiIn *rm = _rmidi_in.at(i);
1529                                 void *bptr = (*it)->get_buffer(0);
1530                                 midi_clear(bptr); // zero midi buffer
1531
1532                                 // TODO add an API call for this.
1533                                 pframes_t time;
1534                                 uint8_t data[64]; // match MaxAlsaEventSize in alsa_rawmidi.cc
1535                                 size_t size = sizeof(data);
1536                                 while (rm->recv_event (time, data, size)) {
1537                                         ; // discard midi-data from HW.
1538                                 }
1539                                 rm->sync_time (clock1);
1540                         }
1541
1542                         if (engine.process_callback (_samples_per_period)) {
1543                                 _pcmi->pcm_stop ();
1544                                 _active = false;
1545                                 return 0;
1546                         }
1547
1548                         // drop all outgoing MIDI messages
1549                         for (std::vector<AlsaPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) {
1550                                         void *bptr = (*it)->get_buffer(0);
1551                                         midi_clear(bptr);
1552                         }
1553
1554                         _dsp_load = 1.0;
1555                         Glib::usleep (100); // don't hog cpu
1556                 }
1557
1558                 bool connections_changed = false;
1559                 bool ports_changed = false;
1560                 if (!pthread_mutex_trylock (&_port_callback_mutex)) {
1561                         if (_port_change_flag) {
1562                                 ports_changed = true;
1563                                 _port_change_flag = false;
1564                         }
1565                         if (!_port_connection_queue.empty ()) {
1566                                 connections_changed = true;
1567                         }
1568                         while (!_port_connection_queue.empty ()) {
1569                                 PortConnectData *c = _port_connection_queue.back ();
1570                                 manager.connect_callback (c->a, c->b, c->c);
1571                                 _port_connection_queue.pop_back ();
1572                                 delete c;
1573                         }
1574                         pthread_mutex_unlock (&_port_callback_mutex);
1575                 }
1576                 if (ports_changed) {
1577                         manager.registration_callback();
1578                 }
1579                 if (connections_changed) {
1580                         manager.graph_order_callback();
1581                 }
1582                 if (connections_changed || ports_changed) {
1583                         engine.latency_callback(false);
1584                         engine.latency_callback(true);
1585                 }
1586
1587         }
1588         _pcmi->pcm_stop ();
1589         _active = false;
1590         if (_run) {
1591                 engine.halted_callback("ALSA I/O error.");
1592         }
1593         return 0;
1594 }
1595
1596
1597 /******************************************************************************/
1598
1599 static boost::shared_ptr<AlsaAudioBackend> _instance;
1600
1601 static boost::shared_ptr<AudioBackend> backend_factory (AudioEngine& e);
1602 static int instantiate (const std::string& arg1, const std::string& /* arg2 */);
1603 static int deinstantiate ();
1604 static bool already_configured ();
1605 static bool available ();
1606
1607 static ARDOUR::AudioBackendInfo _descriptor = {
1608         "ALSA",
1609         instantiate,
1610         deinstantiate,
1611         backend_factory,
1612         already_configured,
1613         available
1614 };
1615
1616 static boost::shared_ptr<AudioBackend>
1617 backend_factory (AudioEngine& e)
1618 {
1619         if (!_instance) {
1620                 _instance.reset (new AlsaAudioBackend (e, _descriptor));
1621         }
1622         return _instance;
1623 }
1624
1625 static int
1626 instantiate (const std::string& arg1, const std::string& /* arg2 */)
1627 {
1628         s_instance_name = arg1;
1629         return 0;
1630 }
1631
1632 static int
1633 deinstantiate ()
1634 {
1635         _instance.reset ();
1636         return 0;
1637 }
1638
1639 static bool
1640 already_configured ()
1641 {
1642         return false;
1643 }
1644
1645 static bool
1646 available ()
1647 {
1648         return true;
1649 }
1650
1651 extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor ()
1652 {
1653         return &_descriptor;
1654 }
1655
1656
1657 /******************************************************************************/
1658 AlsaPort::AlsaPort (AlsaAudioBackend &b, const std::string& name, PortFlags flags)
1659         : _alsa_backend (b)
1660         , _name  (name)
1661         , _flags (flags)
1662 {
1663         _capture_latency_range.min = 0;
1664         _capture_latency_range.max = 0;
1665         _playback_latency_range.min = 0;
1666         _playback_latency_range.max = 0;
1667 }
1668
1669 AlsaPort::~AlsaPort () {
1670         disconnect_all ();
1671 }
1672
1673
1674 int AlsaPort::connect (AlsaPort *port)
1675 {
1676         if (!port) {
1677                 PBD::error << _("AlsaPort::connect (): invalid (null) port") << endmsg;
1678                 return -1;
1679         }
1680
1681         if (type () != port->type ()) {
1682                 PBD::error << _("AlsaPort::connect (): wrong port-type") << endmsg;
1683                 return -1;
1684         }
1685
1686         if (is_output () && port->is_output ()) {
1687                 PBD::error << _("AlsaPort::connect (): cannot inter-connect output ports.") << endmsg;
1688                 return -1;
1689         }
1690
1691         if (is_input () && port->is_input ()) {
1692                 PBD::error << _("AlsaPort::connect (): cannot inter-connect input ports.") << endmsg;
1693                 return -1;
1694         }
1695
1696         if (this == port) {
1697                 PBD::error << _("AlsaPort::connect (): cannot self-connect ports.") << endmsg;
1698                 return -1;
1699         }
1700
1701         if (is_connected (port)) {
1702 #if 0 // don't bother to warn about this for now. just ignore it
1703                 PBD::error << _("AlsaPort::connect (): ports are already connected:")
1704                         << " (" << name () << ") -> (" << port->name () << ")"
1705                         << endmsg;
1706 #endif
1707                 return -1;
1708         }
1709
1710         _connect (port, true);
1711         return 0;
1712 }
1713
1714
1715 void AlsaPort::_connect (AlsaPort *port, bool callback)
1716 {
1717         _connections.push_back (port);
1718         if (callback) {
1719                 port->_connect (this, false);
1720                 _alsa_backend.port_connect_callback (name(),  port->name(), true);
1721         }
1722 }
1723
1724 int AlsaPort::disconnect (AlsaPort *port)
1725 {
1726         if (!port) {
1727                 PBD::error << _("AlsaPort::disconnect (): invalid (null) port") << endmsg;
1728                 return -1;
1729         }
1730
1731         if (!is_connected (port)) {
1732                 PBD::error << _("AlsaPort::disconnect (): ports are not connected:")
1733                         << " (" << name () << ") -> (" << port->name () << ")"
1734                         << endmsg;
1735                 return -1;
1736         }
1737         _disconnect (port, true);
1738         return 0;
1739 }
1740
1741 void AlsaPort::_disconnect (AlsaPort *port, bool callback)
1742 {
1743         std::vector<AlsaPort*>::iterator it = std::find (_connections.begin (), _connections.end (), port);
1744
1745         assert (it != _connections.end ());
1746
1747         _connections.erase (it);
1748
1749         if (callback) {
1750                 port->_disconnect (this, false);
1751                 _alsa_backend.port_connect_callback (name(),  port->name(), false);
1752         }
1753 }
1754
1755
1756 void AlsaPort::disconnect_all ()
1757 {
1758         while (!_connections.empty ()) {
1759                 _connections.back ()->_disconnect (this, false);
1760                 _alsa_backend.port_connect_callback (name(),  _connections.back ()->name(), false);
1761                 _connections.pop_back ();
1762         }
1763 }
1764
1765 bool
1766 AlsaPort::is_connected (const AlsaPort *port) const
1767 {
1768         return std::find (_connections.begin (), _connections.end (), port) != _connections.end ();
1769 }
1770
1771 bool AlsaPort::is_physically_connected () const
1772 {
1773         for (std::vector<AlsaPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
1774                 if ((*it)->is_physical ()) {
1775                         return true;
1776                 }
1777         }
1778         return false;
1779 }
1780
1781 /******************************************************************************/
1782
1783 AlsaAudioPort::AlsaAudioPort (AlsaAudioBackend &b, const std::string& name, PortFlags flags)
1784         : AlsaPort (b, name, flags)
1785 {
1786         memset (_buffer, 0, sizeof (_buffer));
1787         mlock(_buffer, sizeof (_buffer));
1788 }
1789
1790 AlsaAudioPort::~AlsaAudioPort () { }
1791
1792 void* AlsaAudioPort::get_buffer (pframes_t n_samples)
1793 {
1794         if (is_input ()) {
1795                 std::vector<AlsaPort*>::const_iterator it = get_connections ().begin ();
1796                 if (it == get_connections ().end ()) {
1797                         memset (_buffer, 0, n_samples * sizeof (Sample));
1798                 } else {
1799                         AlsaAudioPort const * source = static_cast<const AlsaAudioPort*>(*it);
1800                         assert (source && source->is_output ());
1801                         memcpy (_buffer, source->const_buffer (), n_samples * sizeof (Sample));
1802                         while (++it != get_connections ().end ()) {
1803                                 source = static_cast<const AlsaAudioPort*>(*it);
1804                                 assert (source && source->is_output ());
1805                                 Sample* dst = buffer ();
1806                                 const Sample* src = source->const_buffer ();
1807                                 for (uint32_t s = 0; s < n_samples; ++s, ++dst, ++src) {
1808                                         *dst += *src;
1809                                 }
1810                         }
1811                 }
1812         }
1813         return _buffer;
1814 }
1815
1816
1817 AlsaMidiPort::AlsaMidiPort (AlsaAudioBackend &b, const std::string& name, PortFlags flags)
1818         : AlsaPort (b, name, flags)
1819         , _n_periods (1)
1820         , _bufperiod (0)
1821 {
1822         _buffer[0].clear ();
1823         _buffer[1].clear ();
1824 }
1825
1826 AlsaMidiPort::~AlsaMidiPort () { }
1827
1828 struct MidiEventSorter {
1829         bool operator() (const boost::shared_ptr<AlsaMidiEvent>& a, const boost::shared_ptr<AlsaMidiEvent>& b) {
1830                 return *a < *b;
1831         }
1832 };
1833
1834 void* AlsaMidiPort::get_buffer (pframes_t /* nframes */)
1835 {
1836         if (is_input ()) {
1837                 (_buffer[_bufperiod]).clear ();
1838                 for (std::vector<AlsaPort*>::const_iterator i = get_connections ().begin ();
1839                                 i != get_connections ().end ();
1840                                 ++i) {
1841                         const AlsaMidiBuffer * src = static_cast<const AlsaMidiPort*>(*i)->const_buffer ();
1842                         for (AlsaMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
1843                                 (_buffer[_bufperiod]).push_back (boost::shared_ptr<AlsaMidiEvent>(new AlsaMidiEvent (**it)));
1844                         }
1845                 }
1846                 std::sort ((_buffer[_bufperiod]).begin (), (_buffer[_bufperiod]).end (), MidiEventSorter());
1847         }
1848         return &(_buffer[_bufperiod]);
1849 }
1850
1851 AlsaMidiEvent::AlsaMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size)
1852         : _size (size)
1853         , _timestamp (timestamp)
1854         , _data (0)
1855 {
1856         if (size > 0) {
1857                 _data = (uint8_t*) malloc (size);
1858                 memcpy (_data, data, size);
1859         }
1860 }
1861
1862 AlsaMidiEvent::AlsaMidiEvent (const AlsaMidiEvent& other)
1863         : _size (other.size ())
1864         , _timestamp (other.timestamp ())
1865         , _data (0)
1866 {
1867         if (other.size () && other.const_data ()) {
1868                 _data = (uint8_t*) malloc (other.size ());
1869                 memcpy (_data, other.const_data (), other.size ());
1870         }
1871 };
1872
1873 AlsaMidiEvent::~AlsaMidiEvent () {
1874         free (_data);
1875 };