Implement MIDI device enumeration and latency offset/calibration in portaudio backend
[ardour.git] / libs / backends / portaudio / portaudio_backend.cc
1 /*
2  * Copyright (C) 2015-2015 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
22 #ifndef PLATFORM_WINDOWS
23 #include <sys/mman.h>
24 #include <sys/time.h>
25 #endif
26
27 #ifdef COMPILER_MINGW
28 #include <sys/time.h>
29 #endif
30
31 #include <glibmm.h>
32
33 #include "portaudio_backend.h"
34 #include "rt_thread.h"
35
36 #include "pbd/compose.h"
37 #include "pbd/error.h"
38 #include "pbd/file_utils.h"
39 #include "pbd/windows_timer_utils.h"
40 #include "pbd/windows_mmcss.h"
41
42 #include "ardour/filesystem_paths.h"
43 #include "ardour/port_manager.h"
44 #include "i18n.h"
45
46 #include "audio_utils.h"
47
48 #include "debug.h"
49
50 using namespace ARDOUR;
51
52 namespace {
53
54 const char * const winmme_driver_name = X_("WinMME");
55
56 }
57
58 static std::string s_instance_name;
59 size_t PortAudioBackend::_max_buffer_size = 8192;
60 std::vector<std::string> PortAudioBackend::_midi_options;
61 std::vector<AudioBackend::DeviceStatus> PortAudioBackend::_input_audio_device_status;
62 std::vector<AudioBackend::DeviceStatus> PortAudioBackend::_output_audio_device_status;
63
64 PortAudioBackend::PortAudioBackend (AudioEngine& e, AudioBackendInfo& info)
65         : AudioBackend (e, info)
66         , _pcmio (0)
67         , _run (false)
68         , _active (false)
69         , _freewheel (false)
70         , _freewheeling (false)
71         , _freewheel_ack (false)
72         , _reinit_thread_callback (false)
73         , _measure_latency (false)
74         , _cycle_count(0)
75         , _total_deviation_us(0)
76         , _max_deviation_us(0)
77         , _input_audio_device("")
78         , _output_audio_device("")
79         , _midi_driver_option(get_standard_device_name(DeviceNone))
80         , _samplerate (48000)
81         , _samples_per_period (1024)
82         , _n_inputs (0)
83         , _n_outputs (0)
84         , _systemic_audio_input_latency (0)
85         , _systemic_audio_output_latency (0)
86         , _dsp_load (0)
87         , _processed_samples (0)
88         , _port_change_flag (false)
89 {
90         _instance_name = s_instance_name;
91         pthread_mutex_init (&_port_callback_mutex, 0);
92         pthread_mutex_init (&_freewheel_mutex, 0);
93         pthread_cond_init (&_freewheel_signal, 0);
94
95         _pcmio = new PortAudioIO ();
96         _midiio = new WinMMEMidiIO ();
97 }
98
99 PortAudioBackend::~PortAudioBackend ()
100 {
101         delete _pcmio; _pcmio = 0;
102         delete _midiio; _midiio = 0;
103
104         pthread_mutex_destroy (&_port_callback_mutex);
105         pthread_mutex_destroy (&_freewheel_mutex);
106         pthread_cond_destroy (&_freewheel_signal);
107 }
108
109 /* AUDIOBACKEND API */
110
111 std::string
112 PortAudioBackend::name () const
113 {
114         return X_("PortAudio");
115 }
116
117 bool
118 PortAudioBackend::is_realtime () const
119 {
120         return true;
121 }
122
123 bool
124 PortAudioBackend::requires_driver_selection() const
125 {
126         // we could do this but implementation would need changing
127         /*
128         if (enumerate_drivers().size() == 1) {
129                 return false;
130         }
131         */
132         return true;
133 }
134
135 std::vector<std::string>
136 PortAudioBackend::enumerate_drivers () const
137 {
138         DEBUG_AUDIO ("Portaudio: enumerate_drivers\n");
139         std::vector<std::string> currently_available;
140         _pcmio->host_api_list (currently_available);
141         return currently_available;
142 }
143
144 int
145 PortAudioBackend::set_driver (const std::string& name)
146 {
147         DEBUG_AUDIO (string_compose ("Portaudio: set_driver %1 \n", name));
148         if (!_pcmio->set_host_api (name)) {
149                 DEBUG_AUDIO (string_compose ("Portaudio: Unable to set_driver %1 \n", name));
150                 return -1;
151         }
152         _pcmio->update_devices();
153         return 0;
154 }
155
156 bool
157 PortAudioBackend::update_devices ()
158 {
159         // update midi device info?
160         return _pcmio->update_devices();
161 }
162
163 std::string
164 PortAudioBackend::driver_name () const
165 {
166         std::string driver_name = _pcmio->get_host_api ();
167         DEBUG_AUDIO (string_compose ("Portaudio: driver_name %1 \n", driver_name));
168         return driver_name;
169 }
170
171 bool
172 PortAudioBackend::use_separate_input_and_output_devices () const
173 {
174         return true;
175 }
176
177 std::vector<AudioBackend::DeviceStatus>
178 PortAudioBackend::enumerate_devices () const
179 {
180         DEBUG_AUDIO ("Portaudio: ERROR enumerate devices should not be called \n");
181         return std::vector<AudioBackend::DeviceStatus>();
182 }
183
184 std::vector<AudioBackend::DeviceStatus>
185 PortAudioBackend::enumerate_input_devices () const
186 {
187         _input_audio_device_status.clear();
188         std::map<int, std::string> input_devices;
189         _pcmio->input_device_list(input_devices);
190
191         for (std::map<int, std::string>::const_iterator i = input_devices.begin (); i != input_devices.end(); ++i) {
192                 if (_input_audio_device == "") _input_audio_device = i->second;
193                 _input_audio_device_status.push_back (DeviceStatus (i->second, true));
194         }
195         return _input_audio_device_status;
196 }
197
198 std::vector<AudioBackend::DeviceStatus>
199 PortAudioBackend::enumerate_output_devices () const
200 {
201         _output_audio_device_status.clear();
202         std::map<int, std::string> output_devices;
203         _pcmio->output_device_list(output_devices);
204
205         for (std::map<int, std::string>::const_iterator i = output_devices.begin (); i != output_devices.end(); ++i) {
206                 if (_output_audio_device == "") _output_audio_device = i->second;
207                 _output_audio_device_status.push_back (DeviceStatus (i->second, true));
208         }
209         return _output_audio_device_status;
210 }
211
212 std::vector<float>
213 PortAudioBackend::available_sample_rates (const std::string&) const
214 {
215         DEBUG_AUDIO ("Portaudio: available_sample_rates\n");
216         std::vector<float> sr;
217         _pcmio->available_sample_rates(name_to_id(_input_audio_device), sr);
218         return sr;
219 }
220
221 std::vector<uint32_t>
222 PortAudioBackend::available_buffer_sizes (const std::string&) const
223 {
224         DEBUG_AUDIO ("Portaudio: available_buffer_sizes\n");
225         std::vector<uint32_t> bs;
226         _pcmio->available_buffer_sizes(name_to_id(_input_audio_device), bs);
227         return bs;
228 }
229
230 uint32_t
231 PortAudioBackend::available_input_channel_count (const std::string&) const
232 {
233         return 128; // TODO query current device
234 }
235
236 uint32_t
237 PortAudioBackend::available_output_channel_count (const std::string&) const
238 {
239         return 128; // TODO query current device
240 }
241
242 bool
243 PortAudioBackend::can_change_sample_rate_when_running () const
244 {
245         return false;
246 }
247
248 bool
249 PortAudioBackend::can_change_buffer_size_when_running () const
250 {
251         return false; // TODO
252 }
253
254 int
255 PortAudioBackend::set_device_name (const std::string& d)
256 {
257         DEBUG_AUDIO ("Portaudio: set_device_name should not be called\n");
258         return 0;
259 }
260
261 int
262 PortAudioBackend::set_input_device_name (const std::string& d)
263 {
264         DEBUG_AUDIO (string_compose ("Portaudio: set_input_device_name %1\n", d));
265         _input_audio_device = d;
266         return 0;
267 }
268
269 int
270 PortAudioBackend::set_output_device_name (const std::string& d)
271 {
272         DEBUG_AUDIO (string_compose ("Portaudio: set_output_device_name %1\n", d));
273         _output_audio_device = d;
274         return 0;
275 }
276
277 int
278 PortAudioBackend::set_sample_rate (float sr)
279 {
280         if (sr <= 0) { return -1; }
281         // TODO check if it's in the list of valid SR
282         _samplerate = sr;
283         engine.sample_rate_change (sr);
284         return 0;
285 }
286
287 int
288 PortAudioBackend::set_buffer_size (uint32_t bs)
289 {
290         if (bs <= 0 || bs >= _max_buffer_size) {
291                 return -1;
292         }
293         _samples_per_period = bs;
294         engine.buffer_size_change (bs);
295         return 0;
296 }
297
298 int
299 PortAudioBackend::set_interleaved (bool yn)
300 {
301         if (!yn) { return 0; }
302         return -1;
303 }
304
305 int
306 PortAudioBackend::set_input_channels (uint32_t cc)
307 {
308         _n_inputs = cc;
309         return 0;
310 }
311
312 int
313 PortAudioBackend::set_output_channels (uint32_t cc)
314 {
315         _n_outputs = cc;
316         return 0;
317 }
318
319 int
320 PortAudioBackend::set_systemic_input_latency (uint32_t sl)
321 {
322         _systemic_audio_input_latency = sl;
323         return 0;
324 }
325
326 int
327 PortAudioBackend::set_systemic_output_latency (uint32_t sl)
328 {
329         _systemic_audio_output_latency = sl;
330         return 0;
331 }
332
333 int
334 PortAudioBackend::set_systemic_midi_input_latency (std::string const device, uint32_t sl)
335 {
336         MidiDeviceInfo* nfo = midi_device_info (device);
337         if (!nfo) return -1;
338         nfo->systemic_input_latency = sl;
339         return 0;
340 }
341
342 int
343 PortAudioBackend::set_systemic_midi_output_latency (std::string const device, uint32_t sl)
344 {
345         MidiDeviceInfo* nfo = midi_device_info (device);
346         if (!nfo) return -1;
347         nfo->systemic_output_latency = sl;
348         return 0;
349 }
350
351 /* Retrieving parameters */
352 std::string
353 PortAudioBackend::device_name () const
354 {
355         return "Unused";
356 }
357
358 std::string
359 PortAudioBackend::input_device_name () const
360 {
361         return _input_audio_device;
362 }
363
364 std::string
365 PortAudioBackend::output_device_name () const
366 {
367         return _output_audio_device;
368 }
369
370 float
371 PortAudioBackend::sample_rate () const
372 {
373         return _samplerate;
374 }
375
376 uint32_t
377 PortAudioBackend::buffer_size () const
378 {
379         return _samples_per_period;
380 }
381
382 bool
383 PortAudioBackend::interleaved () const
384 {
385         return false;
386 }
387
388 uint32_t
389 PortAudioBackend::input_channels () const
390 {
391         return _n_inputs;
392 }
393
394 uint32_t
395 PortAudioBackend::output_channels () const
396 {
397         return _n_outputs;
398 }
399
400 uint32_t
401 PortAudioBackend::systemic_input_latency () const
402 {
403         return _systemic_audio_input_latency;
404 }
405
406 uint32_t
407 PortAudioBackend::systemic_output_latency () const
408 {
409         return _systemic_audio_output_latency;
410 }
411
412 uint32_t
413 PortAudioBackend::systemic_midi_input_latency (std::string const device) const
414 {
415         MidiDeviceInfo* nfo = midi_device_info (device);
416         if (!nfo) return 0;
417         return nfo->systemic_input_latency;
418 }
419
420 uint32_t
421 PortAudioBackend::systemic_midi_output_latency (std::string const device) const
422 {
423         MidiDeviceInfo* nfo = midi_device_info (device);
424         if (!nfo) return 0;
425         return nfo->systemic_output_latency;
426 }
427
428 std::string
429 PortAudioBackend::control_app_name () const
430 {
431         return _pcmio->control_app_name (name_to_id (_input_audio_device));
432 }
433
434 void
435 PortAudioBackend::launch_control_app ()
436 {
437         return _pcmio->launch_control_app (name_to_id(_input_audio_device));
438 }
439
440 /* MIDI */
441
442 std::vector<std::string>
443 PortAudioBackend::enumerate_midi_options () const
444 {
445         if (_midi_options.empty()) {
446                 _midi_options.push_back (winmme_driver_name);
447                 _midi_options.push_back (get_standard_device_name(DeviceNone));
448         }
449         return _midi_options;
450 }
451
452 int
453 PortAudioBackend::set_midi_option (const std::string& opt)
454 {
455         if (opt != get_standard_device_name(DeviceNone) && opt != winmme_driver_name) {
456                 return -1;
457         }
458         DEBUG_MIDI (string_compose ("Setting midi option to %1\n", opt));
459         _midi_driver_option = opt;
460         return 0;
461 }
462
463 std::string
464 PortAudioBackend::midi_option () const
465 {
466         return _midi_driver_option;
467 }
468
469 std::vector<AudioBackend::DeviceStatus>
470 PortAudioBackend::enumerate_midi_devices () const
471 {
472         std::vector<AudioBackend::DeviceStatus> midi_device_status;
473         std::vector<MidiDeviceInfo*> device_info;
474
475         if (_midi_driver_option == winmme_driver_name) {
476                 _midiio->update_device_info ();
477                 device_info = _midiio->get_device_info ();
478         }
479
480         for (std::vector<MidiDeviceInfo*>::const_iterator i = device_info.begin();
481              i != device_info.end();
482              ++i) {
483                 midi_device_status.push_back(DeviceStatus((*i)->device_name, true));
484         }
485         return midi_device_status;
486 }
487
488 MidiDeviceInfo*
489 PortAudioBackend::midi_device_info (const std::string& device_name) const
490 {
491         std::vector<MidiDeviceInfo*> dev_info;
492
493         if (_midi_driver_option == winmme_driver_name) {
494                 dev_info = _midiio->get_device_info();
495
496                 for (std::vector<MidiDeviceInfo*>::const_iterator i = dev_info.begin();
497                      i != dev_info.end();
498                      ++i) {
499                         if ((*i)->device_name == device_name) {
500                                 return *i;
501                         }
502                 }
503         }
504         return 0;
505 }
506
507 int
508 PortAudioBackend::set_midi_device_enabled (std::string const device, bool enable)
509 {
510         MidiDeviceInfo* nfo = midi_device_info(device);
511         if (!nfo) return -1;
512         nfo->enable = enable;
513         return 0;
514 }
515
516 bool
517 PortAudioBackend::midi_device_enabled (std::string const device) const
518 {
519         MidiDeviceInfo* nfo = midi_device_info(device);
520         if (!nfo) return false;
521         return nfo->enable;
522 }
523
524 /* State Control */
525
526 static void * blocking_thread_func (void *arg)
527 {
528         PortAudioBackend *d = static_cast<PortAudioBackend *>(arg);
529         d->blocking_process_thread ();
530         pthread_exit (0);
531         return 0;
532 }
533
534 bool
535 PortAudioBackend::engine_halted ()
536 {
537         return !_active && _run;
538 }
539
540 bool
541 PortAudioBackend::running ()
542 {
543         return _active || _run;
544 }
545
546 int
547 PortAudioBackend::_start (bool for_latency_measurement)
548 {
549         if (engine_halted()) {
550                 stop();
551         }
552
553         if (running()) {
554                 DEBUG_AUDIO("Already started.\n");
555                 return BackendReinitializationError;
556         }
557
558         if (_ports.size()) {
559                 DEBUG_AUDIO(
560                     "Recovering from unclean shutdown, port registry is not empty.\n");
561                 _system_inputs.clear();
562                 _system_outputs.clear();
563                 _system_midi_in.clear();
564                 _system_midi_out.clear();
565                 _ports.clear();
566         }
567
568         /* reset internal state */
569         _dsp_load = 0;
570         _freewheeling = false;
571         _freewheel = false;
572
573         PaErrorCode err = paNoError;
574
575 #ifdef USE_BLOCKING_API
576         err = _pcmio->open_blocking_stream(name_to_id(_input_audio_device),
577                                            name_to_id(_output_audio_device),
578                                            _samplerate,
579                                            _samples_per_period);
580
581 #else
582         err = _pcmio->open_callback_stream(name_to_id(_input_audio_device),
583                                            name_to_id(_output_audio_device),
584                                            _samplerate,
585                                            _samples_per_period,
586                                            portaudio_callback,
587                                            this);
588
589 #endif
590
591         // reintepret Portaudio error messages
592         switch (err) {
593         case paNoError:
594                 break;
595         case paBadIODeviceCombination:
596                 return DeviceConfigurationNotSupportedError;
597         case paInvalidChannelCount:
598                 return ChannelCountNotSupportedError;
599         case paInvalidSampleRate:
600                 return SampleRateNotSupportedError;
601         default:
602                 return AudioDeviceOpenError;
603         }
604
605         if (_n_outputs != _pcmio->n_playback_channels ()) {
606                 _n_outputs = _pcmio->n_playback_channels ();
607                 PBD::info << get_error_string(OutputChannelCountNotSupportedError) << endmsg;
608         }
609
610         if (_n_inputs != _pcmio->n_capture_channels ()) {
611                 _n_inputs = _pcmio->n_capture_channels ();
612                 PBD::info << get_error_string(InputChannelCountNotSupportedError) << endmsg;
613         }
614 #if 0
615         if (_pcmio->samples_per_period() != _samples_per_period) {
616                 _samples_per_period = _pcmio->samples_per_period();
617                 PBD::warning << _("PortAudioBackend: samples per period does not match.") << endmsg;
618         }
619 #endif
620
621         if (_pcmio->sample_rate() != _samplerate) {
622                 _samplerate = _pcmio->sample_rate();
623                 engine.sample_rate_change (_samplerate);
624                 PBD::warning << get_error_string(SampleRateNotSupportedError) << endmsg;
625         }
626
627         _measure_latency = for_latency_measurement;
628
629         _run = true;
630         _port_change_flag = false;
631
632         if (_midi_driver_option == winmme_driver_name) {
633                 _midiio->set_enabled(true);
634                 //_midiio->set_port_changed_callback(midi_port_change, this);
635                 _midiio->start(); // triggers port discovery, callback coremidi_rediscover()
636         }
637
638         _cycle_timer.set_samplerate(_samplerate);
639         _cycle_timer.set_samples_per_cycle(_samples_per_period);
640
641         _dsp_calc.set_max_time_us (_cycle_timer.get_length_us());
642
643         DEBUG_MIDI ("Registering MIDI ports\n");
644
645         if (register_system_midi_ports () != 0) {
646                 DEBUG_PORTS("Failed to register system midi ports.\n")
647                 _run = false;
648                 return PortRegistrationError;
649         }
650
651         DEBUG_AUDIO ("Registering Audio ports\n");
652
653         if (register_system_audio_ports()) {
654                 DEBUG_PORTS("Failed to register system audio ports.\n");
655                 _run = false;
656                 return PortRegistrationError;
657         }
658
659         engine.sample_rate_change (_samplerate);
660         engine.buffer_size_change (_samples_per_period);
661
662         if (engine.reestablish_ports ()) {
663                 DEBUG_PORTS("Could not re-establish ports.\n");
664                 _run = false;
665                 return PortReconnectError;
666         }
667
668         engine.reconnect_ports ();
669         _run = true;
670         _port_change_flag = false;
671
672 #ifdef USE_BLOCKING_API
673         if (!start_blocking_process_thread()) {
674                 return ProcessThreadStartError;
675         }
676 #else
677         if (_pcmio->start_stream() != paNoError) {
678                 DEBUG_AUDIO("Unable to start stream\n");
679                 return AudioDeviceOpenError;
680         }
681
682         if (!start_freewheel_process_thread()) {
683                 DEBUG_AUDIO("Unable to start freewheel thread\n");
684                 stop();
685                 return ProcessThreadStartError;
686         }
687 #endif
688
689         return NoError;
690 }
691
692 int
693 PortAudioBackend::portaudio_callback(const void* input,
694                                      void* output,
695                                      unsigned long frame_count,
696                                      const PaStreamCallbackTimeInfo* time_info,
697                                      PaStreamCallbackFlags status_flags,
698                                      void* user_data)
699 {
700         PortAudioBackend* pa_backend = static_cast<PortAudioBackend*>(user_data);
701
702         if (!pa_backend->process_callback((const float*)input,
703                                           (float*)output,
704                                           frame_count,
705                                           time_info,
706                                           status_flags)) {
707                 return paAbort;
708         }
709
710         return paContinue;
711 }
712
713 bool
714 PortAudioBackend::process_callback(const float* input,
715                                    float* output,
716                                    uint32_t frame_count,
717                                    const PaStreamCallbackTimeInfo* timeInfo,
718                                    PaStreamCallbackFlags statusFlags)
719 {
720         _active = true;
721
722         _dsp_calc.set_start_timestamp_us (PBD::get_microseconds());
723
724         if (_run && _freewheel && !_freewheel_ack) {
725                 // acknowledge freewheeling; hand-over thread ID
726                 pthread_mutex_lock (&_freewheel_mutex);
727                 if (_freewheel) {
728                         DEBUG_AUDIO("Setting _freewheel_ack = true;\n");
729                         _freewheel_ack = true;
730                 }
731                 DEBUG_AUDIO("Signalling freewheel thread\n");
732                 pthread_cond_signal (&_freewheel_signal);
733                 pthread_mutex_unlock (&_freewheel_mutex);
734         }
735
736         if (statusFlags & paInputUnderflow ||
737                 statusFlags & paInputOverflow ||
738                 statusFlags & paOutputUnderflow ||
739                 statusFlags & paOutputOverflow ) {
740                 DEBUG_AUDIO("PortAudio: Xrun\n");
741                 engine.Xrun();
742                 return true;
743         }
744
745         if (!_run || _freewheel) {
746                 memset(output, 0, frame_count * sizeof(float) * _system_outputs.size());
747                 return true;
748         }
749
750         bool in_main_thread = pthread_equal(_main_thread, pthread_self());
751
752         if (_reinit_thread_callback || !in_main_thread) {
753                 _reinit_thread_callback = false;
754                 _main_thread = pthread_self();
755                 AudioEngine::thread_init_callback (this);
756         }
757
758         process_port_connection_changes();
759
760         return blocking_process_main (input, output);
761 }
762
763 bool
764 PortAudioBackend::start_blocking_process_thread ()
765 {
766         if (_realtime_pthread_create (SCHED_FIFO, -20, 100000,
767                                 &_main_blocking_thread, blocking_thread_func, this))
768         {
769                 if (pthread_create (&_main_blocking_thread, NULL, blocking_thread_func, this))
770                 {
771                         DEBUG_AUDIO("Failed to create main audio thread\n");
772                         _run = false;
773                         return false;
774                 } else {
775                         PBD::warning << get_error_string(AquireRealtimePermissionError) << endmsg;
776                 }
777         }
778
779         int timeout = 5000;
780         while (!_active && --timeout > 0) { Glib::usleep (1000); }
781
782         if (timeout == 0 || !_active) {
783                 DEBUG_AUDIO("Failed to start main audio thread\n");
784                 _pcmio->close_stream();
785                 _run = false;
786                 unregister_ports();
787                 _active = false;
788                 return false;
789         }
790         return true;
791 }
792
793 bool
794 PortAudioBackend::stop_blocking_process_thread ()
795 {
796         void *status;
797
798         if (pthread_join (_main_blocking_thread, &status)) {
799                 DEBUG_AUDIO("Failed to stop main audio thread\n");
800                 return false;
801         }
802
803         return true;
804 }
805
806 int
807 PortAudioBackend::stop ()
808 {
809         if (!_run) {
810                 return 0;
811         }
812
813         _midiio->stop();
814
815         _run = false;
816
817 #ifdef USE_BLOCKING_API
818         if (!stop_blocking_process_thread ()) {
819                 return -1;
820         }
821 #else
822         _pcmio->close_stream ();
823         _active = false;
824
825         if (!stop_freewheel_process_thread ()) {
826                 return -1;
827         }
828
829 #endif
830
831         unregister_ports();
832
833         return (_active == false) ? 0 : -1;
834 }
835
836 static void* freewheel_thread(void* arg)
837 {
838         PortAudioBackend* d = static_cast<PortAudioBackend*>(arg);
839         d->freewheel_process_thread ();
840         pthread_exit (0);
841         return 0;
842 }
843
844 bool
845 PortAudioBackend::start_freewheel_process_thread ()
846 {
847         if (pthread_create(&_pthread_freewheel, NULL, freewheel_thread, this)) {
848                 DEBUG_AUDIO("Failed to create main audio thread\n");
849                 return false;
850         }
851
852         int timeout = 5000;
853         while (!_freewheel_thread_active && --timeout > 0) { Glib::usleep (1000); }
854
855         if (timeout == 0 || !_freewheel_thread_active) {
856                 DEBUG_AUDIO("Failed to start freewheel thread\n");
857                 return false;
858         }
859         return true;
860 }
861
862 bool
863 PortAudioBackend::stop_freewheel_process_thread ()
864 {
865         void *status;
866
867         if (!_freewheel_thread_active) {
868                 return true;
869         }
870
871         DEBUG_AUDIO("Signaling freewheel thread to stop\n");
872
873         pthread_mutex_lock (&_freewheel_mutex);
874         pthread_cond_signal (&_freewheel_signal);
875         pthread_mutex_unlock (&_freewheel_mutex);
876
877         if (pthread_join (_pthread_freewheel, &status) != 0) {
878                 DEBUG_AUDIO("Failed to stop freewheel thread\n");
879                 return false;
880         }
881
882         return true;
883 }
884
885 void*
886 PortAudioBackend::freewheel_process_thread()
887 {
888         _freewheel_thread_active = true;
889
890         bool first_run = false;
891
892         pthread_mutex_lock (&_freewheel_mutex);
893
894         while(_run) {
895                 // check if we should run,
896                 if (_freewheeling != _freewheel) {
897                         if (!_freewheeling) {
898                                 DEBUG_AUDIO("Leaving freewheel\n");
899                                 _freewheel = false; // first mark as disabled
900                                 _reinit_thread_callback = true; // hand over _main_thread
901                                 _freewheel_ack = false; // prepare next handshake
902                                 _midiio->set_enabled(true);
903                         } else {
904                                 first_run = true;
905                                 _freewheel = true;
906                         }
907                 }
908
909                 if (!_freewheel || !_freewheel_ack) {
910                         // wait for a change, we use a timed wait to
911                         // terminate early in case some error sets _run = 0
912                         struct timeval tv;
913                         struct timespec ts;
914                         gettimeofday (&tv, NULL);
915                         ts.tv_sec = tv.tv_sec + 3;
916                         ts.tv_nsec = 0;
917                         DEBUG_AUDIO("Waiting for freewheel change\n");
918                         pthread_cond_timedwait (&_freewheel_signal, &_freewheel_mutex, &ts);
919                         continue;
920                 }
921
922                 if (first_run) {
923                         // tell the engine we're ready to GO.
924                         engine.freewheel_callback (_freewheeling);
925                         first_run = false;
926                         _main_thread = pthread_self();
927                         AudioEngine::thread_init_callback (this);
928                         _midiio->set_enabled(false);
929                 }
930
931                 if (!blocking_process_freewheel()) {
932                         break;
933                 }
934
935                 process_port_connection_changes();
936         }
937
938         pthread_mutex_unlock (&_freewheel_mutex);
939
940         _freewheel_thread_active = false;
941
942         if (_run) {
943                 // engine.process_callback() returner error
944                 engine.halted_callback("CoreAudio Freehweeling aborted.");
945         }
946         return 0;
947 }
948
949 int
950 PortAudioBackend::freewheel (bool onoff)
951 {
952         if (onoff == _freewheeling) {
953                 return 0;
954         }
955         _freewheeling = onoff;
956
957         if (0 == pthread_mutex_trylock (&_freewheel_mutex)) {
958                 pthread_cond_signal (&_freewheel_signal);
959                 pthread_mutex_unlock (&_freewheel_mutex);
960         }
961         return 0;
962 }
963
964 float
965 PortAudioBackend::dsp_load () const
966 {
967         return 100.f * _dsp_load;
968 }
969
970 size_t
971 PortAudioBackend::raw_buffer_size (DataType t)
972 {
973         switch (t) {
974         case DataType::AUDIO:
975                 return _samples_per_period * sizeof(Sample);
976         case DataType::MIDI:
977                 return _max_buffer_size; // XXX not really limited
978         }
979         return 0;
980 }
981
982 /* Process time */
983 framepos_t
984 PortAudioBackend::sample_time ()
985 {
986         return _processed_samples;
987 }
988
989 framepos_t
990 PortAudioBackend::sample_time_at_cycle_start ()
991 {
992         return _processed_samples;
993 }
994
995 pframes_t
996 PortAudioBackend::samples_since_cycle_start ()
997 {
998         if (!_active || !_run || _freewheeling || _freewheel) {
999                 return 0;
1000         }
1001         if (!_cycle_timer.valid()) {
1002                 return 0;
1003         }
1004
1005         return _cycle_timer.samples_since_cycle_start (PBD::get_microseconds());
1006 }
1007
1008 int
1009 PortAudioBackend::name_to_id(std::string device_name) const {
1010         uint32_t device_id = UINT32_MAX;
1011         std::map<int, std::string> devices;
1012         _pcmio->input_device_list(devices);
1013         _pcmio->output_device_list(devices);
1014
1015         for (std::map<int, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
1016                 if (i->second == device_name) {
1017                         device_id = i->first;
1018                         break;
1019                 }
1020         }
1021         return device_id;
1022 }
1023
1024 bool
1025 PortAudioBackend::set_mmcss_pro_audio (HANDLE* task_handle)
1026 {
1027         bool mmcss_success = PBD::MMCSS::set_thread_characteristics ("Pro Audio", task_handle);
1028
1029         if (!mmcss_success) {
1030                 PBD::warning << get_error_string(SettingAudioThreadPriorityError) << endmsg;
1031                 return false;
1032         } else {
1033                 DEBUG_THREADS("Thread characteristics set to Pro Audio\n");
1034         }
1035
1036         bool mmcss_priority =
1037                 PBD::MMCSS::set_thread_priority(*task_handle, PBD::MMCSS::AVRT_PRIORITY_NORMAL);
1038
1039         if (!mmcss_priority) {
1040                 PBD::warning << get_error_string(SettingAudioThreadPriorityError) << endmsg;
1041                 return false;
1042         } else {
1043                 DEBUG_THREADS("Thread priority set to AVRT_PRIORITY_NORMAL\n");
1044         }
1045
1046         return true;
1047 }
1048
1049 bool
1050 PortAudioBackend::reset_mmcss (HANDLE task_handle)
1051 {
1052         if (!PBD::MMCSS::revert_thread_characteristics(task_handle)) {
1053                 DEBUG_THREADS("Unable to reset process thread characteristics\n");
1054                 return false;
1055         }
1056         return true;
1057 }
1058
1059 void *
1060 PortAudioBackend::portaudio_process_thread (void *arg)
1061 {
1062         ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1063         boost::function<void ()> f = td->f;
1064         delete td;
1065
1066 #ifdef USE_MMCSS_THREAD_PRIORITIES
1067         HANDLE task_handle;
1068         bool mmcss_success = set_mmcss_pro_audio (&task_handle);
1069 #endif
1070
1071         DWORD tid = GetCurrentThreadId ();
1072         DEBUG_THREADS (string_compose ("Process Thread Child ID: %1\n", tid));
1073
1074         f ();
1075
1076 #ifdef USE_MMCSS_THREAD_PRIORITIES
1077         if (mmcss_success) {
1078                 reset_mmcss (task_handle);
1079         }
1080 #endif
1081
1082         return 0;
1083 }
1084
1085 int
1086 PortAudioBackend::create_process_thread (boost::function<void()> func)
1087 {
1088         pthread_t thread_id;
1089         pthread_attr_t attr;
1090         size_t stacksize = 100000;
1091
1092         ThreadData* td = new ThreadData (this, func, stacksize);
1093
1094         if (_realtime_pthread_create (SCHED_FIFO, -21, stacksize,
1095                                 &thread_id, portaudio_process_thread, td)) {
1096                 pthread_attr_init (&attr);
1097                 pthread_attr_setstacksize (&attr, stacksize);
1098                 if (pthread_create (&thread_id, &attr, portaudio_process_thread, td)) {
1099                         DEBUG_AUDIO("Cannot create process thread.");
1100                         pthread_attr_destroy (&attr);
1101                         return -1;
1102                 }
1103                 pthread_attr_destroy (&attr);
1104         }
1105
1106         _threads.push_back (thread_id);
1107         return 0;
1108 }
1109
1110 int
1111 PortAudioBackend::join_process_threads ()
1112 {
1113         int rv = 0;
1114
1115         for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
1116         {
1117                 void *status;
1118                 if (pthread_join (*i, &status)) {
1119                         DEBUG_AUDIO("Cannot terminate process thread.");
1120                         rv -= 1;
1121                 }
1122         }
1123         _threads.clear ();
1124         return rv;
1125 }
1126
1127 bool
1128 PortAudioBackend::in_process_thread ()
1129 {
1130 #ifdef USE_BLOCKING_API
1131         if (pthread_equal (_main_blocking_thread, pthread_self()) != 0) {
1132                 return true;
1133         }
1134 #else
1135         if (pthread_equal (_main_thread, pthread_self()) != 0) {
1136                 return true;
1137         }
1138 #endif
1139
1140         for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
1141         {
1142                 if (pthread_equal (*i, pthread_self ()) != 0) {
1143                         return true;
1144                 }
1145         }
1146         return false;
1147 }
1148
1149 uint32_t
1150 PortAudioBackend::process_thread_count ()
1151 {
1152         return _threads.size ();
1153 }
1154
1155 void
1156 PortAudioBackend::update_latencies ()
1157 {
1158         // trigger latency callback in RT thread (locked graph)
1159         port_connect_add_remove_callback();
1160 }
1161
1162 /* PORTENGINE API */
1163
1164 void*
1165 PortAudioBackend::private_handle () const
1166 {
1167         return NULL;
1168 }
1169
1170 const std::string&
1171 PortAudioBackend::my_name () const
1172 {
1173         return _instance_name;
1174 }
1175
1176 bool
1177 PortAudioBackend::available () const
1178 {
1179         return _run && _active;
1180 }
1181
1182 uint32_t
1183 PortAudioBackend::port_name_size () const
1184 {
1185         return 256;
1186 }
1187
1188 int
1189 PortAudioBackend::set_port_name (PortEngine::PortHandle port, const std::string& name)
1190 {
1191         if (!valid_port (port)) {
1192                 DEBUG_PORTS("set_port_name: Invalid Port(s)\n");
1193                 return -1;
1194         }
1195         return static_cast<PamPort*>(port)->set_name (_instance_name + ":" + name);
1196 }
1197
1198 std::string
1199 PortAudioBackend::get_port_name (PortEngine::PortHandle port) const
1200 {
1201         if (!valid_port (port)) {
1202                 DEBUG_PORTS("get_port_name: Invalid Port(s)\n");
1203                 return std::string ();
1204         }
1205         return static_cast<PamPort*>(port)->name ();
1206 }
1207
1208 int
1209 PortAudioBackend::get_port_property (PortHandle port,
1210                                      const std::string& key,
1211                                      std::string& value,
1212                                      std::string& type) const
1213 {
1214         if (!valid_port (port)) {
1215                 DEBUG_PORTS("get_port_name: Invalid Port(s)\n");
1216                 return -1;
1217         }
1218
1219         if (key == "http://jackaudio.org/metadata/pretty-name") {
1220                 type = "";
1221                 value = static_cast<PamPort*>(port)->pretty_name ();
1222                 if (!value.empty()) {
1223                         return 0;
1224                 }
1225         }
1226         return -1;
1227 }
1228
1229 PortEngine::PortHandle
1230 PortAudioBackend::get_port_by_name (const std::string& name) const
1231 {
1232         PortHandle port = (PortHandle) find_port (name);
1233         return port;
1234 }
1235
1236 int
1237 PortAudioBackend::get_ports (
1238                 const std::string& port_name_pattern,
1239                 DataType type, PortFlags flags,
1240                 std::vector<std::string>& port_names) const
1241 {
1242         int rv = 0;
1243         regex_t port_regex;
1244         bool use_regexp = false;
1245         if (port_name_pattern.size () > 0) {
1246                 if (!regcomp (&port_regex, port_name_pattern.c_str (), REG_EXTENDED|REG_NOSUB)) {
1247                         use_regexp = true;
1248                 }
1249         }
1250         for (size_t i = 0; i < _ports.size (); ++i) {
1251                 PamPort* port = _ports[i];
1252                 if ((port->type () == type) && flags == (port->flags () & flags)) {
1253                         if (!use_regexp || !regexec (&port_regex, port->name ().c_str (), 0, NULL, 0)) {
1254                                 port_names.push_back (port->name ());
1255                                 ++rv;
1256                         }
1257                 }
1258         }
1259         if (use_regexp) {
1260                 regfree (&port_regex);
1261         }
1262         return rv;
1263 }
1264
1265 DataType
1266 PortAudioBackend::port_data_type (PortEngine::PortHandle port) const
1267 {
1268         if (!valid_port (port)) {
1269                 return DataType::NIL;
1270         }
1271         return static_cast<PamPort*>(port)->type ();
1272 }
1273
1274 PortEngine::PortHandle
1275 PortAudioBackend::register_port (
1276                 const std::string& name,
1277                 ARDOUR::DataType type,
1278                 ARDOUR::PortFlags flags)
1279 {
1280         if (name.size () == 0) { return 0; }
1281         if (flags & IsPhysical) { return 0; }
1282         return add_port (_instance_name + ":" + name, type, flags);
1283 }
1284
1285 PortEngine::PortHandle
1286 PortAudioBackend::add_port (
1287                 const std::string& name,
1288                 ARDOUR::DataType type,
1289                 ARDOUR::PortFlags flags)
1290 {
1291         assert(name.size ());
1292         if (find_port (name)) {
1293                 DEBUG_PORTS(
1294                     string_compose("register_port: Port already exists: (%1)\n", name));
1295                 return 0;
1296         }
1297         PamPort* port = NULL;
1298         switch (type) {
1299         case DataType::AUDIO:
1300                 port = new PortAudioPort(*this, name, flags);
1301                 break;
1302         case DataType::MIDI:
1303                 port = new PortMidiPort(*this, name, flags);
1304                 break;
1305         default:
1306                 DEBUG_PORTS("register_port: Invalid Data Type.\n");
1307                 return 0;
1308         }
1309
1310         _ports.push_back (port);
1311
1312         return port;
1313 }
1314
1315 void
1316 PortAudioBackend::unregister_port (PortEngine::PortHandle port_handle)
1317 {
1318         if (!_run) {
1319                 return;
1320         }
1321         PamPort* port = static_cast<PamPort*>(port_handle);
1322         std::vector<PamPort*>::iterator i = std::find (_ports.begin (), _ports.end (), static_cast<PamPort*>(port_handle));
1323         if (i == _ports.end ()) {
1324                 DEBUG_PORTS("unregister_port: Failed to find port\n");
1325                 return;
1326         }
1327         disconnect_all(port_handle);
1328         _ports.erase (i);
1329         delete port;
1330 }
1331
1332 int
1333 PortAudioBackend::register_system_audio_ports()
1334 {
1335         LatencyRange lr;
1336
1337         const uint32_t a_ins = _n_inputs;
1338         const uint32_t a_out = _n_outputs;
1339
1340         uint32_t capture_latency = 0;
1341         uint32_t playback_latency = 0;
1342
1343         // guard against erroneous latency values
1344         if (_pcmio->capture_latency() > _samples_per_period) {
1345                 capture_latency = _pcmio->capture_latency() - _samples_per_period;
1346         }
1347         if (_pcmio->playback_latency() > _samples_per_period) {
1348                 playback_latency = _pcmio->playback_latency() - _samples_per_period;
1349         }
1350
1351         /* audio ports */
1352         lr.min = lr.max = capture_latency + (_measure_latency ? 0 : _systemic_audio_input_latency);
1353         for (uint32_t i = 0; i < a_ins; ++i) {
1354                 char tmp[64];
1355                 snprintf(tmp, sizeof(tmp), "system:capture_%d", i+1);
1356                 PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsOutput | IsPhysical | IsTerminal));
1357                 if (!p) return -1;
1358                 set_latency_range (p, false, lr);
1359                 PortAudioPort* audio_port = static_cast<PortAudioPort*>(p);
1360                 audio_port->set_pretty_name (
1361                     _pcmio->get_input_channel_name (name_to_id (_input_audio_device), i));
1362                 _system_inputs.push_back (audio_port);
1363         }
1364
1365         lr.min = lr.max = playback_latency + (_measure_latency ? 0 : _systemic_audio_output_latency);
1366         for (uint32_t i = 0; i < a_out; ++i) {
1367                 char tmp[64];
1368                 snprintf(tmp, sizeof(tmp), "system:playback_%d", i+1);
1369                 PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
1370                 if (!p) return -1;
1371                 set_latency_range (p, true, lr);
1372                 PortAudioPort* audio_port = static_cast<PortAudioPort*>(p);
1373                 audio_port->set_pretty_name (
1374                     _pcmio->get_output_channel_name (name_to_id (_output_audio_device), i));
1375                 _system_outputs.push_back(audio_port);
1376         }
1377         return 0;
1378 }
1379
1380 int
1381 PortAudioBackend::register_system_midi_ports()
1382 {
1383         if (_midi_driver_option == get_standard_device_name(DeviceNone)) {
1384                 DEBUG_MIDI("No MIDI backend selected, not system midi ports available\n");
1385                 return 0;
1386         }
1387
1388         LatencyRange lr;
1389         lr.min = lr.max = _samples_per_period;
1390
1391         const std::vector<WinMMEMidiInputDevice*> inputs = _midiio->get_inputs();
1392
1393         for (std::vector<WinMMEMidiInputDevice*>::const_iterator i = inputs.begin ();
1394              i != inputs.end ();
1395              ++i) {
1396                 std::string port_name = "system:midi_capture_" + (*i)->name();
1397                 PortHandle p =
1398                     add_port (port_name,
1399                               DataType::MIDI,
1400                               static_cast<PortFlags>(IsOutput | IsPhysical | IsTerminal));
1401                 if (!p) return -1;
1402
1403                 MidiDeviceInfo* info = _midiio->get_device_info((*i)->name());
1404                 if (info) { // assert?
1405                         lr.min = lr.max = _samples_per_period + info->systemic_input_latency;
1406                 }
1407                 set_latency_range (p, false, lr);
1408
1409                 PortMidiPort* midi_port = static_cast<PortMidiPort*>(p);
1410                 midi_port->set_pretty_name ((*i)->name());
1411                 _system_midi_in.push_back (midi_port);
1412                 DEBUG_MIDI (string_compose ("Registered MIDI input port: %1\n", port_name));
1413         }
1414
1415         const std::vector<WinMMEMidiOutputDevice*> outputs = _midiio->get_outputs();
1416
1417         for (std::vector<WinMMEMidiOutputDevice*>::const_iterator i = outputs.begin ();
1418              i != outputs.end ();
1419              ++i) {
1420                 std::string port_name = "system:midi_playback_" + (*i)->name();
1421                 PortHandle p =
1422                     add_port (port_name,
1423                               DataType::MIDI,
1424                               static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
1425                 if (!p) return -1;
1426
1427                 MidiDeviceInfo* info = _midiio->get_device_info((*i)->name());
1428                 if (info) { // assert?
1429                         lr.min = lr.max = _samples_per_period + info->systemic_output_latency;
1430                 }
1431                 set_latency_range (p, false, lr);
1432
1433                 PortMidiPort* midi_port = static_cast<PortMidiPort*>(p);
1434                 midi_port->set_n_periods(2);
1435                 midi_port->set_pretty_name ((*i)->name());
1436                 _system_midi_out.push_back (midi_port);
1437                 DEBUG_MIDI (string_compose ("Registered MIDI output port: %1\n", port_name));
1438         }
1439         return 0;
1440 }
1441
1442 void
1443 PortAudioBackend::unregister_ports (bool system_only)
1444 {
1445         size_t i = 0;
1446         _system_inputs.clear();
1447         _system_outputs.clear();
1448         _system_midi_in.clear();
1449         _system_midi_out.clear();
1450         while (i <  _ports.size ()) {
1451                 PamPort* port = _ports[i];
1452                 if (! system_only || (port->is_physical () && port->is_terminal ())) {
1453                         port->disconnect_all ();
1454                         delete port;
1455                         _ports.erase (_ports.begin() + i);
1456                 } else {
1457                         ++i;
1458                 }
1459         }
1460 }
1461
1462 int
1463 PortAudioBackend::connect (const std::string& src, const std::string& dst)
1464 {
1465         PamPort* src_port = find_port (src);
1466         PamPort* dst_port = find_port (dst);
1467
1468         if (!src_port) {
1469                 DEBUG_PORTS(string_compose("connect: Invalid Source port: (%1)\n", src));
1470                 return -1;
1471         }
1472         if (!dst_port) {
1473                 DEBUG_PORTS(string_compose("connect: Invalid Destination port: (%1)\n", dst));
1474                 return -1;
1475         }
1476         return src_port->connect (dst_port);
1477 }
1478
1479 int
1480 PortAudioBackend::disconnect (const std::string& src, const std::string& dst)
1481 {
1482         PamPort* src_port = find_port (src);
1483         PamPort* dst_port = find_port (dst);
1484
1485         if (!src_port || !dst_port) {
1486                 DEBUG_PORTS("disconnect: Invalid Port(s)\n");
1487                 return -1;
1488         }
1489         return src_port->disconnect (dst_port);
1490 }
1491
1492 int
1493 PortAudioBackend::connect (PortEngine::PortHandle src, const std::string& dst)
1494 {
1495         PamPort* dst_port = find_port (dst);
1496         if (!valid_port (src)) {
1497                 DEBUG_PORTS("connect: Invalid Source Port Handle\n");
1498                 return -1;
1499         }
1500         if (!dst_port) {
1501                 DEBUG_PORTS(string_compose("connect: Invalid Destination Port (%1)\n", dst));
1502                 return -1;
1503         }
1504         return static_cast<PamPort*>(src)->connect (dst_port);
1505 }
1506
1507 int
1508 PortAudioBackend::disconnect (PortEngine::PortHandle src, const std::string& dst)
1509 {
1510         PamPort* dst_port = find_port (dst);
1511         if (!valid_port (src) || !dst_port) {
1512                 DEBUG_PORTS("disconnect: Invalid Port(s)\n");
1513                 return -1;
1514         }
1515         return static_cast<PamPort*>(src)->disconnect (dst_port);
1516 }
1517
1518 int
1519 PortAudioBackend::disconnect_all (PortEngine::PortHandle port)
1520 {
1521         if (!valid_port (port)) {
1522                 DEBUG_PORTS("disconnect_all: Invalid Port\n");
1523                 return -1;
1524         }
1525         static_cast<PamPort*>(port)->disconnect_all ();
1526         return 0;
1527 }
1528
1529 bool
1530 PortAudioBackend::connected (PortEngine::PortHandle port, bool /* process_callback_safe*/)
1531 {
1532         if (!valid_port (port)) {
1533                 DEBUG_PORTS("disconnect_all: Invalid Port\n");
1534                 return false;
1535         }
1536         return static_cast<PamPort*>(port)->is_connected ();
1537 }
1538
1539 bool
1540 PortAudioBackend::connected_to (PortEngine::PortHandle src, const std::string& dst, bool /*process_callback_safe*/)
1541 {
1542         PamPort* dst_port = find_port (dst);
1543         if (!valid_port (src) || !dst_port) {
1544                 DEBUG_PORTS("connected_to: Invalid Port\n");
1545                 return false;
1546         }
1547         return static_cast<PamPort*>(src)->is_connected (dst_port);
1548 }
1549
1550 bool
1551 PortAudioBackend::physically_connected (PortEngine::PortHandle port, bool /*process_callback_safe*/)
1552 {
1553         if (!valid_port (port)) {
1554                 DEBUG_PORTS("physically_connected: Invalid Port\n");
1555                 return false;
1556         }
1557         return static_cast<PamPort*>(port)->is_physically_connected ();
1558 }
1559
1560 int
1561 PortAudioBackend::get_connections (PortEngine::PortHandle port, std::vector<std::string>& names, bool /*process_callback_safe*/)
1562 {
1563         if (!valid_port (port)) {
1564                 DEBUG_PORTS("get_connections: Invalid Port\n");
1565                 return -1;
1566         }
1567
1568         assert (0 == names.size ());
1569
1570         const std::vector<PamPort*>& connected_ports = static_cast<PamPort*>(port)->get_connections ();
1571
1572         for (std::vector<PamPort*>::const_iterator i = connected_ports.begin (); i != connected_ports.end (); ++i) {
1573                 names.push_back ((*i)->name ());
1574         }
1575
1576         return (int)names.size ();
1577 }
1578
1579 /* MIDI */
1580 int
1581 PortAudioBackend::midi_event_get (
1582                 pframes_t& timestamp,
1583                 size_t& size, uint8_t** buf, void* port_buffer,
1584                 uint32_t event_index)
1585 {
1586         if (!buf || !port_buffer) return -1;
1587         PortMidiBuffer& source = * static_cast<PortMidiBuffer*>(port_buffer);
1588         if (event_index >= source.size ()) {
1589                 return -1;
1590         }
1591         PortMidiEvent * const event = source[event_index].get ();
1592
1593         timestamp = event->timestamp ();
1594         size = event->size ();
1595         *buf = event->data ();
1596         return 0;
1597 }
1598
1599 int
1600 PortAudioBackend::midi_event_put (
1601                 void* port_buffer,
1602                 pframes_t timestamp,
1603                 const uint8_t* buffer, size_t size)
1604 {
1605         if (!buffer || !port_buffer) return -1;
1606         PortMidiBuffer& dst = * static_cast<PortMidiBuffer*>(port_buffer);
1607         if (dst.size () && (pframes_t)dst.back ()->timestamp () > timestamp) {
1608                 // nevermind, ::get_buffer() sorts events
1609                 DEBUG_MIDI (string_compose ("PortMidiBuffer: unordered event: %1 > %2\n",
1610                                             (pframes_t)dst.back ()->timestamp (),
1611                                             timestamp));
1612         }
1613         dst.push_back (boost::shared_ptr<PortMidiEvent>(new PortMidiEvent (timestamp, buffer, size)));
1614         return 0;
1615 }
1616
1617 uint32_t
1618 PortAudioBackend::get_midi_event_count (void* port_buffer)
1619 {
1620         if (!port_buffer) return 0;
1621         return static_cast<PortMidiBuffer*>(port_buffer)->size ();
1622 }
1623
1624 void
1625 PortAudioBackend::midi_clear (void* port_buffer)
1626 {
1627         if (!port_buffer) return;
1628         PortMidiBuffer * buf = static_cast<PortMidiBuffer*>(port_buffer);
1629         assert (buf);
1630         buf->clear ();
1631 }
1632
1633 /* Monitoring */
1634
1635 bool
1636 PortAudioBackend::can_monitor_input () const
1637 {
1638         return false;
1639 }
1640
1641 int
1642 PortAudioBackend::request_input_monitoring (PortEngine::PortHandle, bool)
1643 {
1644         return -1;
1645 }
1646
1647 int
1648 PortAudioBackend::ensure_input_monitoring (PortEngine::PortHandle, bool)
1649 {
1650         return -1;
1651 }
1652
1653 bool
1654 PortAudioBackend::monitoring_input (PortEngine::PortHandle)
1655 {
1656         return false;
1657 }
1658
1659 /* Latency management */
1660
1661 void
1662 PortAudioBackend::set_latency_range (PortEngine::PortHandle port, bool for_playback, LatencyRange latency_range)
1663 {
1664         if (!valid_port (port)) {
1665                 DEBUG_PORTS("PamPort::set_latency_range (): invalid port.\n");
1666         }
1667         static_cast<PamPort*>(port)->set_latency_range (latency_range, for_playback);
1668 }
1669
1670 LatencyRange
1671 PortAudioBackend::get_latency_range (PortEngine::PortHandle port, bool for_playback)
1672 {
1673         LatencyRange r;
1674         if (!valid_port (port)) {
1675                 DEBUG_PORTS("PamPort::get_latency_range (): invalid port.\n");
1676                 r.min = 0;
1677                 r.max = 0;
1678                 return r;
1679         }
1680         PamPort* p = static_cast<PamPort*>(port);
1681         assert(p);
1682
1683         r = p->latency_range (for_playback);
1684         // TODO MIDI
1685         if (p->is_physical() && p->is_terminal() && p->type() == DataType::AUDIO) {
1686                 if (p->is_input() && for_playback) {
1687                         r.min += _samples_per_period;
1688                         r.max += _samples_per_period;
1689                 }
1690                 if (p->is_output() && !for_playback) {
1691                         r.min += _samples_per_period;
1692                         r.max += _samples_per_period;
1693                 }
1694         }
1695         return r;
1696 }
1697
1698 /* Discovering physical ports */
1699
1700 bool
1701 PortAudioBackend::port_is_physical (PortEngine::PortHandle port) const
1702 {
1703         if (!valid_port (port)) {
1704                 DEBUG_PORTS("PamPort::port_is_physical (): invalid port.\n");
1705                 return false;
1706         }
1707         return static_cast<PamPort*>(port)->is_physical ();
1708 }
1709
1710 void
1711 PortAudioBackend::get_physical_outputs (DataType type, std::vector<std::string>& port_names)
1712 {
1713         for (size_t i = 0; i < _ports.size (); ++i) {
1714                 PamPort* port = _ports[i];
1715                 if ((port->type () == type) && port->is_input () && port->is_physical ()) {
1716                         port_names.push_back (port->name ());
1717                 }
1718         }
1719 }
1720
1721 void
1722 PortAudioBackend::get_physical_inputs (DataType type, std::vector<std::string>& port_names)
1723 {
1724         for (size_t i = 0; i < _ports.size (); ++i) {
1725                 PamPort* port = _ports[i];
1726                 if ((port->type () == type) && port->is_output () && port->is_physical ()) {
1727                         port_names.push_back (port->name ());
1728                 }
1729         }
1730 }
1731
1732 ChanCount
1733 PortAudioBackend::n_physical_outputs () const
1734 {
1735         int n_midi = 0;
1736         int n_audio = 0;
1737         for (size_t i = 0; i < _ports.size (); ++i) {
1738                 PamPort* port = _ports[i];
1739                 if (port->is_output () && port->is_physical ()) {
1740                         switch (port->type ()) {
1741                         case DataType::AUDIO:
1742                                 ++n_audio;
1743                                 break;
1744                         case DataType::MIDI:
1745                                 ++n_midi;
1746                                 break;
1747                         default:
1748                                 break;
1749                         }
1750                 }
1751         }
1752         ChanCount cc;
1753         cc.set (DataType::AUDIO, n_audio);
1754         cc.set (DataType::MIDI, n_midi);
1755         return cc;
1756 }
1757
1758 ChanCount
1759 PortAudioBackend::n_physical_inputs () const
1760 {
1761         int n_midi = 0;
1762         int n_audio = 0;
1763         for (size_t i = 0; i < _ports.size (); ++i) {
1764                 PamPort* port = _ports[i];
1765                 if (port->is_input () && port->is_physical ()) {
1766                         switch (port->type ()) {
1767                         case DataType::AUDIO:
1768                                 ++n_audio;
1769                                 break;
1770                         case DataType::MIDI:
1771                                 ++n_midi;
1772                                 break;
1773                         default:
1774                                 break;
1775                         }
1776                 }
1777         }
1778         ChanCount cc;
1779         cc.set (DataType::AUDIO, n_audio);
1780         cc.set (DataType::MIDI, n_midi);
1781         return cc;
1782 }
1783
1784 /* Getting access to the data buffer for a port */
1785
1786 void*
1787 PortAudioBackend::get_buffer (PortEngine::PortHandle port, pframes_t nframes)
1788 {
1789         if (!port || !valid_port (port)) return NULL;
1790         return static_cast<PamPort*>(port)->get_buffer (nframes);
1791 }
1792
1793
1794 void *
1795 PortAudioBackend::blocking_process_thread ()
1796 {
1797         AudioEngine::thread_init_callback (this);
1798         _active = true;
1799         _processed_samples = 0;
1800
1801         manager.registration_callback();
1802         manager.graph_order_callback();
1803
1804         if (_pcmio->start_stream() != paNoError) {
1805                 _pcmio->close_stream ();
1806                 _active = false;
1807                 engine.halted_callback(get_error_string(AudioDeviceIOError).c_str());
1808         }
1809
1810 #ifdef USE_MMCSS_THREAD_PRIORITIES
1811         HANDLE task_handle;
1812         bool mmcss_success = set_mmcss_pro_audio (&task_handle);
1813 #endif
1814
1815         DWORD tid = GetCurrentThreadId ();
1816         DEBUG_THREADS (string_compose ("Process Thread Master ID: %1\n", tid));
1817
1818         while (_run) {
1819
1820                 if (_freewheeling != _freewheel) {
1821                         _freewheel = _freewheeling;
1822                         engine.freewheel_callback (_freewheel);
1823                 }
1824
1825                 if (!_freewheel) {
1826
1827                         switch (_pcmio->next_cycle (_samples_per_period)) {
1828                         case 0: // OK
1829                                 break;
1830                         case 1:
1831                                 DEBUG_AUDIO("PortAudio: Xrun\n");
1832                                 engine.Xrun();
1833                                 break;
1834                         default:
1835                                 PBD::error << get_error_string(AudioDeviceIOError) << endmsg;
1836                                 break;
1837                         }
1838
1839                         if (!blocking_process_main(_pcmio->get_capture_buffer(),
1840                                                    _pcmio->get_playback_buffer())) {
1841                                 return 0;
1842                         }
1843                 } else {
1844
1845                         if (!blocking_process_freewheel()) {
1846                                 return 0;
1847                         }
1848                 }
1849
1850                 process_port_connection_changes();
1851         }
1852         _pcmio->close_stream();
1853         _active = false;
1854         if (_run) {
1855                 engine.halted_callback(get_error_string(AudioDeviceIOError).c_str());
1856         }
1857
1858 #ifdef USE_MMCSS_THREAD_PRIORITIES
1859         if (mmcss_success) {
1860                 reset_mmcss(task_handle);
1861         }
1862 #endif
1863
1864         return 0;
1865 }
1866
1867 bool
1868 PortAudioBackend::blocking_process_main(const float* interleaved_input_data,
1869                                         float* interleaved_output_data)
1870 {
1871         uint32_t i = 0;
1872         int64_t min_elapsed_us = 1000000;
1873         int64_t max_elapsed_us = 0;
1874
1875         _dsp_calc.set_start_timestamp_us (PBD::get_microseconds());
1876
1877         i = 0;
1878         /* Copy input audio data into input port buffers */
1879         for (std::vector<PamPort*>::const_iterator it = _system_inputs.begin();
1880              it != _system_inputs.end();
1881              ++it, ++i) {
1882                 assert(_system_inputs.size() == _pcmio->n_capture_channels());
1883                 uint32_t channels = _system_inputs.size();
1884                 float* input_port_buffer = (float*)(*it)->get_buffer(_samples_per_period);
1885                 deinterleave_audio_data(
1886                     interleaved_input_data, input_port_buffer, _samples_per_period, i, channels);
1887         }
1888
1889         process_incoming_midi ();
1890
1891         /* clear output buffers */
1892         for (std::vector<PamPort*>::const_iterator it = _system_outputs.begin();
1893              it != _system_outputs.end();
1894              ++it) {
1895                 memset((*it)->get_buffer(_samples_per_period),
1896                        0,
1897                        _samples_per_period * sizeof(Sample));
1898         }
1899
1900         _last_cycle_start = _cycle_timer.get_start();
1901         _cycle_timer.reset_start(PBD::get_microseconds());
1902         _cycle_count++;
1903
1904         uint64_t cycle_diff_us = (_cycle_timer.get_start() - _last_cycle_start);
1905         int64_t deviation_us = (cycle_diff_us - _cycle_timer.get_length_us());
1906         _total_deviation_us += ::llabs(deviation_us);
1907         _max_deviation_us =
1908             std::max(_max_deviation_us, (uint64_t)::llabs(deviation_us));
1909
1910         if ((_cycle_count % 1000) == 0) {
1911                 uint64_t mean_deviation_us = _total_deviation_us / _cycle_count;
1912                 DEBUG_TIMING(string_compose("Mean avg cycle deviation: %1(ms), max %2(ms)\n",
1913                                             mean_deviation_us * 1e-3,
1914                                             _max_deviation_us * 1e-3));
1915         }
1916
1917         if (::llabs(deviation_us) > _cycle_timer.get_length_us()) {
1918                 DEBUG_TIMING(
1919                     string_compose("time between process(ms): %1, Est(ms): %2, Dev(ms): %3\n",
1920                                    cycle_diff_us * 1e-3,
1921                                    _cycle_timer.get_length_us() * 1e-3,
1922                                    deviation_us * 1e-3));
1923         }
1924
1925         /* call engine process callback */
1926         if (engine.process_callback(_samples_per_period)) {
1927                 _pcmio->close_stream();
1928                 _active = false;
1929                 return false;
1930         }
1931
1932         process_outgoing_midi ();
1933
1934         /* write back audio */
1935         i = 0;
1936         for (std::vector<PamPort*>::const_iterator it = _system_outputs.begin();
1937              it != _system_outputs.end();
1938              ++it, ++i) {
1939                 assert(_system_outputs.size() == _pcmio->n_playback_channels());
1940                 const uint32_t channels = _system_outputs.size();
1941                 float* output_port_buffer = (float*)(*it)->get_buffer(_samples_per_period);
1942                 interleave_audio_data(
1943                     output_port_buffer, interleaved_output_data, _samples_per_period, i, channels);
1944         }
1945
1946         _processed_samples += _samples_per_period;
1947
1948         /* calculate DSP load */
1949         _dsp_calc.set_stop_timestamp_us (PBD::get_microseconds());
1950         _dsp_load = _dsp_calc.get_dsp_load();
1951
1952         DEBUG_TIMING(string_compose("DSP Load: %1\n", _dsp_load));
1953
1954         max_elapsed_us = std::max(_dsp_calc.elapsed_time_us(), max_elapsed_us);
1955         min_elapsed_us = std::min(_dsp_calc.elapsed_time_us(), min_elapsed_us);
1956         if ((_cycle_count % 1000) == 0) {
1957                 DEBUG_TIMING(string_compose("Elapsed process time(usecs) max: %1, min: %2\n",
1958                                             max_elapsed_us,
1959                                             min_elapsed_us));
1960         }
1961
1962         return true;
1963 }
1964
1965 bool
1966 PortAudioBackend::blocking_process_freewheel()
1967 {
1968         // zero audio input buffers
1969         for (std::vector<PamPort*>::const_iterator it = _system_inputs.begin();
1970              it != _system_inputs.end();
1971              ++it) {
1972                 memset((*it)->get_buffer(_samples_per_period),
1973                        0,
1974                        _samples_per_period * sizeof(Sample));
1975         }
1976
1977         // TODO clear midi or stop midi recv when entering fwheelin'
1978
1979         if (engine.process_callback(_samples_per_period)) {
1980                 _pcmio->close_stream();
1981                 _active = false;
1982                 return false;
1983         }
1984
1985         // drop all outgoing MIDI messages
1986         for (std::vector<PamPort*>::const_iterator it = _system_midi_out.begin();
1987              it != _system_midi_out.end();
1988              ++it) {
1989                 void* bptr = (*it)->get_buffer(0);
1990                 midi_clear(bptr);
1991         }
1992
1993         _dsp_load = 1.0;
1994         Glib::usleep(100); // don't hog cpu
1995         return true;
1996 }
1997
1998 void
1999 PortAudioBackend::process_incoming_midi ()
2000 {
2001         uint32_t i = 0;
2002         for (std::vector<PamPort*>::const_iterator it = _system_midi_in.begin();
2003              it != _system_midi_in.end();
2004              ++it, ++i) {
2005                 PortMidiBuffer* mbuf = static_cast<PortMidiBuffer*>((*it)->get_buffer(0));
2006                 mbuf->clear();
2007                 uint64_t timestamp;
2008                 pframes_t sample_offset;
2009                 uint8_t data[256];
2010                 size_t size = sizeof(data);
2011                 while (_midiio->dequeue_input_event(i,
2012                                                     _cycle_timer.get_start(),
2013                                                     _cycle_timer.get_next_start(),
2014                                                     timestamp,
2015                                                     data,
2016                                                     size)) {
2017                         sample_offset = _cycle_timer.samples_since_cycle_start(timestamp);
2018                         midi_event_put(mbuf, sample_offset, data, size);
2019                         DEBUG_MIDI(string_compose("Dequeuing incoming MIDI data for device: %1 "
2020                                                   "sample_offset: %2 timestamp: %3, size: %4\n",
2021                                                   _midiio->get_inputs()[i]->name(),
2022                                                   sample_offset,
2023                                                   timestamp,
2024                                                   size));
2025                         size = sizeof(data);
2026                 }
2027         }
2028 }
2029
2030 void
2031 PortAudioBackend::process_outgoing_midi ()
2032 {
2033         /* mixdown midi */
2034         for (std::vector<PamPort*>::iterator it = _system_midi_out.begin();
2035              it != _system_midi_out.end();
2036              ++it) {
2037                 static_cast<PortMidiPort*>(*it)->next_period();
2038         }
2039         /* queue outgoing midi */
2040         uint32_t i = 0;
2041         for (std::vector<PamPort*>::const_iterator it = _system_midi_out.begin();
2042              it != _system_midi_out.end();
2043              ++it, ++i) {
2044                 const PortMidiBuffer* src =
2045                     static_cast<const PortMidiPort*>(*it)->const_buffer();
2046
2047                 for (PortMidiBuffer::const_iterator mit = src->begin(); mit != src->end();
2048                      ++mit) {
2049                         uint64_t timestamp =
2050                             _cycle_timer.timestamp_from_sample_offset((*mit)->timestamp());
2051                         DEBUG_MIDI(string_compose("Queuing outgoing MIDI data for device: "
2052                                                   "%1 sample_offset: %2 timestamp: %3, size: %4\n",
2053                                                   _midiio->get_outputs()[i]->name(),
2054                                                   (*mit)->timestamp(),
2055                                                   timestamp,
2056                                                   (*mit)->size()));
2057                         _midiio->enqueue_output_event(i, timestamp, (*mit)->data(), (*mit)->size());
2058                 }
2059         }
2060 }
2061
2062 void
2063 PortAudioBackend::process_port_connection_changes ()
2064 {
2065         bool connections_changed = false;
2066         bool ports_changed = false;
2067         if (!pthread_mutex_trylock (&_port_callback_mutex)) {
2068                 if (_port_change_flag) {
2069                         ports_changed = true;
2070                         _port_change_flag = false;
2071                 }
2072                 if (!_port_connection_queue.empty ()) {
2073                         connections_changed = true;
2074                 }
2075                 while (!_port_connection_queue.empty ()) {
2076                         PortConnectData *c = _port_connection_queue.back ();
2077                         manager.connect_callback (c->a, c->b, c->c);
2078                         _port_connection_queue.pop_back ();
2079                         delete c;
2080                 }
2081                 pthread_mutex_unlock (&_port_callback_mutex);
2082         }
2083         if (ports_changed) {
2084                 manager.registration_callback();
2085         }
2086         if (connections_changed) {
2087                 manager.graph_order_callback();
2088         }
2089         if (connections_changed || ports_changed) {
2090                 engine.latency_callback(false);
2091                 engine.latency_callback(true);
2092         }
2093 }
2094
2095 /******************************************************************************/
2096
2097 static boost::shared_ptr<PortAudioBackend> _instance;
2098
2099 static boost::shared_ptr<AudioBackend> backend_factory (AudioEngine& e);
2100 static int instantiate (const std::string& arg1, const std::string& /* arg2 */);
2101 static int deinstantiate ();
2102 static bool already_configured ();
2103 static bool available ();
2104
2105 static ARDOUR::AudioBackendInfo _descriptor = {
2106         BACKEND_NAME,
2107         instantiate,
2108         deinstantiate,
2109         backend_factory,
2110         already_configured,
2111         available
2112 };
2113
2114 static boost::shared_ptr<AudioBackend>
2115 backend_factory (AudioEngine& e)
2116 {
2117         if (!_instance) {
2118                 _instance.reset (new PortAudioBackend (e, _descriptor));
2119         }
2120         return _instance;
2121 }
2122
2123 static int
2124 instantiate (const std::string& arg1, const std::string& /* arg2 */)
2125 {
2126         s_instance_name = arg1;
2127         return 0;
2128 }
2129
2130 static int
2131 deinstantiate ()
2132 {
2133         _instance.reset ();
2134         return 0;
2135 }
2136
2137 static bool
2138 already_configured ()
2139 {
2140         return false;
2141 }
2142
2143 static bool
2144 available ()
2145 {
2146         return true;
2147 }
2148
2149 extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor ()
2150 {
2151         return &_descriptor;
2152 }
2153
2154
2155 /******************************************************************************/
2156 PamPort::PamPort (PortAudioBackend &b, const std::string& name, PortFlags flags)
2157         : _osx_backend (b)
2158         , _name  (name)
2159         , _flags (flags)
2160 {
2161         _capture_latency_range.min = 0;
2162         _capture_latency_range.max = 0;
2163         _playback_latency_range.min = 0;
2164         _playback_latency_range.max = 0;
2165 }
2166
2167 PamPort::~PamPort () {
2168         disconnect_all ();
2169 }
2170
2171
2172 int PamPort::connect (PamPort *port)
2173 {
2174         if (!port) {
2175                 DEBUG_PORTS("PamPort::connect (): invalid (null) port\n");
2176                 return -1;
2177         }
2178
2179         if (type () != port->type ()) {
2180                 DEBUG_PORTS("PamPort::connect (): wrong port-type\n");
2181                 return -1;
2182         }
2183
2184         if (is_output () && port->is_output ()) {
2185                 DEBUG_PORTS("PamPort::connect (): cannot inter-connect output ports.\n");
2186                 return -1;
2187         }
2188
2189         if (is_input () && port->is_input ()) {
2190                 DEBUG_PORTS("PamPort::connect (): cannot inter-connect input ports.\n");
2191                 return -1;
2192         }
2193
2194         if (this == port) {
2195                 DEBUG_PORTS("PamPort::connect (): cannot self-connect ports.\n");
2196                 return -1;
2197         }
2198
2199         if (is_connected (port)) {
2200 #if 0 // don't bother to warn about this for now. just ignore it
2201                 PBD::error << _("PamPort::connect (): ports are already connected:")
2202                         << " (" << name () << ") -> (" << port->name () << ")"
2203                         << endmsg;
2204 #endif
2205                 return -1;
2206         }
2207
2208         _connect (port, true);
2209         return 0;
2210 }
2211
2212
2213 void PamPort::_connect (PamPort *port, bool callback)
2214 {
2215         _connections.push_back (port);
2216         if (callback) {
2217                 port->_connect (this, false);
2218                 _osx_backend.port_connect_callback (name(),  port->name(), true);
2219         }
2220 }
2221
2222 int PamPort::disconnect (PamPort *port)
2223 {
2224         if (!port) {
2225                 DEBUG_PORTS("PamPort::disconnect (): invalid (null) port\n");
2226                 return -1;
2227         }
2228
2229         if (!is_connected (port)) {
2230                 DEBUG_PORTS(string_compose(
2231                     "PamPort::disconnect (): ports are not connected: (%1) -> (%2)\n",
2232                     name(),
2233                     port->name()));
2234                 return -1;
2235         }
2236         _disconnect (port, true);
2237         return 0;
2238 }
2239
2240 void PamPort::_disconnect (PamPort *port, bool callback)
2241 {
2242         std::vector<PamPort*>::iterator it = std::find (_connections.begin (), _connections.end (), port);
2243
2244         assert (it != _connections.end ());
2245
2246         _connections.erase (it);
2247
2248         if (callback) {
2249                 port->_disconnect (this, false);
2250                 _osx_backend.port_connect_callback (name(),  port->name(), false);
2251         }
2252 }
2253
2254
2255 void PamPort::disconnect_all ()
2256 {
2257         while (!_connections.empty ()) {
2258                 _connections.back ()->_disconnect (this, false);
2259                 _osx_backend.port_connect_callback (name(),  _connections.back ()->name(), false);
2260                 _connections.pop_back ();
2261         }
2262 }
2263
2264 bool
2265 PamPort::is_connected (const PamPort *port) const
2266 {
2267         return std::find (_connections.begin (), _connections.end (), port) != _connections.end ();
2268 }
2269
2270 bool PamPort::is_physically_connected () const
2271 {
2272         for (std::vector<PamPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
2273                 if ((*it)->is_physical ()) {
2274                         return true;
2275                 }
2276         }
2277         return false;
2278 }
2279
2280 /******************************************************************************/
2281
2282 PortAudioPort::PortAudioPort (PortAudioBackend &b, const std::string& name, PortFlags flags)
2283         : PamPort (b, name, flags)
2284 {
2285         memset (_buffer, 0, sizeof (_buffer));
2286 #ifndef PLATFORM_WINDOWS
2287         mlock(_buffer, sizeof (_buffer));
2288 #endif
2289 }
2290
2291 PortAudioPort::~PortAudioPort () { }
2292
2293 void* PortAudioPort::get_buffer (pframes_t n_samples)
2294 {
2295         if (is_input ()) {
2296                 std::vector<PamPort*>::const_iterator it = get_connections ().begin ();
2297                 if (it == get_connections ().end ()) {
2298                         memset (_buffer, 0, n_samples * sizeof (Sample));
2299                 } else {
2300                         PortAudioPort const * source = static_cast<const PortAudioPort*>(*it);
2301                         assert (source && source->is_output ());
2302                         memcpy (_buffer, source->const_buffer (), n_samples * sizeof (Sample));
2303                         while (++it != get_connections ().end ()) {
2304                                 source = static_cast<const PortAudioPort*>(*it);
2305                                 assert (source && source->is_output ());
2306                                 Sample* dst = buffer ();
2307                                 const Sample* src = source->const_buffer ();
2308                                 for (uint32_t s = 0; s < n_samples; ++s, ++dst, ++src) {
2309                                         *dst += *src;
2310                                 }
2311                         }
2312                 }
2313         }
2314         return _buffer;
2315 }
2316
2317
2318 PortMidiPort::PortMidiPort (PortAudioBackend &b, const std::string& name, PortFlags flags)
2319         : PamPort (b, name, flags)
2320         , _n_periods (1)
2321         , _bufperiod (0)
2322 {
2323         _buffer[0].clear ();
2324         _buffer[1].clear ();
2325 }
2326
2327 PortMidiPort::~PortMidiPort () { }
2328
2329 struct MidiEventSorter {
2330         bool operator() (const boost::shared_ptr<PortMidiEvent>& a, const boost::shared_ptr<PortMidiEvent>& b) {
2331                 return *a < *b;
2332         }
2333 };
2334
2335 void* PortMidiPort::get_buffer (pframes_t /* nframes */)
2336 {
2337         if (is_input ()) {
2338                 (_buffer[_bufperiod]).clear ();
2339                 for (std::vector<PamPort*>::const_iterator i = get_connections ().begin ();
2340                                 i != get_connections ().end ();
2341                                 ++i) {
2342                         const PortMidiBuffer * src = static_cast<const PortMidiPort*>(*i)->const_buffer ();
2343                         for (PortMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
2344                                 (_buffer[_bufperiod]).push_back (boost::shared_ptr<PortMidiEvent>(new PortMidiEvent (**it)));
2345                         }
2346                 }
2347                 std::sort ((_buffer[_bufperiod]).begin (), (_buffer[_bufperiod]).end (), MidiEventSorter());
2348         }
2349         return &(_buffer[_bufperiod]);
2350 }
2351
2352 PortMidiEvent::PortMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size)
2353         : _size (size)
2354         , _timestamp (timestamp)
2355         , _data (0)
2356 {
2357         if (size > 0) {
2358                 _data = (uint8_t*) malloc (size);
2359                 memcpy (_data, data, size);
2360         }
2361 }
2362
2363 PortMidiEvent::PortMidiEvent (const PortMidiEvent& other)
2364         : _size (other.size ())
2365         , _timestamp (other.timestamp ())
2366         , _data (0)
2367 {
2368         if (other.size () && other.const_data ()) {
2369                 _data = (uint8_t*) malloc (other.size ());
2370                 memcpy (_data, other.const_data (), other.size ());
2371         }
2372 };
2373
2374 PortMidiEvent::~PortMidiEvent () {
2375         free (_data);
2376 };