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