fix --disable-plugins (bypass ‘em all)
[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/mididm.h"
52 #include "ardour/mtdm.h"
53 #include "ardour/port.h"
54 #include "ardour/process_thread.h"
55 #include "ardour/session.h"
56
57 #include "i18n.h"
58
59 using namespace std;
60 using namespace ARDOUR;
61 using namespace PBD;
62
63 gint AudioEngine::m_meter_exit;
64 AudioEngine* AudioEngine::_instance = 0;
65
66 AudioEngine::AudioEngine ()
67         : session_remove_pending (false)
68         , session_removal_countdown (-1)
69         , _running (false)
70         , _freewheeling (false)
71         , monitor_check_interval (INT32_MAX)
72         , last_monitor_check (0)
73         , _processed_frames (0)
74         , m_meter_thread (0)
75         , _main_thread (0)
76         , _mtdm (0)
77         , _mididm (0)
78         , _measuring_latency (MeasureNone)
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         , _started_for_latency (false)
85         , _in_destructor (false)
86     , _hw_reset_event_thread(0)
87     , _hw_reset_request_count(0)
88     , _stop_hw_reset_processing(0)
89     , _hw_devicelist_update_thread(0)
90     , _hw_devicelist_update_count(0)
91     , _stop_hw_devicelist_processing(0)
92 {
93         g_atomic_int_set (&m_meter_exit, 0);
94     start_hw_event_processing();
95         discover_backends ();
96 }
97
98 AudioEngine::~AudioEngine ()
99 {
100         _in_destructor = true;
101         stop_metering_thread ();
102         stop_hw_event_processing();
103         drop_backend ();
104         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
105                 i->second->deinstantiate();
106         }
107 }
108
109 AudioEngine*
110 AudioEngine::create ()
111 {
112         if (_instance) {
113                 return _instance;
114         }
115
116         _instance = new AudioEngine ();
117         
118         return _instance;
119 }
120
121 void
122 AudioEngine::split_cycle (pframes_t offset)
123 {
124         /* caller must hold process lock */
125
126         Port::increment_global_port_buffer_offset (offset);
127
128         /* tell all Ports that we're going to start a new (split) cycle */
129
130         boost::shared_ptr<Ports> p = ports.reader();
131
132         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
133                 i->second->cycle_split ();
134         }
135 }
136
137 int
138 AudioEngine::sample_rate_change (pframes_t nframes)
139 {
140         /* check for monitor input change every 1/10th of second */
141
142         monitor_check_interval = nframes / 10;
143         last_monitor_check = 0;
144
145         if (_session) {
146                 _session->set_frame_rate (nframes);
147         }
148
149         SampleRateChanged (nframes); /* EMIT SIGNAL */
150
151         return 0;
152 }
153
154 int 
155 AudioEngine::buffer_size_change (pframes_t bufsiz)
156 {
157         if (_session) {
158                 _session->set_block_size (bufsiz);
159                 last_monitor_check = 0;
160         }
161
162         BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
163
164         return 0;
165 }
166
167 /** Method called by our ::process_thread when there is work to be done.
168  *  @param nframes Number of frames to process.
169  */
170 #ifdef __clang__
171 __attribute__((annotate("realtime")))
172 #endif
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 == MeasureAudio && _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 (_measuring_latency == MeasureMIDI && _mididm) {
224                 /* run a normal cycle from the perspective of the PortManager
225                    so that we get silence on all registered ports.
226
227                    we overwrite the silence on the two ports used for latency
228                    measurement.
229                 */
230
231                 PortManager::cycle_start (nframes);
232                 PortManager::silence (nframes);
233
234                 if (_latency_input_port && _latency_output_port) {
235                         PortEngine& pe (port_engine());
236
237                         _mididm->process (nframes, pe,
238                                         pe.get_buffer (_latency_input_port, nframes),
239                                         pe.get_buffer (_latency_output_port, nframes));
240                 }
241
242                 PortManager::cycle_end (nframes);
243                 return_after_remove_check = true;
244
245         } else if (_latency_flush_frames) {
246                 
247                 /* wait for the appropriate duration for the MTDM signal to
248                  * drain from the ports before we revert to normal behaviour.
249                  */
250
251                 PortManager::cycle_start (nframes);
252                 PortManager::silence (nframes);
253                 PortManager::cycle_end (nframes);
254                 
255                 if (_latency_flush_frames > nframes) {
256                         _latency_flush_frames -= nframes;
257                 } else {
258                         _latency_flush_frames = 0;
259                 }
260
261                 return_after_remove_check = true;
262         }
263
264         if (session_remove_pending) {
265
266                 /* perform the actual session removal */
267
268                 if (session_removal_countdown < 0) {
269
270                         /* fade out over 1 second */
271                         session_removal_countdown = sample_rate()/2;
272                         session_removal_gain = 1.0;
273                         session_removal_gain_step = 1.0/session_removal_countdown;
274
275                 } else if (session_removal_countdown > 0) {
276
277                         /* we'll be fading audio out.
278                            
279                            if this is the last time we do this as part 
280                            of session removal, do a MIDI panic now
281                            to get MIDI stopped. This relies on the fact
282                            that "immediate data" (aka "out of band data") from
283                            MIDI tracks is *appended* after any other data, 
284                            so that it emerges after any outbound note ons, etc.
285                         */
286
287                         if (session_removal_countdown <= nframes) {
288                                 _session->midi_panic ();
289                         }
290
291                 } else {
292                         /* fade out done */
293                         _session = 0;
294                         session_removal_countdown = -1; // reset to "not in progress"
295                         session_remove_pending = false;
296                         session_removed.signal(); // wakes up thread that initiated session removal
297                 }
298         }
299
300         if (return_after_remove_check) {
301                 return 0;
302         }
303
304         if (_session == 0) {
305
306                 if (!_freewheeling) {
307                         PortManager::cycle_start (nframes);
308                         PortManager::cycle_end (nframes);
309                 }
310
311                 _processed_frames = next_processed_frames;
312
313                 return 0;
314         }
315
316         /* tell all relevant objects that we're starting a new cycle */
317
318         InternalSend::CycleStart (nframes);
319
320         /* tell all Ports that we're starting a new cycle */
321
322         PortManager::cycle_start (nframes);
323
324         /* test if we are freewheeling and there are freewheel signals connected.
325            ardour should act normally even when freewheeling unless /it/ is
326            exporting (which is what Freewheel.empty() tests for).
327         */
328
329         if (_freewheeling && !Freewheel.empty()) {
330                 Freewheel (nframes);
331         } else {
332                 _session->process (nframes);
333         }
334
335         if (_freewheeling) {
336                 PortManager::cycle_end (nframes);
337                 return 0;
338         }
339
340         if (!_running) {
341                 PortManager::cycle_end (nframes);
342                 _processed_frames = next_processed_frames;
343                 return 0;
344         }
345
346         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
347                 
348                 PortManager::check_monitoring ();
349                 last_monitor_check = next_processed_frames;
350         }
351
352         if (_session->silent()) {
353                 PortManager::silence (nframes);
354         }
355
356         if (session_remove_pending && session_removal_countdown) {
357
358                 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
359                 
360                 if (session_removal_countdown > nframes) {
361                         session_removal_countdown -= nframes;
362                 } else {
363                         session_removal_countdown = 0;
364                 }
365
366                 session_removal_gain -= (nframes * session_removal_gain_step);
367         }
368
369         PortManager::cycle_end (nframes);
370
371         _processed_frames = next_processed_frames;
372
373         PT_TIMING_CHECK (2);
374         
375         return 0;
376 }
377
378
379 void
380 AudioEngine::request_backend_reset()
381 {
382     Glib::Threads::Mutex::Lock guard (_reset_request_lock);
383     g_atomic_int_inc (&_hw_reset_request_count);
384     _hw_reset_condition.signal ();
385 }
386
387
388 void
389 AudioEngine::do_reset_backend()
390 {
391     SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 512);
392     
393     Glib::Threads::Mutex::Lock guard (_reset_request_lock);
394     
395     while (!_stop_hw_reset_processing) {
396         
397         if (_hw_reset_request_count && _backend) {
398
399                         _reset_request_lock.unlock();
400             
401                         Glib::Threads::RecMutex::Lock pl (_state_lock);
402
403             g_atomic_int_dec_and_test (&_hw_reset_request_count);
404
405                         std::cout << "AudioEngine::RESET::Reset request processing" << std::endl;
406
407             // backup the device name
408             std::string name = _backend->device_name ();
409             
410                         std::cout << "AudioEngine::RESET::Stoping engine..." << std::endl;
411                         stop();
412
413                         std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
414                         if ( 0 == _backend->reset_device () ) {
415                                 
416                                 std::cout << "AudioEngine::RESET::Starting engine..." << std::endl;
417                                 start ();
418
419                                 // inform about possible changes
420                                 BufferSizeChanged (_backend->buffer_size() );
421                         } else {
422                                 DeviceError();
423                         }
424             
425                         std::cout << "AudioEngine::RESET::Done." << std::endl;
426
427             _reset_request_lock.lock();
428             
429         } else {
430             
431             _hw_reset_condition.wait (_reset_request_lock);
432             
433         }
434     }
435 }
436
437
438 void
439 AudioEngine::request_device_list_update()
440 {
441     Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
442     g_atomic_int_inc (&_hw_devicelist_update_count);
443     _hw_devicelist_update_condition.signal ();
444 }
445
446
447 void
448 AudioEngine::do_devicelist_update()
449 {
450     SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
451     
452     Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
453     
454     while (!_stop_hw_devicelist_processing) {
455         
456         if (_hw_devicelist_update_count) {
457
458             _devicelist_update_lock.unlock();
459             
460             g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
461             DeviceListChanged (); /* EMIT SIGNAL */
462         
463             _devicelist_update_lock.lock();
464             
465         } else {
466             _hw_devicelist_update_condition.wait (_devicelist_update_lock);
467         }
468     }
469 }
470
471
472 void
473 AudioEngine::start_hw_event_processing()
474 {   
475     if (_hw_reset_event_thread == 0) {
476         g_atomic_int_set(&_hw_reset_request_count, 0);
477         g_atomic_int_set(&_stop_hw_reset_processing, 0);
478         _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
479     }
480     
481     if (_hw_devicelist_update_thread == 0) {
482         g_atomic_int_set(&_hw_devicelist_update_count, 0);
483         g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
484         _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
485     }
486 }
487
488
489 void
490 AudioEngine::stop_hw_event_processing()
491 {
492     if (_hw_reset_event_thread) {
493         g_atomic_int_set(&_stop_hw_reset_processing, 1);
494         g_atomic_int_set(&_hw_reset_request_count, 0);
495         _hw_reset_condition.signal ();
496         _hw_reset_event_thread->join ();
497         _hw_reset_event_thread = 0;
498     }
499     
500     if (_hw_devicelist_update_thread) {
501         g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
502         g_atomic_int_set(&_hw_devicelist_update_count, 0);
503         _hw_devicelist_update_condition.signal ();
504         _hw_devicelist_update_thread->join ();
505         _hw_devicelist_update_thread = 0;
506     }
507         
508 }
509
510
511
512 void
513 AudioEngine::stop_metering_thread ()
514 {
515         if (m_meter_thread) {
516                 g_atomic_int_set (&m_meter_exit, 1);
517                 m_meter_thread->join ();
518                 m_meter_thread = 0;
519         }
520 }
521
522 void
523 AudioEngine::start_metering_thread ()
524 {
525         if (m_meter_thread == 0) {
526                 g_atomic_int_set (&m_meter_exit, 0);
527                 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
528         }
529 }
530
531 void
532 AudioEngine::meter_thread ()
533 {
534         pthread_set_name (X_("meter"));
535
536         while (true) {
537                 Glib::usleep (10000); /* 1/100th sec interval */
538                 if (g_atomic_int_get(&m_meter_exit)) {
539                         break;
540                 }
541                 Metering::Meter ();
542         }
543 }
544
545 void
546 AudioEngine::set_session (Session *s)
547 {
548         Glib::Threads::Mutex::Lock pl (_process_lock);
549
550         SessionHandlePtr::set_session (s);
551
552         if (_session) {
553
554                 pframes_t blocksize = samples_per_cycle ();
555
556                 PortManager::cycle_start (blocksize);
557
558                 _session->process (blocksize);
559                 _session->process (blocksize);
560                 _session->process (blocksize);
561                 _session->process (blocksize);
562                 _session->process (blocksize);
563                 _session->process (blocksize);
564                 _session->process (blocksize);
565                 _session->process (blocksize);
566
567                 PortManager::cycle_end (blocksize);
568         }
569 }
570
571 void
572 AudioEngine::remove_session ()
573 {
574         Glib::Threads::Mutex::Lock lm (_process_lock);
575
576         if (_running) {
577
578                 if (_session) {
579                         session_remove_pending = true;
580                         session_removal_countdown = 0;
581                         session_removed.wait(_process_lock);
582                 }
583
584         } else {
585                 SessionHandlePtr::set_session (0);
586         }
587
588         remove_all_ports ();
589 }
590
591
592 void
593 AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs)
594 {
595     if (_session) {
596         _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs);
597     }
598 }
599
600
601 void
602 AudioEngine::died ()
603 {
604         /* called from a signal handler for SIGPIPE */
605
606         stop_metering_thread ();
607
608     _running = false;
609 }
610
611 int
612 AudioEngine::reset_timebase ()
613 {
614         if (_session) {
615                 if (_session->config.get_jack_time_master()) {
616                         _backend->set_time_master (true);
617                 } else {
618                         _backend->set_time_master (false);
619                 }
620         }
621         return 0;
622 }
623
624
625 void
626 AudioEngine::destroy ()
627 {
628         delete _instance;
629         _instance = 0;
630 }
631
632 int
633 AudioEngine::discover_backends ()
634 {
635         vector<std::string> backend_modules;
636
637         _backends.clear ();
638
639         Glib::PatternSpec so_extension_pattern("*backend.so");
640         Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
641
642 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
643         #if defined(DEBUG) || defined(_DEBUG)
644                 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
645         #else
646                 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
647         #endif
648 #else
649         Glib::PatternSpec dll_extension_pattern("*backend.dll");
650 #endif
651
652         find_files_matching_pattern (backend_modules, backend_search_path (),
653                                      so_extension_pattern);
654
655         find_files_matching_pattern (backend_modules, backend_search_path (),
656                                      dylib_extension_pattern);
657
658         find_files_matching_pattern (backend_modules, backend_search_path (),
659                                      dll_extension_pattern);
660
661         DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
662
663         for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
664
665                 AudioBackendInfo* info;
666
667                 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
668
669                 if ((info = backend_discover (*i)) != 0) {
670                         _backends.insert (make_pair (info->name, info));
671                 }
672         }
673
674         DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
675
676         return _backends.size();
677 }
678
679 AudioBackendInfo*
680 AudioEngine::backend_discover (const string& path)
681 {
682 #ifdef PLATFORM_WINDOWS
683         // do not show popup dialog (e.g. missing libjack.dll)
684         // win7+ should use SetThreadErrorMode()
685         SetErrorMode(SEM_FAILCRITICALERRORS);
686 #endif
687         Glib::Module module (path);
688 #ifdef PLATFORM_WINDOWS
689         SetErrorMode(0); // reset to system default
690 #endif
691         AudioBackendInfo* info;
692         AudioBackendInfo* (*dfunc)(void);
693         void* func = 0;
694
695         if (!module) {
696                 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
697                                         Glib::Module::get_last_error()) << endmsg;
698                 return 0;
699         }
700         
701         if (!module.get_symbol ("descriptor", func)) {
702                 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
703                 error << Glib::Module::get_last_error() << endmsg;
704                 return 0;
705         }
706         
707         dfunc = (AudioBackendInfo* (*)(void))func;
708         info = dfunc();
709         if (!info->available()) {
710                 return 0;
711         }
712
713         module.make_resident ();
714         
715         return info;
716 }
717
718 vector<const AudioBackendInfo*>
719 AudioEngine::available_backends() const
720 {
721         vector<const AudioBackendInfo*> r;
722         
723         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
724                 r.push_back (i->second);
725         }
726
727         return r;
728 }
729
730 string
731 AudioEngine::current_backend_name() const
732 {
733         if (_backend) {
734                 return _backend->name();
735         } 
736         return string();
737 }
738
739 void
740 AudioEngine::drop_backend ()
741 {
742         if (_backend) {
743                 stop(false);
744                 _backend->drop_device ();
745                 _backend.reset ();
746                 _running = false;
747         }
748 }
749
750 boost::shared_ptr<AudioBackend>
751 AudioEngine::set_default_backend ()
752 {
753         if (_backends.empty()) {
754                 return boost::shared_ptr<AudioBackend>();
755         }
756
757         return set_backend (_backends.begin()->first, "", "");
758 }
759
760 boost::shared_ptr<AudioBackend>
761 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
762 {
763         BackendMap::iterator b = _backends.find (name);
764
765         if (b == _backends.end()) {
766                 return boost::shared_ptr<AudioBackend>();
767         }
768
769         drop_backend ();
770         
771         try {
772                 if (b->second->instantiate (arg1, arg2)) {
773                         throw failed_constructor ();
774                 }
775                 
776                 _backend = b->second->factory (*this);
777
778         } catch (exception& e) {
779                 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
780                 return boost::shared_ptr<AudioBackend>();
781         }
782
783         return _backend;
784 }
785
786 /* BACKEND PROXY WRAPPERS */
787
788 int
789 AudioEngine::start (bool for_latency)
790 {
791         if (!_backend) {
792                 return -1;
793         }
794
795         if (_running) {
796                 return 0;
797         }
798
799         _processed_frames = 0;
800         last_monitor_check = 0;
801         
802         if (_backend->start (for_latency)) {
803                 return -1;
804         }
805
806         _running = true;
807         
808         if (_session) {
809                 _session->set_frame_rate (_backend->sample_rate());
810                 
811                 if (_session->config.get_jack_time_master()) {
812                         _backend->set_time_master (true);
813                 }
814
815         }
816         
817         start_metering_thread ();
818         
819         if (!for_latency) {
820                 Running(); /* EMIT SIGNAL */
821         }
822         
823         return 0;
824 }
825
826 int
827 AudioEngine::stop (bool for_latency)
828 {
829         if (!_backend) {
830                 return 0;
831         }
832
833         if (_session && _running) {
834                 // it's not a halt, but should be handled the same way:
835                 // disable record, stop transport and I/O processign but save the data.
836                 _session->engine_halted ();
837         }
838
839         Glib::Threads::Mutex::Lock lm (_process_lock);
840
841         if (_backend->stop ()) {
842                 return -1;
843         }
844         
845         _running = false;
846         _processed_frames = 0;
847         _measuring_latency = MeasureNone;
848         _latency_output_port = 0;
849         _latency_input_port = 0;
850         _started_for_latency = false;
851         stop_metering_thread ();
852         
853         Port::PortDrop ();
854
855         if (!for_latency) {
856                 Stopped (); /* EMIT SIGNAL */
857         }
858         
859         return 0;
860 }
861
862 int
863 AudioEngine::freewheel (bool start_stop)
864 {
865         if (!_backend) {
866                 return -1;
867         }
868
869         /* _freewheeling will be set when first Freewheel signal occurs */
870
871         return _backend->freewheel (start_stop);
872 }
873
874 float
875 AudioEngine::get_dsp_load() const 
876 {
877         if (!_backend) {
878                 return 0.0;
879         }
880         return _backend->dsp_load ();
881 }
882
883 bool
884 AudioEngine::is_realtime() const 
885 {
886         if (!_backend) {
887                 return false;
888         }
889
890         return _backend->is_realtime();
891 }
892
893 bool
894 AudioEngine::connected() const 
895 {
896         if (!_backend) {
897                 return false;
898         }
899
900         return _backend->available();
901 }
902
903 void
904 AudioEngine::transport_start ()
905 {
906         if (!_backend) {
907                 return;
908         }
909         return _backend->transport_start ();
910 }
911
912 void
913 AudioEngine::transport_stop ()
914 {
915         if (!_backend) {
916                 return;
917         }
918         return _backend->transport_stop ();
919 }
920
921 TransportState
922 AudioEngine::transport_state ()
923 {
924         if (!_backend) {
925                 return TransportStopped;
926         }
927         return _backend->transport_state ();
928 }
929
930 void
931 AudioEngine::transport_locate (framepos_t pos)
932 {
933         if (!_backend) {
934                 return;
935         }
936         return _backend->transport_locate (pos);
937 }
938
939 framepos_t
940 AudioEngine::transport_frame()
941 {
942         if (!_backend) {
943                 return 0;
944         }
945         return _backend->transport_frame ();
946 }
947
948 framecnt_t
949 AudioEngine::sample_rate () const
950 {
951         if (!_backend) {
952                 return 0;
953         }
954         return _backend->sample_rate ();
955 }
956
957 pframes_t
958 AudioEngine::samples_per_cycle () const
959 {
960         if (!_backend) {
961                 return 0;
962         }
963         return _backend->buffer_size ();
964 }
965
966 int
967 AudioEngine::usecs_per_cycle () const
968 {
969         if (!_backend) {
970                 return -1;
971         }
972         return _backend->usecs_per_cycle ();
973 }
974
975 size_t
976 AudioEngine::raw_buffer_size (DataType t)
977 {
978         if (!_backend) {
979                 return -1;
980         }
981         return _backend->raw_buffer_size (t);
982 }
983
984 framepos_t
985 AudioEngine::sample_time ()
986 {
987         if (!_backend) {
988                 return 0;
989         }
990         return _backend->sample_time ();
991 }
992
993 framepos_t
994 AudioEngine::sample_time_at_cycle_start ()
995 {
996         if (!_backend) {
997                 return 0;
998         }
999         return _backend->sample_time_at_cycle_start ();
1000 }
1001
1002 pframes_t
1003 AudioEngine::samples_since_cycle_start ()
1004 {
1005         if (!_backend) {
1006                 return 0;
1007         }
1008         return _backend->samples_since_cycle_start ();
1009 }
1010
1011 bool
1012 AudioEngine::get_sync_offset (pframes_t& offset) const
1013 {
1014         if (!_backend) {
1015                 return false;
1016         }
1017         return _backend->get_sync_offset (offset);
1018 }
1019
1020 int
1021 AudioEngine::create_process_thread (boost::function<void()> func)
1022 {
1023         if (!_backend) {
1024                 return -1;
1025         }
1026         return _backend->create_process_thread (func);
1027 }
1028
1029 int
1030 AudioEngine::join_process_threads ()
1031 {
1032         if (!_backend) {
1033                 return -1;
1034         }
1035         return _backend->join_process_threads ();
1036 }
1037
1038 bool
1039 AudioEngine::in_process_thread ()
1040 {
1041         if (!_backend) {
1042                 return false;
1043         }
1044         return _backend->in_process_thread ();
1045 }
1046
1047 uint32_t
1048 AudioEngine::process_thread_count ()
1049 {
1050         if (!_backend) {
1051                 return 0;
1052         }
1053         return _backend->process_thread_count ();
1054 }
1055
1056 int
1057 AudioEngine::set_device_name (const std::string& name)
1058 {
1059         if (!_backend) {
1060                 return -1;
1061         }
1062         return _backend->set_device_name  (name);
1063 }
1064
1065 int
1066 AudioEngine::set_sample_rate (float sr)
1067 {
1068         if (!_backend) {
1069                 return -1;
1070         }
1071         return _backend->set_sample_rate  (sr);
1072 }
1073
1074 int
1075 AudioEngine::set_buffer_size (uint32_t bufsiz)
1076 {
1077         if (!_backend) {
1078                 return -1;
1079         }
1080         return _backend->set_buffer_size  (bufsiz);
1081 }
1082
1083 int
1084 AudioEngine::set_interleaved (bool yn)
1085 {
1086         if (!_backend) {
1087                 return -1;
1088         }
1089         return _backend->set_interleaved  (yn);
1090 }
1091
1092 int
1093 AudioEngine::set_input_channels (uint32_t ic)
1094 {
1095         if (!_backend) {
1096                 return -1;
1097         }
1098         return _backend->set_input_channels  (ic);
1099 }
1100
1101 int
1102 AudioEngine::set_output_channels (uint32_t oc)
1103 {
1104         if (!_backend) {
1105                 return -1;
1106         }
1107         return _backend->set_output_channels (oc);
1108 }
1109
1110 int
1111 AudioEngine::set_systemic_input_latency (uint32_t il)
1112 {
1113         if (!_backend) {
1114                 return -1;
1115         }
1116         return _backend->set_systemic_input_latency  (il);
1117 }
1118
1119 int
1120 AudioEngine::set_systemic_output_latency (uint32_t ol)
1121 {
1122         if (!_backend) {
1123                 return -1;
1124         }
1125         return _backend->set_systemic_output_latency  (ol);
1126 }
1127
1128 /* END OF BACKEND PROXY API */
1129
1130 void
1131 AudioEngine::thread_init_callback (void* arg)
1132 {
1133         /* make sure that anybody who needs to know about this thread
1134            knows about it.
1135         */
1136
1137         pthread_set_name (X_("audioengine"));
1138
1139         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
1140
1141         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
1142         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
1143
1144         AsyncMIDIPort::set_process_thread (pthread_self());
1145
1146         if (arg) {
1147                 /* the special thread created/managed by the backend */
1148                 AudioEngine::instance()->_main_thread = new ProcessThread;
1149         }
1150 }
1151
1152 int
1153 AudioEngine::sync_callback (TransportState state, framepos_t position)
1154 {
1155         if (_session) {
1156                 return _session->backend_sync_callback (state, position);
1157         }
1158         return 0;
1159 }
1160
1161 void
1162 AudioEngine::freewheel_callback (bool onoff)
1163 {
1164         _freewheeling = onoff;
1165 }
1166
1167 void
1168 AudioEngine::latency_callback (bool for_playback)
1169 {
1170         if (_session) {
1171                 _session->update_latency (for_playback);
1172         }
1173 }
1174
1175 void
1176 AudioEngine::update_latencies ()
1177 {
1178         if (_backend) {
1179                 _backend->update_latencies ();
1180         }
1181 }
1182
1183 void
1184 AudioEngine::halted_callback (const char* why)
1185 {
1186         if (_in_destructor) {
1187                 /* everything is under control */
1188                 return;
1189         }
1190
1191     stop_metering_thread ();
1192         _running = false;
1193
1194         Port::PortDrop (); /* EMIT SIGNAL */
1195
1196         if (!_started_for_latency) {
1197                 Halted (why);      /* EMIT SIGNAL */
1198         }
1199 }
1200
1201 bool
1202 AudioEngine::setup_required () const
1203 {
1204         if (_backend) {
1205                 if (_backend->info().already_configured())
1206                         return false;
1207         } else {
1208                 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1209                         return false;
1210                 }
1211         }
1212         
1213         return true;
1214 }
1215
1216 int
1217 AudioEngine::prepare_for_latency_measurement ()
1218 {
1219         if (running()) {
1220                 _stopped_for_latency = true;
1221                 stop (true);
1222         }
1223
1224         if (start (true)) {
1225                 _started_for_latency = true;
1226                 return -1;
1227         }
1228
1229         return 0;
1230 }
1231
1232 int
1233 AudioEngine::start_latency_detection (bool for_midi)
1234 {
1235         if (!running()) {
1236                 if (prepare_for_latency_measurement ()) {
1237                         return -1;
1238                 }
1239         }
1240
1241         PortEngine& pe (port_engine());
1242
1243         delete _mtdm;
1244         _mtdm = 0;
1245
1246         delete _mididm;
1247         _mididm = 0;
1248
1249         /* find the ports we will connect to */
1250
1251         PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1252         PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1253
1254         if (!out || !in) {
1255                 stop (true);
1256                 return -1;
1257         }
1258
1259         /* create the ports we will use to read/write data */
1260         if (for_midi) {
1261                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1262                         stop (true);
1263                         return -1;
1264                 }
1265                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1266                         pe.unregister_port (_latency_output_port);
1267                         stop (true);
1268                         return -1;
1269                 }
1270
1271                 const string portname ("latency_in");
1272                 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1273                         pe.unregister_port (_latency_input_port);
1274                         pe.unregister_port (_latency_output_port);
1275                         stop (true);
1276                         return -1;
1277                 }
1278                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1279                         pe.unregister_port (_latency_input_port);
1280                         pe.unregister_port (_latency_output_port);
1281                         stop (true);
1282                         return -1;
1283                 }
1284
1285                 _mididm = new MIDIDM (sample_rate());
1286
1287         } else {
1288
1289                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1290                         stop (true);
1291                         return -1;
1292                 }
1293                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1294                         pe.unregister_port (_latency_output_port);
1295                         stop (true);
1296                         return -1;
1297                 }
1298
1299                 const string portname ("latency_in");
1300                 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1301                         pe.unregister_port (_latency_input_port);
1302                         pe.unregister_port (_latency_output_port);
1303                         stop (true);
1304                         return -1;
1305                 }
1306                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1307                         pe.unregister_port (_latency_input_port);
1308                         pe.unregister_port (_latency_output_port);
1309                         stop (true);
1310                         return -1;
1311                 }
1312
1313                 _mtdm = new MTDM (sample_rate());
1314
1315         }
1316
1317         LatencyRange lr;
1318         _latency_signal_latency = 0;
1319         lr = pe.get_latency_range (in, false);
1320         _latency_signal_latency = lr.max;
1321         lr = pe.get_latency_range (out, true);
1322         _latency_signal_latency += lr.max;
1323
1324         /* all created and connected, lets go */
1325         _latency_flush_frames = samples_per_cycle();
1326         _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1327
1328         return 0;
1329 }
1330
1331 void
1332 AudioEngine::stop_latency_detection ()
1333 {
1334         _measuring_latency = MeasureNone;
1335
1336         if (_latency_output_port) {
1337                 port_engine().unregister_port (_latency_output_port);
1338                 _latency_output_port = 0;
1339         }
1340         if (_latency_input_port) {
1341                 port_engine().unregister_port (_latency_input_port);
1342                 _latency_input_port = 0;
1343         }
1344
1345         stop (true);
1346
1347         if (_stopped_for_latency) {
1348                 start ();
1349         }
1350
1351         _stopped_for_latency = false;
1352         _started_for_latency = false;
1353 }
1354
1355 void
1356 AudioEngine::set_latency_output_port (const string& name)
1357 {
1358         _latency_output_name = name;
1359 }
1360
1361 void
1362 AudioEngine::set_latency_input_port (const string& name)
1363 {
1364         _latency_input_name = name;
1365 }