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