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