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