2 Copyright (C) 2002 Paul Davis
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.
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.
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.
28 #include <glibmm/timer.h>
29 #include <glibmm/pattern.h>
30 #include <glibmm/module.h>
33 #include "pbd/file_utils.h"
34 #include "pbd/pthread_utils.h"
35 #include "pbd/stacktrace.h"
36 #include "pbd/unknown_type.h"
38 #include "midi++/port.h"
39 #include "midi++/mmc.h"
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/rc_configuration.h"
57 #include "ardour/session.h"
62 using namespace ARDOUR;
65 AudioEngine* AudioEngine::_instance = 0;
67 static gint audioengine_thread_cnt = 1;
70 #define SILENCE_AFTER_SECONDS 600
73 AudioEngine::AudioEngine ()
74 : session_remove_pending (false)
75 , session_removal_countdown (-1)
77 , _freewheeling (false)
78 , monitor_check_interval (INT32_MAX)
79 , last_monitor_check (0)
80 , _processed_samples (0)
85 , _measuring_latency (MeasureNone)
86 , _latency_input_port (0)
87 , _latency_output_port (0)
88 , _latency_flush_samples (0)
89 , _latency_signal_latency (0)
90 , _stopped_for_latency (false)
91 , _started_for_latency (false)
92 , _in_destructor (false)
93 , _last_backend_error_string(AudioBackend::get_error_string((AudioBackend::ErrorCode)-1))
94 , _hw_reset_event_thread(0)
95 , _hw_reset_request_count(0)
96 , _stop_hw_reset_processing(0)
97 , _hw_devicelist_update_thread(0)
98 , _hw_devicelist_update_count(0)
99 , _stop_hw_devicelist_processing(0)
100 #ifdef SILENCE_AFTER_SECONDS
101 , _silence_countdown (0)
102 , _silence_hit_cnt (0)
105 reset_silence_countdown ();
106 start_hw_event_processing();
107 discover_backends ();
110 AudioEngine::~AudioEngine ()
112 _in_destructor = true;
113 stop_hw_event_processing();
115 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
116 i->second->deinstantiate();
122 AudioEngine::create ()
128 _instance = new AudioEngine ();
134 AudioEngine::split_cycle (pframes_t offset)
136 /* caller must hold process lock */
138 Port::increment_global_port_buffer_offset (offset);
140 /* tell all Ports that we're going to start a new (split) cycle */
142 boost::shared_ptr<Ports> p = ports.reader();
144 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
145 i->second->cycle_split ();
150 AudioEngine::sample_rate_change (pframes_t nframes)
152 /* check for monitor input change every 1/10th of second */
154 monitor_check_interval = nframes / 10;
155 last_monitor_check = 0;
158 _session->set_sample_rate (nframes);
161 SampleRateChanged (nframes); /* EMIT SIGNAL */
163 #ifdef SILENCE_AFTER_SECONDS
164 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
171 AudioEngine::buffer_size_change (pframes_t bufsiz)
174 _session->set_block_size (bufsiz);
175 last_monitor_check = 0;
178 BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
183 /** Method called by our ::process_thread when there is work to be done.
184 * @param nframes Number of samples to process.
187 __attribute__((annotate("realtime")))
190 AudioEngine::process_callback (pframes_t nframes)
192 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
193 Port::set_speed_ratio (1.0);
198 /// The number of samples that will have been processed when we've finished
199 pframes_t next_processed_samples;
201 /* handle wrap around of total samples counter */
203 if (max_samplepos - _processed_samples < nframes) {
204 next_processed_samples = nframes - (max_samplepos - _processed_samples);
206 next_processed_samples = _processed_samples + nframes;
210 /* return having done nothing */
214 /* really only JACK requires this
215 * (other backends clear the output buffers
216 * before the process_callback. it may even be
217 * jack/alsa only). but better safe than sorry.
219 PortManager::silence_outputs (nframes);
223 /* The coreaudio-backend calls thread_init_callback() if
224 * the hardware changes or pthread_self() changes.
226 * However there are cases when neither holds true, yet
227 * the thread-pool changes: e.g. connect a headphone to
228 * a shared mic/headphone jack.
229 * It's probably related to, or caused by clocksource changes.
231 * For reasons yet unknown Glib::Threads::Private() can
232 * use a different thread-private in the same pthread
233 * (coreaudio render callback).
235 * Coreaudio must set something which influences
236 * pthread_key_t uniqness or reset the key using
237 * pthread_getspecific().
239 if (! SessionEvent::has_per_thread_pool ()) {
240 thread_init_callback (NULL);
243 bool return_after_remove_check = false;
245 if (_measuring_latency == MeasureAudio && _mtdm) {
246 /* run a normal cycle from the perspective of the PortManager
247 so that we get silence on all registered ports.
249 we overwrite the silence on the two ports used for latency
253 PortManager::cycle_start (nframes);
254 PortManager::silence (nframes);
256 if (_latency_input_port && _latency_output_port) {
257 PortEngine& pe (port_engine());
259 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
260 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
262 _mtdm->process (nframes, in, out);
265 PortManager::cycle_end (nframes);
266 return_after_remove_check = true;
268 } else if (_measuring_latency == MeasureMIDI && _mididm) {
269 /* run a normal cycle from the perspective of the PortManager
270 so that we get silence on all registered ports.
272 we overwrite the silence on the two ports used for latency
276 PortManager::cycle_start (nframes);
277 PortManager::silence (nframes);
279 if (_latency_input_port && _latency_output_port) {
280 PortEngine& pe (port_engine());
282 _mididm->process (nframes, pe,
283 pe.get_buffer (_latency_input_port, nframes),
284 pe.get_buffer (_latency_output_port, nframes));
287 PortManager::cycle_end (nframes);
288 return_after_remove_check = true;
290 } else if (_latency_flush_samples) {
292 /* wait for the appropriate duration for the MTDM signal to
293 * drain from the ports before we revert to normal behaviour.
296 PortManager::cycle_start (nframes);
297 PortManager::silence (nframes);
298 PortManager::cycle_end (nframes);
300 if (_latency_flush_samples > nframes) {
301 _latency_flush_samples -= nframes;
303 _latency_flush_samples = 0;
306 return_after_remove_check = true;
309 if (session_remove_pending) {
311 /* perform the actual session removal */
313 if (session_removal_countdown < 0) {
315 /* fade out over 1 second */
316 session_removal_countdown = sample_rate()/2;
317 session_removal_gain = GAIN_COEFF_UNITY;
318 session_removal_gain_step = 1.0/session_removal_countdown;
320 } else if (session_removal_countdown > 0) {
322 /* we'll be fading audio out.
324 if this is the last time we do this as part
325 of session removal, do a MIDI panic now
326 to get MIDI stopped. This relies on the fact
327 that "immediate data" (aka "out of band data") from
328 MIDI tracks is *appended* after any other data,
329 so that it emerges after any outbound note ons, etc.
332 if (session_removal_countdown <= nframes) {
333 _session->midi_panic ();
339 session_removal_countdown = -1; // reset to "not in progress"
340 session_remove_pending = false;
341 session_removed.signal(); // wakes up thread that initiated session removal
345 if (return_after_remove_check) {
351 if (!_freewheeling) {
352 PortManager::cycle_start (nframes);
353 PortManager::cycle_end (nframes);
356 _processed_samples = next_processed_samples;
361 if (!_freewheeling || Freewheel.empty()) {
362 // run a list of slaves here
363 // - multiple slaves (ow_many_dsp_threads() in paralell)
364 // - session can pick one (ask for position & speed)
365 // - GUI can display all
366 Port::set_speed_ratio (_session->engine_speed ());
369 /* tell all relevant objects that we're starting a new cycle */
371 InternalSend::CycleStart (nframes);
373 /* tell all Ports that we're starting a new cycle */
375 PortManager::cycle_start (nframes);
377 /* test if we are freewheeling and there are freewheel signals connected.
378 * ardour should act normally even when freewheeling unless /it/ is
379 * exporting (which is what Freewheel.empty() tests for).
382 if (_freewheeling && !Freewheel.empty()) {
385 if (Port::cycle_nframes () <= nframes) {
386 _session->process (Port::cycle_nframes ());
388 pframes_t remain = Port::cycle_nframes ();
390 pframes_t nf = std::min (remain, nframes);
391 _session->process (nf);
401 PortManager::cycle_end (nframes);
406 _processed_samples = next_processed_samples;
410 if (last_monitor_check + monitor_check_interval < next_processed_samples) {
412 PortManager::check_monitoring ();
413 last_monitor_check = next_processed_samples;
416 #ifdef SILENCE_AFTER_SECONDS
418 bool was_silent = (_silence_countdown == 0);
420 if (_silence_countdown >= nframes) {
421 _silence_countdown -= nframes;
423 _silence_countdown = 0;
426 if (!was_silent && _silence_countdown == 0) {
428 BecameSilent (); /* EMIT SIGNAL */
431 if (_silence_countdown == 0 || _session->silent()) {
432 PortManager::silence (nframes);
436 if (_session->silent()) {
437 PortManager::silence (nframes, _session);
441 if (session_remove_pending && session_removal_countdown) {
443 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
445 if (session_removal_countdown > nframes) {
446 session_removal_countdown -= nframes;
448 session_removal_countdown = 0;
451 session_removal_gain -= (nframes * session_removal_gain_step);
454 PortManager::cycle_end (nframes);
456 _processed_samples = next_processed_samples;
464 AudioEngine::reset_silence_countdown ()
466 #ifdef SILENCE_AFTER_SECONDS
467 double sr = 48000; /* default in case there is no backend */
471 _silence_countdown = max (60 * sr, /* 60 seconds */
472 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (double) _silence_hit_cnt)));
478 AudioEngine::launch_device_control_app()
480 if (_state_lock.trylock () ) {
481 _backend->launch_control_app ();
482 _state_lock.unlock ();
488 AudioEngine::request_backend_reset()
490 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
491 g_atomic_int_inc (&_hw_reset_request_count);
492 _hw_reset_condition.signal ();
496 AudioEngine::backend_reset_requested()
498 return g_atomic_int_get (&_hw_reset_request_count);
502 AudioEngine::do_reset_backend()
504 SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 1024);
506 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
508 while (!_stop_hw_reset_processing) {
510 if (g_atomic_int_get (&_hw_reset_request_count) != 0 && _backend) {
512 _reset_request_lock.unlock();
514 Glib::Threads::RecMutex::Lock pl (_state_lock);
515 g_atomic_int_dec_and_test (&_hw_reset_request_count);
517 std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
518 DeviceResetStarted(); // notify about device reset to be started
520 // backup the device name
521 std::string name = _backend->device_name ();
523 std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
524 if ( ( 0 == stop () ) &&
525 ( 0 == _backend->reset_device () ) &&
526 ( 0 == start () ) ) {
528 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
530 // inform about possible changes
531 BufferSizeChanged (_backend->buffer_size() );
532 DeviceResetFinished(); // notify about device reset finish
536 DeviceResetFinished(); // notify about device reset finish
537 // we've got an error
541 std::cout << "AudioEngine::RESET::Done." << std::endl;
543 _reset_request_lock.lock();
547 _hw_reset_condition.wait (_reset_request_lock);
554 AudioEngine::request_device_list_update()
556 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
557 g_atomic_int_inc (&_hw_devicelist_update_count);
558 _hw_devicelist_update_condition.signal ();
562 AudioEngine::do_devicelist_update()
564 SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
566 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
568 while (!_stop_hw_devicelist_processing) {
570 if (_hw_devicelist_update_count) {
572 _devicelist_update_lock.unlock();
574 Glib::Threads::RecMutex::Lock pl (_state_lock);
576 g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
577 DeviceListChanged (); /* EMIT SIGNAL */
579 _devicelist_update_lock.lock();
582 _hw_devicelist_update_condition.wait (_devicelist_update_lock);
589 AudioEngine::start_hw_event_processing()
591 if (_hw_reset_event_thread == 0) {
592 g_atomic_int_set(&_hw_reset_request_count, 0);
593 g_atomic_int_set(&_stop_hw_reset_processing, 0);
594 _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
597 if (_hw_devicelist_update_thread == 0) {
598 g_atomic_int_set(&_hw_devicelist_update_count, 0);
599 g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
600 _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
606 AudioEngine::stop_hw_event_processing()
608 if (_hw_reset_event_thread) {
609 g_atomic_int_set(&_stop_hw_reset_processing, 1);
610 g_atomic_int_set(&_hw_reset_request_count, 0);
611 _hw_reset_condition.signal ();
612 _hw_reset_event_thread->join ();
613 _hw_reset_event_thread = 0;
616 if (_hw_devicelist_update_thread) {
617 g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
618 g_atomic_int_set(&_hw_devicelist_update_count, 0);
619 _hw_devicelist_update_condition.signal ();
620 _hw_devicelist_update_thread->join ();
621 _hw_devicelist_update_thread = 0;
626 AudioEngine::set_session (Session *s)
628 Glib::Threads::Mutex::Lock pl (_process_lock);
630 SessionHandlePtr::set_session (s);
634 pframes_t blocksize = samples_per_cycle ();
636 PortManager::cycle_start (blocksize);
638 _session->process (blocksize);
639 _session->process (blocksize);
640 _session->process (blocksize);
641 _session->process (blocksize);
642 _session->process (blocksize);
643 _session->process (blocksize);
644 _session->process (blocksize);
645 _session->process (blocksize);
647 PortManager::cycle_end (blocksize);
652 AudioEngine::remove_session ()
654 Glib::Threads::Mutex::Lock lm (_process_lock);
659 session_remove_pending = true;
660 /* signal the start of the fade out countdown */
661 session_removal_countdown = -1;
662 session_removed.wait(_process_lock);
666 SessionHandlePtr::set_session (0);
674 AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs)
676 #ifdef USE_TRACKS_CODE_FEATURES
678 _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs);
687 /* called from a signal handler for SIGPIPE */
692 AudioEngine::reset_timebase ()
695 if (_session->config.get_jack_time_master()) {
696 _backend->set_time_master (true);
698 _backend->set_time_master (false);
706 AudioEngine::destroy ()
713 AudioEngine::discover_backends ()
715 vector<std::string> backend_modules;
719 Glib::PatternSpec so_extension_pattern("*backend.so");
720 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
722 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
723 #if defined(DEBUG) || defined(_DEBUG)
724 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
726 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
729 Glib::PatternSpec dll_extension_pattern("*backend.dll");
732 find_files_matching_pattern (backend_modules, backend_search_path (),
733 so_extension_pattern);
735 find_files_matching_pattern (backend_modules, backend_search_path (),
736 dylib_extension_pattern);
738 find_files_matching_pattern (backend_modules, backend_search_path (),
739 dll_extension_pattern);
741 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
743 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
745 AudioBackendInfo* info;
747 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
749 if ((info = backend_discover (*i)) != 0) {
750 _backends.insert (make_pair (info->name, info));
754 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
756 return _backends.size();
760 AudioEngine::backend_discover (const string& path)
762 #ifdef PLATFORM_WINDOWS
763 // do not show popup dialog (e.g. missing libjack.dll)
764 // win7+ should use SetThreadErrorMode()
765 SetErrorMode(SEM_FAILCRITICALERRORS);
767 Glib::Module module (path);
768 #ifdef PLATFORM_WINDOWS
769 SetErrorMode(0); // reset to system default
771 AudioBackendInfo* info;
772 AudioBackendInfo* (*dfunc)(void);
776 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
777 Glib::Module::get_last_error()) << endmsg;
781 if (!module.get_symbol ("descriptor", func)) {
782 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
783 error << Glib::Module::get_last_error() << endmsg;
787 dfunc = (AudioBackendInfo* (*)(void))func;
789 if (!info->available()) {
793 module.make_resident ();
799 static bool running_from_source_tree ()
801 // dup ARDOUR_UI_UTILS::running_from_source_tree ()
802 gchar const *x = g_getenv ("ARDOUR_THEMES_PATH");
803 return x && (string (x).find ("gtk2_ardour") != string::npos);
807 vector<const AudioBackendInfo*>
808 AudioEngine::available_backends() const
810 vector<const AudioBackendInfo*> r;
812 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
814 if (i->first == "None (Dummy)" && !running_from_source_tree () && Config->get_hide_dummy_backend ()) {
818 r.push_back (i->second);
825 AudioEngine::current_backend_name() const
828 return _backend->name();
834 AudioEngine::drop_backend ()
838 // Stopped is needed for Graph to explicitly terminate threads
839 Stopped (); /* EMIT SIGNAL */
840 _backend->drop_device ();
846 boost::shared_ptr<AudioBackend>
847 AudioEngine::set_default_backend ()
849 if (_backends.empty()) {
850 return boost::shared_ptr<AudioBackend>();
853 return set_backend (_backends.begin()->first, "", "");
856 boost::shared_ptr<AudioBackend>
857 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
859 BackendMap::iterator b = _backends.find (name);
861 if (b == _backends.end()) {
862 return boost::shared_ptr<AudioBackend>();
868 if (b->second->instantiate (arg1, arg2)) {
869 throw failed_constructor ();
872 _backend = b->second->factory (*this);
874 } catch (exception& e) {
875 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
876 return boost::shared_ptr<AudioBackend>();
882 /* BACKEND PROXY WRAPPERS */
885 AudioEngine::start (bool for_latency)
895 _processed_samples = 0;
896 last_monitor_check = 0;
898 int error_code = _backend->start (for_latency);
900 if (error_code != 0) {
901 _last_backend_error_string = AudioBackend::get_error_string((AudioBackend::ErrorCode) error_code);
908 _session->set_sample_rate (_backend->sample_rate());
910 if (_session->config.get_jack_time_master()) {
911 _backend->set_time_master (true);
916 /* XXX MIDI ports may not actually be available here yet .. */
918 PortManager::fill_midi_port_info ();
921 Running(); /* EMIT SIGNAL */
928 AudioEngine::stop (bool for_latency)
930 bool stop_engine = true;
936 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
942 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
945 _backend->start (false); // keep running, reload latencies
948 if (_backend->stop ()) {
960 if (_session && _running && stop_engine &&
961 (_session->state_of_the_state() & Session::Loading) == 0 &&
962 (_session->state_of_the_state() & Session::Deletion) == 0) {
963 // it's not a halt, but should be handled the same way:
964 // disable record, stop transport and I/O processign but save the data.
965 _session->engine_halted ();
968 if (stop_engine && _running) {
971 _started_for_latency = false;
972 } else if (!_started_for_latency) {
973 _stopped_for_latency = true;
976 _processed_samples = 0;
977 _measuring_latency = MeasureNone;
978 _latency_output_port = 0;
979 _latency_input_port = 0;
986 Stopped (); /* EMIT SIGNAL */
993 AudioEngine::freewheel (bool start_stop)
999 /* _freewheeling will be set when first Freewheel signal occurs */
1001 return _backend->freewheel (start_stop);
1005 AudioEngine::get_dsp_load() const
1007 if (!_backend || !_running) {
1010 return _backend->dsp_load ();
1014 AudioEngine::is_realtime() const
1020 return _backend->is_realtime();
1024 AudioEngine::connected() const
1030 return _backend->available();
1034 AudioEngine::transport_start ()
1039 return _backend->transport_start ();
1043 AudioEngine::transport_stop ()
1048 return _backend->transport_stop ();
1052 AudioEngine::transport_state ()
1055 return TransportStopped;
1057 return _backend->transport_state ();
1061 AudioEngine::transport_locate (samplepos_t pos)
1066 return _backend->transport_locate (pos);
1070 AudioEngine::transport_sample()
1075 return _backend->transport_sample ();
1079 AudioEngine::sample_rate () const
1084 return _backend->sample_rate ();
1088 AudioEngine::samples_per_cycle () const
1093 return _backend->buffer_size ();
1097 AudioEngine::usecs_per_cycle () const
1102 return _backend->usecs_per_cycle ();
1106 AudioEngine::raw_buffer_size (DataType t)
1111 return _backend->raw_buffer_size (t);
1115 AudioEngine::sample_time ()
1120 return _backend->sample_time ();
1124 AudioEngine::sample_time_at_cycle_start ()
1129 return _backend->sample_time_at_cycle_start ();
1133 AudioEngine::samples_since_cycle_start ()
1138 return _backend->samples_since_cycle_start ();
1142 AudioEngine::get_sync_offset (pframes_t& offset) const
1147 return _backend->get_sync_offset (offset);
1151 AudioEngine::create_process_thread (boost::function<void()> func)
1156 return _backend->create_process_thread (func);
1160 AudioEngine::join_process_threads ()
1165 return _backend->join_process_threads ();
1169 AudioEngine::in_process_thread ()
1174 return _backend->in_process_thread ();
1178 AudioEngine::process_thread_count ()
1183 return _backend->process_thread_count ();
1187 AudioEngine::set_device_name (const std::string& name)
1192 return _backend->set_device_name (name);
1196 AudioEngine::set_sample_rate (float sr)
1202 return _backend->set_sample_rate (sr);
1206 AudioEngine::set_buffer_size (uint32_t bufsiz)
1211 return _backend->set_buffer_size (bufsiz);
1215 AudioEngine::set_interleaved (bool yn)
1220 return _backend->set_interleaved (yn);
1224 AudioEngine::set_input_channels (uint32_t ic)
1229 return _backend->set_input_channels (ic);
1233 AudioEngine::set_output_channels (uint32_t oc)
1238 return _backend->set_output_channels (oc);
1242 AudioEngine::set_systemic_input_latency (uint32_t il)
1247 return _backend->set_systemic_input_latency (il);
1251 AudioEngine::set_systemic_output_latency (uint32_t ol)
1256 return _backend->set_systemic_output_latency (ol);
1260 AudioEngine::thread_initialised_for_audio_processing ()
1262 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1265 /* END OF BACKEND PROXY API */
1268 AudioEngine::thread_init_callback (void* arg)
1270 /* make sure that anybody who needs to know about this thread
1274 pthread_set_name (X_("audioengine"));
1276 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1277 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1279 SessionEvent::create_per_thread_pool (thread_name, 512);
1280 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1281 AsyncMIDIPort::set_process_thread (pthread_self());
1284 delete AudioEngine::instance()->_main_thread;
1285 /* the special thread created/managed by the backend */
1286 AudioEngine::instance()->_main_thread = new ProcessThread;
1291 AudioEngine::sync_callback (TransportState state, samplepos_t position)
1294 return _session->backend_sync_callback (state, position);
1300 AudioEngine::freewheel_callback (bool onoff)
1302 _freewheeling = onoff;
1306 AudioEngine::latency_callback (bool for_playback)
1309 _session->update_latency (for_playback);
1314 AudioEngine::update_latencies ()
1317 _backend->update_latencies ();
1322 AudioEngine::halted_callback (const char* why)
1324 if (_in_destructor) {
1325 /* everything is under control */
1331 Port::PortDrop (); /* EMIT SIGNAL */
1333 if (!_started_for_latency) {
1334 Halted (why); /* EMIT SIGNAL */
1339 AudioEngine::setup_required () const
1342 if (_backend->info().already_configured())
1345 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1354 AudioEngine::prepare_for_latency_measurement ()
1360 if (running() && _started_for_latency) {
1364 if (_backend->can_change_systemic_latency_when_running()) {
1366 _backend->start (true); // zero latency reporting of running backend
1367 } else if (start (true)) {
1370 _started_for_latency = true;
1381 _started_for_latency = true;
1386 AudioEngine::start_latency_detection (bool for_midi)
1388 if (prepare_for_latency_measurement ()) {
1392 PortEngine& pe (port_engine());
1400 /* find the ports we will connect to */
1402 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1403 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1410 /* create the ports we will use to read/write data */
1412 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1416 if (pe.connect (_latency_output_port, _latency_output_name)) {
1417 pe.unregister_port (_latency_output_port);
1422 const string portname ("latency_in");
1423 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1424 pe.unregister_port (_latency_input_port);
1425 pe.unregister_port (_latency_output_port);
1429 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1430 pe.unregister_port (_latency_input_port);
1431 pe.unregister_port (_latency_output_port);
1436 _mididm = new MIDIDM (sample_rate());
1440 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1444 if (pe.connect (_latency_output_port, _latency_output_name)) {
1445 pe.unregister_port (_latency_output_port);
1450 const string portname ("latency_in");
1451 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1452 pe.unregister_port (_latency_input_port);
1453 pe.unregister_port (_latency_output_port);
1457 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1458 pe.unregister_port (_latency_input_port);
1459 pe.unregister_port (_latency_output_port);
1464 _mtdm = new MTDM (sample_rate());
1469 _latency_signal_latency = 0;
1470 lr = pe.get_latency_range (in, false);
1471 _latency_signal_latency = lr.max;
1472 lr = pe.get_latency_range (out, true);
1473 _latency_signal_latency += lr.max;
1475 /* all created and connected, lets go */
1476 _latency_flush_samples = samples_per_cycle();
1477 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1483 AudioEngine::stop_latency_detection ()
1485 _measuring_latency = MeasureNone;
1487 if (_latency_output_port) {
1488 port_engine().unregister_port (_latency_output_port);
1489 _latency_output_port = 0;
1491 if (_latency_input_port) {
1492 port_engine().unregister_port (_latency_input_port);
1493 _latency_input_port = 0;
1496 if (_running && _backend->can_change_systemic_latency_when_running()) {
1497 if (_started_for_latency) {
1498 _running = false; // force reload: reset latencies and emit Running()
1503 if (_running && !_started_for_latency) {
1504 assert (!_stopped_for_latency);
1508 if (!_backend->can_change_systemic_latency_when_running()) {
1512 if (_stopped_for_latency) {
1516 _stopped_for_latency = false;
1517 _started_for_latency = false;
1521 AudioEngine::set_latency_output_port (const string& name)
1523 _latency_output_name = name;
1527 AudioEngine::set_latency_input_port (const string& name)
1529 _latency_input_name = name;
1533 AudioEngine::add_pending_port_deletion (Port* p)
1536 DEBUG_TRACE (DEBUG::Ports, string_compose ("adding %1 to pending port deletion list\n", p->name()));
1537 if (_port_deletions_pending.write (&p, 1) != 1) {
1538 error << string_compose (_("programming error: port %1 could not be placed on the pending deletion queue\n"), p->name()) << endmsg;
1540 _session->auto_connect_thread_wakeup ();
1542 DEBUG_TRACE (DEBUG::Ports, string_compose ("Directly delete port %1\n", p->name()));