2 * Copyright (C) 2005-2019 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2006-2016 David Robillard <d@drobilla.net>
4 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
5 * Copyright (C) 2008-2010 Sakari Bergen <sakari.bergen@beatwaves.net>
6 * Copyright (C) 2008 Hans Baier <hansfbaier@googlemail.com>
7 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
8 * Copyright (C) 2013-2014 John Emmas <john@creativepost.co.uk>
9 * Copyright (C) 2013-2015 Tim Mayberry <mojofunk@gmail.com>
10 * Copyright (C) 2015 GZharun <grygoriiz@wavesglobal.com>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include <glibmm/timer.h>
36 #include <glibmm/pattern.h>
37 #include <glibmm/module.h>
40 #include "pbd/file_utils.h"
41 #include "pbd/pthread_utils.h"
42 #include "pbd/stacktrace.h"
43 #include "pbd/unknown_type.h"
45 #include "midi++/port.h"
46 #include "midi++/mmc.h"
48 #include "ardour/async_midi_port.h"
49 #include "ardour/ardour.h"
50 #include "ardour/audio_port.h"
51 #include "ardour/audio_backend.h"
52 #include "ardour/audioengine.h"
53 #include "ardour/search_paths.h"
54 #include "ardour/buffer.h"
55 #include "ardour/cycle_timer.h"
56 #include "ardour/internal_send.h"
57 #include "ardour/meter.h"
58 #include "ardour/midi_port.h"
59 #include "ardour/midiport_manager.h"
60 #include "ardour/mididm.h"
61 #include "ardour/mtdm.h"
62 #include "ardour/port.h"
63 #include "ardour/process_thread.h"
64 #include "ardour/rc_configuration.h"
65 #include "ardour/session.h"
66 #include "ardour/transport_master_manager.h"
71 using namespace ARDOUR;
74 AudioEngine* AudioEngine::_instance = 0;
76 static gint audioengine_thread_cnt = 1;
79 #define SILENCE_AFTER_SECONDS 600
82 AudioEngine::AudioEngine ()
83 : session_remove_pending (false)
84 , session_removal_countdown (-1)
86 , _freewheeling (false)
87 , monitor_check_interval (INT32_MAX)
88 , last_monitor_check (0)
89 , _processed_samples (-1)
94 , _measuring_latency (MeasureNone)
95 , _latency_input_port (0)
96 , _latency_output_port (0)
97 , _latency_flush_samples (0)
98 , _latency_signal_latency (0)
99 , _stopped_for_latency (false)
100 , _started_for_latency (false)
101 , _in_destructor (false)
102 , _last_backend_error_string(AudioBackend::get_error_string((AudioBackend::ErrorCode)-1))
103 , _hw_reset_event_thread(0)
104 , _hw_reset_request_count(0)
105 , _stop_hw_reset_processing(0)
106 , _hw_devicelist_update_thread(0)
107 , _hw_devicelist_update_count(0)
108 , _stop_hw_devicelist_processing(0)
110 , _init_countdown (0)
111 #ifdef SILENCE_AFTER_SECONDS
112 , _silence_countdown (0)
113 , _silence_hit_cnt (0)
116 reset_silence_countdown ();
117 start_hw_event_processing();
118 discover_backends ();
121 AudioEngine::~AudioEngine ()
123 _in_destructor = true;
124 stop_hw_event_processing();
126 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
127 i->second->deinstantiate();
133 AudioEngine::create ()
139 _instance = new AudioEngine ();
145 AudioEngine::split_cycle (pframes_t offset)
147 /* caller must hold process lock */
149 Port::increment_global_port_buffer_offset (offset);
151 /* tell all Ports that we're going to start a new (split) cycle */
153 boost::shared_ptr<Ports> p = ports.reader();
155 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
156 i->second->cycle_split ();
161 AudioEngine::sample_rate_change (pframes_t nframes)
163 /* check for monitor input change every 1/10th of second */
165 monitor_check_interval = nframes / 10;
166 last_monitor_check = 0;
169 _session->set_sample_rate (nframes);
172 SampleRateChanged (nframes); /* EMIT SIGNAL */
174 #ifdef SILENCE_AFTER_SECONDS
175 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
182 AudioEngine::buffer_size_change (pframes_t bufsiz)
184 set_port_buffer_sizes (bufsiz);
187 _session->set_block_size (bufsiz);
188 last_monitor_check = 0;
191 BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
196 /** Method called by our ::process_thread when there is work to be done.
197 * @param nframes Number of samples to process.
200 __attribute__((annotate("realtime")))
203 AudioEngine::process_callback (pframes_t nframes)
205 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
206 Port::set_speed_ratio (1.0);
211 /// The number of samples that will have been processed when we've finished
212 pframes_t next_processed_samples;
214 if (_processed_samples < 0) {
215 _processed_samples = sample_time();
216 cerr << "IIIIINIT PS to " << _processed_samples << endl;
219 /* handle wrap around of total samples counter */
221 if (max_samplepos - _processed_samples < nframes) {
222 next_processed_samples = nframes - (max_samplepos - _processed_samples);
224 next_processed_samples = _processed_samples + nframes;
228 /* return having done nothing */
232 /* really only JACK requires this
233 * (other backends clear the output buffers
234 * before the process_callback. it may even be
235 * jack/alsa only). but better safe than sorry.
237 PortManager::silence_outputs (nframes);
241 /* The coreaudio-backend calls thread_init_callback() if
242 * the hardware changes or pthread_self() changes.
244 * However there are cases when neither holds true, yet
245 * the thread-pool changes: e.g. connect a headphone to
246 * a shared mic/headphone jack.
247 * It's probably related to, or caused by clocksource changes.
249 * For reasons yet unknown Glib::Threads::Private() can
250 * use a different thread-private in the same pthread
251 * (coreaudio render callback).
253 * Coreaudio must set something which influences
254 * pthread_key_t uniqness or reset the key using
255 * pthread_getspecific().
257 if (! SessionEvent::has_per_thread_pool ()) {
258 thread_init_callback (NULL);
261 if (_session && _init_countdown > 0) {
264 PortManager::cycle_start (nframes);
265 PortManager::silence (nframes);
266 _session->process (nframes);
267 PortManager::cycle_end (nframes);
271 bool return_after_remove_check = false;
273 if (_measuring_latency == MeasureAudio && _mtdm) {
274 /* run a normal cycle from the perspective of the PortManager
275 so that we get silence on all registered ports.
277 we overwrite the silence on the two ports used for latency
281 PortManager::cycle_start (nframes);
282 PortManager::silence (nframes);
284 if (_latency_input_port && _latency_output_port) {
285 PortEngine& pe (port_engine());
287 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
288 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
290 _mtdm->process (nframes, in, out);
293 PortManager::cycle_end (nframes);
294 return_after_remove_check = true;
296 } else if (_measuring_latency == MeasureMIDI && _mididm) {
297 /* run a normal cycle from the perspective of the PortManager
298 so that we get silence on all registered ports.
300 we overwrite the silence on the two ports used for latency
304 PortManager::cycle_start (nframes);
305 PortManager::silence (nframes);
307 if (_latency_input_port && _latency_output_port) {
308 PortEngine& pe (port_engine());
310 _mididm->process (nframes, pe,
311 pe.get_buffer (_latency_input_port, nframes),
312 pe.get_buffer (_latency_output_port, nframes));
315 PortManager::cycle_end (nframes);
316 return_after_remove_check = true;
318 } else if (_latency_flush_samples) {
320 /* wait for the appropriate duration for the MTDM signal to
321 * drain from the ports before we revert to normal behaviour.
324 PortManager::cycle_start (nframes);
325 PortManager::silence (nframes);
326 PortManager::cycle_end (nframes);
328 if (_latency_flush_samples > nframes) {
329 _latency_flush_samples -= nframes;
331 _latency_flush_samples = 0;
334 return_after_remove_check = true;
337 if (session_remove_pending) {
339 /* perform the actual session removal */
341 if (session_removal_countdown < 0) {
343 /* fade out over 1 second */
344 session_removal_countdown = sample_rate()/2;
345 session_removal_gain = GAIN_COEFF_UNITY;
346 session_removal_gain_step = 1.0/session_removal_countdown;
348 } else if (session_removal_countdown > 0) {
350 /* we'll be fading audio out.
352 if this is the last time we do this as part
353 of session removal, do a MIDI panic now
354 to get MIDI stopped. This relies on the fact
355 that "immediate data" (aka "out of band data") from
356 MIDI tracks is *appended* after any other data,
357 so that it emerges after any outbound note ons, etc.
360 if (session_removal_countdown <= nframes) {
362 _session->midi_panic ();
368 session_removal_countdown = -1; // reset to "not in progress"
369 session_remove_pending = false;
370 session_removed.signal(); // wakes up thread that initiated session removal
374 if (return_after_remove_check) {
378 TransportMasterManager& tmm (TransportMasterManager::instance());
380 /* make sure the TMM is up to date about the current session */
382 if (_session != tmm.session()) {
383 tmm.set_session (_session);
388 if (!_freewheeling) {
389 PortManager::silence_outputs (nframes);
392 _processed_samples = next_processed_samples;
397 if (!_freewheeling || Freewheel.empty()) {
398 const double engine_speed = tmm.pre_process_transport_masters (nframes, sample_time_at_cycle_start());
399 Port::set_speed_ratio (engine_speed);
400 DEBUG_TRACE (DEBUG::Slave, string_compose ("transport master (current=%1) gives speed %2 (ports using %3)\n", tmm.current() ? tmm.current()->name() : string("[]"), engine_speed, Port::speed_ratio()));
403 /* tell all relevant objects that we're starting a new cycle */
405 InternalSend::CycleStart (nframes);
407 /* tell all Ports that we're starting a new cycle */
409 PortManager::cycle_start (nframes, _session);
411 /* test if we are freewheeling and there are freewheel signals connected.
412 * ardour should act normally even when freewheeling unless /it/ is
413 * exporting (which is what Freewheel.empty() tests for).
416 if (_freewheeling && !Freewheel.empty()) {
419 if (Port::cycle_nframes () <= nframes) {
420 _session->process (Port::cycle_nframes ());
422 pframes_t remain = Port::cycle_nframes ();
424 pframes_t nf = std::min (remain, nframes);
425 _session->process (nf);
435 PortManager::cycle_end (nframes, _session);
440 _processed_samples = next_processed_samples;
444 if (last_monitor_check + monitor_check_interval < next_processed_samples) {
446 PortManager::check_monitoring ();
447 last_monitor_check = next_processed_samples;
450 #ifdef SILENCE_AFTER_SECONDS
452 bool was_silent = (_silence_countdown == 0);
454 if (_silence_countdown >= nframes) {
455 _silence_countdown -= nframes;
457 _silence_countdown = 0;
460 if (!was_silent && _silence_countdown == 0) {
462 BecameSilent (); /* EMIT SIGNAL */
465 if (_silence_countdown == 0 || _session->silent()) {
466 PortManager::silence (nframes);
470 if (_session->silent()) {
471 PortManager::silence (nframes, _session);
475 if (session_remove_pending && session_removal_countdown) {
477 PortManager::cycle_end_fade_out (session_removal_gain, session_removal_gain_step, nframes, _session);
479 if (session_removal_countdown > nframes) {
480 session_removal_countdown -= nframes;
482 session_removal_countdown = 0;
485 session_removal_gain -= (nframes * session_removal_gain_step);
487 PortManager::cycle_end (nframes, _session);
490 _processed_samples = next_processed_samples;
498 AudioEngine::reset_silence_countdown ()
500 #ifdef SILENCE_AFTER_SECONDS
501 double sr = 48000; /* default in case there is no backend */
505 _silence_countdown = max (60 * sr, /* 60 seconds */
506 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (double) _silence_hit_cnt)));
512 AudioEngine::launch_device_control_app()
514 if (_state_lock.trylock () ) {
515 _backend->launch_control_app ();
516 _state_lock.unlock ();
522 AudioEngine::request_backend_reset()
524 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
525 g_atomic_int_inc (&_hw_reset_request_count);
526 _hw_reset_condition.signal ();
530 AudioEngine::backend_reset_requested()
532 return g_atomic_int_get (&_hw_reset_request_count);
536 AudioEngine::do_reset_backend()
538 SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 1024);
540 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
542 while (!_stop_hw_reset_processing) {
544 if (g_atomic_int_get (&_hw_reset_request_count) != 0 && _backend) {
546 _reset_request_lock.unlock();
548 Glib::Threads::RecMutex::Lock pl (_state_lock);
549 g_atomic_int_dec_and_test (&_hw_reset_request_count);
551 std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
552 DeviceResetStarted(); // notify about device reset to be started
554 // backup the device name
555 std::string name = _backend->device_name ();
557 std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
558 if ( ( 0 == stop () ) &&
559 ( 0 == _backend->reset_device () ) &&
560 ( 0 == start () ) ) {
562 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
564 // inform about possible changes
565 BufferSizeChanged (_backend->buffer_size() );
566 DeviceResetFinished(); // notify about device reset finish
570 DeviceResetFinished(); // notify about device reset finish
571 // we've got an error
575 std::cout << "AudioEngine::RESET::Done." << std::endl;
577 _reset_request_lock.lock();
581 _hw_reset_condition.wait (_reset_request_lock);
588 AudioEngine::request_device_list_update()
590 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
591 g_atomic_int_inc (&_hw_devicelist_update_count);
592 _hw_devicelist_update_condition.signal ();
596 AudioEngine::do_devicelist_update()
598 SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
600 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
602 while (!_stop_hw_devicelist_processing) {
604 if (g_atomic_int_get (&_hw_devicelist_update_count)) {
606 _devicelist_update_lock.unlock();
608 Glib::Threads::RecMutex::Lock pl (_state_lock);
610 g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
611 DeviceListChanged (); /* EMIT SIGNAL */
613 _devicelist_update_lock.lock();
616 _hw_devicelist_update_condition.wait (_devicelist_update_lock);
623 AudioEngine::start_hw_event_processing()
625 if (_hw_reset_event_thread == 0) {
626 g_atomic_int_set(&_hw_reset_request_count, 0);
627 g_atomic_int_set(&_stop_hw_reset_processing, 0);
628 _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
631 if (_hw_devicelist_update_thread == 0) {
632 g_atomic_int_set(&_hw_devicelist_update_count, 0);
633 g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
634 _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
640 AudioEngine::stop_hw_event_processing()
642 if (_hw_reset_event_thread) {
643 g_atomic_int_set(&_stop_hw_reset_processing, 1);
644 g_atomic_int_set(&_hw_reset_request_count, 0);
645 _hw_reset_condition.signal ();
646 _hw_reset_event_thread->join ();
647 _hw_reset_event_thread = 0;
650 if (_hw_devicelist_update_thread) {
651 g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
652 g_atomic_int_set(&_hw_devicelist_update_count, 0);
653 _hw_devicelist_update_condition.signal ();
654 _hw_devicelist_update_thread->join ();
655 _hw_devicelist_update_thread = 0;
660 AudioEngine::set_session (Session *s)
662 Glib::Threads::Mutex::Lock pl (_process_lock);
664 SessionHandlePtr::set_session (s);
672 AudioEngine::remove_session ()
674 Glib::Threads::Mutex::Lock lm (_process_lock);
679 session_remove_pending = true;
680 /* signal the start of the fade out countdown */
681 session_removal_countdown = -1;
682 session_removed.wait(_process_lock);
686 SessionHandlePtr::set_session (0);
695 /* called from a signal handler for SIGPIPE */
700 AudioEngine::reset_timebase ()
703 if (_session->config.get_jack_time_master()) {
704 _backend->set_time_master (true);
706 _backend->set_time_master (false);
714 AudioEngine::destroy ()
721 AudioEngine::discover_backends ()
723 vector<std::string> backend_modules;
727 Glib::PatternSpec so_extension_pattern("*backend.so");
728 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
730 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
731 #if defined(DEBUG) || defined(_DEBUG)
732 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
734 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
737 Glib::PatternSpec dll_extension_pattern("*backend.dll");
740 find_files_matching_pattern (backend_modules, backend_search_path (),
741 so_extension_pattern);
743 find_files_matching_pattern (backend_modules, backend_search_path (),
744 dylib_extension_pattern);
746 find_files_matching_pattern (backend_modules, backend_search_path (),
747 dll_extension_pattern);
749 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
751 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
753 AudioBackendInfo* info;
755 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
757 if ((info = backend_discover (*i)) != 0) {
758 _backends.insert (make_pair (info->name, info));
762 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
764 return _backends.size();
768 AudioEngine::backend_discover (const string& path)
770 #ifdef PLATFORM_WINDOWS
771 // do not show popup dialog (e.g. missing libjack.dll)
772 // win7+ should use SetThreadErrorMode()
773 SetErrorMode(SEM_FAILCRITICALERRORS);
775 Glib::Module module (path);
776 #ifdef PLATFORM_WINDOWS
777 SetErrorMode(0); // reset to system default
779 AudioBackendInfo* info;
780 AudioBackendInfo* (*dfunc)(void);
784 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
785 Glib::Module::get_last_error()) << endmsg;
789 if (!module.get_symbol ("descriptor", func)) {
790 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
791 error << Glib::Module::get_last_error() << endmsg;
795 dfunc = (AudioBackendInfo* (*)(void))func;
797 if (!info->available()) {
801 module.make_resident ();
807 static bool running_from_source_tree ()
809 // dup ARDOUR_UI_UTILS::running_from_source_tree ()
810 gchar const *x = g_getenv ("ARDOUR_THEMES_PATH");
811 return x && (string (x).find ("gtk2_ardour") != string::npos);
815 vector<const AudioBackendInfo*>
816 AudioEngine::available_backends() const
818 vector<const AudioBackendInfo*> r;
820 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
822 if (i->first == "None (Dummy)" && !running_from_source_tree () && Config->get_hide_dummy_backend ()) {
826 r.push_back (i->second);
833 AudioEngine::current_backend_name() const
836 return _backend->name();
842 AudioEngine::drop_backend ()
846 // Stopped is needed for Graph to explicitly terminate threads
847 Stopped (); /* EMIT SIGNAL */
848 _backend->drop_device ();
854 boost::shared_ptr<AudioBackend>
855 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
857 BackendMap::iterator b = _backends.find (name);
859 if (b == _backends.end()) {
860 return boost::shared_ptr<AudioBackend>();
866 if (b->second->instantiate (arg1, arg2)) {
867 throw failed_constructor ();
870 _backend = b->second->factory (*this);
872 } catch (exception& e) {
873 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
874 return boost::shared_ptr<AudioBackend>();
880 /* BACKEND PROXY WRAPPERS */
883 AudioEngine::start (bool for_latency)
889 if (_running && _backend->can_change_systemic_latency_when_running()) {
890 _started_for_latency = for_latency;
897 _processed_samples = 0;
898 last_monitor_check = 0;
900 int error_code = _backend->start (for_latency);
902 if (error_code != 0) {
903 _last_backend_error_string = AudioBackend::get_error_string((AudioBackend::ErrorCode) error_code);
910 _session->set_sample_rate (_backend->sample_rate());
912 if (_session->config.get_jack_time_master()) {
913 _backend->set_time_master (true);
918 midi_info_dirty = true;
921 /* Call the library-wide ::init_post_engine() before emitting
922 * running to ensure that its tasks are complete before any
923 * signal handlers execute. PBD::Signal does not ensure
924 * ordering of signal handlers so even if ::init_post_engine()
925 * is connected first, it may not run first.
928 ARDOUR::init_post_engine (_start_cnt);
930 Running (_start_cnt); /* EMIT SIGNAL */
932 /* latency start/stop cycles do not count as "starts" */
942 AudioEngine::stop (bool for_latency)
944 bool stop_engine = true;
950 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
956 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
958 if (_running && _started_for_latency) {
959 _backend->start (false); // keep running, reload latencies
962 if (_backend->stop ()) {
974 const bool was_running_will_stop = (_running && stop_engine);
976 if (was_running_will_stop) {
980 if (_session && was_running_will_stop && !_session->loading() && !_session->deletion_in_progress()) {
981 // it's not a halt, but should be handled the same way:
982 // disable record, stop transport and I/O processign but save the data.
983 _session->engine_halted ();
986 if (was_running_will_stop) {
988 _started_for_latency = false;
989 } else if (!_started_for_latency) {
990 _stopped_for_latency = true;
993 _processed_samples = 0;
994 _measuring_latency = MeasureNone;
995 _latency_output_port = 0;
996 _latency_input_port = 0;
1003 TransportMasterManager& tmm (TransportMasterManager::instance());
1004 tmm.engine_stopped ();
1005 Stopped (); /* EMIT SIGNAL */
1012 AudioEngine::freewheel (bool start_stop)
1018 /* _freewheeling will be set when first Freewheel signal occurs */
1020 return _backend->freewheel (start_stop);
1024 AudioEngine::get_dsp_load() const
1026 if (!_backend || !_running) {
1029 return _backend->dsp_load ();
1033 AudioEngine::is_realtime() const
1039 return _backend->is_realtime();
1043 AudioEngine::transport_start ()
1048 return _backend->transport_start ();
1052 AudioEngine::transport_stop ()
1057 return _backend->transport_stop ();
1061 AudioEngine::transport_state ()
1064 return TransportStopped;
1066 return _backend->transport_state ();
1070 AudioEngine::transport_locate (samplepos_t pos)
1075 return _backend->transport_locate (pos);
1079 AudioEngine::transport_sample()
1084 return _backend->transport_sample ();
1088 AudioEngine::sample_rate () const
1093 return _backend->sample_rate ();
1097 AudioEngine::samples_per_cycle () const
1102 return _backend->buffer_size ();
1106 AudioEngine::usecs_per_cycle () const
1111 return _backend->usecs_per_cycle ();
1115 AudioEngine::raw_buffer_size (DataType t)
1120 return _backend->raw_buffer_size (t);
1124 AudioEngine::sample_time ()
1129 return _backend->sample_time ();
1133 AudioEngine::sample_time_at_cycle_start ()
1138 return _backend->sample_time_at_cycle_start ();
1142 AudioEngine::samples_since_cycle_start ()
1147 return _backend->samples_since_cycle_start ();
1151 AudioEngine::get_sync_offset (pframes_t& offset) const
1156 return _backend->get_sync_offset (offset);
1160 AudioEngine::create_process_thread (boost::function<void()> func)
1165 return _backend->create_process_thread (func);
1169 AudioEngine::join_process_threads ()
1174 return _backend->join_process_threads ();
1178 AudioEngine::in_process_thread ()
1183 return _backend->in_process_thread ();
1187 AudioEngine::process_thread_count ()
1192 return _backend->process_thread_count ();
1196 AudioEngine::set_device_name (const std::string& name)
1201 return _backend->set_device_name (name);
1205 AudioEngine::set_sample_rate (float sr)
1211 return _backend->set_sample_rate (sr);
1215 AudioEngine::set_buffer_size (uint32_t bufsiz)
1220 return _backend->set_buffer_size (bufsiz);
1224 AudioEngine::set_interleaved (bool yn)
1229 return _backend->set_interleaved (yn);
1233 AudioEngine::set_input_channels (uint32_t ic)
1238 return _backend->set_input_channels (ic);
1242 AudioEngine::set_output_channels (uint32_t oc)
1247 return _backend->set_output_channels (oc);
1251 AudioEngine::set_systemic_input_latency (uint32_t il)
1256 return _backend->set_systemic_input_latency (il);
1260 AudioEngine::set_systemic_output_latency (uint32_t ol)
1265 return _backend->set_systemic_output_latency (ol);
1269 AudioEngine::thread_initialised_for_audio_processing ()
1271 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1274 /* END OF BACKEND PROXY API */
1277 AudioEngine::thread_init_callback (void* arg)
1279 /* make sure that anybody who needs to know about this thread
1283 pthread_set_name (X_("audioengine"));
1285 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1286 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1288 SessionEvent::create_per_thread_pool (thread_name, 512);
1289 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1290 AsyncMIDIPort::set_process_thread (pthread_self());
1293 delete AudioEngine::instance()->_main_thread;
1294 /* the special thread created/managed by the backend */
1295 AudioEngine::instance()->_main_thread = new ProcessThread;
1300 AudioEngine::sync_callback (TransportState state, samplepos_t position)
1303 return _session->backend_sync_callback (state, position);
1309 AudioEngine::freewheel_callback (bool onoff)
1311 _freewheeling = onoff;
1315 AudioEngine::latency_callback (bool for_playback)
1318 _session->update_latency (for_playback);
1323 AudioEngine::update_latencies ()
1326 _backend->update_latencies ();
1331 AudioEngine::halted_callback (const char* why)
1333 if (_in_destructor) {
1334 /* everything is under control */
1340 Port::PortDrop (); /* EMIT SIGNAL */
1342 if (!_started_for_latency) {
1343 Halted (why); /* EMIT SIGNAL */
1348 AudioEngine::setup_required () const
1351 if (_backend->info().already_configured())
1354 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1363 AudioEngine::prepare_for_latency_measurement ()
1369 if (running() && _started_for_latency) {
1373 if (_backend->can_change_systemic_latency_when_running()) {
1375 _backend->start (true); // zero latency reporting of running backend
1376 } else if (start (true)) {
1379 _started_for_latency = true;
1390 _started_for_latency = true;
1395 AudioEngine::start_latency_detection (bool for_midi)
1397 if (prepare_for_latency_measurement ()) {
1401 PortEngine& pe (port_engine());
1409 /* find the ports we will connect to */
1411 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1412 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1419 /* create the ports we will use to read/write data */
1421 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1425 if (pe.connect (_latency_output_port, _latency_output_name)) {
1426 pe.unregister_port (_latency_output_port);
1431 const string portname ("latency_in");
1432 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1433 pe.unregister_port (_latency_input_port);
1434 pe.unregister_port (_latency_output_port);
1438 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1439 pe.unregister_port (_latency_input_port);
1440 pe.unregister_port (_latency_output_port);
1445 _mididm = new MIDIDM (sample_rate());
1449 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1453 if (pe.connect (_latency_output_port, _latency_output_name)) {
1454 pe.unregister_port (_latency_output_port);
1459 const string portname ("latency_in");
1460 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1461 pe.unregister_port (_latency_input_port);
1462 pe.unregister_port (_latency_output_port);
1466 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1467 pe.unregister_port (_latency_input_port);
1468 pe.unregister_port (_latency_output_port);
1473 _mtdm = new MTDM (sample_rate());
1478 _latency_signal_latency = 0;
1479 lr = pe.get_latency_range (in, false);
1480 _latency_signal_latency = lr.max;
1481 lr = pe.get_latency_range (out, true);
1482 _latency_signal_latency += lr.max;
1484 /* all created and connected, lets go */
1485 _latency_flush_samples = samples_per_cycle();
1486 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1492 AudioEngine::stop_latency_detection ()
1494 _measuring_latency = MeasureNone;
1496 if (_latency_output_port) {
1497 port_engine().unregister_port (_latency_output_port);
1498 _latency_output_port = 0;
1500 if (_latency_input_port) {
1501 port_engine().unregister_port (_latency_input_port);
1502 _latency_input_port = 0;
1505 if (_running && _backend->can_change_systemic_latency_when_running()) {
1506 if (_started_for_latency) {
1507 _running = false; // force reload: reset latencies and emit Running()
1512 if (_running && !_started_for_latency) {
1513 assert (!_stopped_for_latency);
1517 if (!_backend->can_change_systemic_latency_when_running()) {
1521 if (_stopped_for_latency) {
1525 _stopped_for_latency = false;
1526 _started_for_latency = false;
1530 AudioEngine::set_latency_output_port (const string& name)
1532 _latency_output_name = name;
1536 AudioEngine::set_latency_input_port (const string& name)
1538 _latency_input_name = name;
1542 AudioEngine::add_pending_port_deletion (Port* p)
1545 DEBUG_TRACE (DEBUG::Ports, string_compose ("adding %1 to pending port deletion list\n", p->name()));
1546 if (_port_deletions_pending.write (&p, 1) != 1) {
1547 error << string_compose (_("programming error: port %1 could not be placed on the pending deletion queue\n"), p->name()) << endmsg;
1549 _session->auto_connect_thread_wakeup ();
1551 DEBUG_TRACE (DEBUG::Ports, string_compose ("Directly delete port %1\n", p->name()));