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 ()) {
920 if (_session && _running && stop_engine &&
921 (_session->state_of_the_state() & Session::Loading) == 0 &&
922 (_session->state_of_the_state() & Session::Deletion) == 0) {
923 // it's not a halt, but should be handled the same way:
924 // disable record, stop transport and I/O processign but save the data.
925 _session->engine_halted ();
931 _processed_frames = 0;
932 _measuring_latency = MeasureNone;
933 _latency_output_port = 0;
934 _latency_input_port = 0;
935 _started_for_latency = false;
941 if (!for_latency && stop_engine) {
942 Stopped (); /* EMIT SIGNAL */
949 AudioEngine::freewheel (bool start_stop)
955 /* _freewheeling will be set when first Freewheel signal occurs */
957 return _backend->freewheel (start_stop);
961 AudioEngine::get_dsp_load() const
963 if (!_backend || !_running) {
966 return _backend->dsp_load ();
970 AudioEngine::is_realtime() const
976 return _backend->is_realtime();
980 AudioEngine::connected() const
986 return _backend->available();
990 AudioEngine::transport_start ()
995 return _backend->transport_start ();
999 AudioEngine::transport_stop ()
1004 return _backend->transport_stop ();
1008 AudioEngine::transport_state ()
1011 return TransportStopped;
1013 return _backend->transport_state ();
1017 AudioEngine::transport_locate (framepos_t pos)
1022 return _backend->transport_locate (pos);
1026 AudioEngine::transport_frame()
1031 return _backend->transport_frame ();
1035 AudioEngine::sample_rate () const
1040 return _backend->sample_rate ();
1044 AudioEngine::samples_per_cycle () const
1049 return _backend->buffer_size ();
1053 AudioEngine::usecs_per_cycle () const
1058 return _backend->usecs_per_cycle ();
1062 AudioEngine::raw_buffer_size (DataType t)
1067 return _backend->raw_buffer_size (t);
1071 AudioEngine::sample_time ()
1076 return _backend->sample_time ();
1080 AudioEngine::sample_time_at_cycle_start ()
1085 return _backend->sample_time_at_cycle_start ();
1089 AudioEngine::samples_since_cycle_start ()
1094 return _backend->samples_since_cycle_start ();
1098 AudioEngine::get_sync_offset (pframes_t& offset) const
1103 return _backend->get_sync_offset (offset);
1107 AudioEngine::create_process_thread (boost::function<void()> func)
1112 return _backend->create_process_thread (func);
1116 AudioEngine::join_process_threads ()
1121 return _backend->join_process_threads ();
1125 AudioEngine::in_process_thread ()
1130 return _backend->in_process_thread ();
1134 AudioEngine::process_thread_count ()
1139 return _backend->process_thread_count ();
1143 AudioEngine::set_device_name (const std::string& name)
1148 return _backend->set_device_name (name);
1152 AudioEngine::set_sample_rate (float sr)
1158 return _backend->set_sample_rate (sr);
1162 AudioEngine::set_buffer_size (uint32_t bufsiz)
1167 return _backend->set_buffer_size (bufsiz);
1171 AudioEngine::set_interleaved (bool yn)
1176 return _backend->set_interleaved (yn);
1180 AudioEngine::set_input_channels (uint32_t ic)
1185 return _backend->set_input_channels (ic);
1189 AudioEngine::set_output_channels (uint32_t oc)
1194 return _backend->set_output_channels (oc);
1198 AudioEngine::set_systemic_input_latency (uint32_t il)
1203 return _backend->set_systemic_input_latency (il);
1207 AudioEngine::set_systemic_output_latency (uint32_t ol)
1212 return _backend->set_systemic_output_latency (ol);
1216 AudioEngine::thread_initialised_for_audio_processing ()
1218 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1221 /* END OF BACKEND PROXY API */
1224 AudioEngine::thread_init_callback (void* arg)
1226 /* make sure that anybody who needs to know about this thread
1230 pthread_set_name (X_("audioengine"));
1232 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1233 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1235 SessionEvent::create_per_thread_pool (thread_name, 512);
1236 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1237 AsyncMIDIPort::set_process_thread (pthread_self());
1240 delete AudioEngine::instance()->_main_thread;
1241 /* the special thread created/managed by the backend */
1242 AudioEngine::instance()->_main_thread = new ProcessThread;
1247 AudioEngine::sync_callback (TransportState state, framepos_t position)
1250 return _session->backend_sync_callback (state, position);
1256 AudioEngine::freewheel_callback (bool onoff)
1258 _freewheeling = onoff;
1262 AudioEngine::latency_callback (bool for_playback)
1265 _session->update_latency (for_playback);
1270 AudioEngine::update_latencies ()
1273 _backend->update_latencies ();
1278 AudioEngine::halted_callback (const char* why)
1280 if (_in_destructor) {
1281 /* everything is under control */
1287 Port::PortDrop (); /* EMIT SIGNAL */
1289 if (!_started_for_latency) {
1290 Halted (why); /* EMIT SIGNAL */
1295 AudioEngine::setup_required () const
1298 if (_backend->info().already_configured())
1301 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1310 AudioEngine::prepare_for_latency_measurement ()
1316 if (_backend->can_change_systemic_latency_when_running()) {
1320 _backend->set_systemic_input_latency (0);
1321 _backend->set_systemic_output_latency (0);
1326 _stopped_for_latency = true;
1333 _started_for_latency = true;
1339 AudioEngine::start_latency_detection (bool for_midi)
1341 if (prepare_for_latency_measurement ()) {
1345 PortEngine& pe (port_engine());
1353 /* find the ports we will connect to */
1355 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1356 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1363 /* create the ports we will use to read/write data */
1365 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1369 if (pe.connect (_latency_output_port, _latency_output_name)) {
1370 pe.unregister_port (_latency_output_port);
1375 const string portname ("latency_in");
1376 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1377 pe.unregister_port (_latency_input_port);
1378 pe.unregister_port (_latency_output_port);
1382 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1383 pe.unregister_port (_latency_input_port);
1384 pe.unregister_port (_latency_output_port);
1389 _mididm = new MIDIDM (sample_rate());
1393 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1397 if (pe.connect (_latency_output_port, _latency_output_name)) {
1398 pe.unregister_port (_latency_output_port);
1403 const string portname ("latency_in");
1404 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1405 pe.unregister_port (_latency_input_port);
1406 pe.unregister_port (_latency_output_port);
1410 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1411 pe.unregister_port (_latency_input_port);
1412 pe.unregister_port (_latency_output_port);
1417 _mtdm = new MTDM (sample_rate());
1422 _latency_signal_latency = 0;
1423 lr = pe.get_latency_range (in, false);
1424 _latency_signal_latency = lr.max;
1425 lr = pe.get_latency_range (out, true);
1426 _latency_signal_latency += lr.max;
1428 /* all created and connected, lets go */
1429 _latency_flush_frames = samples_per_cycle();
1430 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1436 AudioEngine::stop_latency_detection ()
1438 _measuring_latency = MeasureNone;
1440 if (_latency_output_port) {
1441 port_engine().unregister_port (_latency_output_port);
1442 _latency_output_port = 0;
1444 if (_latency_input_port) {
1445 port_engine().unregister_port (_latency_input_port);
1446 _latency_input_port = 0;
1449 if (!_backend->can_change_systemic_latency_when_running()) {
1453 if (_stopped_for_latency) {
1457 _stopped_for_latency = false;
1458 _started_for_latency = false;
1462 AudioEngine::set_latency_output_port (const string& name)
1464 _latency_output_name = name;
1468 AudioEngine::set_latency_input_port (const string& name)
1470 _latency_input_name = name;