merge fix
[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"), 1024);
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::Reseting device..." << std::endl;
478                         if ( ( 0 == stop () ) &&
479                  ( 0 == _backend->reset_device () ) &&
480                  ( 0 == start () ) ) {
481                                 
482                                 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
483                                 
484                                 // inform about possible changes
485                                 BufferSizeChanged (_backend->buffer_size() );
486                 DeviceResetFinished(); // notify about device reset finish
487             
488             } else {
489             
490                 DeviceResetFinished(); // notify about device reset finish
491                                 // we've got an error
492                 DeviceError();
493                         }
494                         
495                         std::cout << "AudioEngine::RESET::Done." << std::endl;
496
497                         _reset_request_lock.lock();
498             
499                 } else {
500             
501                         _hw_reset_condition.wait (_reset_request_lock);
502             
503                 }
504         }
505 }
506 void
507 AudioEngine::request_device_list_update()
508 {
509     Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
510     g_atomic_int_inc (&_hw_devicelist_update_count);
511     _hw_devicelist_update_condition.signal ();
512 }
513
514
515 void
516 AudioEngine::do_devicelist_update()
517 {
518     SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
519     
520     Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
521     
522     while (!_stop_hw_devicelist_processing) {
523         
524         if (_hw_devicelist_update_count) {
525
526             _devicelist_update_lock.unlock();
527             
528             Glib::Threads::RecMutex::Lock pl (_state_lock);
529             
530             g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
531             DeviceListChanged (); /* EMIT SIGNAL */
532         
533             _devicelist_update_lock.lock();
534             
535         } else {
536             _hw_devicelist_update_condition.wait (_devicelist_update_lock);
537         }
538     }
539 }
540
541
542 void
543 AudioEngine::start_hw_event_processing()
544 {   
545     if (_hw_reset_event_thread == 0) {
546         g_atomic_int_set(&_hw_reset_request_count, 0);
547         g_atomic_int_set(&_stop_hw_reset_processing, 0);
548         _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
549     }
550     
551     if (_hw_devicelist_update_thread == 0) {
552         g_atomic_int_set(&_hw_devicelist_update_count, 0);
553         g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
554         _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
555     }
556 }
557
558
559 void
560 AudioEngine::stop_hw_event_processing()
561 {
562     if (_hw_reset_event_thread) {
563         g_atomic_int_set(&_stop_hw_reset_processing, 1);
564         g_atomic_int_set(&_hw_reset_request_count, 0);
565         _hw_reset_condition.signal ();
566         _hw_reset_event_thread->join ();
567         _hw_reset_event_thread = 0;
568     }
569     
570     if (_hw_devicelist_update_thread) {
571         g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
572         g_atomic_int_set(&_hw_devicelist_update_count, 0);
573         _hw_devicelist_update_condition.signal ();
574         _hw_devicelist_update_thread->join ();
575         _hw_devicelist_update_thread = 0;
576     }
577         
578 }
579
580
581 void
582 AudioEngine::set_session (Session *s)
583 {
584         Glib::Threads::Mutex::Lock pl (_process_lock);
585
586         SessionHandlePtr::set_session (s);
587
588         if (_session) {
589
590                 pframes_t blocksize = samples_per_cycle ();
591
592                 PortManager::cycle_start (blocksize);
593
594                 _session->process (blocksize);
595                 _session->process (blocksize);
596                 _session->process (blocksize);
597                 _session->process (blocksize);
598                 _session->process (blocksize);
599                 _session->process (blocksize);
600                 _session->process (blocksize);
601                 _session->process (blocksize);
602
603                 PortManager::cycle_end (blocksize);
604         }
605 }
606
607 void
608 AudioEngine::remove_session ()
609 {
610         Glib::Threads::Mutex::Lock lm (_process_lock);
611
612         if (_running) {
613
614                 if (_session) {
615                         session_remove_pending = true;
616                         session_removal_countdown = 0;
617                         session_removed.wait(_process_lock);
618                 }
619
620         } else {
621                 SessionHandlePtr::set_session (0);
622         }
623
624         remove_all_ports ();
625 }
626
627
628 void
629 AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs)
630 {
631 #ifdef USE_TRACKS_CODE_FEATURES
632         if (_session) {
633                 _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs);
634         }
635 #endif  
636 }
637
638
639 void
640 AudioEngine::died ()
641 {
642         /* called from a signal handler for SIGPIPE */
643         _running = false;
644 }
645
646 int
647 AudioEngine::reset_timebase ()
648 {
649         if (_session) {
650                 if (_session->config.get_jack_time_master()) {
651                         _backend->set_time_master (true);
652                 } else {
653                         _backend->set_time_master (false);
654                 }
655         }
656         return 0;
657 }
658
659
660 void
661 AudioEngine::destroy ()
662 {
663         delete _instance;
664         _instance = 0;
665 }
666
667 int
668 AudioEngine::discover_backends ()
669 {
670         vector<std::string> backend_modules;
671
672         _backends.clear ();
673
674         Glib::PatternSpec so_extension_pattern("*backend.so");
675         Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
676
677 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
678         #if defined(DEBUG) || defined(_DEBUG)
679                 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
680         #else
681                 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
682         #endif
683 #else
684         Glib::PatternSpec dll_extension_pattern("*backend.dll");
685 #endif
686
687         find_files_matching_pattern (backend_modules, backend_search_path (),
688                                      so_extension_pattern);
689
690         find_files_matching_pattern (backend_modules, backend_search_path (),
691                                      dylib_extension_pattern);
692
693         find_files_matching_pattern (backend_modules, backend_search_path (),
694                                      dll_extension_pattern);
695
696         DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
697
698         for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
699
700                 AudioBackendInfo* info;
701
702                 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
703
704                 if ((info = backend_discover (*i)) != 0) {
705                         _backends.insert (make_pair (info->name, info));
706                 }
707         }
708
709         DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
710
711         return _backends.size();
712 }
713
714 AudioBackendInfo*
715 AudioEngine::backend_discover (const string& path)
716 {
717 #ifdef PLATFORM_WINDOWS
718         // do not show popup dialog (e.g. missing libjack.dll)
719         // win7+ should use SetThreadErrorMode()
720         SetErrorMode(SEM_FAILCRITICALERRORS);
721 #endif
722         Glib::Module module (path);
723 #ifdef PLATFORM_WINDOWS
724         SetErrorMode(0); // reset to system default
725 #endif
726         AudioBackendInfo* info;
727         AudioBackendInfo* (*dfunc)(void);
728         void* func = 0;
729
730         if (!module) {
731                 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
732                                         Glib::Module::get_last_error()) << endmsg;
733                 return 0;
734         }
735         
736         if (!module.get_symbol ("descriptor", func)) {
737                 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
738                 error << Glib::Module::get_last_error() << endmsg;
739                 return 0;
740         }
741         
742         dfunc = (AudioBackendInfo* (*)(void))func;
743         info = dfunc();
744         if (!info->available()) {
745                 return 0;
746         }
747
748         module.make_resident ();
749         
750         return info;
751 }
752
753 vector<const AudioBackendInfo*>
754 AudioEngine::available_backends() const
755 {
756         vector<const AudioBackendInfo*> r;
757         
758         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
759                 r.push_back (i->second);
760         }
761
762         return r;
763 }
764
765 string
766 AudioEngine::current_backend_name() const
767 {
768         if (_backend) {
769                 return _backend->name();
770         } 
771         return string();
772 }
773
774 void
775 AudioEngine::drop_backend ()
776 {
777         if (_backend) {
778                 _backend->stop ();
779                 _backend->drop_device ();
780                 _backend.reset ();
781                 _running = false;
782         }
783 }
784
785 boost::shared_ptr<AudioBackend>
786 AudioEngine::set_default_backend ()
787 {
788         if (_backends.empty()) {
789                 return boost::shared_ptr<AudioBackend>();
790         }
791
792         return set_backend (_backends.begin()->first, "", "");
793 }
794
795 boost::shared_ptr<AudioBackend>
796 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
797 {
798         BackendMap::iterator b = _backends.find (name);
799
800         if (b == _backends.end()) {
801                 return boost::shared_ptr<AudioBackend>();
802         }
803
804         drop_backend ();
805         
806         try {
807                 if (b->second->instantiate (arg1, arg2)) {
808                         throw failed_constructor ();
809                 }
810                 
811                 _backend = b->second->factory (*this);
812
813         } catch (exception& e) {
814                 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
815                 return boost::shared_ptr<AudioBackend>();
816         }
817
818         return _backend;
819 }
820
821 /* BACKEND PROXY WRAPPERS */
822
823 int
824 AudioEngine::start (bool for_latency)
825 {
826         if (!_backend) {
827                 return -1;
828         }
829
830         if (_running) {
831                 return 0;
832         }
833
834         _processed_frames = 0;
835         last_monitor_check = 0;
836         
837         if (_backend->start (for_latency)) {
838                 return -1;
839         }
840
841         _running = true;
842         
843         if (_session) {
844                 _session->set_frame_rate (_backend->sample_rate());
845                 
846                 if (_session->config.get_jack_time_master()) {
847                         _backend->set_time_master (true);
848                 }
849
850         }
851         
852         if (!for_latency) {
853                 Running(); /* EMIT SIGNAL */
854         }
855         
856         return 0;
857 }
858
859 int
860 AudioEngine::stop (bool for_latency)
861 {
862         if (!_backend) {
863                 return 0;
864         }
865
866         if (_backend->stop ()) {
867                 return -1;
868         }
869         
870         if (_session && _running &&
871             (_session->state_of_the_state() & Session::Loading) == 0 &&
872             (_session->state_of_the_state() & Session::Deletion) == 0) {
873                 // it's not a halt, but should be handled the same way:
874                 // disable record, stop transport and I/O processign but save the data.
875                 _session->engine_halted ();
876         }
877
878         _running = false;
879         _processed_frames = 0;
880         _measuring_latency = MeasureNone;
881         _latency_output_port = 0;
882         _latency_input_port = 0;
883         _started_for_latency = false;
884         
885         Port::PortDrop ();
886
887         if (!for_latency) {
888                 Stopped (); /* EMIT SIGNAL */
889         }
890         
891         return 0;
892 }
893
894 int
895 AudioEngine::freewheel (bool start_stop)
896 {
897         if (!_backend) {
898                 return -1;
899         }
900
901         /* _freewheeling will be set when first Freewheel signal occurs */
902
903         return _backend->freewheel (start_stop);
904 }
905
906 float
907 AudioEngine::get_dsp_load() const 
908 {
909         if (!_backend) {
910                 return 0.0;
911         }
912         return _backend->dsp_load ();
913 }
914
915 bool
916 AudioEngine::is_realtime() const 
917 {
918         if (!_backend) {
919                 return false;
920         }
921
922         return _backend->is_realtime();
923 }
924
925 bool
926 AudioEngine::connected() const 
927 {
928         if (!_backend) {
929                 return false;
930         }
931
932         return _backend->available();
933 }
934
935 void
936 AudioEngine::transport_start ()
937 {
938         if (!_backend) {
939                 return;
940         }
941         return _backend->transport_start ();
942 }
943
944 void
945 AudioEngine::transport_stop ()
946 {
947         if (!_backend) {
948                 return;
949         }
950         return _backend->transport_stop ();
951 }
952
953 TransportState
954 AudioEngine::transport_state ()
955 {
956         if (!_backend) {
957                 return TransportStopped;
958         }
959         return _backend->transport_state ();
960 }
961
962 void
963 AudioEngine::transport_locate (framepos_t pos)
964 {
965         if (!_backend) {
966                 return;
967         }
968         return _backend->transport_locate (pos);
969 }
970
971 framepos_t
972 AudioEngine::transport_frame()
973 {
974         if (!_backend) {
975                 return 0;
976         }
977         return _backend->transport_frame ();
978 }
979
980 framecnt_t
981 AudioEngine::sample_rate () const
982 {
983         if (!_backend) {
984                 return 0;
985         }
986         return _backend->sample_rate ();
987 }
988
989 pframes_t
990 AudioEngine::samples_per_cycle () const
991 {
992         if (!_backend) {
993                 return 0;
994         }
995         return _backend->buffer_size ();
996 }
997
998 int
999 AudioEngine::usecs_per_cycle () const
1000 {
1001         if (!_backend) {
1002                 return -1;
1003         }
1004         return _backend->usecs_per_cycle ();
1005 }
1006
1007 size_t
1008 AudioEngine::raw_buffer_size (DataType t)
1009 {
1010         if (!_backend) {
1011                 return -1;
1012         }
1013         return _backend->raw_buffer_size (t);
1014 }
1015
1016 framepos_t
1017 AudioEngine::sample_time ()
1018 {
1019         if (!_backend) {
1020                 return 0;
1021         }
1022         return _backend->sample_time ();
1023 }
1024
1025 framepos_t
1026 AudioEngine::sample_time_at_cycle_start ()
1027 {
1028         if (!_backend) {
1029                 return 0;
1030         }
1031         return _backend->sample_time_at_cycle_start ();
1032 }
1033
1034 pframes_t
1035 AudioEngine::samples_since_cycle_start ()
1036 {
1037         if (!_backend) {
1038                 return 0;
1039         }
1040         return _backend->samples_since_cycle_start ();
1041 }
1042
1043 bool
1044 AudioEngine::get_sync_offset (pframes_t& offset) const
1045 {
1046         if (!_backend) {
1047                 return false;
1048         }
1049         return _backend->get_sync_offset (offset);
1050 }
1051
1052 int
1053 AudioEngine::create_process_thread (boost::function<void()> func)
1054 {
1055         if (!_backend) {
1056                 return -1;
1057         }
1058         return _backend->create_process_thread (func);
1059 }
1060
1061 int
1062 AudioEngine::join_process_threads ()
1063 {
1064         if (!_backend) {
1065                 return -1;
1066         }
1067         return _backend->join_process_threads ();
1068 }
1069
1070 bool
1071 AudioEngine::in_process_thread ()
1072 {
1073         if (!_backend) {
1074                 return false;
1075         }
1076         return _backend->in_process_thread ();
1077 }
1078
1079 uint32_t
1080 AudioEngine::process_thread_count ()
1081 {
1082         if (!_backend) {
1083                 return 0;
1084         }
1085         return _backend->process_thread_count ();
1086 }
1087
1088 int
1089 AudioEngine::set_device_name (const std::string& name)
1090 {
1091         if (!_backend) {
1092                 return -1;
1093         }
1094         return _backend->set_device_name  (name);
1095 }
1096
1097 int
1098 AudioEngine::set_sample_rate (float sr)
1099 {
1100         if (!_backend) {
1101                 return -1;
1102         }
1103
1104         return _backend->set_sample_rate  (sr);
1105 }
1106
1107 int
1108 AudioEngine::set_buffer_size (uint32_t bufsiz)
1109 {
1110         if (!_backend) {
1111                 return -1;
1112         }
1113         return _backend->set_buffer_size  (bufsiz);
1114 }
1115
1116 int
1117 AudioEngine::set_interleaved (bool yn)
1118 {
1119         if (!_backend) {
1120                 return -1;
1121         }
1122         return _backend->set_interleaved  (yn);
1123 }
1124
1125 int
1126 AudioEngine::set_input_channels (uint32_t ic)
1127 {
1128         if (!_backend) {
1129                 return -1;
1130         }
1131         return _backend->set_input_channels  (ic);
1132 }
1133
1134 int
1135 AudioEngine::set_output_channels (uint32_t oc)
1136 {
1137         if (!_backend) {
1138                 return -1;
1139         }
1140         return _backend->set_output_channels (oc);
1141 }
1142
1143 int
1144 AudioEngine::set_systemic_input_latency (uint32_t il)
1145 {
1146         if (!_backend) {
1147                 return -1;
1148         }
1149         return _backend->set_systemic_input_latency  (il);
1150 }
1151
1152 int
1153 AudioEngine::set_systemic_output_latency (uint32_t ol)
1154 {
1155         if (!_backend) {
1156                 return -1;
1157         }
1158         return _backend->set_systemic_output_latency  (ol);
1159 }
1160
1161 bool
1162 AudioEngine::thread_initialised_for_audio_processing ()
1163 {
1164     return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1165 }
1166
1167 /* END OF BACKEND PROXY API */
1168
1169 void
1170 AudioEngine::thread_init_callback (void* arg)
1171 {
1172         /* make sure that anybody who needs to know about this thread
1173            knows about it.
1174         */
1175
1176         pthread_set_name (X_("audioengine"));
1177
1178         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
1179
1180         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
1181         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
1182
1183         AsyncMIDIPort::set_process_thread (pthread_self());
1184
1185         if (arg) {
1186                 /* the special thread created/managed by the backend */
1187                 AudioEngine::instance()->_main_thread = new ProcessThread;
1188         }
1189 }
1190
1191 int
1192 AudioEngine::sync_callback (TransportState state, framepos_t position)
1193 {
1194         if (_session) {
1195                 return _session->backend_sync_callback (state, position);
1196         }
1197         return 0;
1198 }
1199
1200 void
1201 AudioEngine::freewheel_callback (bool onoff)
1202 {
1203         _freewheeling = onoff;
1204 }
1205
1206 void
1207 AudioEngine::latency_callback (bool for_playback)
1208 {
1209         if (_session) {
1210                 _session->update_latency (for_playback);
1211         }
1212 }
1213
1214 void
1215 AudioEngine::update_latencies ()
1216 {
1217         if (_backend) {
1218                 _backend->update_latencies ();
1219         }
1220 }
1221
1222 void
1223 AudioEngine::halted_callback (const char* why)
1224 {
1225         if (_in_destructor) {
1226                 /* everything is under control */
1227                 return;
1228         }
1229
1230         _running = false;
1231
1232         Port::PortDrop (); /* EMIT SIGNAL */
1233
1234         if (!_started_for_latency) {
1235                 Halted (why);      /* EMIT SIGNAL */
1236         }
1237 }
1238
1239 bool
1240 AudioEngine::setup_required () const
1241 {
1242         if (_backend) {
1243                 if (_backend->info().already_configured())
1244                         return false;
1245         } else {
1246                 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1247                         return false;
1248                 }
1249         }
1250         
1251         return true;
1252 }
1253
1254 int
1255 AudioEngine::prepare_for_latency_measurement ()
1256 {
1257         if (running()) {
1258                 _stopped_for_latency = true;
1259                 stop (true);
1260         }
1261
1262         if (start (true)) {
1263                 _started_for_latency = true;
1264                 return -1;
1265         }
1266
1267         return 0;
1268 }
1269
1270 int
1271 AudioEngine::start_latency_detection (bool for_midi)
1272 {
1273         if (!running()) {
1274                 if (prepare_for_latency_measurement ()) {
1275                         return -1;
1276                 }
1277         }
1278
1279         PortEngine& pe (port_engine());
1280
1281         delete _mtdm;
1282         _mtdm = 0;
1283
1284         delete _mididm;
1285         _mididm = 0;
1286
1287         /* find the ports we will connect to */
1288
1289         PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1290         PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1291
1292         if (!out || !in) {
1293                 stop (true);
1294                 return -1;
1295         }
1296
1297         /* create the ports we will use to read/write data */
1298         if (for_midi) {
1299                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1300                         stop (true);
1301                         return -1;
1302                 }
1303                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1304                         pe.unregister_port (_latency_output_port);
1305                         stop (true);
1306                         return -1;
1307                 }
1308
1309                 const string portname ("latency_in");
1310                 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1311                         pe.unregister_port (_latency_input_port);
1312                         pe.unregister_port (_latency_output_port);
1313                         stop (true);
1314                         return -1;
1315                 }
1316                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1317                         pe.unregister_port (_latency_input_port);
1318                         pe.unregister_port (_latency_output_port);
1319                         stop (true);
1320                         return -1;
1321                 }
1322
1323                 _mididm = new MIDIDM (sample_rate());
1324
1325         } else {
1326
1327                 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1328                         stop (true);
1329                         return -1;
1330                 }
1331                 if (pe.connect (_latency_output_port, _latency_output_name)) {
1332                         pe.unregister_port (_latency_output_port);
1333                         stop (true);
1334                         return -1;
1335                 }
1336
1337                 const string portname ("latency_in");
1338                 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1339                         pe.unregister_port (_latency_input_port);
1340                         pe.unregister_port (_latency_output_port);
1341                         stop (true);
1342                         return -1;
1343                 }
1344                 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1345                         pe.unregister_port (_latency_input_port);
1346                         pe.unregister_port (_latency_output_port);
1347                         stop (true);
1348                         return -1;
1349                 }
1350
1351                 _mtdm = new MTDM (sample_rate());
1352
1353         }
1354
1355         LatencyRange lr;
1356         _latency_signal_latency = 0;
1357         lr = pe.get_latency_range (in, false);
1358         _latency_signal_latency = lr.max;
1359         lr = pe.get_latency_range (out, true);
1360         _latency_signal_latency += lr.max;
1361
1362         /* all created and connected, lets go */
1363         _latency_flush_frames = samples_per_cycle();
1364         _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1365
1366         return 0;
1367 }
1368
1369 void
1370 AudioEngine::stop_latency_detection ()
1371 {
1372         _measuring_latency = MeasureNone;
1373
1374         if (_latency_output_port) {
1375                 port_engine().unregister_port (_latency_output_port);
1376                 _latency_output_port = 0;
1377         }
1378         if (_latency_input_port) {
1379                 port_engine().unregister_port (_latency_input_port);
1380                 _latency_input_port = 0;
1381         }
1382
1383         stop (true);
1384
1385         if (_stopped_for_latency) {
1386                 start ();
1387         }
1388
1389         _stopped_for_latency = false;
1390         _started_for_latency = false;
1391 }
1392
1393 void
1394 AudioEngine::set_latency_output_port (const string& name)
1395 {
1396         _latency_output_name = name;
1397 }
1398
1399 void
1400 AudioEngine::set_latency_input_port (const string& name)
1401 {
1402         _latency_input_name = name;
1403 }