substantive changes to allow the audio/MIDI setup dialog to change settings as intended
[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         AudioBackendInfo* (*dfunc)(void);
509         void* func = 0;
510
511         if (!module) {
512                 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
513                                         Glib::Module::get_last_error()) << endmsg;
514                 return 0;
515         }
516         
517         if (!module.get_symbol ("descriptor", func)) {
518                 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
519                 error << Glib::Module::get_last_error() << endmsg;
520                 return 0;
521         }
522
523         module.make_resident ();
524         
525         dfunc = (AudioBackendInfo* (*)(void))func;
526         info = dfunc();
527         
528         return info;
529 }
530
531 vector<const AudioBackendInfo*>
532 AudioEngine::available_backends() const
533 {
534         vector<const AudioBackendInfo*> r;
535         
536         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
537                 r.push_back (i->second);
538         }
539
540         return r;
541 }
542
543 string
544 AudioEngine::current_backend_name() const
545 {
546         if (_backend) {
547                 return _backend->name();
548         } 
549         return string();
550 }
551
552 void
553 AudioEngine::drop_backend ()
554 {
555         if (_backend) {
556                 _backend->stop ();
557                 _backend.reset ();
558         }
559 }
560
561 boost::shared_ptr<AudioBackend>
562 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
563 {
564         BackendMap::iterator b = _backends.find (name);
565
566         if (b == _backends.end()) {
567                 return boost::shared_ptr<AudioBackend>();
568         }
569
570         drop_backend ();
571         
572         try {
573                 if (b->second->instantiate (arg1, arg2)) {
574                         throw failed_constructor ();
575                 }
576
577                 _backend = b->second->factory (*this);
578
579         } catch (exception& e) {
580                 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
581                 return boost::shared_ptr<AudioBackend>();
582         }
583
584         return _backend;
585 }
586
587 /* BACKEND PROXY WRAPPERS */
588
589 int
590 AudioEngine::start ()
591 {
592         if (!_backend) {
593                 return -1;
594         }
595
596         if (_running) {
597                 return 0;
598         }
599
600         _processed_frames = 0;
601         last_monitor_check = 0;
602         
603         if (_backend->start()) {
604                 return -1;
605         }
606
607         _running = true;
608         
609         if (_session) {
610                 _session->set_frame_rate (_backend->sample_rate());
611                 
612                 if (_session->config.get_jack_time_master()) {
613                         _backend->set_time_master (true);
614                 }
615         }
616         
617         start_metering_thread ();
618         
619         if (!_started_for_latency) {
620                 Running(); /* EMIT SIGNAL */
621         }
622         
623         return 0;
624 }
625
626 int
627 AudioEngine::stop ()
628 {
629         if (!_backend) {
630                 return 0;
631         }
632
633         Glib::Threads::Mutex::Lock lm (_process_lock);
634
635         if (_backend->stop ()) {
636                 return -1;
637         }
638         
639         _running = false;
640         _processed_frames = 0;
641         _measuring_latency = false;
642         _latency_output_port = 0;
643         _latency_input_port = 0;
644         _started_for_latency = false;
645         stop_metering_thread ();
646         
647         Port::PortDrop ();
648         Stopped (); /* EMIT SIGNAL */
649         
650         return 0;
651 }
652
653 int
654 AudioEngine::pause ()
655 {
656         if (!_backend) {
657                 return 0;
658         }
659         
660         if (_backend->pause ()) {
661                 return -1;
662         }
663
664         _running = false;
665         
666         Stopped(); /* EMIT SIGNAL */
667         return 0;
668 }
669
670 int
671 AudioEngine::freewheel (bool start_stop)
672 {
673         if (!_backend) {
674                 return -1;
675         }
676
677         /* _freewheeling will be set when first Freewheel signal occurs */
678
679         return _backend->freewheel (start_stop);
680 }
681
682 float
683 AudioEngine::get_cpu_load() const 
684 {
685         if (!_backend) {
686                 return 0.0;
687         }
688         return _backend->cpu_load ();
689 }
690
691 bool
692 AudioEngine::is_realtime() const 
693 {
694         if (!_backend) {
695                 return false;
696         }
697
698         return _backend->is_realtime();
699 }
700
701 bool
702 AudioEngine::connected() const 
703 {
704         if (!_backend) {
705                 return false;
706         }
707
708         return _backend->available();
709 }
710
711 void
712 AudioEngine::transport_start ()
713 {
714         if (!_backend) {
715                 return;
716         }
717         return _backend->transport_start ();
718 }
719
720 void
721 AudioEngine::transport_stop ()
722 {
723         if (!_backend) {
724                 return;
725         }
726         return _backend->transport_stop ();
727 }
728
729 TransportState
730 AudioEngine::transport_state ()
731 {
732         if (!_backend) {
733                 return TransportStopped;
734         }
735         return _backend->transport_state ();
736 }
737
738 void
739 AudioEngine::transport_locate (framepos_t pos)
740 {
741         if (!_backend) {
742                 return;
743         }
744         return _backend->transport_locate (pos);
745 }
746
747 framepos_t
748 AudioEngine::transport_frame()
749 {
750         if (!_backend) {
751                 return 0;
752         }
753         return _backend->transport_frame ();
754 }
755
756 framecnt_t
757 AudioEngine::sample_rate () const
758 {
759         if (!_backend) {
760                 return 0;
761         }
762         return _backend->sample_rate ();
763 }
764
765 pframes_t
766 AudioEngine::samples_per_cycle () const
767 {
768         if (!_backend) {
769                 return 0;
770         }
771         return _backend->buffer_size ();
772 }
773
774 int
775 AudioEngine::usecs_per_cycle () const
776 {
777         if (!_backend) {
778                 return -1;
779         }
780         return _backend->usecs_per_cycle ();
781 }
782
783 size_t
784 AudioEngine::raw_buffer_size (DataType t)
785 {
786         if (!_backend) {
787                 return -1;
788         }
789         return _backend->raw_buffer_size (t);
790 }
791
792 pframes_t
793 AudioEngine::sample_time ()
794 {
795         if (!_backend) {
796                 return 0;
797         }
798         return _backend->sample_time ();
799 }
800
801 pframes_t
802 AudioEngine::sample_time_at_cycle_start ()
803 {
804         if (!_backend) {
805                 return 0;
806         }
807         return _backend->sample_time_at_cycle_start ();
808 }
809
810 pframes_t
811 AudioEngine::samples_since_cycle_start ()
812 {
813         if (!_backend) {
814                 return 0;
815         }
816         return _backend->samples_since_cycle_start ();
817 }
818
819 bool
820 AudioEngine::get_sync_offset (pframes_t& offset) const
821 {
822         if (!_backend) {
823                 return false;
824         }
825         return _backend->get_sync_offset (offset);
826 }
827
828 int
829 AudioEngine::create_process_thread (boost::function<void()> func, AudioBackendNativeThread* thr, size_t stacksize)
830 {
831         if (!_backend) {
832                 return -1;
833         }
834         return _backend->create_process_thread (func, thr, stacksize);
835 }
836
837 int
838 AudioEngine::wait_for_process_thread_exit (AudioBackendNativeThread thr)
839 {
840         if (!_backend) {
841                 return 0;
842         }
843         return _backend->wait_for_process_thread_exit (thr);
844 }
845
846 int
847 AudioEngine::set_device_name (const std::string& name)
848 {
849         if (!_backend) {
850                 return -1;
851         }
852         return _backend->set_device_name  (name);
853 }
854
855 int
856 AudioEngine::set_sample_rate (float sr)
857 {
858         if (!_backend) {
859                 return -1;
860         }
861         return _backend->set_sample_rate  (sr);
862 }
863
864 int
865 AudioEngine::set_buffer_size (uint32_t bufsiz)
866 {
867         if (!_backend) {
868                 return -1;
869         }
870         return _backend->set_buffer_size  (bufsiz);
871 }
872
873 int
874 AudioEngine::set_sample_format (SampleFormat sf)
875 {
876         if (!_backend) {
877                 return -1;
878         }
879         return _backend->set_sample_format  (sf);
880 }
881
882 int
883 AudioEngine::set_interleaved (bool yn)
884 {
885         if (!_backend) {
886                 return -1;
887         }
888         return _backend->set_interleaved  (yn);
889 }
890
891 int
892 AudioEngine::set_input_channels (uint32_t ic)
893 {
894         if (!_backend) {
895                 return -1;
896         }
897         return _backend->set_input_channels  (ic);
898 }
899
900 int
901 AudioEngine::set_output_channels (uint32_t oc)
902 {
903         if (!_backend) {
904                 return -1;
905         }
906         return _backend->set_output_channels (oc);
907 }
908
909 int
910 AudioEngine::set_systemic_input_latency (uint32_t il)
911 {
912         if (!_backend) {
913                 return -1;
914         }
915         return _backend->set_systemic_input_latency  (il);
916 }
917
918 int
919 AudioEngine::set_systemic_output_latency (uint32_t ol)
920 {
921         if (!_backend) {
922                 return -1;
923         }
924         return _backend->set_systemic_output_latency  (ol);
925 }
926
927 /* END OF BACKEND PROXY API */
928
929 void
930 AudioEngine::thread_init_callback (void* arg)
931 {
932         /* make sure that anybody who needs to know about this thread
933            knows about it.
934         */
935
936         pthread_set_name (X_("audioengine"));
937
938         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
939         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
940
941         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
942
943         AsyncMIDIPort::set_process_thread (pthread_self());
944
945         if (arg) {
946                 /* the special thread created/managed by the backend */
947                 AudioEngine::instance()->_main_thread = new ProcessThread;
948         }
949 }
950
951 int
952 AudioEngine::sync_callback (TransportState state, framepos_t position)
953 {
954         if (_session) {
955                 return _session->backend_sync_callback (state, position);
956         }
957         return 0;
958 }
959
960 void
961 AudioEngine::freewheel_callback (bool onoff)
962 {
963         _freewheeling = onoff;
964 }
965
966 void
967 AudioEngine::latency_callback (bool for_playback)
968 {
969         if (_session) {
970                 _session->update_latency (for_playback);
971         }
972 }
973
974 void
975 AudioEngine::update_latencies ()
976 {
977         if (_backend) {
978                 _backend->update_latencies ();
979         }
980 }
981
982 void
983 AudioEngine::halted_callback (const char* why)
984 {
985         stop_metering_thread ();
986         _running = false;
987
988         Port::PortDrop (); /* EMIT SIGNAL */
989         Halted (why);      /* EMIT SIGNAL */
990 }
991
992 bool
993 AudioEngine::setup_required () const
994 {
995         /* If there is only a single backend and it claims to be configured
996          * already there is no setup to be done.
997          *
998          * Primarily for a case where there is only a JACK backend and
999          * JACK is already running.
1000          */
1001          
1002         if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1003                 return false;
1004         }
1005
1006         return true;
1007 }
1008
1009 MTDM*
1010 AudioEngine::mtdm() 
1011 {
1012         return _mtdm;
1013 }
1014
1015 int
1016 AudioEngine::prepare_for_latency_measurement ()
1017 {
1018         if (!running()) {
1019                 _started_for_latency = true;
1020
1021                 if (start()) {
1022                         _started_for_latency = false;
1023                         return -1;
1024                 }
1025         }
1026
1027         return 0;
1028 }
1029
1030 void
1031 AudioEngine::start_latency_detection ()
1032 {
1033         if (prepare_for_latency_measurement ()) {
1034                 return;
1035         }
1036
1037         PortEngine& pe (port_engine());
1038
1039         delete _mtdm;
1040         _mtdm = 0;
1041
1042         /* find the ports we will connect to */
1043
1044         PortEngine::PortHandle* out = pe.get_port_by_name (_latency_output_name);
1045         PortEngine::PortHandle* in = pe.get_port_by_name (_latency_input_name);
1046
1047         if (!out || !in) {
1048                 return;
1049         }
1050
1051         /* create the ports we will use to read/write data */
1052         
1053         if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1054                 return;
1055         }
1056         if (pe.connect (_latency_output_port, _latency_output_name)) {
1057                 pe.unregister_port (_latency_output_port);
1058                 return;
1059         }
1060
1061         const string portname ("latency_in");
1062         if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1063                 pe.unregister_port (_latency_output_port);
1064                 return;
1065         }
1066         if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1067                 pe.unregister_port (_latency_output_port);
1068                 return;
1069         }
1070
1071         LatencyRange lr;
1072         _latency_signal_latency = 0;
1073         lr = pe.get_latency_range (in, false);
1074         _latency_signal_latency = lr.max;
1075         lr = pe.get_latency_range (out, true);
1076         _latency_signal_latency += lr.max;
1077
1078         /* all created and connected, lets go */
1079
1080         _mtdm = new MTDM (sample_rate());
1081         _measuring_latency = true;
1082         _latency_flush_frames = samples_per_cycle();
1083
1084 }
1085
1086 void
1087 AudioEngine::stop_latency_detection ()
1088 {
1089         _measuring_latency = false;
1090
1091         if (_latency_output_port) {
1092                 port_engine().unregister_port (_latency_output_port);
1093                 _latency_output_port = 0;
1094         }
1095         if (_latency_input_port) {
1096                 port_engine().unregister_port (_latency_input_port);
1097                 _latency_input_port = 0;
1098         }
1099         if (_started_for_latency) {
1100                 stop ();
1101         }
1102 }
1103
1104 void
1105 AudioEngine::set_latency_output_port (const string& name)
1106 {
1107         _latency_output_name = name;
1108 }
1109
1110 void
1111 AudioEngine::set_latency_input_port (const string& name)
1112 {
1113         _latency_input_name = name;
1114 }