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