adapt AudioEngine to new AudioBackend API
[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::pause ()
667 {
668         if (!_backend) {
669                 return 0;
670         }
671         
672         if (_backend->pause ()) {
673                 return -1;
674         }
675
676         _running = false;
677         
678         Stopped(); /* EMIT SIGNAL */
679         return 0;
680 }
681
682 int
683 AudioEngine::freewheel (bool start_stop)
684 {
685         if (!_backend) {
686                 return -1;
687         }
688
689         /* _freewheeling will be set when first Freewheel signal occurs */
690
691         return _backend->freewheel (start_stop);
692 }
693
694 float
695 AudioEngine::get_cpu_load() const 
696 {
697         if (!_backend) {
698                 return 0.0;
699         }
700         return _backend->cpu_load ();
701 }
702
703 bool
704 AudioEngine::is_realtime() const 
705 {
706         if (!_backend) {
707                 return false;
708         }
709
710         return _backend->is_realtime();
711 }
712
713 bool
714 AudioEngine::connected() const 
715 {
716         if (!_backend) {
717                 return false;
718         }
719
720         return _backend->available();
721 }
722
723 void
724 AudioEngine::transport_start ()
725 {
726         if (!_backend) {
727                 return;
728         }
729         return _backend->transport_start ();
730 }
731
732 void
733 AudioEngine::transport_stop ()
734 {
735         if (!_backend) {
736                 return;
737         }
738         return _backend->transport_stop ();
739 }
740
741 TransportState
742 AudioEngine::transport_state ()
743 {
744         if (!_backend) {
745                 return TransportStopped;
746         }
747         return _backend->transport_state ();
748 }
749
750 void
751 AudioEngine::transport_locate (framepos_t pos)
752 {
753         if (!_backend) {
754                 return;
755         }
756         return _backend->transport_locate (pos);
757 }
758
759 framepos_t
760 AudioEngine::transport_frame()
761 {
762         if (!_backend) {
763                 return 0;
764         }
765         return _backend->transport_frame ();
766 }
767
768 framecnt_t
769 AudioEngine::sample_rate () const
770 {
771         if (!_backend) {
772                 return 0;
773         }
774         return _backend->sample_rate ();
775 }
776
777 pframes_t
778 AudioEngine::samples_per_cycle () const
779 {
780         if (!_backend) {
781                 return 0;
782         }
783         return _backend->buffer_size ();
784 }
785
786 int
787 AudioEngine::usecs_per_cycle () const
788 {
789         if (!_backend) {
790                 return -1;
791         }
792         return _backend->usecs_per_cycle ();
793 }
794
795 size_t
796 AudioEngine::raw_buffer_size (DataType t)
797 {
798         if (!_backend) {
799                 return -1;
800         }
801         return _backend->raw_buffer_size (t);
802 }
803
804 pframes_t
805 AudioEngine::sample_time ()
806 {
807         if (!_backend) {
808                 return 0;
809         }
810         return _backend->sample_time ();
811 }
812
813 pframes_t
814 AudioEngine::sample_time_at_cycle_start ()
815 {
816         if (!_backend) {
817                 return 0;
818         }
819         return _backend->sample_time_at_cycle_start ();
820 }
821
822 pframes_t
823 AudioEngine::samples_since_cycle_start ()
824 {
825         if (!_backend) {
826                 return 0;
827         }
828         return _backend->samples_since_cycle_start ();
829 }
830
831 bool
832 AudioEngine::get_sync_offset (pframes_t& offset) const
833 {
834         if (!_backend) {
835                 return false;
836         }
837         return _backend->get_sync_offset (offset);
838 }
839
840 int
841 AudioEngine::create_process_thread (boost::function<void()> func)
842 {
843         if (!_backend) {
844                 return -1;
845         }
846         return _backend->create_process_thread (func);
847 }
848
849 int
850 AudioEngine::join_process_threads ()
851 {
852         if (!_backend) {
853                 return -1;
854         }
855         return _backend->join_process_threads ();
856 }
857
858 bool
859 AudioEngine::in_process_thread ()
860 {
861         if (!_backend) {
862                 return false;
863         }
864         return _backend->in_process_thread ();
865 }
866
867 uint32_t
868 AudioEngine::process_thread_count ()
869 {
870         if (!_backend) {
871                 return 0;
872         }
873         return _backend->process_thread_count ();
874 }
875
876 int
877 AudioEngine::set_device_name (const std::string& name)
878 {
879         if (!_backend) {
880                 return -1;
881         }
882         return _backend->set_device_name  (name);
883 }
884
885 int
886 AudioEngine::set_sample_rate (float sr)
887 {
888         if (!_backend) {
889                 return -1;
890         }
891         return _backend->set_sample_rate  (sr);
892 }
893
894 int
895 AudioEngine::set_buffer_size (uint32_t bufsiz)
896 {
897         if (!_backend) {
898                 return -1;
899         }
900         return _backend->set_buffer_size  (bufsiz);
901 }
902
903 int
904 AudioEngine::set_sample_format (SampleFormat sf)
905 {
906         if (!_backend) {
907                 return -1;
908         }
909         return _backend->set_sample_format  (sf);
910 }
911
912 int
913 AudioEngine::set_interleaved (bool yn)
914 {
915         if (!_backend) {
916                 return -1;
917         }
918         return _backend->set_interleaved  (yn);
919 }
920
921 int
922 AudioEngine::set_input_channels (uint32_t ic)
923 {
924         if (!_backend) {
925                 return -1;
926         }
927         return _backend->set_input_channels  (ic);
928 }
929
930 int
931 AudioEngine::set_output_channels (uint32_t oc)
932 {
933         if (!_backend) {
934                 return -1;
935         }
936         return _backend->set_output_channels (oc);
937 }
938
939 int
940 AudioEngine::set_systemic_input_latency (uint32_t il)
941 {
942         if (!_backend) {
943                 return -1;
944         }
945         return _backend->set_systemic_input_latency  (il);
946 }
947
948 int
949 AudioEngine::set_systemic_output_latency (uint32_t ol)
950 {
951         if (!_backend) {
952                 return -1;
953         }
954         return _backend->set_systemic_output_latency  (ol);
955 }
956
957 /* END OF BACKEND PROXY API */
958
959 void
960 AudioEngine::thread_init_callback (void* arg)
961 {
962         /* make sure that anybody who needs to know about this thread
963            knows about it.
964         */
965
966         pthread_set_name (X_("audioengine"));
967
968         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
969         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
970
971         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
972
973         AsyncMIDIPort::set_process_thread (pthread_self());
974
975         if (arg) {
976                 /* the special thread created/managed by the backend */
977                 AudioEngine::instance()->_main_thread = new ProcessThread;
978         }
979 }
980
981 int
982 AudioEngine::sync_callback (TransportState state, framepos_t position)
983 {
984         if (_session) {
985                 return _session->backend_sync_callback (state, position);
986         }
987         return 0;
988 }
989
990 void
991 AudioEngine::freewheel_callback (bool onoff)
992 {
993         _freewheeling = onoff;
994 }
995
996 void
997 AudioEngine::latency_callback (bool for_playback)
998 {
999         if (_session) {
1000                 _session->update_latency (for_playback);
1001         }
1002 }
1003
1004 void
1005 AudioEngine::update_latencies ()
1006 {
1007         if (_backend) {
1008                 _backend->update_latencies ();
1009         }
1010 }
1011
1012 void
1013 AudioEngine::halted_callback (const char* why)
1014 {
1015         if (_in_destructor) {
1016                 /* everything is under control */
1017                 return;
1018         }
1019
1020         stop_metering_thread ();
1021         _running = false;
1022
1023         Port::PortDrop (); /* EMIT SIGNAL */
1024
1025         if (!_started_for_latency) {
1026                 Halted (why);      /* EMIT SIGNAL */
1027         }
1028 }
1029
1030 bool
1031 AudioEngine::setup_required () const
1032 {
1033         /* If there is only a single backend and it claims to be configured
1034          * already there is no setup to be done.
1035          *
1036          * Primarily for a case where there is only a JACK backend and
1037          * JACK is already running.
1038          */
1039          
1040         if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1041                 return false;
1042         }
1043
1044         return true;
1045 }
1046
1047 MTDM*
1048 AudioEngine::mtdm() 
1049 {
1050         return _mtdm;
1051 }
1052
1053 int
1054 AudioEngine::prepare_for_latency_measurement ()
1055 {
1056         if (running()) {
1057                 _stopped_for_latency = true;
1058                 stop (true);
1059         }
1060
1061         if (start (true)) {
1062                 _started_for_latency = true;
1063                 return -1;
1064         }
1065
1066         return 0;
1067 }
1068
1069 int
1070 AudioEngine::start_latency_detection ()
1071 {
1072         if (!running()) {
1073                 if (prepare_for_latency_measurement ()) {
1074                         return -1;
1075                 }
1076         }
1077
1078         PortEngine& pe (port_engine());
1079
1080         delete _mtdm;
1081         _mtdm = 0;
1082
1083         /* find the ports we will connect to */
1084
1085         PortEngine::PortHandle* out = pe.get_port_by_name (_latency_output_name);
1086         PortEngine::PortHandle* in = pe.get_port_by_name (_latency_input_name);
1087
1088         if (!out || !in) {
1089                 stop (true);
1090                 return -1;
1091         }
1092
1093         /* create the ports we will use to read/write data */
1094         
1095         if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1096                 stop (true);
1097                 return -1;
1098         }
1099         if (pe.connect (_latency_output_port, _latency_output_name)) {
1100                 pe.unregister_port (_latency_output_port);
1101                 stop (true);
1102                 return -1;
1103         }
1104
1105         const string portname ("latency_in");
1106         if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1107                 pe.unregister_port (_latency_output_port);
1108                 stop (true);
1109                 return -1;
1110         }
1111         if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1112                 pe.unregister_port (_latency_output_port);
1113                 stop (true);
1114                 return -1;
1115         }
1116
1117         LatencyRange lr;
1118         _latency_signal_latency = 0;
1119         lr = pe.get_latency_range (in, false);
1120         _latency_signal_latency = lr.max;
1121         lr = pe.get_latency_range (out, true);
1122         _latency_signal_latency += lr.max;
1123
1124         /* all created and connected, lets go */
1125
1126         _mtdm = new MTDM (sample_rate());
1127         _measuring_latency = true;
1128         _latency_flush_frames = samples_per_cycle();
1129
1130         return 0;
1131 }
1132
1133 void
1134 AudioEngine::stop_latency_detection ()
1135 {
1136         _measuring_latency = false;
1137
1138         if (_latency_output_port) {
1139                 port_engine().unregister_port (_latency_output_port);
1140                 _latency_output_port = 0;
1141         }
1142         if (_latency_input_port) {
1143                 port_engine().unregister_port (_latency_input_port);
1144                 _latency_input_port = 0;
1145         }
1146
1147         stop (true);
1148
1149         if (_stopped_for_latency) {
1150                 start ();
1151         }
1152
1153         _stopped_for_latency = false;
1154         _started_for_latency = false;
1155 }
1156
1157 void
1158 AudioEngine::set_latency_output_port (const string& name)
1159 {
1160         _latency_output_name = name;
1161 }
1162
1163 void
1164 AudioEngine::set_latency_input_port (const string& name)
1165 {
1166         _latency_input_name = name;
1167 }