windows: don’t popup message box when libjack is not found
[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 #ifdef PLATFORM_WINDOWS
697         // do not show popup dialog (e.g. missing libjack.dll)
698         // win7+ should use SetThreadErrorMode()
699         SetErrorMode(SEM_FAILCRITICALERRORS);
700 #endif
701         Glib::Module module (path);
702 #ifdef PLATFORM_WINDOWS
703         SetErrorMode(0); // reset to system default
704 #endif
705         AudioBackendInfo* info;
706         AudioBackendInfo* (*dfunc)(void);
707         void* func = 0;
708
709         if (!module) {
710                 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
711                                         Glib::Module::get_last_error()) << endmsg;
712                 return 0;
713         }
714         
715         if (!module.get_symbol ("descriptor", func)) {
716                 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
717                 error << Glib::Module::get_last_error() << endmsg;
718                 return 0;
719         }
720
721         module.make_resident ();
722         
723         dfunc = (AudioBackendInfo* (*)(void))func;
724         info = dfunc();
725         
726         return info;
727 }
728
729 vector<const AudioBackendInfo*>
730 AudioEngine::available_backends() const
731 {
732         vector<const AudioBackendInfo*> r;
733         
734         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
735                 r.push_back (i->second);
736         }
737
738         return r;
739 }
740
741 string
742 AudioEngine::current_backend_name() const
743 {
744         if (_backend) {
745                 return _backend->name();
746         } 
747         return string();
748 }
749
750 void
751 AudioEngine::drop_backend ()
752 {
753         if (_backend) {
754                 _backend->stop ();
755                 _backend->drop_device ();
756                 _backend.reset ();
757                 _running = false;
758         }
759 }
760
761 boost::shared_ptr<AudioBackend>
762 AudioEngine::set_default_backend ()
763 {
764         if (_backends.empty()) {
765                 return boost::shared_ptr<AudioBackend>();
766         }
767
768         return set_backend (_backends.begin()->first, "", "");
769 }
770
771 boost::shared_ptr<AudioBackend>
772 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
773 {
774         BackendMap::iterator b = _backends.find (name);
775
776         if (b == _backends.end()) {
777                 return boost::shared_ptr<AudioBackend>();
778         }
779
780         drop_backend ();
781         
782         try {
783                 if (b->second->instantiate (arg1, arg2)) {
784                         throw failed_constructor ();
785                 }
786                 
787                 _backend = b->second->factory (*this);
788
789         } catch (exception& e) {
790                 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
791                 return boost::shared_ptr<AudioBackend>();
792         }
793
794         return _backend;
795 }
796
797 /* BACKEND PROXY WRAPPERS */
798
799 int
800 AudioEngine::start (bool for_latency)
801 {
802         if (!_backend) {
803                 return -1;
804         }
805
806         if (_running) {
807                 return 0;
808         }
809
810         _processed_frames = 0;
811         last_monitor_check = 0;
812         
813         if (_backend->start (for_latency)) {
814                 return -1;
815         }
816
817         _running = true;
818         
819         if (_session) {
820                 _session->set_frame_rate (_backend->sample_rate());
821                 
822                 if (_session->config.get_jack_time_master()) {
823                         _backend->set_time_master (true);
824                 }
825
826         }
827         
828         start_metering_thread ();
829         
830         if (!for_latency) {
831                 Running(); /* EMIT SIGNAL */
832         }
833         
834         return 0;
835 }
836
837 int
838 AudioEngine::stop (bool for_latency)
839 {
840         if (!_backend) {
841                 return 0;
842         }
843
844         if (_session && _running) {
845                 // it's not a halt, but should be handled the same way:
846                 // disable record, stop transport and I/O processign but save the data.
847                 _session->engine_halted ();
848         }
849
850         Glib::Threads::Mutex::Lock lm (_process_lock);
851
852         if (_backend->stop ()) {
853                 return -1;
854         }
855         
856         _running = false;
857         _processed_frames = 0;
858         _measuring_latency = MeasureNone;
859         _latency_output_port = 0;
860         _latency_input_port = 0;
861         _started_for_latency = false;
862         stop_metering_thread ();
863         
864         Port::PortDrop ();
865
866         if (!for_latency) {
867                 Stopped (); /* EMIT SIGNAL */
868         }
869         
870         return 0;
871 }
872
873 int
874 AudioEngine::freewheel (bool start_stop)
875 {
876         if (!_backend) {
877                 return -1;
878         }
879
880         /* _freewheeling will be set when first Freewheel signal occurs */
881
882         return _backend->freewheel (start_stop);
883 }
884
885 float
886 AudioEngine::get_dsp_load() const 
887 {
888         if (!_backend) {
889                 return 0.0;
890         }
891         return _backend->dsp_load ();
892 }
893
894 bool
895 AudioEngine::is_realtime() const 
896 {
897         if (!_backend) {
898                 return false;
899         }
900
901         return _backend->is_realtime();
902 }
903
904 bool
905 AudioEngine::connected() const 
906 {
907         if (!_backend) {
908                 return false;
909         }
910
911         return _backend->available();
912 }
913
914 void
915 AudioEngine::transport_start ()
916 {
917         if (!_backend) {
918                 return;
919         }
920         return _backend->transport_start ();
921 }
922
923 void
924 AudioEngine::transport_stop ()
925 {
926         if (!_backend) {
927                 return;
928         }
929         return _backend->transport_stop ();
930 }
931
932 TransportState
933 AudioEngine::transport_state ()
934 {
935         if (!_backend) {
936                 return TransportStopped;
937         }
938         return _backend->transport_state ();
939 }
940
941 void
942 AudioEngine::transport_locate (framepos_t pos)
943 {
944         if (!_backend) {
945                 return;
946         }
947         return _backend->transport_locate (pos);
948 }
949
950 framepos_t
951 AudioEngine::transport_frame()
952 {
953         if (!_backend) {
954                 return 0;
955         }
956         return _backend->transport_frame ();
957 }
958
959 framecnt_t
960 AudioEngine::sample_rate () const
961 {
962         if (!_backend) {
963                 return 0;
964         }
965         return _backend->sample_rate ();
966 }
967
968 pframes_t
969 AudioEngine::samples_per_cycle () const
970 {
971         if (!_backend) {
972                 return 0;
973         }
974         return _backend->buffer_size ();
975 }
976
977 int
978 AudioEngine::usecs_per_cycle () const
979 {
980         if (!_backend) {
981                 return -1;
982         }
983         return _backend->usecs_per_cycle ();
984 }
985
986 size_t
987 AudioEngine::raw_buffer_size (DataType t)
988 {
989         if (!_backend) {
990                 return -1;
991         }
992         return _backend->raw_buffer_size (t);
993 }
994
995 pframes_t
996 AudioEngine::sample_time ()
997 {
998         if (!_backend) {
999                 return 0;
1000         }
1001         return _backend->sample_time ();
1002 }
1003
1004 pframes_t
1005 AudioEngine::sample_time_at_cycle_start ()
1006 {
1007         if (!_backend) {
1008                 return 0;
1009         }
1010         return _backend->sample_time_at_cycle_start ();
1011 }
1012
1013 pframes_t
1014 AudioEngine::samples_since_cycle_start ()
1015 {
1016         if (!_backend) {
1017                 return 0;
1018         }
1019         return _backend->samples_since_cycle_start ();
1020 }
1021
1022 bool
1023 AudioEngine::get_sync_offset (pframes_t& offset) const
1024 {
1025         if (!_backend) {
1026                 return false;
1027         }
1028         return _backend->get_sync_offset (offset);
1029 }
1030
1031 int
1032 AudioEngine::create_process_thread (boost::function<void()> func)
1033 {
1034         if (!_backend) {
1035                 return -1;
1036         }
1037         return _backend->create_process_thread (func);
1038 }
1039
1040 int
1041 AudioEngine::join_process_threads ()
1042 {
1043         if (!_backend) {
1044                 return -1;
1045         }
1046         return _backend->join_process_threads ();
1047 }
1048
1049 bool
1050 AudioEngine::in_process_thread ()
1051 {
1052         if (!_backend) {
1053                 return false;
1054         }
1055         return _backend->in_process_thread ();
1056 }
1057
1058 uint32_t
1059 AudioEngine::process_thread_count ()
1060 {
1061         if (!_backend) {
1062                 return 0;
1063         }
1064         return _backend->process_thread_count ();
1065 }
1066
1067 int
1068 AudioEngine::set_device_name (const std::string& name)
1069 {
1070         if (!_backend) {
1071                 return -1;
1072         }
1073         return _backend->set_device_name  (name);
1074 }
1075
1076 int
1077 AudioEngine::set_sample_rate (float sr)
1078 {
1079         if (!_backend) {
1080                 return -1;
1081         }
1082         return _backend->set_sample_rate  (sr);
1083 }
1084
1085 int
1086 AudioEngine::set_buffer_size (uint32_t bufsiz)
1087 {
1088         if (!_backend) {
1089                 return -1;
1090         }
1091         return _backend->set_buffer_size  (bufsiz);
1092 }
1093
1094 int
1095 AudioEngine::set_interleaved (bool yn)
1096 {
1097         if (!_backend) {
1098                 return -1;
1099         }
1100         return _backend->set_interleaved  (yn);
1101 }
1102
1103 int
1104 AudioEngine::set_input_channels (uint32_t ic)
1105 {
1106         if (!_backend) {
1107                 return -1;
1108         }
1109         return _backend->set_input_channels  (ic);
1110 }
1111
1112 int
1113 AudioEngine::set_output_channels (uint32_t oc)
1114 {
1115         if (!_backend) {
1116                 return -1;
1117         }
1118         return _backend->set_output_channels (oc);
1119 }
1120
1121 int
1122 AudioEngine::set_systemic_input_latency (uint32_t il)
1123 {
1124         if (!_backend) {
1125                 return -1;
1126         }
1127         return _backend->set_systemic_input_latency  (il);
1128 }
1129
1130 int
1131 AudioEngine::set_systemic_output_latency (uint32_t ol)
1132 {
1133         if (!_backend) {
1134                 return -1;
1135         }
1136         return _backend->set_systemic_output_latency  (ol);
1137 }
1138
1139 /* END OF BACKEND PROXY API */
1140
1141 void
1142 AudioEngine::thread_init_callback (void* arg)
1143 {
1144         /* make sure that anybody who needs to know about this thread
1145            knows about it.
1146         */
1147
1148         pthread_set_name (X_("audioengine"));
1149
1150         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
1151         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
1152
1153         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
1154
1155         AsyncMIDIPort::set_process_thread (pthread_self());
1156
1157         if (arg) {
1158                 /* the special thread created/managed by the backend */
1159                 AudioEngine::instance()->_main_thread = new ProcessThread;
1160         }
1161 }
1162
1163 int
1164 AudioEngine::sync_callback (TransportState state, framepos_t position)
1165 {
1166         if (_session) {
1167                 return _session->backend_sync_callback (state, position);
1168         }
1169         return 0;
1170 }
1171
1172 void
1173 AudioEngine::freewheel_callback (bool onoff)
1174 {
1175         _freewheeling = onoff;
1176 }
1177
1178 void
1179 AudioEngine::latency_callback (bool for_playback)
1180 {
1181         if (_session) {
1182                 _session->update_latency (for_playback);
1183         }
1184 }
1185
1186 void
1187 AudioEngine::update_latencies ()
1188 {
1189         if (_backend) {
1190                 _backend->update_latencies ();
1191         }
1192 }
1193
1194 void
1195 AudioEngine::halted_callback (const char* why)
1196 {
1197         if (_in_destructor) {
1198                 /* everything is under control */
1199                 return;
1200         }
1201
1202     stop_metering_thread ();
1203         _running = false;
1204
1205         Port::PortDrop (); /* EMIT SIGNAL */
1206
1207         if (!_started_for_latency) {
1208                 Halted (why);      /* EMIT SIGNAL */
1209         }
1210 }
1211
1212 bool
1213 AudioEngine::setup_required () const
1214 {
1215         if (_backend) {
1216                 if (_backend->info().already_configured())
1217                         return false;
1218         } else {
1219                 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1220                         return false;
1221                 }
1222         }
1223         
1224         return true;
1225 }
1226
1227 int
1228 AudioEngine::prepare_for_latency_measurement ()
1229 {
1230         if (running()) {
1231                 _stopped_for_latency = true;
1232                 stop (true);
1233         }
1234
1235         if (start (true)) {
1236                 _started_for_latency = true;
1237                 return -1;
1238         }
1239
1240         return 0;
1241 }
1242
1243 int
1244 AudioEngine::start_latency_detection (bool for_midi)
1245 {
1246         if (!running()) {
1247                 if (prepare_for_latency_measurement ()) {
1248                         return -1;
1249                 }
1250         }
1251
1252         PortEngine& pe (port_engine());
1253
1254         delete _mtdm;
1255         _mtdm = 0;
1256
1257         delete _mididm;
1258         _mididm = 0;
1259
1260         /* find the ports we will connect to */
1261
1262         PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1263         PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1264
1265         if (!out || !in) {
1266                 stop (true);
1267                 return -1;
1268         }
1269
1270         /* create the ports we will use to read/write data */
1271         if (for_midi) {
1272                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1273                         stop (true);
1274                         return -1;
1275                 }
1276                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1277                         pe.unregister_port (_latency_output_port);
1278                         stop (true);
1279                         return -1;
1280                 }
1281
1282                 const string portname ("latency_in");
1283                 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1284                         pe.unregister_port (_latency_input_port);
1285                         pe.unregister_port (_latency_output_port);
1286                         stop (true);
1287                         return -1;
1288                 }
1289                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1290                         pe.unregister_port (_latency_input_port);
1291                         pe.unregister_port (_latency_output_port);
1292                         stop (true);
1293                         return -1;
1294                 }
1295
1296                 _mididm = new MIDIDM (sample_rate());
1297
1298         } else {
1299
1300                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1301                         stop (true);
1302                         return -1;
1303                 }
1304                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1305                         pe.unregister_port (_latency_output_port);
1306                         stop (true);
1307                         return -1;
1308                 }
1309
1310                 const string portname ("latency_in");
1311                 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1312                         pe.unregister_port (_latency_input_port);
1313                         pe.unregister_port (_latency_output_port);
1314                         stop (true);
1315                         return -1;
1316                 }
1317                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1318                         pe.unregister_port (_latency_input_port);
1319                         pe.unregister_port (_latency_output_port);
1320                         stop (true);
1321                         return -1;
1322                 }
1323
1324                 _mtdm = new MTDM (sample_rate());
1325
1326         }
1327
1328         LatencyRange lr;
1329         _latency_signal_latency = 0;
1330         lr = pe.get_latency_range (in, false);
1331         _latency_signal_latency = lr.max;
1332         lr = pe.get_latency_range (out, true);
1333         _latency_signal_latency += lr.max;
1334
1335         /* all created and connected, lets go */
1336         _latency_flush_frames = samples_per_cycle();
1337         _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1338
1339         return 0;
1340 }
1341
1342 void
1343 AudioEngine::stop_latency_detection ()
1344 {
1345         _measuring_latency = MeasureNone;
1346
1347         if (_latency_output_port) {
1348                 port_engine().unregister_port (_latency_output_port);
1349                 _latency_output_port = 0;
1350         }
1351         if (_latency_input_port) {
1352                 port_engine().unregister_port (_latency_input_port);
1353                 _latency_input_port = 0;
1354         }
1355
1356         stop (true);
1357
1358         if (_stopped_for_latency) {
1359                 start ();
1360         }
1361
1362         _stopped_for_latency = false;
1363         _started_for_latency = false;
1364 }
1365
1366 void
1367 AudioEngine::set_latency_output_port (const string& name)
1368 {
1369         _latency_output_name = name;
1370 }
1371
1372 void
1373 AudioEngine::set_latency_input_port (const string& name)
1374 {
1375         _latency_input_name = name;
1376 }