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