replace "None" with DeviceNone in ALSA/Coreaudio
[ardour.git] / libs / backends / coreaudio / coreaudio_backend.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
21 /* use an additional midi message parser
22  *
23  * coreaudio does packetize midi. every packet includes a timestamp.
24  * With any real midi-device with a phyical layer
25  * 1 packet = 1 event (no concurrent events are possible on a cable)
26  *
27  * Howver, some USB-midi keyboards manage to send concurrent events
28  * which end up in the same packet (eg. 6 byte message: 2 note-on).
29  *
30  * An additional parser is needed to separate them
31  */
32 #define USE_MIDI_PARSER
33
34
35 #include <regex.h>
36 #include <sys/mman.h>
37 #include <sys/time.h>
38
39 #include <glibmm.h>
40
41 #include "coreaudio_backend.h"
42 #include "rt_thread.h"
43
44 #include "pbd/compose.h"
45 #include "pbd/error.h"
46 #include "pbd/file_utils.h"
47 #include "ardour/filesystem_paths.h"
48 #include "ardour/port_manager.h"
49 #include "i18n.h"
50
51 using namespace ARDOUR;
52
53 static std::string s_instance_name;
54 size_t CoreAudioBackend::_max_buffer_size = 8192;
55 std::vector<std::string> CoreAudioBackend::_midi_options;
56 std::vector<AudioBackend::DeviceStatus> CoreAudioBackend::_duplex_audio_device_status;
57 std::vector<AudioBackend::DeviceStatus> CoreAudioBackend::_input_audio_device_status;
58 std::vector<AudioBackend::DeviceStatus> CoreAudioBackend::_output_audio_device_status;
59
60
61 /* static class instance access */
62 static void hw_changed_callback_ptr (void *arg)
63 {
64         CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
65         d->hw_changed_callback();
66 }
67
68 static void error_callback_ptr (void *arg)
69 {
70         CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
71         d->error_callback();
72 }
73
74 static void xrun_callback_ptr (void *arg)
75 {
76         CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
77         d->xrun_callback();
78 }
79
80 static void buffer_size_callback_ptr (void *arg)
81 {
82         CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
83         d->buffer_size_callback();
84 }
85
86 static void sample_rate_callback_ptr (void *arg)
87 {
88         CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
89         d->sample_rate_callback();
90 }
91
92 static void midi_port_change (void *arg)
93 {
94         CoreAudioBackend *d = static_cast<CoreAudioBackend *>(arg);
95         d->coremidi_rediscover ();
96 }
97
98
99 CoreAudioBackend::CoreAudioBackend (AudioEngine& e, AudioBackendInfo& info)
100         : AudioBackend (e, info)
101         , _run (false)
102         , _active_ca (false)
103         , _active_fw (false)
104         , _freewheeling (false)
105         , _freewheel (false)
106         , _freewheel_ack (false)
107         , _reinit_thread_callback (false)
108         , _measure_latency (false)
109         , _last_process_start (0)
110         , _input_audio_device("")
111         , _output_audio_device("")
112         , _midi_driver_option(get_standard_device_name(DeviceNone))
113         , _samplerate (48000)
114         , _samples_per_period (1024)
115         , _n_inputs (0)
116         , _n_outputs (0)
117         , _systemic_audio_input_latency (0)
118         , _systemic_audio_output_latency (0)
119         , _dsp_load (0)
120         , _processed_samples (0)
121         , _port_change_flag (false)
122 #ifdef USE_MIDI_PARSER
123         , _unbuffered_bytes(0)
124         , _total_bytes(0)
125         , _expected_bytes(0)
126         , _status_byte(0)
127         , _parser_bytes(0)
128 #endif
129 {
130         _instance_name = s_instance_name;
131         pthread_mutex_init (&_port_callback_mutex, 0);
132         pthread_mutex_init (&_process_callback_mutex, 0);
133         pthread_mutex_init (&_freewheel_mutex, 0);
134         pthread_cond_init  (&_freewheel_signal, 0);
135
136         _pcmio = new CoreAudioPCM ();
137         _midiio = new CoreMidiIo ();
138
139         _pcmio->set_hw_changed_callback (hw_changed_callback_ptr, this);
140         _pcmio->discover();
141 }
142
143 CoreAudioBackend::~CoreAudioBackend ()
144 {
145         delete _pcmio; _pcmio = 0;
146         delete _midiio; _midiio = 0;
147         pthread_mutex_destroy (&_port_callback_mutex);
148         pthread_mutex_destroy (&_process_callback_mutex);
149         pthread_mutex_destroy (&_freewheel_mutex);
150         pthread_cond_destroy  (&_freewheel_signal);
151 }
152
153 /* AUDIOBACKEND API */
154
155 std::string
156 CoreAudioBackend::name () const
157 {
158         return X_("CoreAudio");
159 }
160
161 bool
162 CoreAudioBackend::is_realtime () const
163 {
164         return true;
165 }
166
167 std::vector<AudioBackend::DeviceStatus>
168 CoreAudioBackend::enumerate_devices () const
169 {
170         _duplex_audio_device_status.clear();
171         std::map<size_t, std::string> devices;
172         _pcmio->duplex_device_list(devices);
173
174         for (std::map<size_t, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
175                 if (_input_audio_device == "") _input_audio_device = i->second;
176                 if (_output_audio_device == "") _output_audio_device = i->second;
177                 _duplex_audio_device_status.push_back (DeviceStatus (i->second, true));
178         }
179         return _duplex_audio_device_status;
180 }
181
182 std::vector<AudioBackend::DeviceStatus>
183 CoreAudioBackend::enumerate_input_devices () const
184 {
185         _input_audio_device_status.clear();
186         std::map<size_t, std::string> devices;
187         _pcmio->input_device_list(devices);
188
189         _input_audio_device_status.push_back (DeviceStatus (get_standard_device_name(DeviceNone), true));
190         for (std::map<size_t, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
191                 if (_input_audio_device == "") _input_audio_device = i->second;
192                 _input_audio_device_status.push_back (DeviceStatus (i->second, true));
193         }
194         return _input_audio_device_status;
195 }
196
197
198 std::vector<AudioBackend::DeviceStatus>
199 CoreAudioBackend::enumerate_output_devices () const
200 {
201         _output_audio_device_status.clear();
202         std::map<size_t, std::string> devices;
203         _pcmio->output_device_list(devices);
204
205         _output_audio_device_status.push_back (DeviceStatus (get_standard_device_name(DeviceNone), true));
206         for (std::map<size_t, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
207                 if (_output_audio_device == "") _output_audio_device = i->second;
208                 _output_audio_device_status.push_back (DeviceStatus (i->second, true));
209         }
210         return _output_audio_device_status;
211 }
212
213 std::vector<float>
214 CoreAudioBackend::available_sample_rates (const std::string& device) const
215 {
216         std::vector<float> sr;
217         _pcmio->available_sample_rates (name_to_id (device), sr);
218         return sr;
219 }
220
221 std::vector<float>
222 CoreAudioBackend::available_sample_rates2 (const std::string& input_device, const std::string& output_device) const
223 {
224         std::vector<float> sr;
225         std::vector<float> sr_in;
226         std::vector<float> sr_out;
227
228         const uint32_t inp = name_to_id (input_device);
229         const uint32_t out = name_to_id (output_device);
230
231         if (inp == UINT32_MAX && out == UINT32_MAX) {
232                 return sr;
233         } else if (inp == UINT32_MAX) {
234                 _pcmio->available_sample_rates (out, sr_out);
235                 return sr_out;
236         } else if (out == UINT32_MAX) {
237                 _pcmio->available_sample_rates (inp, sr_in);
238                 return sr_in;
239         } else {
240                 _pcmio->available_sample_rates (inp, sr_in);
241                 _pcmio->available_sample_rates (out, sr_out);
242                 // TODO allow to use different SR per device, tweak aggregate
243                 std::set_intersection (sr_in.begin(), sr_in.end(), sr_out.begin(), sr_out.end(), std::back_inserter(sr));
244                 return sr;
245         }
246 }
247
248 std::vector<uint32_t>
249 CoreAudioBackend::available_buffer_sizes (const std::string& device) const
250 {
251         std::vector<uint32_t> bs;
252         _pcmio->available_buffer_sizes (name_to_id (device), bs);
253         return bs;
254 }
255
256 std::vector<uint32_t>
257 CoreAudioBackend::available_buffer_sizes2 (const std::string& input_device, const std::string& output_device) const
258 {
259         std::vector<uint32_t> bs;
260         std::vector<uint32_t> bs_in;
261         std::vector<uint32_t> bs_out;
262         const uint32_t inp = name_to_id (input_device);
263         const uint32_t out = name_to_id (output_device);
264         if (inp == UINT32_MAX && out == UINT32_MAX) {
265                 return bs;
266         } else if (inp == UINT32_MAX) {
267                 _pcmio->available_buffer_sizes (out, bs_out);
268                 return bs_out;
269         } else if (out == UINT32_MAX) {
270                 _pcmio->available_buffer_sizes (inp, bs_in);
271                 return bs_in;
272         } else {
273                 _pcmio->available_buffer_sizes (inp, bs_in);
274                 _pcmio->available_buffer_sizes (out, bs_out);
275                 std::set_intersection (bs_in.begin(), bs_in.end(), bs_out.begin(), bs_out.end(), std::back_inserter(bs));
276                 return bs;
277         }
278 }
279
280 uint32_t
281 CoreAudioBackend::available_input_channel_count (const std::string&) const
282 {
283         return 128; // TODO query current device
284 }
285
286 uint32_t
287 CoreAudioBackend::available_output_channel_count (const std::string&) const
288 {
289         return 128; // TODO query current device
290 }
291
292 bool
293 CoreAudioBackend::can_change_sample_rate_when_running () const
294 {
295         return false;
296 }
297
298 bool
299 CoreAudioBackend::can_change_buffer_size_when_running () const
300 {
301         return true;
302 }
303
304 int
305 CoreAudioBackend::set_device_name (const std::string& d)
306 {
307         int rv = 0;
308         rv |= set_input_device_name (d);
309         rv |= set_output_device_name (d);
310         return rv;
311 }
312
313 int
314 CoreAudioBackend::set_input_device_name (const std::string& d)
315 {
316         _input_audio_device = d;
317         const float sr = _pcmio->current_sample_rate(name_to_id(_input_audio_device));
318         if (sr > 0) { set_sample_rate(sr); }
319         return 0;
320 }
321
322 int
323 CoreAudioBackend::set_output_device_name (const std::string& d)
324 {
325         _output_audio_device = d;
326         // TODO check SR.
327         const float sr = _pcmio->current_sample_rate(name_to_id(_output_audio_device));
328         if (sr > 0) { set_sample_rate(sr); }
329         return 0;
330 }
331
332 int
333 CoreAudioBackend::set_sample_rate (float sr)
334 {
335         std::vector<float> srs = available_sample_rates2 (_input_audio_device, _output_audio_device);
336         if (std::find(srs.begin(), srs.end(), sr) == srs.end()) {
337                 return -1;
338         }
339         _samplerate = sr;
340         engine.sample_rate_change (sr);
341         return 0;
342 }
343
344 int
345 CoreAudioBackend::set_buffer_size (uint32_t bs)
346 {
347         if (bs <= 0 || bs >= _max_buffer_size) {
348                 return -1;
349         }
350         _samples_per_period = bs;
351         _pcmio->set_samples_per_period(bs);
352         engine.buffer_size_change (bs);
353         return 0;
354 }
355
356 int
357 CoreAudioBackend::set_interleaved (bool yn)
358 {
359         if (!yn) { return 0; }
360         return -1;
361 }
362
363 int
364 CoreAudioBackend::set_input_channels (uint32_t cc)
365 {
366         _n_inputs = cc;
367         return 0;
368 }
369
370 int
371 CoreAudioBackend::set_output_channels (uint32_t cc)
372 {
373         _n_outputs = cc;
374         return 0;
375 }
376
377 int
378 CoreAudioBackend::set_systemic_input_latency (uint32_t sl)
379 {
380         _systemic_audio_input_latency = sl;
381         return 0;
382 }
383
384 int
385 CoreAudioBackend::set_systemic_output_latency (uint32_t sl)
386 {
387         _systemic_audio_output_latency = sl;
388         return 0;
389 }
390
391 /* Retrieving parameters */
392 std::string
393 CoreAudioBackend::device_name () const
394 {
395         return "";
396 }
397
398 std::string
399 CoreAudioBackend::input_device_name () const
400 {
401         return _input_audio_device;
402 }
403
404 std::string
405 CoreAudioBackend::output_device_name () const
406 {
407         return _output_audio_device;
408 }
409
410 float
411 CoreAudioBackend::sample_rate () const
412 {
413         return _samplerate;
414 }
415
416 uint32_t
417 CoreAudioBackend::buffer_size () const
418 {
419         return _samples_per_period;
420 }
421
422 bool
423 CoreAudioBackend::interleaved () const
424 {
425         return false;
426 }
427
428 uint32_t
429 CoreAudioBackend::input_channels () const
430 {
431         return _n_inputs;
432 }
433
434 uint32_t
435 CoreAudioBackend::output_channels () const
436 {
437         return _n_outputs;
438 }
439
440 uint32_t
441 CoreAudioBackend::systemic_input_latency () const
442 {
443         return _systemic_audio_input_latency;
444 }
445
446 uint32_t
447 CoreAudioBackend::systemic_output_latency () const
448 {
449         return _systemic_audio_output_latency;
450 }
451
452 /* MIDI */
453
454 std::vector<std::string>
455 CoreAudioBackend::enumerate_midi_options () const
456 {
457         if (_midi_options.empty()) {
458                 _midi_options.push_back (_("CoreMidi"));
459                 _midi_options.push_back (get_standard_device_name(DeviceNone));
460         }
461         return _midi_options;
462 }
463
464 int
465 CoreAudioBackend::set_midi_option (const std::string& opt)
466 {
467         if (opt != get_standard_device_name(DeviceNone) && opt != _("CoreMidi")) {
468                 return -1;
469         }
470         _midi_driver_option = opt;
471         return 0;
472 }
473
474 std::string
475 CoreAudioBackend::midi_option () const
476 {
477         return _midi_driver_option;
478 }
479
480 void
481 CoreAudioBackend::launch_control_app ()
482 {
483         if (name_to_id (_input_audio_device) != UINT32_MAX) {
484                 _pcmio->launch_control_app(name_to_id(_input_audio_device));
485         }
486         if (name_to_id (_output_audio_device) != UINT32_MAX) {
487                 _pcmio->launch_control_app(name_to_id(_output_audio_device));
488         }
489 }
490
491 /* State Control */
492
493 static void * pthread_freewheel (void *arg)
494 {
495         CoreAudioBackend *d = static_cast<CoreAudioBackend *>(arg);
496         d->freewheel_thread ();
497         pthread_exit (0);
498         return 0;
499 }
500
501 static int process_callback_ptr (void *arg, const uint32_t n_samples, const uint64_t host_time)
502 {
503         CoreAudioBackend *d = static_cast<CoreAudioBackend*> (arg);
504         return d->process_callback(n_samples, host_time);
505 }
506
507 int
508 CoreAudioBackend::_start (bool for_latency_measurement)
509 {
510         if ((!_active_ca || !_active_fw)  && _run) {
511                 // recover from 'halted', reap threads
512                 stop();
513         }
514
515         if (_active_ca || _active_fw || _run) {
516                 PBD::error << _("CoreAudioBackend: already active.") << endmsg;
517                 return -1;
518         }
519
520         if (_ports.size()) {
521                 PBD::warning << _("CoreAudioBackend: recovering from unclean shutdown, port registry is not empty.") << endmsg;
522                 _system_inputs.clear();
523                 _system_outputs.clear();
524                 _system_midi_in.clear();
525                 _system_midi_out.clear();
526                 _ports.clear();
527         }
528
529         uint32_t device1 = name_to_id(_input_audio_device);
530         uint32_t device2 = name_to_id(_output_audio_device);
531
532         assert(_active_ca == false);
533         assert(_active_fw == false);
534
535         _freewheel_ack = false;
536         _reinit_thread_callback = true;
537         _last_process_start = 0;
538
539         _pcmio->set_error_callback (error_callback_ptr, this);
540         _pcmio->set_buffer_size_callback (buffer_size_callback_ptr, this);
541         _pcmio->set_sample_rate_callback (sample_rate_callback_ptr, this);
542
543         _pcmio->pcm_start (device1, device2, _samplerate, _samples_per_period, process_callback_ptr, this);
544         printf("STATE: %d\n", _pcmio->state ());
545
546         switch (_pcmio->state ()) {
547                 case 0: /* OK */ break;
548                 case -1: PBD::error << _("CoreAudioBackend: failed to open device.") << endmsg; break;
549                 default: PBD::error << _("CoreAudioBackend: initialization failed.") << endmsg; break;
550         }
551         if (_pcmio->state ()) {
552                 return -1;
553         }
554
555         if (_n_outputs != _pcmio->n_playback_channels ()) {
556                 if (_n_outputs == 0) {
557                  _n_outputs = _pcmio->n_playback_channels ();
558                 } else {
559                  _n_outputs = std::min (_n_outputs, _pcmio->n_playback_channels ());
560                 }
561                 PBD::info << _("CoreAudioBackend: adjusted output channel count to match device.") << endmsg;
562         }
563
564         if (_n_inputs != _pcmio->n_capture_channels ()) {
565                 if (_n_inputs == 0) {
566                  _n_inputs = _pcmio->n_capture_channels ();
567                 } else {
568                  _n_inputs = std::min (_n_inputs, _pcmio->n_capture_channels ());
569                 }
570                 PBD::info << _("CoreAudioBackend: adjusted input channel count to match device.") << endmsg;
571         }
572
573         if (_pcmio->samples_per_period() != _samples_per_period) {
574                 _samples_per_period = _pcmio->samples_per_period();
575                 PBD::warning << _("CoreAudioBackend: samples per period does not match.") << endmsg;
576         }
577
578         if (_pcmio->sample_rate() != _samplerate) {
579                 _samplerate = _pcmio->sample_rate();
580                 engine.sample_rate_change (_samplerate);
581                 PBD::warning << _("CoreAudioBackend: sample rate does not match.") << endmsg;
582         }
583
584         _measure_latency = for_latency_measurement;
585
586         _preinit = true;
587         _run = true;
588         _port_change_flag = false;
589
590         if (_midi_driver_option == _("CoreMidi")) {
591                 _midiio->set_enabled(true);
592                 _midiio->set_port_changed_callback(midi_port_change, this);
593                 _midiio->start(); // triggers port discovery, callback coremidi_rediscover()
594         }
595
596         if (register_system_audio_ports()) {
597                 PBD::error << _("CoreAudioBackend: failed to register system ports.") << endmsg;
598                 _run = false;
599                 return -1;
600         }
601
602         engine.sample_rate_change (_samplerate);
603         engine.buffer_size_change (_samples_per_period);
604
605         if (engine.reestablish_ports ()) {
606                 PBD::error << _("CoreAudioBackend: Could not re-establish ports.") << endmsg;
607                 _run = false;
608                 return -1;
609         }
610
611         if (pthread_create (&_freeewheel_thread, NULL, pthread_freewheel, this))
612         {
613                 PBD::error << _("CoreAudioBackend: failed to create process thread.") << endmsg;
614                 delete _pcmio; _pcmio = 0;
615                 _run = false;
616                 return -1;
617         }
618
619         int timeout = 5000;
620         while ((!_active_ca || !_active_fw) && --timeout > 0) { Glib::usleep (1000); }
621
622         if (timeout == 0) {
623                 PBD::error << _("CoreAudioBackend: failed to start.") << endmsg;
624         }
625
626         if (!_active_fw) {
627                 PBD::error << _("CoreAudioBackend: failed to start freewheeling thread.") << endmsg;
628                 _run = false;
629                 _pcmio->pcm_stop();
630                 unregister_ports();
631                 _active_ca = false;
632                 _active_fw = false;
633                 return -1;
634         }
635
636         if (!_active_ca) {
637                 PBD::error << _("CoreAudioBackend: failed to start coreaudio.") << endmsg;
638                 stop();
639                 _run = false;
640                 return -1;
641         }
642
643         engine.reconnect_ports ();
644
645         // force  an initial registration_callback() & latency re-compute
646         _port_change_flag = true;
647         pre_process ();
648
649         // all systems go.
650         _pcmio->set_xrun_callback (xrun_callback_ptr, this);
651         _preinit = false;
652
653         return 0;
654 }
655
656 int
657 CoreAudioBackend::stop ()
658 {
659         void *status;
660         if (!_run) {
661                 return 0;
662         }
663
664         _run = false;
665         _pcmio->pcm_stop();
666         _midiio->set_port_changed_callback(NULL, NULL);
667         _midiio->stop();
668
669         pthread_mutex_lock (&_freewheel_mutex);
670         pthread_cond_signal (&_freewheel_signal);
671         pthread_mutex_unlock (&_freewheel_mutex);
672
673         if (pthread_join (_freeewheel_thread, &status)) {
674                 PBD::error << _("CoreAudioBackend: failed to terminate.") << endmsg;
675                 return -1;
676         }
677
678         unregister_ports();
679
680         _active_ca = false;
681         _active_fw = false; // ??
682
683         return 0;
684 }
685
686 int
687 CoreAudioBackend::freewheel (bool onoff)
688 {
689         if (onoff == _freewheeling) {
690                 return 0;
691         }
692         _freewheeling = onoff;
693         // wake up freewheeling thread
694         if (0 == pthread_mutex_trylock (&_freewheel_mutex)) {
695                 pthread_cond_signal (&_freewheel_signal);
696                 pthread_mutex_unlock (&_freewheel_mutex);
697         }
698         return 0;
699 }
700
701 float
702 CoreAudioBackend::dsp_load () const
703 {
704         return std::min(100.f, 100.f * _dsp_load);
705 }
706
707 size_t
708 CoreAudioBackend::raw_buffer_size (DataType t)
709 {
710         switch (t) {
711                 case DataType::AUDIO:
712                         return _samples_per_period * sizeof(Sample);
713                 case DataType::MIDI:
714                         return _max_buffer_size; // XXX not really limited
715         }
716         return 0;
717 }
718
719 /* Process time */
720 framepos_t
721 CoreAudioBackend::sample_time ()
722 {
723         return _processed_samples;
724 }
725
726 framepos_t
727 CoreAudioBackend::sample_time_at_cycle_start ()
728 {
729         return _processed_samples;
730 }
731
732 pframes_t
733 CoreAudioBackend::samples_since_cycle_start ()
734 {
735         if (!_active_ca || !_run || _freewheeling || _freewheel) {
736                 return 0;
737         }
738         if (_last_process_start == 0) {
739                 return 0;
740         }
741
742         const uint64_t now = AudioGetCurrentHostTime ();
743         const int64_t elapsed_time_ns = AudioConvertHostTimeToNanos(now - _last_process_start);
744         return std::max((pframes_t)0, (pframes_t)rint(1e-9 * elapsed_time_ns * _samplerate));
745 }
746
747 uint32_t
748 CoreAudioBackend::name_to_id(std::string device_name) const {
749         uint32_t device_id = UINT32_MAX;
750         std::map<size_t, std::string> devices;
751         _pcmio->device_list(devices);
752
753         for (std::map<size_t, std::string>::const_iterator i = devices.begin (); i != devices.end(); ++i) {
754                 if (i->second == device_name) {
755                         device_id = i->first;
756                         break;
757                 }
758         }
759         return device_id;
760 }
761
762 void *
763 CoreAudioBackend::coreaudio_process_thread (void *arg)
764 {
765         ThreadData* td = reinterpret_cast<ThreadData*> (arg);
766         boost::function<void ()> f = td->f;
767         delete td;
768         f ();
769         return 0;
770 }
771
772 int
773 CoreAudioBackend::create_process_thread (boost::function<void()> func)
774 {
775         pthread_t thread_id;
776         pthread_attr_t attr;
777         size_t stacksize = 100000;
778
779         ThreadData* td = new ThreadData (this, func, stacksize);
780
781         if (_realtime_pthread_create (SCHED_FIFO, -21, stacksize,
782                                 &thread_id, coreaudio_process_thread, td)) {
783                 pthread_attr_init (&attr);
784                 pthread_attr_setstacksize (&attr, stacksize);
785                 if (pthread_create (&thread_id, &attr, coreaudio_process_thread, td)) {
786                         PBD::error << _("AudioEngine: cannot create process thread.") << endmsg;
787                         pthread_attr_destroy (&attr);
788                         return -1;
789                 }
790                 pthread_attr_destroy (&attr);
791         }
792
793         _threads.push_back (thread_id);
794         return 0;
795 }
796
797 int
798 CoreAudioBackend::join_process_threads ()
799 {
800         int rv = 0;
801
802         for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
803         {
804                 void *status;
805                 if (pthread_join (*i, &status)) {
806                         PBD::error << _("AudioEngine: cannot terminate process thread.") << endmsg;
807                         rv -= 1;
808                 }
809         }
810         _threads.clear ();
811         return rv;
812 }
813
814 bool
815 CoreAudioBackend::in_process_thread ()
816 {
817         if (pthread_equal (_main_thread, pthread_self()) != 0) {
818                 return true;
819         }
820
821         for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
822         {
823                 if (pthread_equal (*i, pthread_self ()) != 0) {
824                         return true;
825                 }
826         }
827         return false;
828 }
829
830 uint32_t
831 CoreAudioBackend::process_thread_count ()
832 {
833         return _threads.size ();
834 }
835
836 void
837 CoreAudioBackend::update_latencies ()
838 {
839         // trigger latency callback in RT thread (locked graph)
840         port_connect_add_remove_callback();
841 }
842
843 /* PORTENGINE API */
844
845 void*
846 CoreAudioBackend::private_handle () const
847 {
848         return NULL;
849 }
850
851 const std::string&
852 CoreAudioBackend::my_name () const
853 {
854         return _instance_name;
855 }
856
857 bool
858 CoreAudioBackend::available () const
859 {
860         return _run && _active_fw && _active_ca;
861 }
862
863 uint32_t
864 CoreAudioBackend::port_name_size () const
865 {
866         return 256;
867 }
868
869 int
870 CoreAudioBackend::set_port_name (PortEngine::PortHandle port, const std::string& name)
871 {
872         if (!valid_port (port)) {
873                 PBD::warning << _("CoreAudioBackend::set_port_name: Invalid Port(s)") << endmsg;
874                 return -1;
875         }
876         return static_cast<CoreBackendPort*>(port)->set_name (_instance_name + ":" + name);
877 }
878
879 std::string
880 CoreAudioBackend::get_port_name (PortEngine::PortHandle port) const
881 {
882         if (!valid_port (port)) {
883                 PBD::warning << _("CoreAudioBackend::get_port_name: Invalid Port(s)") << endmsg;
884                 return std::string ();
885         }
886         return static_cast<CoreBackendPort*>(port)->name ();
887 }
888
889 int
890 CoreAudioBackend::get_port_property (PortHandle port, const std::string& key, std::string& value, std::string& type) const
891 {
892         if (!valid_port (port)) {
893                 PBD::warning << _("CoreAudioBackend::get_port_name: Invalid Port(s)") << endmsg;
894                 return -1;
895         }
896         if (key == "http://jackaudio.org/metadata/pretty-name") {
897                 type = "";
898                 value = static_cast<CoreBackendPort*>(port)->pretty_name ();
899                 if (!value.empty()) {
900                         return 0;
901                 }
902         }
903         return -1;
904 }
905
906 PortEngine::PortHandle
907 CoreAudioBackend::get_port_by_name (const std::string& name) const
908 {
909         PortHandle port = (PortHandle) find_port (name);
910         return port;
911 }
912
913 int
914 CoreAudioBackend::get_ports (
915                 const std::string& port_name_pattern,
916                 DataType type, PortFlags flags,
917                 std::vector<std::string>& port_names) const
918 {
919         int rv = 0;
920         regex_t port_regex;
921         bool use_regexp = false;
922         if (port_name_pattern.size () > 0) {
923                 if (!regcomp (&port_regex, port_name_pattern.c_str (), REG_EXTENDED|REG_NOSUB)) {
924                         use_regexp = true;
925                 }
926         }
927         for (size_t i = 0; i < _ports.size (); ++i) {
928                 CoreBackendPort* port = _ports[i];
929                 if ((port->type () == type) && flags == (port->flags () & flags)) {
930                         if (!use_regexp || !regexec (&port_regex, port->name ().c_str (), 0, NULL, 0)) {
931                                 port_names.push_back (port->name ());
932                                 ++rv;
933                         }
934                 }
935         }
936         if (use_regexp) {
937                 regfree (&port_regex);
938         }
939         return rv;
940 }
941
942 DataType
943 CoreAudioBackend::port_data_type (PortEngine::PortHandle port) const
944 {
945         if (!valid_port (port)) {
946                 return DataType::NIL;
947         }
948         return static_cast<CoreBackendPort*>(port)->type ();
949 }
950
951 PortEngine::PortHandle
952 CoreAudioBackend::register_port (
953                 const std::string& name,
954                 ARDOUR::DataType type,
955                 ARDOUR::PortFlags flags)
956 {
957         if (name.size () == 0) { return 0; }
958         if (flags & IsPhysical) { return 0; }
959         return add_port (_instance_name + ":" + name, type, flags);
960 }
961
962 PortEngine::PortHandle
963 CoreAudioBackend::add_port (
964                 const std::string& name,
965                 ARDOUR::DataType type,
966                 ARDOUR::PortFlags flags)
967 {
968         assert(name.size ());
969         if (find_port (name)) {
970                 PBD::warning << _("CoreAudioBackend::register_port: Port already exists:")
971                                 << " (" << name << ")" << endmsg;
972                 return 0;
973         }
974         CoreBackendPort* port = NULL;
975         switch (type) {
976                 case DataType::AUDIO:
977                         port = new CoreAudioPort (*this, name, flags);
978                         break;
979                 case DataType::MIDI:
980                         port = new CoreMidiPort (*this, name, flags);
981                         break;
982                 default:
983                         PBD::error << _("CoreAudioBackend::register_port: Invalid Data Type.") << endmsg;
984                         return 0;
985         }
986
987         _ports.push_back (port);
988
989         return port;
990 }
991
992 void
993 CoreAudioBackend::unregister_port (PortEngine::PortHandle port_handle)
994 {
995         if (!_run) {
996                 return;
997         }
998         CoreBackendPort* port = static_cast<CoreBackendPort*>(port_handle);
999         std::vector<CoreBackendPort*>::iterator i = std::find (_ports.begin (), _ports.end (), static_cast<CoreBackendPort*>(port_handle));
1000         if (i == _ports.end ()) {
1001                 PBD::warning << _("CoreAudioBackend::unregister_port: Failed to find port") << endmsg;
1002                 return;
1003         }
1004         disconnect_all(port_handle);
1005         _ports.erase (i);
1006         delete port;
1007 }
1008
1009 int
1010 CoreAudioBackend::register_system_audio_ports()
1011 {
1012         LatencyRange lr;
1013
1014         const uint32_t a_ins = _n_inputs;
1015         const uint32_t a_out = _n_outputs;
1016
1017         const uint32_t coreaudio_reported_input_latency = _pcmio->get_latency(name_to_id(_input_audio_device), true);
1018         const uint32_t coreaudio_reported_output_latency = _pcmio->get_latency(name_to_id(_output_audio_device), false);
1019
1020 #ifndef NDEBUG
1021         printf("COREAUDIO LATENCY: i:%d, o:%d\n",
1022                         coreaudio_reported_input_latency,
1023                         coreaudio_reported_output_latency);
1024 #endif
1025
1026         /* audio ports */
1027         lr.min = lr.max = coreaudio_reported_input_latency + (_measure_latency ? 0 : _systemic_audio_input_latency);
1028         for (uint32_t i = 0; i < a_ins; ++i) {
1029                 char tmp[64];
1030                 snprintf(tmp, sizeof(tmp), "system:capture_%d", i+1);
1031                 PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsOutput | IsPhysical | IsTerminal));
1032                 if (!p) return -1;
1033                 set_latency_range (p, false, lr);
1034                 CoreBackendPort *cp = static_cast<CoreBackendPort*>(p);
1035                 cp->set_pretty_name (_pcmio->cached_port_name(i, true));
1036                 _system_inputs.push_back(cp);
1037         }
1038
1039         lr.min = lr.max = coreaudio_reported_output_latency + (_measure_latency ? 0 : _systemic_audio_output_latency);
1040         for (uint32_t i = 0; i < a_out; ++i) {
1041                 char tmp[64];
1042                 snprintf(tmp, sizeof(tmp), "system:playback_%d", i+1);
1043                 PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
1044                 if (!p) return -1;
1045                 set_latency_range (p, true, lr);
1046                 CoreBackendPort *cp = static_cast<CoreBackendPort*>(p);
1047                 cp->set_pretty_name (_pcmio->cached_port_name(i, false));
1048                 _system_outputs.push_back(cp);
1049         }
1050         return 0;
1051 }
1052
1053 void
1054 CoreAudioBackend::coremidi_rediscover()
1055 {
1056         if (!_run) { return; }
1057         assert(_midi_driver_option == _("CoreMidi"));
1058
1059         pthread_mutex_lock (&_process_callback_mutex);
1060
1061         for (std::vector<CoreBackendPort*>::iterator it = _system_midi_out.begin (); it != _system_midi_out.end ();) {
1062                 bool found = false;
1063                 for (size_t i = 0; i < _midiio->n_midi_outputs(); ++i) {
1064                         if ((*it)->name() == _midiio->port_id(i, false)) {
1065                                 found = true;
1066                                 break;
1067                         }
1068                 }
1069                 if (found) {
1070                         ++it;
1071                 } else {
1072 #ifndef NDEBUG
1073                         printf("unregister MIDI Output: %s\n", (*it)->name().c_str());
1074 #endif
1075                         _port_change_flag = true;
1076                         unregister_port((*it));
1077                         it = _system_midi_out.erase(it);
1078                 }
1079         }
1080
1081         for (std::vector<CoreBackendPort*>::iterator it = _system_midi_in.begin (); it != _system_midi_in.end ();) {
1082                 bool found = false;
1083                 for (size_t i = 0; i < _midiio->n_midi_inputs(); ++i) {
1084                         if ((*it)->name() == _midiio->port_id(i, true)) {
1085                                 found = true;
1086                                 break;
1087                         }
1088                 }
1089                 if (found) {
1090                         ++it;
1091                 } else {
1092 #ifndef NDEBUG
1093                         printf("unregister MIDI Input: %s\n", (*it)->name().c_str());
1094 #endif
1095                         _port_change_flag = true;
1096                         unregister_port((*it));
1097                         it = _system_midi_in.erase(it);
1098                 }
1099         }
1100
1101         for (size_t i = 0; i < _midiio->n_midi_inputs(); ++i) {
1102                 std::string name = _midiio->port_id(i, true);
1103                 if (find_port_in(_system_midi_in, name)) {
1104                         continue;
1105                 }
1106
1107 #ifndef NDEBUG
1108                 printf("register MIDI Input: %s\n", name.c_str());
1109 #endif
1110                 PortHandle p = add_port(name, DataType::MIDI, static_cast<PortFlags>(IsOutput | IsPhysical | IsTerminal));
1111                 if (!p) {
1112                         fprintf(stderr, "failed to register MIDI IN: %s\n", name.c_str());
1113                         continue;
1114                 }
1115                 LatencyRange lr;
1116                 lr.min = lr.max = _samples_per_period; // TODO add per-port midi-systemic latency
1117                 set_latency_range (p, false, lr);
1118                 CoreBackendPort *pp = static_cast<CoreBackendPort*>(p);
1119                 pp->set_pretty_name(_midiio->port_name(i, true));
1120                 _system_midi_in.push_back(pp);
1121                 _port_change_flag = true;
1122         }
1123
1124         for (size_t i = 0; i < _midiio->n_midi_outputs(); ++i) {
1125                 std::string name = _midiio->port_id(i, false);
1126                 if (find_port_in(_system_midi_out, name)) {
1127                         continue;
1128                 }
1129
1130 #ifndef NDEBUG
1131                 printf("register MIDI OUT: %s\n", name.c_str());
1132 #endif
1133                 PortHandle p = add_port(name, DataType::MIDI, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
1134                 if (!p) {
1135                         fprintf(stderr, "failed to register MIDI OUT: %s\n", name.c_str());
1136                         continue;
1137                 }
1138                 LatencyRange lr;
1139                 lr.min = lr.max = _samples_per_period; // TODO add per-port midi-systemic latency
1140                 set_latency_range (p, false, lr);
1141                 CoreBackendPort *pp = static_cast<CoreBackendPort*>(p);
1142                 pp->set_pretty_name(_midiio->port_name(i, false));
1143                 _system_midi_out.push_back(pp);
1144                 _port_change_flag = true;
1145         }
1146
1147
1148         assert(_system_midi_out.size() == _midiio->n_midi_outputs());
1149         assert(_system_midi_in.size() == _midiio->n_midi_inputs());
1150
1151         pthread_mutex_unlock (&_process_callback_mutex);
1152 }
1153
1154 void
1155 CoreAudioBackend::unregister_ports (bool system_only)
1156 {
1157         size_t i = 0;
1158         _system_inputs.clear();
1159         _system_outputs.clear();
1160         _system_midi_in.clear();
1161         _system_midi_out.clear();
1162         while (i <  _ports.size ()) {
1163                 CoreBackendPort* port = _ports[i];
1164                 if (! system_only || (port->is_physical () && port->is_terminal ())) {
1165                         port->disconnect_all ();
1166                         delete port;
1167                         _ports.erase (_ports.begin() + i);
1168                 } else {
1169                         ++i;
1170                 }
1171         }
1172 }
1173
1174 int
1175 CoreAudioBackend::connect (const std::string& src, const std::string& dst)
1176 {
1177         CoreBackendPort* src_port = find_port (src);
1178         CoreBackendPort* dst_port = find_port (dst);
1179
1180         if (!src_port) {
1181                 PBD::warning << _("CoreAudioBackend::connect: Invalid Source port:")
1182                                 << " (" << src <<")" << endmsg;
1183                 return -1;
1184         }
1185         if (!dst_port) {
1186                 PBD::warning << _("CoreAudioBackend::connect: Invalid Destination port:")
1187                         << " (" << dst <<")" << endmsg;
1188                 return -1;
1189         }
1190         return src_port->connect (dst_port);
1191 }
1192
1193 int
1194 CoreAudioBackend::disconnect (const std::string& src, const std::string& dst)
1195 {
1196         CoreBackendPort* src_port = find_port (src);
1197         CoreBackendPort* dst_port = find_port (dst);
1198
1199         if (!src_port || !dst_port) {
1200                 PBD::warning << _("CoreAudioBackend::disconnect: Invalid Port(s)") << endmsg;
1201                 return -1;
1202         }
1203         return src_port->disconnect (dst_port);
1204 }
1205
1206 int
1207 CoreAudioBackend::connect (PortEngine::PortHandle src, const std::string& dst)
1208 {
1209         CoreBackendPort* dst_port = find_port (dst);
1210         if (!valid_port (src)) {
1211                 PBD::warning << _("CoreAudioBackend::connect: Invalid Source Port Handle") << endmsg;
1212                 return -1;
1213         }
1214         if (!dst_port) {
1215                 PBD::warning << _("CoreAudioBackend::connect: Invalid Destination Port")
1216                         << " (" << dst << ")" << endmsg;
1217                 return -1;
1218         }
1219         return static_cast<CoreBackendPort*>(src)->connect (dst_port);
1220 }
1221
1222 int
1223 CoreAudioBackend::disconnect (PortEngine::PortHandle src, const std::string& dst)
1224 {
1225         CoreBackendPort* dst_port = find_port (dst);
1226         if (!valid_port (src) || !dst_port) {
1227                 PBD::warning << _("CoreAudioBackend::disconnect: Invalid Port(s)") << endmsg;
1228                 return -1;
1229         }
1230         return static_cast<CoreBackendPort*>(src)->disconnect (dst_port);
1231 }
1232
1233 int
1234 CoreAudioBackend::disconnect_all (PortEngine::PortHandle port)
1235 {
1236         if (!valid_port (port)) {
1237                 PBD::warning << _("CoreAudioBackend::disconnect_all: Invalid Port") << endmsg;
1238                 return -1;
1239         }
1240         static_cast<CoreBackendPort*>(port)->disconnect_all ();
1241         return 0;
1242 }
1243
1244 bool
1245 CoreAudioBackend::connected (PortEngine::PortHandle port, bool /* process_callback_safe*/)
1246 {
1247         if (!valid_port (port)) {
1248                 PBD::warning << _("CoreAudioBackend::disconnect_all: Invalid Port") << endmsg;
1249                 return false;
1250         }
1251         return static_cast<CoreBackendPort*>(port)->is_connected ();
1252 }
1253
1254 bool
1255 CoreAudioBackend::connected_to (PortEngine::PortHandle src, const std::string& dst, bool /*process_callback_safe*/)
1256 {
1257         CoreBackendPort* dst_port = find_port (dst);
1258         if (!valid_port (src) || !dst_port) {
1259                 PBD::warning << _("CoreAudioBackend::connected_to: Invalid Port") << endmsg;
1260                 return false;
1261         }
1262         return static_cast<CoreBackendPort*>(src)->is_connected (dst_port);
1263 }
1264
1265 bool
1266 CoreAudioBackend::physically_connected (PortEngine::PortHandle port, bool /*process_callback_safe*/)
1267 {
1268         if (!valid_port (port)) {
1269                 PBD::warning << _("CoreAudioBackend::physically_connected: Invalid Port") << endmsg;
1270                 return false;
1271         }
1272         return static_cast<CoreBackendPort*>(port)->is_physically_connected ();
1273 }
1274
1275 int
1276 CoreAudioBackend::get_connections (PortEngine::PortHandle port, std::vector<std::string>& names, bool /*process_callback_safe*/)
1277 {
1278         if (!valid_port (port)) {
1279                 PBD::warning << _("CoreAudioBackend::get_connections: Invalid Port") << endmsg;
1280                 return -1;
1281         }
1282
1283         assert (0 == names.size ());
1284
1285         const std::vector<CoreBackendPort*>& connected_ports = static_cast<CoreBackendPort*>(port)->get_connections ();
1286
1287         for (std::vector<CoreBackendPort*>::const_iterator i = connected_ports.begin (); i != connected_ports.end (); ++i) {
1288                 names.push_back ((*i)->name ());
1289         }
1290
1291         return (int)names.size ();
1292 }
1293
1294 /* MIDI */
1295 int
1296 CoreAudioBackend::midi_event_get (
1297                 pframes_t& timestamp,
1298                 size_t& size, uint8_t** buf, void* port_buffer,
1299                 uint32_t event_index)
1300 {
1301         if (!buf || !port_buffer) return -1;
1302         CoreMidiBuffer& source = * static_cast<CoreMidiBuffer*>(port_buffer);
1303         if (event_index >= source.size ()) {
1304                 return -1;
1305         }
1306         CoreMidiEvent * const event = source[event_index].get ();
1307
1308         timestamp = event->timestamp ();
1309         size = event->size ();
1310         *buf = event->data ();
1311         return 0;
1312 }
1313
1314 int
1315 CoreAudioBackend::midi_event_put (
1316                 void* port_buffer,
1317                 pframes_t timestamp,
1318                 const uint8_t* buffer, size_t size)
1319 {
1320         if (!buffer || !port_buffer) return -1;
1321         CoreMidiBuffer& dst = * static_cast<CoreMidiBuffer*>(port_buffer);
1322         if (dst.size () && (pframes_t)dst.back ()->timestamp () > timestamp) {
1323 #ifndef NDEBUG
1324                 // nevermind, ::get_buffer() sorts events
1325                 fprintf (stderr, "CoreMidiBuffer: unordered event: %d > %d\n",
1326                                 (pframes_t)dst.back ()->timestamp (), timestamp);
1327 #endif
1328         }
1329         dst.push_back (boost::shared_ptr<CoreMidiEvent>(new CoreMidiEvent (timestamp, buffer, size)));
1330         return 0;
1331 }
1332
1333 uint32_t
1334 CoreAudioBackend::get_midi_event_count (void* port_buffer)
1335 {
1336         if (!port_buffer) return 0;
1337         return static_cast<CoreMidiBuffer*>(port_buffer)->size ();
1338 }
1339
1340 void
1341 CoreAudioBackend::midi_clear (void* port_buffer)
1342 {
1343         if (!port_buffer) return;
1344         CoreMidiBuffer * buf = static_cast<CoreMidiBuffer*>(port_buffer);
1345         assert (buf);
1346         buf->clear ();
1347 }
1348
1349 /* Monitoring */
1350
1351 bool
1352 CoreAudioBackend::can_monitor_input () const
1353 {
1354         return false;
1355 }
1356
1357 int
1358 CoreAudioBackend::request_input_monitoring (PortEngine::PortHandle, bool)
1359 {
1360         return -1;
1361 }
1362
1363 int
1364 CoreAudioBackend::ensure_input_monitoring (PortEngine::PortHandle, bool)
1365 {
1366         return -1;
1367 }
1368
1369 bool
1370 CoreAudioBackend::monitoring_input (PortEngine::PortHandle)
1371 {
1372         return false;
1373 }
1374
1375 /* Latency management */
1376
1377 void
1378 CoreAudioBackend::set_latency_range (PortEngine::PortHandle port, bool for_playback, LatencyRange latency_range)
1379 {
1380         if (!valid_port (port)) {
1381                 PBD::warning << _("CoreBackendPort::set_latency_range (): invalid port.") << endmsg;
1382                 return;
1383         }
1384         static_cast<CoreBackendPort*>(port)->set_latency_range (latency_range, for_playback);
1385 }
1386
1387 LatencyRange
1388 CoreAudioBackend::get_latency_range (PortEngine::PortHandle port, bool for_playback)
1389 {
1390         LatencyRange r;
1391         if (!valid_port (port)) {
1392                 PBD::warning << _("CoreBackendPort::get_latency_range (): invalid port.") << endmsg;
1393                 r.min = 0;
1394                 r.max = 0;
1395                 return r;
1396         }
1397         CoreBackendPort* p = static_cast<CoreBackendPort*>(port);
1398         assert(p);
1399
1400         r = p->latency_range (for_playback);
1401         if (p->is_physical() && p->is_terminal() && p->type() == DataType::AUDIO) {
1402                 if (p->is_input() && for_playback) {
1403                         r.min += _samples_per_period;
1404                         r.max += _samples_per_period;
1405                 }
1406                 if (p->is_output() && !for_playback) {
1407                         r.min += _samples_per_period;
1408                         r.max += _samples_per_period;
1409                 }
1410         }
1411         return r;
1412 }
1413
1414 /* Discovering physical ports */
1415
1416 bool
1417 CoreAudioBackend::port_is_physical (PortEngine::PortHandle port) const
1418 {
1419         if (!valid_port (port)) {
1420                 PBD::warning << _("CoreBackendPort::port_is_physical (): invalid port.") << endmsg;
1421                 return false;
1422         }
1423         return static_cast<CoreBackendPort*>(port)->is_physical ();
1424 }
1425
1426 void
1427 CoreAudioBackend::get_physical_outputs (DataType type, std::vector<std::string>& port_names)
1428 {
1429         for (size_t i = 0; i < _ports.size (); ++i) {
1430                 CoreBackendPort* port = _ports[i];
1431                 if ((port->type () == type) && port->is_input () && port->is_physical ()) {
1432                         port_names.push_back (port->name ());
1433                 }
1434         }
1435 }
1436
1437 void
1438 CoreAudioBackend::get_physical_inputs (DataType type, std::vector<std::string>& port_names)
1439 {
1440         for (size_t i = 0; i < _ports.size (); ++i) {
1441                 CoreBackendPort* port = _ports[i];
1442                 if ((port->type () == type) && port->is_output () && port->is_physical ()) {
1443                         port_names.push_back (port->name ());
1444                 }
1445         }
1446 }
1447
1448 ChanCount
1449 CoreAudioBackend::n_physical_outputs () const
1450 {
1451         int n_midi = 0;
1452         int n_audio = 0;
1453         for (size_t i = 0; i < _ports.size (); ++i) {
1454                 CoreBackendPort* port = _ports[i];
1455                 if (port->is_output () && port->is_physical ()) {
1456                         switch (port->type ()) {
1457                                 case DataType::AUDIO: ++n_audio; break;
1458                                 case DataType::MIDI: ++n_midi; break;
1459                                 default: break;
1460                         }
1461                 }
1462         }
1463         ChanCount cc;
1464         cc.set (DataType::AUDIO, n_audio);
1465         cc.set (DataType::MIDI, n_midi);
1466         return cc;
1467 }
1468
1469 ChanCount
1470 CoreAudioBackend::n_physical_inputs () const
1471 {
1472         int n_midi = 0;
1473         int n_audio = 0;
1474         for (size_t i = 0; i < _ports.size (); ++i) {
1475                 CoreBackendPort* port = _ports[i];
1476                 if (port->is_input () && port->is_physical ()) {
1477                         switch (port->type ()) {
1478                                 case DataType::AUDIO: ++n_audio; break;
1479                                 case DataType::MIDI: ++n_midi; break;
1480                                 default: break;
1481                         }
1482                 }
1483         }
1484         ChanCount cc;
1485         cc.set (DataType::AUDIO, n_audio);
1486         cc.set (DataType::MIDI, n_midi);
1487         return cc;
1488 }
1489
1490 /* Getting access to the data buffer for a port */
1491
1492 void*
1493 CoreAudioBackend::get_buffer (PortEngine::PortHandle port, pframes_t nframes)
1494 {
1495         if (!port || !valid_port (port)) return NULL;
1496         return static_cast<CoreBackendPort*>(port)->get_buffer (nframes);
1497 }
1498
1499 void
1500 CoreAudioBackend::pre_process ()
1501 {
1502         bool connections_changed = false;
1503         bool ports_changed = false;
1504         if (!pthread_mutex_trylock (&_port_callback_mutex)) {
1505                 if (_port_change_flag) {
1506                         ports_changed = true;
1507                         _port_change_flag = false;
1508                 }
1509                 if (!_port_connection_queue.empty ()) {
1510                         connections_changed = true;
1511                 }
1512                 while (!_port_connection_queue.empty ()) {
1513                         PortConnectData *c = _port_connection_queue.back ();
1514                         manager.connect_callback (c->a, c->b, c->c);
1515                         _port_connection_queue.pop_back ();
1516                         delete c;
1517                 }
1518                 pthread_mutex_unlock (&_port_callback_mutex);
1519         }
1520         if (ports_changed) {
1521                 manager.registration_callback();
1522         }
1523         if (connections_changed) {
1524                 manager.graph_order_callback();
1525         }
1526         if (connections_changed || ports_changed) {
1527                 engine.latency_callback(false);
1528                 engine.latency_callback(true);
1529         }
1530 }
1531
1532 void *
1533 CoreAudioBackend::freewheel_thread ()
1534 {
1535         _active_fw = true;
1536         bool first_run = false;
1537         /* Freewheeling - use for export.   The first call to
1538          * engine.process_callback() after engine.freewheel_callback will
1539          * if the first export cycle.
1540          * For reliable precise export timing, the calls need to be in sync.
1541          *
1542          * Furthermore we need to make sure the registered process thread
1543          * is correct.
1544          *
1545          * _freewheeling = GUI thread state as set by ::freewheel()
1546          * _freewheel = in sync here (export thread)
1547          */
1548         pthread_mutex_lock (&_freewheel_mutex);
1549         while (_run) {
1550                 // check if we should run,
1551                 if (_freewheeling != _freewheel) {
1552                         if (!_freewheeling) {
1553                                 // prepare leaving freewheeling mode
1554                                 _freewheel = false; // first mark as disabled
1555                                 _reinit_thread_callback = true; // hand over _main_thread
1556                                 _freewheel_ack = false; // prepare next handshake
1557                                 _midiio->set_enabled(true);
1558                         } else {
1559                                 first_run = true;
1560                                 _freewheel = true;
1561                         }
1562                 }
1563
1564                 if (!_freewheel || !_freewheel_ack) {
1565                         // wait for a change, we use a timed wait to
1566                         // terminate early in case some error sets _run = 0
1567                         struct timeval tv;
1568                         struct timespec ts;
1569                         gettimeofday (&tv, NULL);
1570                         ts.tv_sec = tv.tv_sec + 3;
1571                         ts.tv_nsec = 0;
1572                         pthread_cond_timedwait (&_freewheel_signal, &_freewheel_mutex, &ts);
1573                         continue;
1574                 }
1575
1576                 if (first_run) {
1577                         // tell the engine we're ready to GO.
1578                         engine.freewheel_callback (_freewheeling);
1579                         first_run = false;
1580                         _main_thread = pthread_self();
1581                         AudioEngine::thread_init_callback (this);
1582                         _midiio->set_enabled(false);
1583                 }
1584
1585                 // process port updates first in every cycle.
1586                 pre_process();
1587
1588                 // prevent coreaudio device changes
1589                 pthread_mutex_lock (&_process_callback_mutex);
1590
1591                 /* Freewheelin' */
1592                 
1593                 // clear input buffers
1594                 for (std::vector<CoreBackendPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) {
1595                         memset ((*it)->get_buffer (_samples_per_period), 0, _samples_per_period * sizeof (Sample));
1596                 }
1597                 for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it) {
1598                         static_cast<CoreMidiBuffer*>((*it)->get_buffer(0))->clear ();
1599                 }
1600
1601                 _last_process_start = 0;
1602                 if (engine.process_callback (_samples_per_period)) {
1603                         pthread_mutex_unlock (&_process_callback_mutex);
1604                         break;
1605                 }
1606
1607                 pthread_mutex_unlock (&_process_callback_mutex);
1608                 _dsp_load = 1.0;
1609                 Glib::usleep (100); // don't hog cpu
1610         }
1611
1612         pthread_mutex_unlock (&_freewheel_mutex);
1613
1614         _active_fw = false;
1615
1616         if (_run) {
1617                 // engine.process_callback() returner error
1618                 engine.halted_callback("CoreAudio Freehweeling aborted.");
1619         }
1620         return 0;
1621 }
1622
1623 #ifdef USE_MIDI_PARSER
1624 bool
1625 CoreAudioBackend::midi_process_byte (const uint8_t byte)
1626 {
1627         if (byte >= 0xf8) {
1628                 // Realtime
1629                 if (byte == 0xfd) {
1630                         // undefined
1631                         return false;
1632                 }
1633                 midi_prepare_byte_event (byte);
1634                 return true;
1635         }
1636         if (byte == 0xf7) {
1637                 // Sysex end
1638                 if (_status_byte == 0xf0) {
1639                         midi_record_byte (byte);
1640                         return midi_prepare_buffered_event ();
1641                 }
1642                 _total_bytes = 0;
1643                 _unbuffered_bytes = 0;
1644                 _expected_bytes = 0;
1645                 _status_byte = 0;
1646                 return false;
1647         }
1648         if (byte >= 0x80) {
1649                 // Non-realtime status byte
1650                 if (_total_bytes) {
1651                         _total_bytes = 0;
1652                         _unbuffered_bytes = 0;
1653                 }
1654                 _status_byte = byte;
1655                 switch (byte & 0xf0) {
1656                         case 0x80:
1657                         case 0x90:
1658                         case 0xa0:
1659                         case 0xb0:
1660                         case 0xe0:
1661                                 // Note On, Note Off, Aftertouch, Control Change, Pitch Wheel
1662                                 _expected_bytes = 3;
1663                                 break;
1664                         case 0xc0:
1665                         case 0xd0:
1666                                 // Program Change, Channel Pressure
1667                                 _expected_bytes = 2;
1668                                 break;
1669                         case 0xf0:
1670                                 switch (byte) {
1671                                         case 0xf0:
1672                                                 // Sysex
1673                                                 _expected_bytes = 0;
1674                                                 break;
1675                                         case 0xf1:
1676                                         case 0xf3:
1677                                                 // MTC Quarter Frame, Song Select
1678                                                 _expected_bytes = 2;
1679                                                 break;
1680                                         case 0xf2:
1681                                                 // Song Position
1682                                                 _expected_bytes = 3;
1683                                                 break;
1684                                         case 0xf4:
1685                                         case 0xf5:
1686                                                 // Undefined
1687                                                 _expected_bytes = 0;
1688                                                 _status_byte = 0;
1689                                                 return false;
1690                                         case 0xf6:
1691                                                 // Tune Request
1692                                                 midi_prepare_byte_event (byte);
1693                                                 _expected_bytes = 0;
1694                                                 _status_byte = 0;
1695                                                 return true;
1696                                 }
1697                 }
1698                 midi_record_byte (byte);
1699                 return false;
1700         }
1701         // Data byte
1702         if (! _status_byte) {
1703                 // Data bytes without a status will be discarded.
1704                 _total_bytes++;
1705                 _unbuffered_bytes++;
1706                 return false;
1707         }
1708         if (! _total_bytes) {
1709                 midi_record_byte (_status_byte);
1710         }
1711         midi_record_byte(byte);
1712         return (_total_bytes == _expected_bytes) ? midi_prepare_buffered_event() : false;
1713 }
1714 #endif
1715
1716
1717 int
1718 CoreAudioBackend::process_callback (const uint32_t n_samples, const uint64_t host_time)
1719 {
1720         uint32_t i = 0;
1721         uint64_t clock1, clock2;
1722
1723         _active_ca = true;
1724
1725         if (_run && _freewheel && !_freewheel_ack) {
1726                 // acknowledge freewheeling; hand-over thread ID
1727                 pthread_mutex_lock (&_freewheel_mutex);
1728                 if (_freewheel) _freewheel_ack = true;
1729                 pthread_cond_signal (&_freewheel_signal);
1730                 pthread_mutex_unlock (&_freewheel_mutex);
1731         }
1732
1733         if (!_run || _freewheel || _preinit) {
1734                 // NB if we return 1, the output is
1735                 // zeroed by the coreaudio callback
1736                 return 1;
1737         }
1738
1739         if (_reinit_thread_callback || _main_thread != pthread_self()) {
1740                 _reinit_thread_callback = false;
1741                 _main_thread = pthread_self();
1742                 AudioEngine::thread_init_callback (this);
1743         }
1744
1745         if (pthread_mutex_trylock (&_process_callback_mutex)) {
1746                 // block while devices are added/removed
1747 #ifndef NDEBUG
1748                 printf("Xrun due to device change\n");
1749 #endif
1750                 engine.Xrun();
1751                 return 1;
1752         }
1753         /* port-connection change */
1754         pre_process();
1755
1756         // cycle-length in usec
1757         const double nominal_time = 1e6 * n_samples / _samplerate;
1758
1759         clock1 = g_get_monotonic_time();
1760
1761         /* get midi */
1762         i=0;
1763         for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it, ++i) {
1764                 CoreMidiBuffer* mbuf = static_cast<CoreMidiBuffer*>((*it)->get_buffer(0));
1765                 mbuf->clear();
1766                 uint64_t time_ns;
1767                 uint8_t data[128]; // matches CoreMidi's MIDIPacket
1768                 size_t size = sizeof(data);
1769                 while (_midiio->recv_event (i, nominal_time, time_ns, data, size)) {
1770                         pframes_t time = floor((float) time_ns * _samplerate * 1e-9);
1771                         assert (time < n_samples);
1772 #ifndef USE_MIDI_PARSER
1773                         midi_event_put((void*)mbuf, time, data, size);
1774 #else
1775                         assert (size < 128);// coremidi limit per packet
1776                         bool first_time = true; // this would need to be rememberd per port.
1777                         for (size_t mb = 0; mb < size; ++mb) {
1778                                 if (first_time && !(data[mb] & 0x80)) {
1779                                         /* expect a status byte at the beginning or every Packet.
1780                                          *
1781                                          * This parser drops messages spanning multiple packets
1782                                          * (sysex > 127 bytes).
1783                                          * see also libs/backends/alsa/alsa_rawmidi.cc
1784                                          * which implements a complete parser per port without this limit.
1785                                          */
1786                                         continue;
1787                                 }
1788                                 first_time = false;
1789
1790                                 if (midi_process_byte (data[mb])) {
1791                                         midi_event_put ((void*)mbuf, time, _parser_buffer, _parser_bytes);
1792                                 }
1793                         }
1794 #endif
1795                         size = sizeof(data);
1796                 }
1797         }
1798
1799         /* get audio */
1800         i = 0;
1801         for (std::vector<CoreBackendPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it, ++i) {
1802                 _pcmio->get_capture_channel (i, (float*)((*it)->get_buffer(n_samples)), n_samples);
1803         }
1804
1805         /* clear output buffers */
1806         for (std::vector<CoreBackendPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it) {
1807                 memset ((*it)->get_buffer (n_samples), 0, n_samples * sizeof (Sample));
1808         }
1809
1810         _midiio->start_cycle();
1811         _last_process_start = host_time;
1812
1813         if (engine.process_callback (n_samples)) {
1814                 fprintf(stderr, "ENGINE PROCESS ERROR\n");
1815                 //_pcmio->pcm_stop ();
1816                 _active_ca = false;
1817                 pthread_mutex_unlock (&_process_callback_mutex);
1818                 return -1;
1819         }
1820
1821         /* mixdown midi */
1822         for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) {
1823                 static_cast<CoreMidiPort*>(*it)->get_buffer(0);
1824         }
1825
1826         /* queue outgoing midi */
1827         i = 0;
1828         for (std::vector<CoreBackendPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it, ++i) {
1829 #if 0 // something's still b0rked with CoreMidiIo::send_events()
1830                 const CoreMidiBuffer *src = static_cast<const CoreMidiPort*>(*it)->const_buffer();
1831                 _midiio->send_events (i, nominal_time, (void*)src);
1832 #else // works..
1833                 const CoreMidiBuffer *src = static_cast<const CoreMidiPort*>(*it)->const_buffer();
1834                 for (CoreMidiBuffer::const_iterator mit = src->begin (); mit != src->end (); ++mit) {
1835                         _midiio->send_event (i, (*mit)->timestamp() / nominal_time, (*mit)->data(), (*mit)->size());
1836                 }
1837 #endif
1838         }
1839
1840         /* write back audio */
1841         i = 0;
1842         for (std::vector<CoreBackendPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it, ++i) {
1843                 _pcmio->set_playback_channel (i, (float const*)(*it)->get_buffer (n_samples), n_samples);
1844         }
1845
1846         _processed_samples += n_samples;
1847
1848         /* calc DSP load. */
1849         clock2 = g_get_monotonic_time();
1850         const int64_t elapsed_time = clock2 - clock1;
1851         // low pass filter
1852         const float load = elapsed_time / (float) nominal_time;
1853         if (load > _dsp_load) {
1854                 _dsp_load = load;
1855         } else {
1856                 const float a = .2 * _samples_per_period / _samplerate;
1857                 _dsp_load = _dsp_load + a * (load - _dsp_load) + 1e-12;
1858         }
1859
1860         pthread_mutex_unlock (&_process_callback_mutex);
1861         return 0;
1862 }
1863
1864 void
1865 CoreAudioBackend::error_callback ()
1866 {
1867         _pcmio->set_error_callback (NULL, NULL);
1868         _pcmio->set_sample_rate_callback (NULL, NULL);
1869         _pcmio->set_xrun_callback (NULL, NULL);
1870         _midiio->set_port_changed_callback(NULL, NULL);
1871         engine.halted_callback("CoreAudio Process aborted.");
1872         _active_ca = false;
1873 }
1874
1875 void
1876 CoreAudioBackend::xrun_callback ()
1877 {
1878         engine.Xrun ();
1879 }
1880
1881 void
1882 CoreAudioBackend::buffer_size_callback ()
1883 {
1884         uint32_t bs = _pcmio->samples_per_period();
1885         if (bs == _samples_per_period) {
1886                 return;
1887         }
1888         _samples_per_period = bs;
1889         engine.buffer_size_change (_samples_per_period);
1890 }
1891
1892 void
1893 CoreAudioBackend::sample_rate_callback ()
1894 {
1895         if (_preinit) {
1896 #ifndef NDEBUG
1897                 printf("Samplerate change during initialization.\n");
1898 #endif
1899                 return;
1900         }
1901         _pcmio->set_error_callback (NULL, NULL);
1902         _pcmio->set_sample_rate_callback (NULL, NULL);
1903         _pcmio->set_xrun_callback (NULL, NULL);
1904         _midiio->set_port_changed_callback(NULL, NULL);
1905         engine.halted_callback("Sample Rate Changed.");
1906         stop();
1907 }
1908
1909 void
1910 CoreAudioBackend::hw_changed_callback ()
1911 {
1912         _reinit_thread_callback = true;
1913         engine.request_device_list_update();
1914 }
1915
1916 /******************************************************************************/
1917
1918 static boost::shared_ptr<CoreAudioBackend> _instance;
1919
1920 static boost::shared_ptr<AudioBackend> backend_factory (AudioEngine& e);
1921 static int instantiate (const std::string& arg1, const std::string& /* arg2 */);
1922 static int deinstantiate ();
1923 static bool already_configured ();
1924 static bool available ();
1925
1926 static ARDOUR::AudioBackendInfo _descriptor = {
1927         "CoreAudio",
1928         instantiate,
1929         deinstantiate,
1930         backend_factory,
1931         already_configured,
1932         available
1933 };
1934
1935 static boost::shared_ptr<AudioBackend>
1936 backend_factory (AudioEngine& e)
1937 {
1938         if (!_instance) {
1939                 _instance.reset (new CoreAudioBackend (e, _descriptor));
1940         }
1941         return _instance;
1942 }
1943
1944 static int
1945 instantiate (const std::string& arg1, const std::string& /* arg2 */)
1946 {
1947         s_instance_name = arg1;
1948         return 0;
1949 }
1950
1951 static int
1952 deinstantiate ()
1953 {
1954         _instance.reset ();
1955         return 0;
1956 }
1957
1958 static bool
1959 already_configured ()
1960 {
1961         return false;
1962 }
1963
1964 static bool
1965 available ()
1966 {
1967         return true;
1968 }
1969
1970 extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor ()
1971 {
1972         return &_descriptor;
1973 }
1974
1975
1976 /******************************************************************************/
1977 CoreBackendPort::CoreBackendPort (CoreAudioBackend &b, const std::string& name, PortFlags flags)
1978         : _osx_backend (b)
1979         , _name  (name)
1980         , _flags (flags)
1981 {
1982         _capture_latency_range.min = 0;
1983         _capture_latency_range.max = 0;
1984         _playback_latency_range.min = 0;
1985         _playback_latency_range.max = 0;
1986 }
1987
1988 CoreBackendPort::~CoreBackendPort () {
1989         disconnect_all ();
1990 }
1991
1992
1993 int CoreBackendPort::connect (CoreBackendPort *port)
1994 {
1995         if (!port) {
1996                 PBD::warning << _("CoreBackendPort::connect (): invalid (null) port") << endmsg;
1997                 return -1;
1998         }
1999
2000         if (type () != port->type ()) {
2001                 PBD::warning << _("CoreBackendPort::connect (): wrong port-type") << endmsg;
2002                 return -1;
2003         }
2004
2005         if (is_output () && port->is_output ()) {
2006                 PBD::warning << _("CoreBackendPort::connect (): cannot inter-connect output ports.") << endmsg;
2007                 return -1;
2008         }
2009
2010         if (is_input () && port->is_input ()) {
2011                 PBD::warning << _("CoreBackendPort::connect (): cannot inter-connect input ports.") << endmsg;
2012                 return -1;
2013         }
2014
2015         if (this == port) {
2016                 PBD::warning << _("CoreBackendPort::connect (): cannot self-connect ports.") << endmsg;
2017                 return -1;
2018         }
2019
2020         if (is_connected (port)) {
2021 #if 0 // don't bother to warn about this for now. just ignore it
2022                 PBD::info << _("CoreBackendPort::connect (): ports are already connected:")
2023                         << " (" << name () << ") -> (" << port->name () << ")"
2024                         << endmsg;
2025 #endif
2026                 return -1;
2027         }
2028
2029         _connect (port, true);
2030         return 0;
2031 }
2032
2033
2034 void CoreBackendPort::_connect (CoreBackendPort *port, bool callback)
2035 {
2036         _connections.push_back (port);
2037         if (callback) {
2038                 port->_connect (this, false);
2039                 _osx_backend.port_connect_callback (name(),  port->name(), true);
2040         }
2041 }
2042
2043 int CoreBackendPort::disconnect (CoreBackendPort *port)
2044 {
2045         if (!port) {
2046                 PBD::warning << _("CoreBackendPort::disconnect (): invalid (null) port") << endmsg;
2047                 return -1;
2048         }
2049
2050         if (!is_connected (port)) {
2051                 PBD::warning << _("CoreBackendPort::disconnect (): ports are not connected:")
2052                         << " (" << name () << ") -> (" << port->name () << ")"
2053                         << endmsg;
2054                 return -1;
2055         }
2056         _disconnect (port, true);
2057         return 0;
2058 }
2059
2060 void CoreBackendPort::_disconnect (CoreBackendPort *port, bool callback)
2061 {
2062         std::vector<CoreBackendPort*>::iterator it = std::find (_connections.begin (), _connections.end (), port);
2063
2064         assert (it != _connections.end ());
2065
2066         _connections.erase (it);
2067
2068         if (callback) {
2069                 port->_disconnect (this, false);
2070                 _osx_backend.port_connect_callback (name(),  port->name(), false);
2071         }
2072 }
2073
2074
2075 void CoreBackendPort::disconnect_all ()
2076 {
2077         while (!_connections.empty ()) {
2078                 _connections.back ()->_disconnect (this, false);
2079                 _osx_backend.port_connect_callback (name(),  _connections.back ()->name(), false);
2080                 _connections.pop_back ();
2081         }
2082 }
2083
2084 bool
2085 CoreBackendPort::is_connected (const CoreBackendPort *port) const
2086 {
2087         return std::find (_connections.begin (), _connections.end (), port) != _connections.end ();
2088 }
2089
2090 bool CoreBackendPort::is_physically_connected () const
2091 {
2092         for (std::vector<CoreBackendPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
2093                 if ((*it)->is_physical ()) {
2094                         return true;
2095                 }
2096         }
2097         return false;
2098 }
2099
2100 /******************************************************************************/
2101
2102 CoreAudioPort::CoreAudioPort (CoreAudioBackend &b, const std::string& name, PortFlags flags)
2103         : CoreBackendPort (b, name, flags)
2104 {
2105         memset (_buffer, 0, sizeof (_buffer));
2106         mlock(_buffer, sizeof (_buffer));
2107 }
2108
2109 CoreAudioPort::~CoreAudioPort () { }
2110
2111 void* CoreAudioPort::get_buffer (pframes_t n_samples)
2112 {
2113         if (is_input ()) {
2114                 std::vector<CoreBackendPort*>::const_iterator it = get_connections ().begin ();
2115                 if (it == get_connections ().end ()) {
2116                         memset (_buffer, 0, n_samples * sizeof (Sample));
2117                 } else {
2118                         CoreAudioPort const * source = static_cast<const CoreAudioPort*>(*it);
2119                         assert (source && source->is_output ());
2120                         memcpy (_buffer, source->const_buffer (), n_samples * sizeof (Sample));
2121                         while (++it != get_connections ().end ()) {
2122                                 source = static_cast<const CoreAudioPort*>(*it);
2123                                 assert (source && source->is_output ());
2124                                 Sample* dst = buffer ();
2125                                 const Sample* src = source->const_buffer ();
2126                                 for (uint32_t s = 0; s < n_samples; ++s, ++dst, ++src) {
2127                                         *dst += *src;
2128                                 }
2129                         }
2130                 }
2131         }
2132         return _buffer;
2133 }
2134
2135
2136 CoreMidiPort::CoreMidiPort (CoreAudioBackend &b, const std::string& name, PortFlags flags)
2137         : CoreBackendPort (b, name, flags)
2138         , _n_periods (1)
2139         , _bufperiod (0)
2140 {
2141         _buffer[0].clear ();
2142         _buffer[1].clear ();
2143 }
2144
2145 CoreMidiPort::~CoreMidiPort () { }
2146
2147 struct MidiEventSorter {
2148         bool operator() (const boost::shared_ptr<CoreMidiEvent>& a, const boost::shared_ptr<CoreMidiEvent>& b) {
2149                 return *a < *b;
2150         }
2151 };
2152
2153 void* CoreMidiPort::get_buffer (pframes_t /* nframes */)
2154 {
2155         if (is_input ()) {
2156                 (_buffer[_bufperiod]).clear ();
2157                 for (std::vector<CoreBackendPort*>::const_iterator i = get_connections ().begin ();
2158                                 i != get_connections ().end ();
2159                                 ++i) {
2160                         const CoreMidiBuffer * src = static_cast<const CoreMidiPort*>(*i)->const_buffer ();
2161                         for (CoreMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
2162                                 (_buffer[_bufperiod]).push_back (boost::shared_ptr<CoreMidiEvent>(new CoreMidiEvent (**it)));
2163                         }
2164                 }
2165                 std::sort ((_buffer[_bufperiod]).begin (), (_buffer[_bufperiod]).end (), MidiEventSorter());
2166         }
2167         return &(_buffer[_bufperiod]);
2168 }
2169
2170 CoreMidiEvent::CoreMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size)
2171         : _size (size)
2172         , _timestamp (timestamp)
2173         , _data (0)
2174 {
2175         if (size > 0) {
2176                 _data = (uint8_t*) malloc (size);
2177                 memcpy (_data, data, size);
2178         }
2179 }
2180
2181 CoreMidiEvent::CoreMidiEvent (const CoreMidiEvent& other)
2182         : _size (other.size ())
2183         , _timestamp (other.timestamp ())
2184         , _data (0)
2185 {
2186         if (other.size () && other.const_data ()) {
2187                 _data = (uint8_t*) malloc (other.size ());
2188                 memcpy (_data, other.const_data (), other.size ());
2189         }
2190 };
2191
2192 CoreMidiEvent::~CoreMidiEvent () {
2193         free (_data);
2194 };