AudioEngine tweaks from Tracks, related to stopping audioengine and halting
[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                 _backend->stop ();
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         Glib::Threads::Mutex::Lock lm (_process_lock);
862
863         if (_backend->stop ()) {
864                 return -1;
865         }
866         
867         if (_session && _running &&
868             (_session->state_of_the_state() & Session::Loading) == 0 &&
869             (_session->state_of_the_state() & Session::Deletion) == 0) {
870                 // it's not a halt, but should be handled the same way:
871                 // disable record, stop transport and I/O processign but save the data.
872                 _session->engine_halted ();
873         }
874
875         _running = false;
876         _processed_frames = 0;
877         _measuring_latency = MeasureNone;
878         _latency_output_port = 0;
879         _latency_input_port = 0;
880         _started_for_latency = false;
881         
882         Port::PortDrop ();
883
884         if (!for_latency) {
885                 Stopped (); /* EMIT SIGNAL */
886         }
887         
888         return 0;
889 }
890
891 int
892 AudioEngine::freewheel (bool start_stop)
893 {
894         if (!_backend) {
895                 return -1;
896         }
897
898         /* _freewheeling will be set when first Freewheel signal occurs */
899
900         return _backend->freewheel (start_stop);
901 }
902
903 float
904 AudioEngine::get_dsp_load() const 
905 {
906         if (!_backend) {
907                 return 0.0;
908         }
909         return _backend->dsp_load ();
910 }
911
912 bool
913 AudioEngine::is_realtime() const 
914 {
915         if (!_backend) {
916                 return false;
917         }
918
919         return _backend->is_realtime();
920 }
921
922 bool
923 AudioEngine::connected() const 
924 {
925         if (!_backend) {
926                 return false;
927         }
928
929         return _backend->available();
930 }
931
932 void
933 AudioEngine::transport_start ()
934 {
935         if (!_backend) {
936                 return;
937         }
938         return _backend->transport_start ();
939 }
940
941 void
942 AudioEngine::transport_stop ()
943 {
944         if (!_backend) {
945                 return;
946         }
947         return _backend->transport_stop ();
948 }
949
950 TransportState
951 AudioEngine::transport_state ()
952 {
953         if (!_backend) {
954                 return TransportStopped;
955         }
956         return _backend->transport_state ();
957 }
958
959 void
960 AudioEngine::transport_locate (framepos_t pos)
961 {
962         if (!_backend) {
963                 return;
964         }
965         return _backend->transport_locate (pos);
966 }
967
968 framepos_t
969 AudioEngine::transport_frame()
970 {
971         if (!_backend) {
972                 return 0;
973         }
974         return _backend->transport_frame ();
975 }
976
977 framecnt_t
978 AudioEngine::sample_rate () const
979 {
980         if (!_backend) {
981                 return 0;
982         }
983         return _backend->sample_rate ();
984 }
985
986 pframes_t
987 AudioEngine::samples_per_cycle () const
988 {
989         if (!_backend) {
990                 return 0;
991         }
992         return _backend->buffer_size ();
993 }
994
995 int
996 AudioEngine::usecs_per_cycle () const
997 {
998         if (!_backend) {
999                 return -1;
1000         }
1001         return _backend->usecs_per_cycle ();
1002 }
1003
1004 size_t
1005 AudioEngine::raw_buffer_size (DataType t)
1006 {
1007         if (!_backend) {
1008                 return -1;
1009         }
1010         return _backend->raw_buffer_size (t);
1011 }
1012
1013 framepos_t
1014 AudioEngine::sample_time ()
1015 {
1016         if (!_backend) {
1017                 return 0;
1018         }
1019         return _backend->sample_time ();
1020 }
1021
1022 framepos_t
1023 AudioEngine::sample_time_at_cycle_start ()
1024 {
1025         if (!_backend) {
1026                 return 0;
1027         }
1028         return _backend->sample_time_at_cycle_start ();
1029 }
1030
1031 pframes_t
1032 AudioEngine::samples_since_cycle_start ()
1033 {
1034         if (!_backend) {
1035                 return 0;
1036         }
1037         return _backend->samples_since_cycle_start ();
1038 }
1039
1040 bool
1041 AudioEngine::get_sync_offset (pframes_t& offset) const
1042 {
1043         if (!_backend) {
1044                 return false;
1045         }
1046         return _backend->get_sync_offset (offset);
1047 }
1048
1049 int
1050 AudioEngine::create_process_thread (boost::function<void()> func)
1051 {
1052         if (!_backend) {
1053                 return -1;
1054         }
1055         return _backend->create_process_thread (func);
1056 }
1057
1058 int
1059 AudioEngine::join_process_threads ()
1060 {
1061         if (!_backend) {
1062                 return -1;
1063         }
1064         return _backend->join_process_threads ();
1065 }
1066
1067 bool
1068 AudioEngine::in_process_thread ()
1069 {
1070         if (!_backend) {
1071                 return false;
1072         }
1073         return _backend->in_process_thread ();
1074 }
1075
1076 uint32_t
1077 AudioEngine::process_thread_count ()
1078 {
1079         if (!_backend) {
1080                 return 0;
1081         }
1082         return _backend->process_thread_count ();
1083 }
1084
1085 int
1086 AudioEngine::set_device_name (const std::string& name)
1087 {
1088         if (!_backend) {
1089                 return -1;
1090         }
1091         return _backend->set_device_name  (name);
1092 }
1093
1094 int
1095 AudioEngine::set_sample_rate (float sr)
1096 {
1097         if (!_backend) {
1098                 return -1;
1099         }
1100
1101         return _backend->set_sample_rate  (sr);
1102 }
1103
1104 int
1105 AudioEngine::set_buffer_size (uint32_t bufsiz)
1106 {
1107         if (!_backend) {
1108                 return -1;
1109         }
1110         return _backend->set_buffer_size  (bufsiz);
1111 }
1112
1113 int
1114 AudioEngine::set_interleaved (bool yn)
1115 {
1116         if (!_backend) {
1117                 return -1;
1118         }
1119         return _backend->set_interleaved  (yn);
1120 }
1121
1122 int
1123 AudioEngine::set_input_channels (uint32_t ic)
1124 {
1125         if (!_backend) {
1126                 return -1;
1127         }
1128         return _backend->set_input_channels  (ic);
1129 }
1130
1131 int
1132 AudioEngine::set_output_channels (uint32_t oc)
1133 {
1134         if (!_backend) {
1135                 return -1;
1136         }
1137         return _backend->set_output_channels (oc);
1138 }
1139
1140 int
1141 AudioEngine::set_systemic_input_latency (uint32_t il)
1142 {
1143         if (!_backend) {
1144                 return -1;
1145         }
1146         return _backend->set_systemic_input_latency  (il);
1147 }
1148
1149 int
1150 AudioEngine::set_systemic_output_latency (uint32_t ol)
1151 {
1152         if (!_backend) {
1153                 return -1;
1154         }
1155         return _backend->set_systemic_output_latency  (ol);
1156 }
1157
1158 bool
1159 AudioEngine::thread_initialised_for_audio_processing ()
1160 {
1161     return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1162 }
1163
1164 /* END OF BACKEND PROXY API */
1165
1166 void
1167 AudioEngine::thread_init_callback (void* arg)
1168 {
1169         /* make sure that anybody who needs to know about this thread
1170            knows about it.
1171         */
1172
1173         pthread_set_name (X_("audioengine"));
1174
1175         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
1176
1177         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
1178         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
1179
1180         AsyncMIDIPort::set_process_thread (pthread_self());
1181
1182         if (arg) {
1183                 /* the special thread created/managed by the backend */
1184                 AudioEngine::instance()->_main_thread = new ProcessThread;
1185         }
1186 }
1187
1188 int
1189 AudioEngine::sync_callback (TransportState state, framepos_t position)
1190 {
1191         if (_session) {
1192                 return _session->backend_sync_callback (state, position);
1193         }
1194         return 0;
1195 }
1196
1197 void
1198 AudioEngine::freewheel_callback (bool onoff)
1199 {
1200         _freewheeling = onoff;
1201 }
1202
1203 void
1204 AudioEngine::latency_callback (bool for_playback)
1205 {
1206         if (_session) {
1207                 _session->update_latency (for_playback);
1208         }
1209 }
1210
1211 void
1212 AudioEngine::update_latencies ()
1213 {
1214         if (_backend) {
1215                 _backend->update_latencies ();
1216         }
1217 }
1218
1219 void
1220 AudioEngine::halted_callback (const char* why)
1221 {
1222         if (_in_destructor) {
1223                 /* everything is under control */
1224                 return;
1225         }
1226
1227         _running = false;
1228
1229         Port::PortDrop (); /* EMIT SIGNAL */
1230
1231         if (!_started_for_latency) {
1232                 Halted (why);      /* EMIT SIGNAL */
1233         }
1234 }
1235
1236 bool
1237 AudioEngine::setup_required () const
1238 {
1239         if (_backend) {
1240                 if (_backend->info().already_configured())
1241                         return false;
1242         } else {
1243                 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1244                         return false;
1245                 }
1246         }
1247         
1248         return true;
1249 }
1250
1251 int
1252 AudioEngine::prepare_for_latency_measurement ()
1253 {
1254         if (running()) {
1255                 _stopped_for_latency = true;
1256                 stop (true);
1257         }
1258
1259         if (start (true)) {
1260                 _started_for_latency = true;
1261                 return -1;
1262         }
1263
1264         return 0;
1265 }
1266
1267 int
1268 AudioEngine::start_latency_detection (bool for_midi)
1269 {
1270         if (!running()) {
1271                 if (prepare_for_latency_measurement ()) {
1272                         return -1;
1273                 }
1274         }
1275
1276         PortEngine& pe (port_engine());
1277
1278         delete _mtdm;
1279         _mtdm = 0;
1280
1281         delete _mididm;
1282         _mididm = 0;
1283
1284         /* find the ports we will connect to */
1285
1286         PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1287         PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1288
1289         if (!out || !in) {
1290                 stop (true);
1291                 return -1;
1292         }
1293
1294         /* create the ports we will use to read/write data */
1295         if (for_midi) {
1296                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1297                         stop (true);
1298                         return -1;
1299                 }
1300                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1301                         pe.unregister_port (_latency_output_port);
1302                         stop (true);
1303                         return -1;
1304                 }
1305
1306                 const string portname ("latency_in");
1307                 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1308                         pe.unregister_port (_latency_input_port);
1309                         pe.unregister_port (_latency_output_port);
1310                         stop (true);
1311                         return -1;
1312                 }
1313                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1314                         pe.unregister_port (_latency_input_port);
1315                         pe.unregister_port (_latency_output_port);
1316                         stop (true);
1317                         return -1;
1318                 }
1319
1320                 _mididm = new MIDIDM (sample_rate());
1321
1322         } else {
1323
1324                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1325                         stop (true);
1326                         return -1;
1327                 }
1328                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1329                         pe.unregister_port (_latency_output_port);
1330                         stop (true);
1331                         return -1;
1332                 }
1333
1334                 const string portname ("latency_in");
1335                 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1336                         pe.unregister_port (_latency_input_port);
1337                         pe.unregister_port (_latency_output_port);
1338                         stop (true);
1339                         return -1;
1340                 }
1341                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1342                         pe.unregister_port (_latency_input_port);
1343                         pe.unregister_port (_latency_output_port);
1344                         stop (true);
1345                         return -1;
1346                 }
1347
1348                 _mtdm = new MTDM (sample_rate());
1349
1350         }
1351
1352         LatencyRange lr;
1353         _latency_signal_latency = 0;
1354         lr = pe.get_latency_range (in, false);
1355         _latency_signal_latency = lr.max;
1356         lr = pe.get_latency_range (out, true);
1357         _latency_signal_latency += lr.max;
1358
1359         /* all created and connected, lets go */
1360         _latency_flush_frames = samples_per_cycle();
1361         _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1362
1363         return 0;
1364 }
1365
1366 void
1367 AudioEngine::stop_latency_detection ()
1368 {
1369         _measuring_latency = MeasureNone;
1370
1371         if (_latency_output_port) {
1372                 port_engine().unregister_port (_latency_output_port);
1373                 _latency_output_port = 0;
1374         }
1375         if (_latency_input_port) {
1376                 port_engine().unregister_port (_latency_input_port);
1377                 _latency_input_port = 0;
1378         }
1379
1380         stop (true);
1381
1382         if (_stopped_for_latency) {
1383                 start ();
1384         }
1385
1386         _stopped_for_latency = false;
1387         _started_for_latency = false;
1388 }
1389
1390 void
1391 AudioEngine::set_latency_output_port (const string& name)
1392 {
1393         _latency_output_name = name;
1394 }
1395
1396 void
1397 AudioEngine::set_latency_input_port (const string& name)
1398 {
1399         _latency_input_name = name;
1400 }