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