[Summary] Added actions to handle abnormal behavior during stream stop for MIDI and...
[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         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
105                 i->second->deinstantiate();
106         }
107 }
108
109 AudioEngine*
110 AudioEngine::create ()
111 {
112         if (_instance) {
113                 return _instance;
114         }
115
116         _instance = new AudioEngine ();
117         
118         return _instance;
119 }
120
121 void
122 AudioEngine::split_cycle (pframes_t offset)
123 {
124         /* caller must hold process lock */
125
126         Port::increment_global_port_buffer_offset (offset);
127
128         /* tell all Ports that we're going to start a new (split) cycle */
129
130         boost::shared_ptr<Ports> p = ports.reader();
131
132         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
133                 i->second->cycle_split ();
134         }
135 }
136
137 int
138 AudioEngine::sample_rate_change (pframes_t nframes)
139 {
140         /* check for monitor input change every 1/10th of second */
141
142         monitor_check_interval = nframes / 10;
143         last_monitor_check = 0;
144
145         if (_session) {
146                 _session->set_frame_rate (nframes);
147         }
148
149         SampleRateChanged (nframes); /* EMIT SIGNAL */
150
151         return 0;
152 }
153
154 int 
155 AudioEngine::buffer_size_change (pframes_t bufsiz)
156 {
157         if (_session) {
158                 _session->set_block_size (bufsiz);
159                 last_monitor_check = 0;
160         }
161
162         BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
163
164         return 0;
165 }
166
167 /** Method called by our ::process_thread when there is work to be done.
168  *  @param nframes Number of frames to process.
169  */
170 #ifdef __clang__
171 __attribute__((annotate("realtime")))
172 #endif
173 int
174 AudioEngine::process_callback (pframes_t nframes)
175 {
176         Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
177
178         PT_TIMING_REF;
179         PT_TIMING_CHECK (1);
180
181         /// The number of frames that will have been processed when we've finished
182         pframes_t next_processed_frames;
183
184         /* handle wrap around of total frames counter */
185
186         if (max_framepos - _processed_frames < nframes) {
187                 next_processed_frames = nframes - (max_framepos - _processed_frames);
188         } else {
189                 next_processed_frames = _processed_frames + nframes;
190         }
191
192         if (!tm.locked()) {
193                 /* return having done nothing */
194                 _processed_frames = next_processed_frames;
195                 return 0;
196         }
197
198         bool return_after_remove_check = false;
199
200         if (_measuring_latency == MeasureAudio && _mtdm) {
201                 /* run a normal cycle from the perspective of the PortManager
202                    so that we get silence on all registered ports.
203                    
204                    we overwrite the silence on the two ports used for latency
205                    measurement.
206                 */
207                 
208                 PortManager::cycle_start (nframes);
209                 PortManager::silence (nframes);
210
211                 if (_latency_input_port && _latency_output_port) {
212                         PortEngine& pe (port_engine());
213
214                         Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
215                         Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
216
217                         _mtdm->process (nframes, in, out);
218                 }
219
220                 PortManager::cycle_end (nframes);
221                 return_after_remove_check = true;
222
223         } else if (_measuring_latency == MeasureMIDI && _mididm) {
224                 /* run a normal cycle from the perspective of the PortManager
225                    so that we get silence on all registered ports.
226
227                    we overwrite the silence on the two ports used for latency
228                    measurement.
229                 */
230
231                 PortManager::cycle_start (nframes);
232                 PortManager::silence (nframes);
233
234                 if (_latency_input_port && _latency_output_port) {
235                         PortEngine& pe (port_engine());
236
237                         _mididm->process (nframes, pe,
238                                         pe.get_buffer (_latency_input_port, nframes),
239                                         pe.get_buffer (_latency_output_port, nframes));
240                 }
241
242                 PortManager::cycle_end (nframes);
243                 return_after_remove_check = true;
244
245         } else if (_latency_flush_frames) {
246                 
247                 /* wait for the appropriate duration for the MTDM signal to
248                  * drain from the ports before we revert to normal behaviour.
249                  */
250
251                 PortManager::cycle_start (nframes);
252                 PortManager::silence (nframes);
253                 PortManager::cycle_end (nframes);
254                 
255                 if (_latency_flush_frames > nframes) {
256                         _latency_flush_frames -= nframes;
257                 } else {
258                         _latency_flush_frames = 0;
259                 }
260
261                 return_after_remove_check = true;
262         }
263
264         if (session_remove_pending) {
265
266                 /* perform the actual session removal */
267
268                 if (session_removal_countdown < 0) {
269
270                         /* fade out over 1 second */
271                         session_removal_countdown = sample_rate()/2;
272                         session_removal_gain = 1.0;
273                         session_removal_gain_step = 1.0/session_removal_countdown;
274
275                 } else if (session_removal_countdown > 0) {
276
277                         /* we'll be fading audio out.
278                            
279                            if this is the last time we do this as part 
280                            of session removal, do a MIDI panic now
281                            to get MIDI stopped. This relies on the fact
282                            that "immediate data" (aka "out of band data") from
283                            MIDI tracks is *appended* after any other data, 
284                            so that it emerges after any outbound note ons, etc.
285                         */
286
287                         if (session_removal_countdown <= nframes) {
288                                 _session->midi_panic ();
289                         }
290
291                 } else {
292                         /* fade out done */
293                         _session = 0;
294                         session_removal_countdown = -1; // reset to "not in progress"
295                         session_remove_pending = false;
296                         session_removed.signal(); // wakes up thread that initiated session removal
297                 }
298         }
299
300         if (return_after_remove_check) {
301                 return 0;
302         }
303
304         if (_session == 0) {
305
306                 if (!_freewheeling) {
307                         PortManager::cycle_start (nframes);
308                         PortManager::cycle_end (nframes);
309                 }
310
311                 _processed_frames = next_processed_frames;
312
313                 return 0;
314         }
315
316         /* tell all relevant objects that we're starting a new cycle */
317
318         InternalSend::CycleStart (nframes);
319
320         /* tell all Ports that we're starting a new cycle */
321
322         PortManager::cycle_start (nframes);
323
324         /* test if we are freewheeling and there are freewheel signals connected.
325            ardour should act normally even when freewheeling unless /it/ is
326            exporting (which is what Freewheel.empty() tests for).
327         */
328
329         if (_freewheeling && !Freewheel.empty()) {
330                 Freewheel (nframes);
331         } else {
332                 _session->process (nframes);
333         }
334
335         if (_freewheeling) {
336                 PortManager::cycle_end (nframes);
337                 return 0;
338         }
339
340         if (!_running) {
341                 PortManager::cycle_end (nframes);
342                 _processed_frames = next_processed_frames;
343                 return 0;
344         }
345
346         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
347                 
348                 PortManager::check_monitoring ();
349                 last_monitor_check = next_processed_frames;
350         }
351
352         if (_session->silent()) {
353                 PortManager::silence (nframes);
354         }
355
356         if (session_remove_pending && session_removal_countdown) {
357
358                 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
359                 
360                 if (session_removal_countdown > nframes) {
361                         session_removal_countdown -= nframes;
362                 } else {
363                         session_removal_countdown = 0;
364                 }
365
366                 session_removal_gain -= (nframes * session_removal_gain_step);
367         }
368
369         PortManager::cycle_end (nframes);
370
371         _processed_frames = next_processed_frames;
372
373         PT_TIMING_CHECK (2);
374         
375         return 0;
376 }
377
378
379 void
380 AudioEngine::launch_device_control_app()
381 {
382         if (_state_lock.trylock () ) {
383                 _backend->launch_control_app ();
384                 _state_lock.unlock ();
385         }
386 }
387
388
389 void
390 AudioEngine::request_backend_reset()
391 {
392     Glib::Threads::Mutex::Lock guard (_reset_request_lock);
393     g_atomic_int_inc (&_hw_reset_request_count);
394     _hw_reset_condition.signal ();
395 }
396
397 int
398 AudioEngine::backend_reset_requested()
399 {
400         return g_atomic_int_get (&_hw_reset_request_count);
401 }
402
403 void
404 AudioEngine::do_reset_backend()
405 {
406     SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 512);
407     
408     Glib::Threads::Mutex::Lock guard (_reset_request_lock);
409     
410     while (!_stop_hw_reset_processing) {
411         
412         if (_hw_reset_request_count && _backend) {
413
414                         _reset_request_lock.unlock();
415             
416                         Glib::Threads::RecMutex::Lock pl (_state_lock);
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         dfunc = (AudioBackendInfo* (*)(void))func;
722         info = dfunc();
723         if (!info->available()) {
724                 return 0;
725         }
726
727         module.make_resident ();
728         
729         return info;
730 }
731
732 vector<const AudioBackendInfo*>
733 AudioEngine::available_backends() const
734 {
735         vector<const AudioBackendInfo*> r;
736         
737         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
738                 r.push_back (i->second);
739         }
740
741         return r;
742 }
743
744 string
745 AudioEngine::current_backend_name() const
746 {
747         if (_backend) {
748                 return _backend->name();
749         } 
750         return string();
751 }
752
753 void
754 AudioEngine::drop_backend ()
755 {
756         if (_backend) {
757                 stop(false);
758                 _backend->drop_device ();
759                 _backend.reset ();
760                 _running = false;
761         }
762 }
763
764 boost::shared_ptr<AudioBackend>
765 AudioEngine::set_default_backend ()
766 {
767         if (_backends.empty()) {
768                 return boost::shared_ptr<AudioBackend>();
769         }
770
771         return set_backend (_backends.begin()->first, "", "");
772 }
773
774 boost::shared_ptr<AudioBackend>
775 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
776 {
777         BackendMap::iterator b = _backends.find (name);
778
779         if (b == _backends.end()) {
780                 return boost::shared_ptr<AudioBackend>();
781         }
782
783         drop_backend ();
784         
785         try {
786                 if (b->second->instantiate (arg1, arg2)) {
787                         throw failed_constructor ();
788                 }
789                 
790                 _backend = b->second->factory (*this);
791
792         } catch (exception& e) {
793                 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
794                 return boost::shared_ptr<AudioBackend>();
795         }
796
797         return _backend;
798 }
799
800 /* BACKEND PROXY WRAPPERS */
801
802 int
803 AudioEngine::start (bool for_latency)
804 {
805         if (!_backend) {
806                 return -1;
807         }
808
809         if (_running) {
810                 return 0;
811         }
812
813         _processed_frames = 0;
814         last_monitor_check = 0;
815         
816         if (_backend->start (for_latency)) {
817                 return -1;
818         }
819
820         _running = true;
821         
822         if (_session) {
823                 _session->set_frame_rate (_backend->sample_rate());
824                 
825                 if (_session->config.get_jack_time_master()) {
826                         _backend->set_time_master (true);
827                 }
828
829         }
830         
831         start_metering_thread ();
832         
833         if (!for_latency) {
834                 Running(); /* EMIT SIGNAL */
835         }
836         
837         return 0;
838 }
839
840 int
841 AudioEngine::stop (bool for_latency)
842 {
843         if (!_backend) {
844                 return 0;
845         }
846
847         if (_session && _running) {
848                 // it's not a halt, but should be handled the same way:
849                 // disable record, stop transport and I/O processign but save the data.
850                 _session->engine_halted ();
851         }
852
853         Glib::Threads::Mutex::Lock lm (_process_lock);
854
855         if (_backend->stop ()) {
856                 return -1;
857         }
858         
859         _running = false;
860         _processed_frames = 0;
861         _measuring_latency = MeasureNone;
862         _latency_output_port = 0;
863         _latency_input_port = 0;
864         _started_for_latency = false;
865         stop_metering_thread ();
866         
867         Port::PortDrop ();
868
869         if (!for_latency) {
870                 Stopped (); /* EMIT SIGNAL */
871         }
872         
873         return 0;
874 }
875
876 int
877 AudioEngine::freewheel (bool start_stop)
878 {
879         if (!_backend) {
880                 return -1;
881         }
882
883         /* _freewheeling will be set when first Freewheel signal occurs */
884
885         return _backend->freewheel (start_stop);
886 }
887
888 float
889 AudioEngine::get_dsp_load() const 
890 {
891         if (!_backend) {
892                 return 0.0;
893         }
894         return _backend->dsp_load ();
895 }
896
897 bool
898 AudioEngine::is_realtime() const 
899 {
900         if (!_backend) {
901                 return false;
902         }
903
904         return _backend->is_realtime();
905 }
906
907 bool
908 AudioEngine::connected() const 
909 {
910         if (!_backend) {
911                 return false;
912         }
913
914         return _backend->available();
915 }
916
917 void
918 AudioEngine::transport_start ()
919 {
920         if (!_backend) {
921                 return;
922         }
923         return _backend->transport_start ();
924 }
925
926 void
927 AudioEngine::transport_stop ()
928 {
929         if (!_backend) {
930                 return;
931         }
932         return _backend->transport_stop ();
933 }
934
935 TransportState
936 AudioEngine::transport_state ()
937 {
938         if (!_backend) {
939                 return TransportStopped;
940         }
941         return _backend->transport_state ();
942 }
943
944 void
945 AudioEngine::transport_locate (framepos_t pos)
946 {
947         if (!_backend) {
948                 return;
949         }
950         return _backend->transport_locate (pos);
951 }
952
953 framepos_t
954 AudioEngine::transport_frame()
955 {
956         if (!_backend) {
957                 return 0;
958         }
959         return _backend->transport_frame ();
960 }
961
962 framecnt_t
963 AudioEngine::sample_rate () const
964 {
965         if (!_backend) {
966                 return 0;
967         }
968         return _backend->sample_rate ();
969 }
970
971 pframes_t
972 AudioEngine::samples_per_cycle () const
973 {
974         if (!_backend) {
975                 return 0;
976         }
977         return _backend->buffer_size ();
978 }
979
980 int
981 AudioEngine::usecs_per_cycle () const
982 {
983         if (!_backend) {
984                 return -1;
985         }
986         return _backend->usecs_per_cycle ();
987 }
988
989 size_t
990 AudioEngine::raw_buffer_size (DataType t)
991 {
992         if (!_backend) {
993                 return -1;
994         }
995         return _backend->raw_buffer_size (t);
996 }
997
998 framepos_t
999 AudioEngine::sample_time ()
1000 {
1001         if (!_backend) {
1002                 return 0;
1003         }
1004         return _backend->sample_time ();
1005 }
1006
1007 framepos_t
1008 AudioEngine::sample_time_at_cycle_start ()
1009 {
1010         if (!_backend) {
1011                 return 0;
1012         }
1013         return _backend->sample_time_at_cycle_start ();
1014 }
1015
1016 pframes_t
1017 AudioEngine::samples_since_cycle_start ()
1018 {
1019         if (!_backend) {
1020                 return 0;
1021         }
1022         return _backend->samples_since_cycle_start ();
1023 }
1024
1025 bool
1026 AudioEngine::get_sync_offset (pframes_t& offset) const
1027 {
1028         if (!_backend) {
1029                 return false;
1030         }
1031         return _backend->get_sync_offset (offset);
1032 }
1033
1034 int
1035 AudioEngine::create_process_thread (boost::function<void()> func)
1036 {
1037         if (!_backend) {
1038                 return -1;
1039         }
1040         return _backend->create_process_thread (func);
1041 }
1042
1043 int
1044 AudioEngine::join_process_threads ()
1045 {
1046         if (!_backend) {
1047                 return -1;
1048         }
1049         return _backend->join_process_threads ();
1050 }
1051
1052 bool
1053 AudioEngine::in_process_thread ()
1054 {
1055         if (!_backend) {
1056                 return false;
1057         }
1058         return _backend->in_process_thread ();
1059 }
1060
1061 uint32_t
1062 AudioEngine::process_thread_count ()
1063 {
1064         if (!_backend) {
1065                 return 0;
1066         }
1067         return _backend->process_thread_count ();
1068 }
1069
1070 int
1071 AudioEngine::set_device_name (const std::string& name)
1072 {
1073         if (!_backend) {
1074                 return -1;
1075         }
1076         return _backend->set_device_name  (name);
1077 }
1078
1079 int
1080 AudioEngine::set_sample_rate (float sr)
1081 {
1082         if (!_backend) {
1083                 return -1;
1084         }
1085         return _backend->set_sample_rate  (sr);
1086 }
1087
1088 int
1089 AudioEngine::set_buffer_size (uint32_t bufsiz)
1090 {
1091         if (!_backend) {
1092                 return -1;
1093         }
1094         return _backend->set_buffer_size  (bufsiz);
1095 }
1096
1097 int
1098 AudioEngine::set_interleaved (bool yn)
1099 {
1100         if (!_backend) {
1101                 return -1;
1102         }
1103         return _backend->set_interleaved  (yn);
1104 }
1105
1106 int
1107 AudioEngine::set_input_channels (uint32_t ic)
1108 {
1109         if (!_backend) {
1110                 return -1;
1111         }
1112         return _backend->set_input_channels  (ic);
1113 }
1114
1115 int
1116 AudioEngine::set_output_channels (uint32_t oc)
1117 {
1118         if (!_backend) {
1119                 return -1;
1120         }
1121         return _backend->set_output_channels (oc);
1122 }
1123
1124 int
1125 AudioEngine::set_systemic_input_latency (uint32_t il)
1126 {
1127         if (!_backend) {
1128                 return -1;
1129         }
1130         return _backend->set_systemic_input_latency  (il);
1131 }
1132
1133 int
1134 AudioEngine::set_systemic_output_latency (uint32_t ol)
1135 {
1136         if (!_backend) {
1137                 return -1;
1138         }
1139         return _backend->set_systemic_output_latency  (ol);
1140 }
1141
1142 /* END OF BACKEND PROXY API */
1143
1144 void
1145 AudioEngine::thread_init_callback (void* arg)
1146 {
1147         /* make sure that anybody who needs to know about this thread
1148            knows about it.
1149         */
1150
1151         pthread_set_name (X_("audioengine"));
1152
1153         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
1154
1155         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
1156         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
1157
1158         AsyncMIDIPort::set_process_thread (pthread_self());
1159
1160         if (arg) {
1161                 /* the special thread created/managed by the backend */
1162                 AudioEngine::instance()->_main_thread = new ProcessThread;
1163         }
1164 }
1165
1166 int
1167 AudioEngine::sync_callback (TransportState state, framepos_t position)
1168 {
1169         if (_session) {
1170                 return _session->backend_sync_callback (state, position);
1171         }
1172         return 0;
1173 }
1174
1175 void
1176 AudioEngine::freewheel_callback (bool onoff)
1177 {
1178         _freewheeling = onoff;
1179 }
1180
1181 void
1182 AudioEngine::latency_callback (bool for_playback)
1183 {
1184         if (_session) {
1185                 _session->update_latency (for_playback);
1186         }
1187 }
1188
1189 void
1190 AudioEngine::update_latencies ()
1191 {
1192         if (_backend) {
1193                 _backend->update_latencies ();
1194         }
1195 }
1196
1197 void
1198 AudioEngine::halted_callback (const char* why)
1199 {
1200         if (_in_destructor) {
1201                 /* everything is under control */
1202                 return;
1203         }
1204
1205     stop_metering_thread ();
1206         _running = false;
1207
1208         Port::PortDrop (); /* EMIT SIGNAL */
1209
1210         if (!_started_for_latency) {
1211                 Halted (why);      /* EMIT SIGNAL */
1212         }
1213 }
1214
1215 bool
1216 AudioEngine::setup_required () const
1217 {
1218         if (_backend) {
1219                 if (_backend->info().already_configured())
1220                         return false;
1221         } else {
1222                 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1223                         return false;
1224                 }
1225         }
1226         
1227         return true;
1228 }
1229
1230 int
1231 AudioEngine::prepare_for_latency_measurement ()
1232 {
1233         if (running()) {
1234                 _stopped_for_latency = true;
1235                 stop (true);
1236         }
1237
1238         if (start (true)) {
1239                 _started_for_latency = true;
1240                 return -1;
1241         }
1242
1243         return 0;
1244 }
1245
1246 int
1247 AudioEngine::start_latency_detection (bool for_midi)
1248 {
1249         if (!running()) {
1250                 if (prepare_for_latency_measurement ()) {
1251                         return -1;
1252                 }
1253         }
1254
1255         PortEngine& pe (port_engine());
1256
1257         delete _mtdm;
1258         _mtdm = 0;
1259
1260         delete _mididm;
1261         _mididm = 0;
1262
1263         /* find the ports we will connect to */
1264
1265         PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1266         PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1267
1268         if (!out || !in) {
1269                 stop (true);
1270                 return -1;
1271         }
1272
1273         /* create the ports we will use to read/write data */
1274         if (for_midi) {
1275                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1276                         stop (true);
1277                         return -1;
1278                 }
1279                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1280                         pe.unregister_port (_latency_output_port);
1281                         stop (true);
1282                         return -1;
1283                 }
1284
1285                 const string portname ("latency_in");
1286                 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1287                         pe.unregister_port (_latency_input_port);
1288                         pe.unregister_port (_latency_output_port);
1289                         stop (true);
1290                         return -1;
1291                 }
1292                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1293                         pe.unregister_port (_latency_input_port);
1294                         pe.unregister_port (_latency_output_port);
1295                         stop (true);
1296                         return -1;
1297                 }
1298
1299                 _mididm = new MIDIDM (sample_rate());
1300
1301         } else {
1302
1303                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1304                         stop (true);
1305                         return -1;
1306                 }
1307                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1308                         pe.unregister_port (_latency_output_port);
1309                         stop (true);
1310                         return -1;
1311                 }
1312
1313                 const string portname ("latency_in");
1314                 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1315                         pe.unregister_port (_latency_input_port);
1316                         pe.unregister_port (_latency_output_port);
1317                         stop (true);
1318                         return -1;
1319                 }
1320                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1321                         pe.unregister_port (_latency_input_port);
1322                         pe.unregister_port (_latency_output_port);
1323                         stop (true);
1324                         return -1;
1325                 }
1326
1327                 _mtdm = new MTDM (sample_rate());
1328
1329         }
1330
1331         LatencyRange lr;
1332         _latency_signal_latency = 0;
1333         lr = pe.get_latency_range (in, false);
1334         _latency_signal_latency = lr.max;
1335         lr = pe.get_latency_range (out, true);
1336         _latency_signal_latency += lr.max;
1337
1338         /* all created and connected, lets go */
1339         _latency_flush_frames = samples_per_cycle();
1340         _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1341
1342         return 0;
1343 }
1344
1345 void
1346 AudioEngine::stop_latency_detection ()
1347 {
1348         _measuring_latency = MeasureNone;
1349
1350         if (_latency_output_port) {
1351                 port_engine().unregister_port (_latency_output_port);
1352                 _latency_output_port = 0;
1353         }
1354         if (_latency_input_port) {
1355                 port_engine().unregister_port (_latency_input_port);
1356                 _latency_input_port = 0;
1357         }
1358
1359         stop (true);
1360
1361         if (_stopped_for_latency) {
1362                 start ();
1363         }
1364
1365         _stopped_for_latency = false;
1366         _started_for_latency = false;
1367 }
1368
1369 void
1370 AudioEngine::set_latency_output_port (const string& name)
1371 {
1372         _latency_output_name = name;
1373 }
1374
1375 void
1376 AudioEngine::set_latency_input_port (const string& name)
1377 {
1378         _latency_input_name = name;
1379 }