ab99ccbda3cc624f84753828d85853e2d017c4ce
[ardour.git] / libs / ardour / audioengine.cc
1 /*
2     Copyright (C) 2002 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <unistd.h>
21 #include <cerrno>
22 #include <vector>
23 #include <exception>
24 #include <stdexcept>
25 #include <sstream>
26
27 #include <glibmm/timer.h>
28 #include <glibmm/pattern.h>
29 #include <glibmm/module.h>
30
31 #include "pbd/epa.h"
32 #include "pbd/file_utils.h"
33 #include "pbd/pthread_utils.h"
34 #include "pbd/stacktrace.h"
35 #include "pbd/unknown_type.h"
36
37 #include "midi++/port.h"
38 #include "midi++/mmc.h"
39
40 #include "ardour/async_midi_port.h"
41 #include "ardour/audio_port.h"
42 #include "ardour/audio_backend.h"
43 #include "ardour/audioengine.h"
44 #include "ardour/search_paths.h"
45 #include "ardour/buffer.h"
46 #include "ardour/cycle_timer.h"
47 #include "ardour/internal_send.h"
48 #include "ardour/meter.h"
49 #include "ardour/midi_port.h"
50 #include "ardour/midiport_manager.h"
51 #include "ardour/mididm.h"
52 #include "ardour/mtdm.h"
53 #include "ardour/port.h"
54 #include "ardour/process_thread.h"
55 #include "ardour/session.h"
56
57 #include "i18n.h"
58
59 using namespace std;
60 using namespace ARDOUR;
61 using namespace PBD;
62
63 gint AudioEngine::m_meter_exit;
64 AudioEngine* AudioEngine::_instance = 0;
65
66 AudioEngine::AudioEngine ()
67         : session_remove_pending (false)
68         , session_removal_countdown (-1)
69         , _running (false)
70         , _freewheeling (false)
71         , monitor_check_interval (INT32_MAX)
72         , last_monitor_check (0)
73         , _processed_frames (0)
74         , m_meter_thread (0)
75         , _main_thread (0)
76         , _mtdm (0)
77         , _mididm (0)
78         , _measuring_latency (MeasureNone)
79         , _latency_input_port (0)
80         , _latency_output_port (0)
81         , _latency_flush_frames (0)
82         , _latency_signal_latency (0)
83         , _stopped_for_latency (false)
84         , _in_destructor (false)
85 {
86         g_atomic_int_set (&m_meter_exit, 0);
87         discover_backends ();
88 }
89
90 AudioEngine::~AudioEngine ()
91 {
92         _in_destructor = true;
93         stop_metering_thread ();
94         drop_backend ();
95 }
96
97 AudioEngine*
98 AudioEngine::create ()
99 {
100         if (_instance) {
101                 return _instance;
102         }
103
104         _instance = new AudioEngine ();
105         
106         return _instance;
107 }
108
109 void
110 _thread_init_callback (void * /*arg*/)
111 {
112         /* make sure that anybody who needs to know about this thread
113            knows about it.
114         */
115
116         pthread_set_name (X_("audioengine"));
117
118         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
119         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
120
121         SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
122
123         AsyncMIDIPort::set_process_thread (pthread_self());
124 }
125
126 void
127 AudioEngine::split_cycle (pframes_t offset)
128 {
129         /* caller must hold process lock */
130
131         Port::increment_global_port_buffer_offset (offset);
132
133         /* tell all Ports that we're going to start a new (split) cycle */
134
135         boost::shared_ptr<Ports> p = ports.reader();
136
137         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
138                 i->second->cycle_split ();
139         }
140 }
141
142 int
143 AudioEngine::sample_rate_change (pframes_t nframes)
144 {
145         /* check for monitor input change every 1/10th of second */
146
147         monitor_check_interval = nframes / 10;
148         last_monitor_check = 0;
149
150         if (_session) {
151                 _session->set_frame_rate (nframes);
152         }
153
154         SampleRateChanged (nframes); /* EMIT SIGNAL */
155
156         return 0;
157 }
158
159 int 
160 AudioEngine::buffer_size_change (pframes_t bufsiz)
161 {
162         if (_session) {
163                 _session->set_block_size (bufsiz);
164                 last_monitor_check = 0;
165         }
166
167         return 0;
168 }
169
170 /** Method called by our ::process_thread when there is work to be done.
171  *  @param nframes Number of frames to process.
172  */
173 #ifdef __clang__
174 __attribute__((annotate("realtime")))
175 #endif
176 int
177 AudioEngine::process_callback (pframes_t nframes)
178 {
179         Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
180
181         PT_TIMING_REF;
182         PT_TIMING_CHECK (1);
183
184         /// The number of frames that will have been processed when we've finished
185         pframes_t next_processed_frames;
186
187         /* handle wrap around of total frames counter */
188
189         if (max_framepos - _processed_frames < nframes) {
190                 next_processed_frames = nframes - (max_framepos - _processed_frames);
191         } else {
192                 next_processed_frames = _processed_frames + nframes;
193         }
194
195         if (!tm.locked()) {
196                 /* return having done nothing */
197                 _processed_frames = next_processed_frames;
198                 return 0;
199         }
200
201         bool return_after_remove_check = false;
202
203         if (_measuring_latency == MeasureAudio && _mtdm) {
204                 /* run a normal cycle from the perspective of the PortManager
205                    so that we get silence on all registered ports.
206                    
207                    we overwrite the silence on the two ports used for latency
208                    measurement.
209                 */
210                 
211                 PortManager::cycle_start (nframes);
212                 PortManager::silence (nframes);
213
214                 if (_latency_input_port && _latency_output_port) {
215                         PortEngine& pe (port_engine());
216
217                         Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
218                         Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
219
220                         _mtdm->process (nframes, in, out);
221                 }
222
223                 PortManager::cycle_end (nframes);
224                 return_after_remove_check = true;
225
226         } else if (_measuring_latency == MeasureMIDI && _mididm) {
227                 /* run a normal cycle from the perspective of the PortManager
228                    so that we get silence on all registered ports.
229
230                    we overwrite the silence on the two ports used for latency
231                    measurement.
232                 */
233
234                 PortManager::cycle_start (nframes);
235                 PortManager::silence (nframes);
236
237                 if (_latency_input_port && _latency_output_port) {
238                         PortEngine& pe (port_engine());
239
240                         _mididm->process (nframes, pe,
241                                         pe.get_buffer (_latency_input_port, nframes),
242                                         pe.get_buffer (_latency_output_port, nframes));
243                 }
244
245                 PortManager::cycle_end (nframes);
246                 return_after_remove_check = true;
247
248         } else if (_latency_flush_frames) {
249                 
250                 /* wait for the appropriate duration for the MTDM signal to
251                  * drain from the ports before we revert to normal behaviour.
252                  */
253
254                 PortManager::cycle_start (nframes);
255                 PortManager::silence (nframes);
256                 PortManager::cycle_end (nframes);
257                 
258                 if (_latency_flush_frames > nframes) {
259                         _latency_flush_frames -= nframes;
260                 } else {
261                         _latency_flush_frames = 0;
262                 }
263
264                 return_after_remove_check = true;
265         }
266
267         if (session_remove_pending) {
268
269                 /* perform the actual session removal */
270
271                 if (session_removal_countdown < 0) {
272
273                         /* fade out over 1 second */
274                         session_removal_countdown = sample_rate()/2;
275                         session_removal_gain = 1.0;
276                         session_removal_gain_step = 1.0/session_removal_countdown;
277
278                 } else if (session_removal_countdown > 0) {
279
280                         /* we'll be fading audio out.
281                            
282                            if this is the last time we do this as part 
283                            of session removal, do a MIDI panic now
284                            to get MIDI stopped. This relies on the fact
285                            that "immediate data" (aka "out of band data") from
286                            MIDI tracks is *appended* after any other data, 
287                            so that it emerges after any outbound note ons, etc.
288                         */
289
290                         if (session_removal_countdown <= nframes) {
291                                 _session->midi_panic ();
292                         }
293
294                 } else {
295                         /* fade out done */
296                         _session = 0;
297                         session_removal_countdown = -1; // reset to "not in progress"
298                         session_remove_pending = false;
299                         session_removed.signal(); // wakes up thread that initiated session removal
300                 }
301         }
302
303         if (return_after_remove_check) {
304                 return 0;
305         }
306
307         if (_session == 0) {
308
309                 if (!_freewheeling) {
310                         PortManager::cycle_start (nframes);
311                         PortManager::cycle_end (nframes);
312                 }
313
314                 _processed_frames = next_processed_frames;
315
316                 return 0;
317         }
318
319         /* tell all relevant objects that we're starting a new cycle */
320
321         InternalSend::CycleStart (nframes);
322
323         /* tell all Ports that we're starting a new cycle */
324
325         PortManager::cycle_start (nframes);
326
327         /* test if we are freewheeling and there are freewheel signals connected.
328            ardour should act normally even when freewheeling unless /it/ is
329            exporting (which is what Freewheel.empty() tests for).
330         */
331
332         if (_freewheeling && !Freewheel.empty()) {
333                 Freewheel (nframes);
334         } else {
335                 if (_session) {
336                         _session->process (nframes);
337                 }
338         }
339
340         if (_freewheeling) {
341                 return 0;
342         }
343
344         if (!_running) {
345                 _processed_frames = next_processed_frames;
346                 return 0;
347         }
348
349         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
350                 
351                 PortManager::check_monitoring ();
352                 last_monitor_check = next_processed_frames;
353         }
354
355         if (_session->silent()) {
356                 PortManager::silence (nframes);
357         }
358
359         if (session_remove_pending && session_removal_countdown) {
360
361                 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
362                 
363                 if (session_removal_countdown > nframes) {
364                         session_removal_countdown -= nframes;
365                 } else {
366                         session_removal_countdown = 0;
367                 }
368
369                 session_removal_gain -= (nframes * session_removal_gain_step);
370         }
371
372         PortManager::cycle_end (nframes);
373
374         _processed_frames = next_processed_frames;
375
376         PT_TIMING_CHECK (2);
377         
378         return 0;
379 }
380
381
382 void
383 AudioEngine::stop_metering_thread ()
384 {
385         if (m_meter_thread) {
386                 g_atomic_int_set (&m_meter_exit, 1);
387                 m_meter_thread->join ();
388                 m_meter_thread = 0;
389         }
390 }
391
392 void
393 AudioEngine::start_metering_thread ()
394 {
395         if (m_meter_thread == 0) {
396                 g_atomic_int_set (&m_meter_exit, 0);
397                 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
398         }
399 }
400
401 void
402 AudioEngine::meter_thread ()
403 {
404         pthread_set_name (X_("meter"));
405
406         while (true) {
407                 Glib::usleep (10000); /* 1/100th sec interval */
408                 if (g_atomic_int_get(&m_meter_exit)) {
409                         break;
410                 }
411                 Metering::Meter ();
412         }
413 }
414
415 void
416 AudioEngine::set_session (Session *s)
417 {
418         Glib::Threads::Mutex::Lock pl (_process_lock);
419
420         SessionHandlePtr::set_session (s);
421
422         if (_session) {
423
424                 pframes_t blocksize = samples_per_cycle ();
425
426                 PortManager::cycle_start (blocksize);
427
428                 _session->process (blocksize);
429                 _session->process (blocksize);
430                 _session->process (blocksize);
431                 _session->process (blocksize);
432                 _session->process (blocksize);
433                 _session->process (blocksize);
434                 _session->process (blocksize);
435                 _session->process (blocksize);
436
437                 PortManager::cycle_end (blocksize);
438         }
439 }
440
441 void
442 AudioEngine::remove_session ()
443 {
444         Glib::Threads::Mutex::Lock lm (_process_lock);
445
446         if (_running) {
447
448                 if (_session) {
449                         session_remove_pending = true;
450                         session_removal_countdown = 0;
451                         session_removed.wait(_process_lock);
452                 }
453
454         } else {
455                 SessionHandlePtr::set_session (0);
456         }
457
458         remove_all_ports ();
459 }
460
461
462 void
463 AudioEngine::died ()
464 {
465         /* called from a signal handler for SIGPIPE */
466
467         stop_metering_thread ();
468
469         _running = false;
470 }
471
472 int
473 AudioEngine::reset_timebase ()
474 {
475         if (_session) {
476                 if (_session->config.get_jack_time_master()) {
477                         _backend->set_time_master (true);
478                 } else {
479                         _backend->set_time_master (false);
480                 }
481         }
482         return 0;
483 }
484
485
486 void
487 AudioEngine::destroy ()
488 {
489         delete _instance;
490         _instance = 0;
491 }
492
493 int
494 AudioEngine::discover_backends ()
495 {
496         vector<std::string> backend_modules;
497
498         _backends.clear ();
499
500         Glib::PatternSpec so_extension_pattern("*backend.so");
501         Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
502
503 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
504         #if defined(DEBUG) || defined(_DEBUG)
505                 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
506         #else
507                 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
508         #endif
509 #else
510         Glib::PatternSpec dll_extension_pattern("*backend.dll");
511 #endif
512
513         find_files_matching_pattern (backend_modules, backend_search_path (),
514                                      so_extension_pattern);
515
516         find_files_matching_pattern (backend_modules, backend_search_path (),
517                                      dylib_extension_pattern);
518
519         find_files_matching_pattern (backend_modules, backend_search_path (),
520                                      dll_extension_pattern);
521
522         DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
523
524         for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
525
526                 AudioBackendInfo* info;
527
528                 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
529
530                 if ((info = backend_discover (*i)) != 0) {
531                         _backends.insert (make_pair (info->name, info));
532                 }
533         }
534
535         DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
536
537         return _backends.size();
538 }
539
540 AudioBackendInfo*
541 AudioEngine::backend_discover (const string& path)
542 {
543         Glib::Module module (path);
544         AudioBackendInfo* info;
545         AudioBackendInfo* (*dfunc)(void);
546         void* func = 0;
547
548         if (!module) {
549                 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
550                                         Glib::Module::get_last_error()) << endmsg;
551                 return 0;
552         }
553         
554         if (!module.get_symbol ("descriptor", func)) {
555                 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
556                 error << Glib::Module::get_last_error() << endmsg;
557                 return 0;
558         }
559
560         module.make_resident ();
561         
562         dfunc = (AudioBackendInfo* (*)(void))func;
563         info = dfunc();
564         
565         return info;
566 }
567
568 vector<const AudioBackendInfo*>
569 AudioEngine::available_backends() const
570 {
571         vector<const AudioBackendInfo*> r;
572         
573         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
574                 r.push_back (i->second);
575         }
576
577         return r;
578 }
579
580 string
581 AudioEngine::current_backend_name() const
582 {
583         if (_backend) {
584                 return _backend->name();
585         } 
586         return string();
587 }
588
589 void
590 AudioEngine::drop_backend ()
591 {
592         if (_backend) {
593                 _backend->stop ();
594                 _backend->drop_device();
595                 _backend.reset ();
596                 _running = false;
597         }
598 }
599
600 boost::shared_ptr<AudioBackend>
601 AudioEngine::set_default_backend ()
602 {
603         if (_backends.empty()) {
604                 return boost::shared_ptr<AudioBackend>();
605         }
606
607         return set_backend (_backends.begin()->first, "", "");
608 }
609
610 boost::shared_ptr<AudioBackend>
611 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
612 {
613         BackendMap::iterator b = _backends.find (name);
614
615         if (b == _backends.end()) {
616                 return boost::shared_ptr<AudioBackend>();
617         }
618
619         drop_backend ();
620         
621         try {
622                 if (b->second->instantiate (arg1, arg2)) {
623                         throw failed_constructor ();
624                 }
625                 
626                 _backend = b->second->factory (*this);
627
628         } catch (exception& e) {
629                 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
630                 return boost::shared_ptr<AudioBackend>();
631         }
632
633         return _backend;
634 }
635
636 /* BACKEND PROXY WRAPPERS */
637
638 int
639 AudioEngine::start (bool for_latency)
640 {
641         if (!_backend) {
642                 return -1;
643         }
644
645         if (_running) {
646                 return 0;
647         }
648
649         _processed_frames = 0;
650         last_monitor_check = 0;
651         
652         if (_backend->start (for_latency)) {
653                 return -1;
654         }
655
656         _running = true;
657         
658         if (_session) {
659                 _session->set_frame_rate (_backend->sample_rate());
660                 
661                 if (_session->config.get_jack_time_master()) {
662                         _backend->set_time_master (true);
663                 }
664         }
665         
666         start_metering_thread ();
667         
668         if (!for_latency) {
669                 Running(); /* EMIT SIGNAL */
670         }
671         
672         return 0;
673 }
674
675 int
676 AudioEngine::stop (bool for_latency)
677 {
678         if (!_backend) {
679                 return 0;
680         }
681
682         Glib::Threads::Mutex::Lock lm (_process_lock);
683
684         if (_backend->stop ()) {
685                 return -1;
686         }
687         
688         _running = false;
689         _processed_frames = 0;
690         _measuring_latency = MeasureNone;
691         _latency_output_port = 0;
692         _latency_input_port = 0;
693         _started_for_latency = false;
694         stop_metering_thread ();
695         
696         Port::PortDrop ();
697
698         if (!for_latency) {
699                 Stopped (); /* EMIT SIGNAL */
700         }
701         
702         return 0;
703 }
704
705 int
706 AudioEngine::freewheel (bool start_stop)
707 {
708         if (!_backend) {
709                 return -1;
710         }
711
712         /* _freewheeling will be set when first Freewheel signal occurs */
713
714         return _backend->freewheel (start_stop);
715 }
716
717 float
718 AudioEngine::get_dsp_load() const 
719 {
720         if (!_backend) {
721                 return 0.0;
722         }
723         return _backend->dsp_load ();
724 }
725
726 bool
727 AudioEngine::is_realtime() const 
728 {
729         if (!_backend) {
730                 return false;
731         }
732
733         return _backend->is_realtime();
734 }
735
736 bool
737 AudioEngine::connected() const 
738 {
739         if (!_backend) {
740                 return false;
741         }
742
743         return _backend->available();
744 }
745
746 void
747 AudioEngine::transport_start ()
748 {
749         if (!_backend) {
750                 return;
751         }
752         return _backend->transport_start ();
753 }
754
755 void
756 AudioEngine::transport_stop ()
757 {
758         if (!_backend) {
759                 return;
760         }
761         return _backend->transport_stop ();
762 }
763
764 TransportState
765 AudioEngine::transport_state ()
766 {
767         if (!_backend) {
768                 return TransportStopped;
769         }
770         return _backend->transport_state ();
771 }
772
773 void
774 AudioEngine::transport_locate (framepos_t pos)
775 {
776         if (!_backend) {
777                 return;
778         }
779         return _backend->transport_locate (pos);
780 }
781
782 framepos_t
783 AudioEngine::transport_frame()
784 {
785         if (!_backend) {
786                 return 0;
787         }
788         return _backend->transport_frame ();
789 }
790
791 framecnt_t
792 AudioEngine::sample_rate () const
793 {
794         if (!_backend) {
795                 return 0;
796         }
797         return _backend->sample_rate ();
798 }
799
800 pframes_t
801 AudioEngine::samples_per_cycle () const
802 {
803         if (!_backend) {
804                 return 0;
805         }
806         return _backend->buffer_size ();
807 }
808
809 int
810 AudioEngine::usecs_per_cycle () const
811 {
812         if (!_backend) {
813                 return -1;
814         }
815         return _backend->usecs_per_cycle ();
816 }
817
818 size_t
819 AudioEngine::raw_buffer_size (DataType t)
820 {
821         if (!_backend) {
822                 return -1;
823         }
824         return _backend->raw_buffer_size (t);
825 }
826
827 pframes_t
828 AudioEngine::sample_time ()
829 {
830         if (!_backend) {
831                 return 0;
832         }
833         return _backend->sample_time ();
834 }
835
836 pframes_t
837 AudioEngine::sample_time_at_cycle_start ()
838 {
839         if (!_backend) {
840                 return 0;
841         }
842         return _backend->sample_time_at_cycle_start ();
843 }
844
845 pframes_t
846 AudioEngine::samples_since_cycle_start ()
847 {
848         if (!_backend) {
849                 return 0;
850         }
851         return _backend->samples_since_cycle_start ();
852 }
853
854 bool
855 AudioEngine::get_sync_offset (pframes_t& offset) const
856 {
857         if (!_backend) {
858                 return false;
859         }
860         return _backend->get_sync_offset (offset);
861 }
862
863 int
864 AudioEngine::create_process_thread (boost::function<void()> func)
865 {
866         if (!_backend) {
867                 return -1;
868         }
869         return _backend->create_process_thread (func);
870 }
871
872 int
873 AudioEngine::join_process_threads ()
874 {
875         if (!_backend) {
876                 return -1;
877         }
878         return _backend->join_process_threads ();
879 }
880
881 bool
882 AudioEngine::in_process_thread ()
883 {
884         if (!_backend) {
885                 return false;
886         }
887         return _backend->in_process_thread ();
888 }
889
890 uint32_t
891 AudioEngine::process_thread_count ()
892 {
893         if (!_backend) {
894                 return 0;
895         }
896         return _backend->process_thread_count ();
897 }
898
899 int
900 AudioEngine::set_device_name (const std::string& name)
901 {
902         if (!_backend) {
903                 return -1;
904         }
905         return _backend->set_device_name  (name);
906 }
907
908 int
909 AudioEngine::set_sample_rate (float sr)
910 {
911         if (!_backend) {
912                 return -1;
913         }
914         return _backend->set_sample_rate  (sr);
915 }
916
917 int
918 AudioEngine::set_buffer_size (uint32_t bufsiz)
919 {
920         if (!_backend) {
921                 return -1;
922         }
923         return _backend->set_buffer_size  (bufsiz);
924 }
925
926 int
927 AudioEngine::set_interleaved (bool yn)
928 {
929         if (!_backend) {
930                 return -1;
931         }
932         return _backend->set_interleaved  (yn);
933 }
934
935 int
936 AudioEngine::set_input_channels (uint32_t ic)
937 {
938         if (!_backend) {
939                 return -1;
940         }
941         return _backend->set_input_channels  (ic);
942 }
943
944 int
945 AudioEngine::set_output_channels (uint32_t oc)
946 {
947         if (!_backend) {
948                 return -1;
949         }
950         return _backend->set_output_channels (oc);
951 }
952
953 int
954 AudioEngine::set_systemic_input_latency (uint32_t il)
955 {
956         if (!_backend) {
957                 return -1;
958         }
959         return _backend->set_systemic_input_latency  (il);
960 }
961
962 int
963 AudioEngine::set_systemic_output_latency (uint32_t ol)
964 {
965         if (!_backend) {
966                 return -1;
967         }
968         return _backend->set_systemic_output_latency  (ol);
969 }
970
971 /* END OF BACKEND PROXY API */
972
973 void
974 AudioEngine::thread_init_callback (void* arg)
975 {
976         /* make sure that anybody who needs to know about this thread
977            knows about it.
978         */
979
980         pthread_set_name (X_("audioengine"));
981
982         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
983         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
984
985         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
986
987         AsyncMIDIPort::set_process_thread (pthread_self());
988
989         if (arg) {
990                 /* the special thread created/managed by the backend */
991                 AudioEngine::instance()->_main_thread = new ProcessThread;
992         }
993 }
994
995 int
996 AudioEngine::sync_callback (TransportState state, framepos_t position)
997 {
998         if (_session) {
999                 return _session->backend_sync_callback (state, position);
1000         }
1001         return 0;
1002 }
1003
1004 void
1005 AudioEngine::freewheel_callback (bool onoff)
1006 {
1007         _freewheeling = onoff;
1008 }
1009
1010 void
1011 AudioEngine::latency_callback (bool for_playback)
1012 {
1013         if (_session) {
1014                 _session->update_latency (for_playback);
1015         }
1016 }
1017
1018 void
1019 AudioEngine::update_latencies ()
1020 {
1021         if (_backend) {
1022                 _backend->update_latencies ();
1023         }
1024 }
1025
1026 void
1027 AudioEngine::halted_callback (const char* why)
1028 {
1029         if (_in_destructor) {
1030                 /* everything is under control */
1031                 return;
1032         }
1033
1034         stop_metering_thread ();
1035         _running = false;
1036
1037         Port::PortDrop (); /* EMIT SIGNAL */
1038
1039         if (!_started_for_latency) {
1040                 Halted (why);      /* EMIT SIGNAL */
1041         }
1042 }
1043
1044 bool
1045 AudioEngine::setup_required () const
1046 {
1047         if (_backend) {
1048                 if (_backend->info().already_configured())
1049                         return false;
1050         } else {
1051                 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1052                         return false;
1053                 }
1054         }
1055         
1056         return true;
1057 }
1058
1059 int
1060 AudioEngine::prepare_for_latency_measurement ()
1061 {
1062         if (running()) {
1063                 _stopped_for_latency = true;
1064                 stop (true);
1065         }
1066
1067         if (start (true)) {
1068                 _started_for_latency = true;
1069                 return -1;
1070         }
1071
1072         return 0;
1073 }
1074
1075 int
1076 AudioEngine::start_latency_detection (bool for_midi)
1077 {
1078         if (!running()) {
1079                 if (prepare_for_latency_measurement ()) {
1080                         return -1;
1081                 }
1082         }
1083
1084         PortEngine& pe (port_engine());
1085
1086         delete _mtdm;
1087         _mtdm = 0;
1088
1089         delete _mididm;
1090         _mididm = 0;
1091
1092         /* find the ports we will connect to */
1093
1094         PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1095         PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1096
1097         if (!out || !in) {
1098                 stop (true);
1099                 return -1;
1100         }
1101
1102         /* create the ports we will use to read/write data */
1103         if (for_midi) {
1104                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1105                         stop (true);
1106                         return -1;
1107                 }
1108                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1109                         pe.unregister_port (_latency_output_port);
1110                         stop (true);
1111                         return -1;
1112                 }
1113
1114                 const string portname ("latency_in");
1115                 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1116                         pe.unregister_port (_latency_input_port);
1117                         pe.unregister_port (_latency_output_port);
1118                         stop (true);
1119                         return -1;
1120                 }
1121                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1122                         pe.unregister_port (_latency_input_port);
1123                         pe.unregister_port (_latency_output_port);
1124                         stop (true);
1125                         return -1;
1126                 }
1127
1128                 _mididm = new MIDIDM (sample_rate());
1129
1130         } else {
1131
1132                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1133                         stop (true);
1134                         return -1;
1135                 }
1136                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1137                         pe.unregister_port (_latency_output_port);
1138                         stop (true);
1139                         return -1;
1140                 }
1141
1142                 const string portname ("latency_in");
1143                 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1144                         pe.unregister_port (_latency_input_port);
1145                         pe.unregister_port (_latency_output_port);
1146                         stop (true);
1147                         return -1;
1148                 }
1149                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1150                         pe.unregister_port (_latency_input_port);
1151                         pe.unregister_port (_latency_output_port);
1152                         stop (true);
1153                         return -1;
1154                 }
1155
1156                 _mtdm = new MTDM (sample_rate());
1157
1158         }
1159
1160         LatencyRange lr;
1161         _latency_signal_latency = 0;
1162         lr = pe.get_latency_range (in, false);
1163         _latency_signal_latency = lr.max;
1164         lr = pe.get_latency_range (out, true);
1165         _latency_signal_latency += lr.max;
1166
1167         /* all created and connected, lets go */
1168         _latency_flush_frames = samples_per_cycle();
1169         _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1170
1171         return 0;
1172 }
1173
1174 void
1175 AudioEngine::stop_latency_detection ()
1176 {
1177         _measuring_latency = MeasureNone;
1178
1179         if (_latency_output_port) {
1180                 port_engine().unregister_port (_latency_output_port);
1181                 _latency_output_port = 0;
1182         }
1183         if (_latency_input_port) {
1184                 port_engine().unregister_port (_latency_input_port);
1185                 _latency_input_port = 0;
1186         }
1187
1188         stop (true);
1189
1190         if (_stopped_for_latency) {
1191                 start ();
1192         }
1193
1194         _stopped_for_latency = false;
1195         _started_for_latency = false;
1196 }
1197
1198 void
1199 AudioEngine::set_latency_output_port (const string& name)
1200 {
1201         _latency_output_name = name;
1202 }
1203
1204 void
1205 AudioEngine::set_latency_input_port (const string& name)
1206 {
1207         _latency_input_name = name;
1208 }