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/session.h"
61 using namespace ARDOUR;
64 AudioEngine* AudioEngine::_instance = 0;
66 static gint audioengine_thread_cnt = 1;
69 #define SILENCE_AFTER_SECONDS 600
72 AudioEngine::AudioEngine ()
73 : session_remove_pending (false)
74 , session_removal_countdown (-1)
76 , _freewheeling (false)
77 , monitor_check_interval (INT32_MAX)
78 , last_monitor_check (0)
79 , _processed_frames (0)
84 , _measuring_latency (MeasureNone)
85 , _latency_input_port (0)
86 , _latency_output_port (0)
87 , _latency_flush_frames (0)
88 , _latency_signal_latency (0)
89 , _stopped_for_latency (false)
90 , _started_for_latency (false)
91 , _in_destructor (false)
92 , _last_backend_error_string(AudioBackend::get_error_string((AudioBackend::ErrorCode)-1))
93 , _hw_reset_event_thread(0)
94 , _hw_reset_request_count(0)
95 , _stop_hw_reset_processing(0)
96 , _hw_devicelist_update_thread(0)
97 , _hw_devicelist_update_count(0)
98 , _stop_hw_devicelist_processing(0)
99 #ifdef SILENCE_AFTER_SECONDS
100 , _silence_countdown (0)
101 , _silence_hit_cnt (0)
104 reset_silence_countdown ();
105 start_hw_event_processing();
106 discover_backends ();
109 AudioEngine::~AudioEngine ()
111 _in_destructor = true;
112 stop_hw_event_processing();
114 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
115 i->second->deinstantiate();
121 AudioEngine::create ()
127 _instance = new AudioEngine ();
133 AudioEngine::split_cycle (pframes_t offset)
135 /* caller must hold process lock */
137 Port::increment_global_port_buffer_offset (offset);
139 /* tell all Ports that we're going to start a new (split) cycle */
141 boost::shared_ptr<Ports> p = ports.reader();
143 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
144 i->second->cycle_split ();
149 AudioEngine::sample_rate_change (pframes_t nframes)
151 /* check for monitor input change every 1/10th of second */
153 monitor_check_interval = nframes / 10;
154 last_monitor_check = 0;
157 _session->set_frame_rate (nframes);
160 SampleRateChanged (nframes); /* EMIT SIGNAL */
162 #ifdef SILENCE_AFTER_SECONDS
163 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
170 AudioEngine::buffer_size_change (pframes_t bufsiz)
173 _session->set_block_size (bufsiz);
174 last_monitor_check = 0;
177 BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
182 /** Method called by our ::process_thread when there is work to be done.
183 * @param nframes Number of frames to process.
186 __attribute__((annotate("realtime")))
189 AudioEngine::process_callback (pframes_t nframes)
191 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
196 /// The number of frames that will have been processed when we've finished
197 pframes_t next_processed_frames;
199 /* handle wrap around of total frames counter */
201 if (max_framepos - _processed_frames < nframes) {
202 next_processed_frames = nframes - (max_framepos - _processed_frames);
204 next_processed_frames = _processed_frames + nframes;
208 /* return having done nothing */
212 /* really only JACK requires this
213 * (other backends clear the output buffers
214 * before the process_callback. it may even be
215 * jack/alsa only). but better safe than sorry.
217 PortManager::silence_outputs (nframes);
221 /* The coreaudio-backend calls thread_init_callback() if
222 * the hardware changes or pthread_self() changes.
224 * However there are cases when neither holds true, yet
225 * the thread-pool changes: e.g. connect a headphone to
226 * a shared mic/headphone jack.
227 * It's probably related to, or caused by clocksource changes.
229 * For reasons yet unknown Glib::Threads::Private() can
230 * use a different thread-private in the same pthread
231 * (coreaudio render callback).
233 * Coreaudio must set something which influences
234 * pthread_key_t uniqness or reset the key using
235 * pthread_getspecific().
237 if (! SessionEvent::has_per_thread_pool ()) {
238 thread_init_callback (NULL);
241 bool return_after_remove_check = false;
243 if (_measuring_latency == MeasureAudio && _mtdm) {
244 /* run a normal cycle from the perspective of the PortManager
245 so that we get silence on all registered ports.
247 we overwrite the silence on the two ports used for latency
251 PortManager::cycle_start (nframes);
252 PortManager::silence (nframes);
254 if (_latency_input_port && _latency_output_port) {
255 PortEngine& pe (port_engine());
257 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
258 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
260 _mtdm->process (nframes, in, out);
263 PortManager::cycle_end (nframes);
264 return_after_remove_check = true;
266 } else if (_measuring_latency == MeasureMIDI && _mididm) {
267 /* run a normal cycle from the perspective of the PortManager
268 so that we get silence on all registered ports.
270 we overwrite the silence on the two ports used for latency
274 PortManager::cycle_start (nframes);
275 PortManager::silence (nframes);
277 if (_latency_input_port && _latency_output_port) {
278 PortEngine& pe (port_engine());
280 _mididm->process (nframes, pe,
281 pe.get_buffer (_latency_input_port, nframes),
282 pe.get_buffer (_latency_output_port, nframes));
285 PortManager::cycle_end (nframes);
286 return_after_remove_check = true;
288 } else if (_latency_flush_frames) {
290 /* wait for the appropriate duration for the MTDM signal to
291 * drain from the ports before we revert to normal behaviour.
294 PortManager::cycle_start (nframes);
295 PortManager::silence (nframes);
296 PortManager::cycle_end (nframes);
298 if (_latency_flush_frames > nframes) {
299 _latency_flush_frames -= nframes;
301 _latency_flush_frames = 0;
304 return_after_remove_check = true;
307 if (session_remove_pending) {
309 /* perform the actual session removal */
311 if (session_removal_countdown < 0) {
313 /* fade out over 1 second */
314 session_removal_countdown = sample_rate()/2;
315 session_removal_gain = GAIN_COEFF_UNITY;
316 session_removal_gain_step = 1.0/session_removal_countdown;
318 } else if (session_removal_countdown > 0) {
320 /* we'll be fading audio out.
322 if this is the last time we do this as part
323 of session removal, do a MIDI panic now
324 to get MIDI stopped. This relies on the fact
325 that "immediate data" (aka "out of band data") from
326 MIDI tracks is *appended* after any other data,
327 so that it emerges after any outbound note ons, etc.
330 if (session_removal_countdown <= nframes) {
331 _session->midi_panic ();
337 session_removal_countdown = -1; // reset to "not in progress"
338 session_remove_pending = false;
339 session_removed.signal(); // wakes up thread that initiated session removal
343 if (return_after_remove_check) {
349 if (!_freewheeling) {
350 PortManager::cycle_start (nframes);
351 PortManager::cycle_end (nframes);
354 _processed_frames = next_processed_frames;
359 /* tell all relevant objects that we're starting a new cycle */
361 InternalSend::CycleStart (nframes);
363 /* tell all Ports that we're starting a new cycle */
365 PortManager::cycle_start (nframes);
367 /* test if we are freewheeling and there are freewheel signals connected.
368 ardour should act normally even when freewheeling unless /it/ is
369 exporting (which is what Freewheel.empty() tests for).
372 if (_freewheeling && !Freewheel.empty()) {
375 _session->process (nframes);
379 PortManager::cycle_end (nframes);
384 _processed_frames = next_processed_frames;
388 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
390 PortManager::check_monitoring ();
391 last_monitor_check = next_processed_frames;
394 #ifdef SILENCE_AFTER_SECONDS
396 bool was_silent = (_silence_countdown == 0);
398 if (_silence_countdown >= nframes) {
399 _silence_countdown -= nframes;
401 _silence_countdown = 0;
404 if (!was_silent && _silence_countdown == 0) {
406 BecameSilent (); /* EMIT SIGNAL */
409 if (_silence_countdown == 0 || _session->silent()) {
410 PortManager::silence (nframes);
414 if (_session->silent()) {
415 PortManager::silence (nframes, _session);
419 if (session_remove_pending && session_removal_countdown) {
421 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
423 if (session_removal_countdown > nframes) {
424 session_removal_countdown -= nframes;
426 session_removal_countdown = 0;
429 session_removal_gain -= (nframes * session_removal_gain_step);
432 PortManager::cycle_end (nframes);
434 _processed_frames = next_processed_frames;
442 AudioEngine::reset_silence_countdown ()
444 #ifdef SILENCE_AFTER_SECONDS
445 double sr = 48000; /* default in case there is no backend */
449 _silence_countdown = max (60 * sr, /* 60 seconds */
450 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (double) _silence_hit_cnt)));
456 AudioEngine::launch_device_control_app()
458 if (_state_lock.trylock () ) {
459 _backend->launch_control_app ();
460 _state_lock.unlock ();
466 AudioEngine::request_backend_reset()
468 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
469 g_atomic_int_inc (&_hw_reset_request_count);
470 _hw_reset_condition.signal ();
474 AudioEngine::backend_reset_requested()
476 return g_atomic_int_get (&_hw_reset_request_count);
480 AudioEngine::do_reset_backend()
482 SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 1024);
484 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
486 while (!_stop_hw_reset_processing) {
488 if (g_atomic_int_get (&_hw_reset_request_count) != 0 && _backend) {
490 _reset_request_lock.unlock();
492 Glib::Threads::RecMutex::Lock pl (_state_lock);
493 g_atomic_int_dec_and_test (&_hw_reset_request_count);
495 std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
496 DeviceResetStarted(); // notify about device reset to be started
498 // backup the device name
499 std::string name = _backend->device_name ();
501 std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
502 if ( ( 0 == stop () ) &&
503 ( 0 == _backend->reset_device () ) &&
504 ( 0 == start () ) ) {
506 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
508 // inform about possible changes
509 BufferSizeChanged (_backend->buffer_size() );
510 DeviceResetFinished(); // notify about device reset finish
514 DeviceResetFinished(); // notify about device reset finish
515 // we've got an error
519 std::cout << "AudioEngine::RESET::Done." << std::endl;
521 _reset_request_lock.lock();
525 _hw_reset_condition.wait (_reset_request_lock);
531 AudioEngine::request_device_list_update()
533 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
534 g_atomic_int_inc (&_hw_devicelist_update_count);
535 _hw_devicelist_update_condition.signal ();
540 AudioEngine::do_devicelist_update()
542 SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
544 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
546 while (!_stop_hw_devicelist_processing) {
548 if (_hw_devicelist_update_count) {
550 _devicelist_update_lock.unlock();
552 Glib::Threads::RecMutex::Lock pl (_state_lock);
554 g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
555 DeviceListChanged (); /* EMIT SIGNAL */
557 _devicelist_update_lock.lock();
560 _hw_devicelist_update_condition.wait (_devicelist_update_lock);
567 AudioEngine::start_hw_event_processing()
569 if (_hw_reset_event_thread == 0) {
570 g_atomic_int_set(&_hw_reset_request_count, 0);
571 g_atomic_int_set(&_stop_hw_reset_processing, 0);
572 _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
575 if (_hw_devicelist_update_thread == 0) {
576 g_atomic_int_set(&_hw_devicelist_update_count, 0);
577 g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
578 _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
584 AudioEngine::stop_hw_event_processing()
586 if (_hw_reset_event_thread) {
587 g_atomic_int_set(&_stop_hw_reset_processing, 1);
588 g_atomic_int_set(&_hw_reset_request_count, 0);
589 _hw_reset_condition.signal ();
590 _hw_reset_event_thread->join ();
591 _hw_reset_event_thread = 0;
594 if (_hw_devicelist_update_thread) {
595 g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
596 g_atomic_int_set(&_hw_devicelist_update_count, 0);
597 _hw_devicelist_update_condition.signal ();
598 _hw_devicelist_update_thread->join ();
599 _hw_devicelist_update_thread = 0;
606 AudioEngine::set_session (Session *s)
608 Glib::Threads::Mutex::Lock pl (_process_lock);
610 SessionHandlePtr::set_session (s);
614 pframes_t blocksize = samples_per_cycle ();
616 PortManager::cycle_start (blocksize);
618 _session->process (blocksize);
619 _session->process (blocksize);
620 _session->process (blocksize);
621 _session->process (blocksize);
622 _session->process (blocksize);
623 _session->process (blocksize);
624 _session->process (blocksize);
625 _session->process (blocksize);
627 PortManager::cycle_end (blocksize);
632 AudioEngine::remove_session ()
634 Glib::Threads::Mutex::Lock lm (_process_lock);
639 session_remove_pending = true;
640 /* signal the start of the fade out countdown */
641 session_removal_countdown = -1;
642 session_removed.wait(_process_lock);
646 SessionHandlePtr::set_session (0);
654 AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs)
656 #ifdef USE_TRACKS_CODE_FEATURES
658 _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs);
667 /* called from a signal handler for SIGPIPE */
672 AudioEngine::reset_timebase ()
675 if (_session->config.get_jack_time_master()) {
676 _backend->set_time_master (true);
678 _backend->set_time_master (false);
686 AudioEngine::destroy ()
693 AudioEngine::discover_backends ()
695 vector<std::string> backend_modules;
699 Glib::PatternSpec so_extension_pattern("*backend.so");
700 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
702 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
703 #if defined(DEBUG) || defined(_DEBUG)
704 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
706 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
709 Glib::PatternSpec dll_extension_pattern("*backend.dll");
712 find_files_matching_pattern (backend_modules, backend_search_path (),
713 so_extension_pattern);
715 find_files_matching_pattern (backend_modules, backend_search_path (),
716 dylib_extension_pattern);
718 find_files_matching_pattern (backend_modules, backend_search_path (),
719 dll_extension_pattern);
721 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
723 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
725 AudioBackendInfo* info;
727 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
729 if ((info = backend_discover (*i)) != 0) {
730 _backends.insert (make_pair (info->name, info));
734 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
736 return _backends.size();
740 AudioEngine::backend_discover (const string& path)
742 #ifdef PLATFORM_WINDOWS
743 // do not show popup dialog (e.g. missing libjack.dll)
744 // win7+ should use SetThreadErrorMode()
745 SetErrorMode(SEM_FAILCRITICALERRORS);
747 Glib::Module module (path);
748 #ifdef PLATFORM_WINDOWS
749 SetErrorMode(0); // reset to system default
751 AudioBackendInfo* info;
752 AudioBackendInfo* (*dfunc)(void);
756 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
757 Glib::Module::get_last_error()) << endmsg;
761 if (!module.get_symbol ("descriptor", func)) {
762 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
763 error << Glib::Module::get_last_error() << endmsg;
767 dfunc = (AudioBackendInfo* (*)(void))func;
769 if (!info->available()) {
773 module.make_resident ();
778 vector<const AudioBackendInfo*>
779 AudioEngine::available_backends() const
781 vector<const AudioBackendInfo*> r;
783 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
784 r.push_back (i->second);
791 AudioEngine::current_backend_name() const
794 return _backend->name();
800 AudioEngine::drop_backend ()
804 // Stopped is needed for Graph to explicitly terminate threads
805 Stopped (); /* EMIT SIGNAL */
806 _backend->drop_device ();
812 boost::shared_ptr<AudioBackend>
813 AudioEngine::set_default_backend ()
815 if (_backends.empty()) {
816 return boost::shared_ptr<AudioBackend>();
819 return set_backend (_backends.begin()->first, "", "");
822 boost::shared_ptr<AudioBackend>
823 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
825 BackendMap::iterator b = _backends.find (name);
827 if (b == _backends.end()) {
828 return boost::shared_ptr<AudioBackend>();
834 if (b->second->instantiate (arg1, arg2)) {
835 throw failed_constructor ();
838 _backend = b->second->factory (*this);
840 } catch (exception& e) {
841 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
842 return boost::shared_ptr<AudioBackend>();
848 /* BACKEND PROXY WRAPPERS */
851 AudioEngine::start (bool for_latency)
861 _processed_frames = 0;
862 last_monitor_check = 0;
864 int error_code = _backend->start (for_latency);
866 if (error_code != 0) {
867 _last_backend_error_string =
868 AudioBackend::get_error_string((AudioBackend::ErrorCode)error_code);
875 _session->set_frame_rate (_backend->sample_rate());
877 if (_session->config.get_jack_time_master()) {
878 _backend->set_time_master (true);
884 Running(); /* EMIT SIGNAL */
891 AudioEngine::stop (bool for_latency)
893 bool stop_engine = true;
899 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
905 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
908 if (_backend->stop ()) {
918 if (_session && _running && stop_engine &&
919 (_session->state_of_the_state() & Session::Loading) == 0 &&
920 (_session->state_of_the_state() & Session::Deletion) == 0) {
921 // it's not a halt, but should be handled the same way:
922 // disable record, stop transport and I/O processign but save the data.
923 _session->engine_halted ();
929 _processed_frames = 0;
930 _measuring_latency = MeasureNone;
931 _latency_output_port = 0;
932 _latency_input_port = 0;
933 _started_for_latency = false;
939 if (!for_latency && stop_engine) {
940 Stopped (); /* EMIT SIGNAL */
947 AudioEngine::freewheel (bool start_stop)
953 /* _freewheeling will be set when first Freewheel signal occurs */
955 return _backend->freewheel (start_stop);
959 AudioEngine::get_dsp_load() const
961 if (!_backend || !_running) {
964 return _backend->dsp_load ();
968 AudioEngine::is_realtime() const
974 return _backend->is_realtime();
978 AudioEngine::connected() const
984 return _backend->available();
988 AudioEngine::transport_start ()
993 return _backend->transport_start ();
997 AudioEngine::transport_stop ()
1002 return _backend->transport_stop ();
1006 AudioEngine::transport_state ()
1009 return TransportStopped;
1011 return _backend->transport_state ();
1015 AudioEngine::transport_locate (framepos_t pos)
1020 return _backend->transport_locate (pos);
1024 AudioEngine::transport_frame()
1029 return _backend->transport_frame ();
1033 AudioEngine::sample_rate () const
1038 return _backend->sample_rate ();
1042 AudioEngine::samples_per_cycle () const
1047 return _backend->buffer_size ();
1051 AudioEngine::usecs_per_cycle () const
1056 return _backend->usecs_per_cycle ();
1060 AudioEngine::raw_buffer_size (DataType t)
1065 return _backend->raw_buffer_size (t);
1069 AudioEngine::sample_time ()
1074 return _backend->sample_time ();
1078 AudioEngine::sample_time_at_cycle_start ()
1083 return _backend->sample_time_at_cycle_start ();
1087 AudioEngine::samples_since_cycle_start ()
1092 return _backend->samples_since_cycle_start ();
1096 AudioEngine::get_sync_offset (pframes_t& offset) const
1101 return _backend->get_sync_offset (offset);
1105 AudioEngine::create_process_thread (boost::function<void()> func)
1110 return _backend->create_process_thread (func);
1114 AudioEngine::join_process_threads ()
1119 return _backend->join_process_threads ();
1123 AudioEngine::in_process_thread ()
1128 return _backend->in_process_thread ();
1132 AudioEngine::process_thread_count ()
1137 return _backend->process_thread_count ();
1141 AudioEngine::set_device_name (const std::string& name)
1146 return _backend->set_device_name (name);
1150 AudioEngine::set_sample_rate (float sr)
1156 return _backend->set_sample_rate (sr);
1160 AudioEngine::set_buffer_size (uint32_t bufsiz)
1165 return _backend->set_buffer_size (bufsiz);
1169 AudioEngine::set_interleaved (bool yn)
1174 return _backend->set_interleaved (yn);
1178 AudioEngine::set_input_channels (uint32_t ic)
1183 return _backend->set_input_channels (ic);
1187 AudioEngine::set_output_channels (uint32_t oc)
1192 return _backend->set_output_channels (oc);
1196 AudioEngine::set_systemic_input_latency (uint32_t il)
1201 return _backend->set_systemic_input_latency (il);
1205 AudioEngine::set_systemic_output_latency (uint32_t ol)
1210 return _backend->set_systemic_output_latency (ol);
1214 AudioEngine::thread_initialised_for_audio_processing ()
1216 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1219 /* END OF BACKEND PROXY API */
1222 AudioEngine::thread_init_callback (void* arg)
1224 /* make sure that anybody who needs to know about this thread
1228 pthread_set_name (X_("audioengine"));
1230 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1231 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1233 SessionEvent::create_per_thread_pool (thread_name, 512);
1234 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1235 AsyncMIDIPort::set_process_thread (pthread_self());
1238 delete AudioEngine::instance()->_main_thread;
1239 /* the special thread created/managed by the backend */
1240 AudioEngine::instance()->_main_thread = new ProcessThread;
1245 AudioEngine::sync_callback (TransportState state, framepos_t position)
1248 return _session->backend_sync_callback (state, position);
1254 AudioEngine::freewheel_callback (bool onoff)
1256 _freewheeling = onoff;
1260 AudioEngine::latency_callback (bool for_playback)
1263 _session->update_latency (for_playback);
1268 AudioEngine::update_latencies ()
1271 _backend->update_latencies ();
1276 AudioEngine::halted_callback (const char* why)
1278 if (_in_destructor) {
1279 /* everything is under control */
1285 Port::PortDrop (); /* EMIT SIGNAL */
1287 if (!_started_for_latency) {
1288 Halted (why); /* EMIT SIGNAL */
1293 AudioEngine::setup_required () const
1296 if (_backend->info().already_configured())
1299 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1308 AudioEngine::prepare_for_latency_measurement ()
1314 if (_backend->can_change_systemic_latency_when_running()) {
1318 _backend->set_systemic_input_latency (0);
1319 _backend->set_systemic_output_latency (0);
1324 _stopped_for_latency = true;
1331 _started_for_latency = true;
1337 AudioEngine::start_latency_detection (bool for_midi)
1339 if (prepare_for_latency_measurement ()) {
1343 PortEngine& pe (port_engine());
1351 /* find the ports we will connect to */
1353 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1354 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1361 /* create the ports we will use to read/write data */
1363 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1367 if (pe.connect (_latency_output_port, _latency_output_name)) {
1368 pe.unregister_port (_latency_output_port);
1373 const string portname ("latency_in");
1374 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1375 pe.unregister_port (_latency_input_port);
1376 pe.unregister_port (_latency_output_port);
1380 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1381 pe.unregister_port (_latency_input_port);
1382 pe.unregister_port (_latency_output_port);
1387 _mididm = new MIDIDM (sample_rate());
1391 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1395 if (pe.connect (_latency_output_port, _latency_output_name)) {
1396 pe.unregister_port (_latency_output_port);
1401 const string portname ("latency_in");
1402 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1403 pe.unregister_port (_latency_input_port);
1404 pe.unregister_port (_latency_output_port);
1408 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1409 pe.unregister_port (_latency_input_port);
1410 pe.unregister_port (_latency_output_port);
1415 _mtdm = new MTDM (sample_rate());
1420 _latency_signal_latency = 0;
1421 lr = pe.get_latency_range (in, false);
1422 _latency_signal_latency = lr.max;
1423 lr = pe.get_latency_range (out, true);
1424 _latency_signal_latency += lr.max;
1426 /* all created and connected, lets go */
1427 _latency_flush_frames = samples_per_cycle();
1428 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1434 AudioEngine::stop_latency_detection ()
1436 _measuring_latency = MeasureNone;
1438 if (_latency_output_port) {
1439 port_engine().unregister_port (_latency_output_port);
1440 _latency_output_port = 0;
1442 if (_latency_input_port) {
1443 port_engine().unregister_port (_latency_input_port);
1444 _latency_input_port = 0;
1447 if (!_backend->can_change_systemic_latency_when_running()) {
1451 if (_stopped_for_latency) {
1455 _stopped_for_latency = false;
1456 _started_for_latency = false;
1460 AudioEngine::set_latency_output_port (const string& name)
1462 _latency_output_name = name;
1466 AudioEngine::set_latency_input_port (const string& name)
1468 _latency_input_name = name;