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