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