Merge branch 'master' into windows
[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/backend_search_path.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/mtdm.h"
52 #include "ardour/port.h"
53 #include "ardour/process_thread.h"
54 #include "ardour/session.h"
55
56 #include "i18n.h"
57
58 using namespace std;
59 using namespace ARDOUR;
60 using namespace PBD;
61
62 gint AudioEngine::m_meter_exit;
63 AudioEngine* AudioEngine::_instance = 0;
64
65 AudioEngine::AudioEngine ()
66         : session_remove_pending (false)
67         , session_removal_countdown (-1)
68         , _running (false)
69         , _freewheeling (false)
70         , monitor_check_interval (INT32_MAX)
71         , last_monitor_check (0)
72         , _processed_frames (0)
73         , m_meter_thread (0)
74         , _main_thread (0)
75         , _mtdm (0)
76         , _measuring_latency (false)
77         , _latency_input_port (0)
78         , _latency_output_port (0)
79         , _latency_flush_frames (0)
80         , _latency_signal_latency (0)
81         , _started_for_latency (false)
82 {
83         g_atomic_int_set (&m_meter_exit, 0);
84         discover_backends ();
85 }
86
87 AudioEngine::~AudioEngine ()
88 {
89         drop_backend ();
90
91         config_connection.disconnect ();
92
93         {
94                 Glib::Threads::Mutex::Lock tm (_process_lock);
95                 session_removed.signal ();
96                 stop_metering_thread ();
97         }
98 }
99
100 AudioEngine*
101 AudioEngine::create ()
102 {
103         if (_instance) {
104                 return _instance;
105         }
106
107         _instance = new AudioEngine ();
108         
109         return _instance;
110 }
111
112 void
113 _thread_init_callback (void * /*arg*/)
114 {
115         /* make sure that anybody who needs to know about this thread
116            knows about it.
117         */
118
119         pthread_set_name (X_("audioengine"));
120
121         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
122         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
123
124         SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
125
126         AsyncMIDIPort::set_process_thread (pthread_self());
127 }
128
129 void
130 AudioEngine::split_cycle (pframes_t offset)
131 {
132         /* caller must hold process lock */
133
134         Port::increment_global_port_buffer_offset (offset);
135
136         /* tell all Ports that we're going to start a new (split) cycle */
137
138         boost::shared_ptr<Ports> p = ports.reader();
139
140         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
141                 i->second->cycle_split ();
142         }
143 }
144
145 int
146 AudioEngine::sample_rate_change (pframes_t nframes)
147 {
148         /* check for monitor input change every 1/10th of second */
149
150         monitor_check_interval = nframes / 10;
151         last_monitor_check = 0;
152
153         if (_session) {
154                 _session->set_frame_rate (nframes);
155         }
156
157         SampleRateChanged (nframes); /* EMIT SIGNAL */
158
159         return 0;
160 }
161
162 int 
163 AudioEngine::buffer_size_change (pframes_t bufsiz)
164 {
165         if (_session) {
166                 _session->set_block_size (bufsiz);
167                 last_monitor_check = 0;
168         }
169
170         return 0;
171 }
172
173 /** Method called by our ::process_thread when there is work to be done.
174  *  @param nframes Number of frames to process.
175  */
176 int
177 AudioEngine::process_callback (pframes_t nframes)
178 {
179         Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
180
181         PT_TIMING_REF;
182         PT_TIMING_CHECK (1);
183
184         /// The number of frames that will have been processed when we've finished
185         pframes_t next_processed_frames;
186
187         /* handle wrap around of total frames counter */
188
189         if (max_framepos - _processed_frames < nframes) {
190                 next_processed_frames = nframes - (max_framepos - _processed_frames);
191         } else {
192                 next_processed_frames = _processed_frames + nframes;
193         }
194
195         if (!tm.locked()) {
196                 /* return having done nothing */
197                 _processed_frames = next_processed_frames;
198                 return 0;
199         }
200
201         bool return_after_remove_check = false;
202
203         if (_measuring_latency && _mtdm) {
204                 /* run a normal cycle from the perspective of the PortManager
205                    so that we get silence on all registered ports.
206                    
207                    we overwrite the silence on the two ports used for latency
208                    measurement.
209                 */
210                 
211                 PortManager::cycle_start (nframes);
212                 PortManager::silence (nframes);
213
214                 if (_latency_input_port && _latency_output_port) {
215                         PortEngine& pe (port_engine());
216
217                         Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
218                         Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
219
220                         _mtdm->process (nframes, in, out);
221                 }
222
223                 PortManager::cycle_end (nframes);
224                 return_after_remove_check = true;
225
226         } else if (_latency_flush_frames) {
227                 
228                 /* wait for the appropriate duration for the MTDM signal to
229                  * drain from the ports before we revert to normal behaviour.
230                  */
231
232                 PortManager::cycle_start (nframes);
233                 PortManager::silence (nframes);
234                 PortManager::cycle_end (nframes);
235                 
236                 if (_latency_flush_frames > nframes) {
237                         _latency_flush_frames -= nframes;
238                 } else {
239                         _latency_flush_frames = 0;
240                 }
241
242                 return_after_remove_check = true;
243         }
244
245         if (session_remove_pending) {
246
247                 /* perform the actual session removal */
248
249                 if (session_removal_countdown < 0) {
250
251                         /* fade out over 1 second */
252                         session_removal_countdown = sample_rate()/2;
253                         session_removal_gain = 1.0;
254                         session_removal_gain_step = 1.0/session_removal_countdown;
255
256                 } else if (session_removal_countdown > 0) {
257
258                         /* we'll be fading audio out.
259                            
260                            if this is the last time we do this as part 
261                            of session removal, do a MIDI panic now
262                            to get MIDI stopped. This relies on the fact
263                            that "immediate data" (aka "out of band data") from
264                            MIDI tracks is *appended* after any other data, 
265                            so that it emerges after any outbound note ons, etc.
266                         */
267
268                         if (session_removal_countdown <= nframes) {
269                                 _session->midi_panic ();
270                         }
271
272                 } else {
273                         /* fade out done */
274                         _session = 0;
275                         session_removal_countdown = -1; // reset to "not in progress"
276                         session_remove_pending = false;
277                         session_removed.signal(); // wakes up thread that initiated session removal
278                 }
279         }
280
281         if (return_after_remove_check) {
282                 return 0;
283         }
284
285         if (_session == 0) {
286
287                 if (!_freewheeling) {
288                         PortManager::cycle_start (nframes);
289                         PortManager::cycle_end (nframes);
290                 }
291
292                 _processed_frames = next_processed_frames;
293
294                 return 0;
295         }
296
297         /* tell all relevant objects that we're starting a new cycle */
298
299         InternalSend::CycleStart (nframes);
300
301         /* tell all Ports that we're starting a new cycle */
302
303         PortManager::cycle_start (nframes);
304
305         /* test if we are freewheeling and there are freewheel signals connected.
306            ardour should act normally even when freewheeling unless /it/ is
307            exporting (which is what Freewheel.empty() tests for).
308         */
309
310         if (_freewheeling && !Freewheel.empty()) {
311                 Freewheel (nframes);
312         } else {
313                 if (_session) {
314                         _session->process (nframes);
315                 }
316         }
317
318         if (_freewheeling) {
319                 return 0;
320         }
321
322         if (!_running) {
323                 _processed_frames = next_processed_frames;
324                 return 0;
325         }
326
327         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
328                 
329                 PortManager::check_monitoring ();
330                 last_monitor_check = next_processed_frames;
331         }
332
333         if (_session->silent()) {
334                 PortManager::silence (nframes);
335         }
336
337         if (session_remove_pending && session_removal_countdown) {
338
339                 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
340                 
341                 if (session_removal_countdown > nframes) {
342                         session_removal_countdown -= nframes;
343                 } else {
344                         session_removal_countdown = 0;
345                 }
346
347                 session_removal_gain -= (nframes * session_removal_gain_step);
348         }
349
350         PortManager::cycle_end (nframes);
351
352         _processed_frames = next_processed_frames;
353
354         PT_TIMING_CHECK (2);
355         
356         return 0;
357 }
358
359
360 void
361 AudioEngine::stop_metering_thread ()
362 {
363         if (m_meter_thread) {
364                 g_atomic_int_set (&m_meter_exit, 1);
365                 m_meter_thread->join ();
366                 m_meter_thread = 0;
367         }
368 }
369
370 void
371 AudioEngine::start_metering_thread ()
372 {
373         if (m_meter_thread == 0) {
374                 g_atomic_int_set (&m_meter_exit, 0);
375                 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
376         }
377 }
378
379 void
380 AudioEngine::meter_thread ()
381 {
382         pthread_set_name (X_("meter"));
383
384         while (true) {
385                 Glib::usleep (10000); /* 1/100th sec interval */
386                 if (g_atomic_int_get(&m_meter_exit)) {
387                         break;
388                 }
389                 Metering::Meter ();
390         }
391 }
392
393 void
394 AudioEngine::set_session (Session *s)
395 {
396         Glib::Threads::Mutex::Lock pl (_process_lock);
397
398         SessionHandlePtr::set_session (s);
399
400         if (_session) {
401
402                 pframes_t blocksize = samples_per_cycle ();
403
404                 PortManager::cycle_start (blocksize);
405
406                 _session->process (blocksize);
407                 _session->process (blocksize);
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
415                 PortManager::cycle_end (blocksize);
416         }
417 }
418
419 void
420 AudioEngine::remove_session ()
421 {
422         Glib::Threads::Mutex::Lock lm (_process_lock);
423
424         if (_running) {
425
426                 if (_session) {
427                         session_remove_pending = true;
428                         session_removal_countdown = 0;
429                         session_removed.wait(_process_lock);
430                 }
431
432         } else {
433                 SessionHandlePtr::set_session (0);
434         }
435
436         remove_all_ports ();
437 }
438
439
440 void
441 AudioEngine::died ()
442 {
443         /* called from a signal handler for SIGPIPE */
444
445         stop_metering_thread ();
446
447         _running = false;
448 }
449
450 int
451 AudioEngine::reset_timebase ()
452 {
453         if (_session) {
454                 if (_session->config.get_jack_time_master()) {
455                         _backend->set_time_master (true);
456                 } else {
457                         _backend->set_time_master (false);
458                 }
459         }
460         return 0;
461 }
462
463
464 void
465 AudioEngine::destroy ()
466 {
467         delete _instance;
468         _instance = 0;
469 }
470
471 int
472 AudioEngine::discover_backends ()
473 {
474         vector<std::string> backend_modules;
475
476         _backends.clear ();
477
478         Glib::PatternSpec so_extension_pattern("*backend.so");
479         Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
480
481         find_matching_files_in_search_path (backend_search_path (),
482                                             so_extension_pattern, backend_modules);
483
484         find_matching_files_in_search_path (backend_search_path (),
485                                             dylib_extension_pattern, backend_modules);
486
487         DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
488
489         for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
490
491                 AudioBackendInfo* info;
492
493                 if ((info = backend_discover (*i)) != 0) {
494                         _backends.insert (make_pair (info->name, info));
495                 }
496         }
497
498         return _backends.size();
499 }
500
501 AudioBackendInfo*
502 AudioEngine::backend_discover (const string& path)
503 {
504         Glib::Module module (path);
505         AudioBackendInfo* info;
506         AudioBackendInfo* (*dfunc)(void);
507         void* func = 0;
508
509         if (!module) {
510                 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
511                                         Glib::Module::get_last_error()) << endmsg;
512                 return 0;
513         }
514         
515         if (!module.get_symbol ("descriptor", func)) {
516                 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
517                 error << Glib::Module::get_last_error() << endmsg;
518                 return 0;
519         }
520
521         module.make_resident ();
522         
523         dfunc = (AudioBackendInfo* (*)(void))func;
524         info = dfunc();
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         /* find the ports we will connect to */
1041
1042         PortEngine::PortHandle* out = pe.get_port_by_name (_latency_output_name);
1043         PortEngine::PortHandle* in = pe.get_port_by_name (_latency_input_name);
1044
1045         if (!out || !in) {
1046                 return;
1047         }
1048
1049         /* create the ports we will use to read/write data */
1050         
1051         if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1052                 return;
1053         }
1054         if (pe.connect (_latency_output_port, _latency_output_name)) {
1055                 pe.unregister_port (_latency_output_port);
1056                 return;
1057         }
1058
1059         const string portname ("latency_in");
1060         if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1061                 pe.unregister_port (_latency_output_port);
1062                 return;
1063         }
1064         if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1065                 pe.unregister_port (_latency_output_port);
1066                 return;
1067         }
1068
1069         LatencyRange lr;
1070         _latency_signal_latency = 0;
1071         lr = pe.get_latency_range (in, false);
1072         _latency_signal_latency = lr.max;
1073         lr = pe.get_latency_range (out, true);
1074         _latency_signal_latency += lr.max;
1075
1076         /* all created and connected, lets go */
1077
1078         _mtdm = new MTDM (sample_rate());
1079         _measuring_latency = true;
1080         _latency_flush_frames = samples_per_cycle();
1081
1082 }
1083
1084 void
1085 AudioEngine::stop_latency_detection ()
1086 {
1087         _measuring_latency = false;
1088
1089         if (_latency_output_port) {
1090                 port_engine().unregister_port (_latency_output_port);
1091                 _latency_output_port = 0;
1092         }
1093         if (_latency_input_port) {
1094                 port_engine().unregister_port (_latency_input_port);
1095                 _latency_input_port = 0;
1096         }
1097         if (_started_for_latency) {
1098                 stop ();
1099         }
1100 }
1101
1102 void
1103 AudioEngine::set_latency_output_port (const string& name)
1104 {
1105         _latency_output_name = name;
1106 }
1107
1108 void
1109 AudioEngine::set_latency_input_port (const string& name)
1110 {
1111         _latency_input_name = name;
1112 }