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