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;
67 #define SILENCE_AFTER_SECONDS 600
70 AudioEngine::AudioEngine ()
71 : session_remove_pending (false)
72 , session_removal_countdown (-1)
74 , _freewheeling (false)
75 , monitor_check_interval (INT32_MAX)
76 , last_monitor_check (0)
77 , _processed_frames (0)
82 , _measuring_latency (MeasureNone)
83 , _latency_input_port (0)
84 , _latency_output_port (0)
85 , _latency_flush_frames (0)
86 , _latency_signal_latency (0)
87 , _stopped_for_latency (false)
88 , _started_for_latency (false)
89 , _in_destructor (false)
90 , _last_backend_error_string(AudioBackend::get_error_string((AudioBackend::ErrorCode)-1))
91 , _hw_reset_event_thread(0)
92 , _hw_reset_request_count(0)
93 , _stop_hw_reset_processing(0)
94 , _hw_devicelist_update_thread(0)
95 , _hw_devicelist_update_count(0)
96 , _stop_hw_devicelist_processing(0)
97 #ifdef SILENCE_AFTER_SECONDS
98 , _silence_countdown (0)
99 , _silence_hit_cnt (0)
102 reset_silence_countdown ();
103 start_hw_event_processing();
104 discover_backends ();
107 AudioEngine::~AudioEngine ()
109 _in_destructor = true;
110 stop_hw_event_processing();
112 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
113 i->second->deinstantiate();
118 AudioEngine::create ()
124 _instance = new AudioEngine ();
130 AudioEngine::split_cycle (pframes_t offset)
132 /* caller must hold process lock */
134 Port::increment_global_port_buffer_offset (offset);
136 /* tell all Ports that we're going to start a new (split) cycle */
138 boost::shared_ptr<Ports> p = ports.reader();
140 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
141 i->second->cycle_split ();
146 AudioEngine::sample_rate_change (pframes_t nframes)
148 /* check for monitor input change every 1/10th of second */
150 monitor_check_interval = nframes / 10;
151 last_monitor_check = 0;
154 _session->set_frame_rate (nframes);
157 SampleRateChanged (nframes); /* EMIT SIGNAL */
159 #ifdef SILENCE_AFTER_SECONDS
160 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
167 AudioEngine::buffer_size_change (pframes_t bufsiz)
170 _session->set_block_size (bufsiz);
171 last_monitor_check = 0;
174 BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
179 /** Method called by our ::process_thread when there is work to be done.
180 * @param nframes Number of frames to process.
183 __attribute__((annotate("realtime")))
186 AudioEngine::process_callback (pframes_t nframes)
188 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
193 /// The number of frames that will have been processed when we've finished
194 pframes_t next_processed_frames;
196 /* handle wrap around of total frames counter */
198 if (max_framepos - _processed_frames < nframes) {
199 next_processed_frames = nframes - (max_framepos - _processed_frames);
201 next_processed_frames = _processed_frames + nframes;
205 /* return having done nothing */
209 /* really only JACK requires this
210 * (other backends clear the output buffers
211 * before the process_callback. it may even be
212 * jack/alsa only). but better safe than sorry.
214 PortManager::silence_outputs (nframes);
218 /* The coreaudio-backend calls thread_init_callback() if
219 * the hardware changes or pthread_self() changes.
221 * However there are cases when neither holds true, yet
222 * the thread-pool changes: e.g. connect a headphone to
223 * a shared mic/headphone jack.
224 * It's probably related to, or caused by clocksource changes.
226 * For reasons yet unknown Glib::Threads::Private() can
227 * use a different thread-private in the same pthread
228 * (coreaudio render callback).
230 * Coreaudio must set something which influences
231 * pthread_key_t uniqness or reset the key using
232 * pthread_getspecific().
234 if (! SessionEvent::has_per_thread_pool ()) {
235 thread_init_callback (NULL);
238 bool return_after_remove_check = false;
240 if (_measuring_latency == MeasureAudio && _mtdm) {
241 /* run a normal cycle from the perspective of the PortManager
242 so that we get silence on all registered ports.
244 we overwrite the silence on the two ports used for latency
248 PortManager::cycle_start (nframes);
249 PortManager::silence (nframes);
251 if (_latency_input_port && _latency_output_port) {
252 PortEngine& pe (port_engine());
254 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
255 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
257 _mtdm->process (nframes, in, out);
260 PortManager::cycle_end (nframes);
261 return_after_remove_check = true;
263 } else if (_measuring_latency == MeasureMIDI && _mididm) {
264 /* run a normal cycle from the perspective of the PortManager
265 so that we get silence on all registered ports.
267 we overwrite the silence on the two ports used for latency
271 PortManager::cycle_start (nframes);
272 PortManager::silence (nframes);
274 if (_latency_input_port && _latency_output_port) {
275 PortEngine& pe (port_engine());
277 _mididm->process (nframes, pe,
278 pe.get_buffer (_latency_input_port, nframes),
279 pe.get_buffer (_latency_output_port, nframes));
282 PortManager::cycle_end (nframes);
283 return_after_remove_check = true;
285 } else if (_latency_flush_frames) {
287 /* wait for the appropriate duration for the MTDM signal to
288 * drain from the ports before we revert to normal behaviour.
291 PortManager::cycle_start (nframes);
292 PortManager::silence (nframes);
293 PortManager::cycle_end (nframes);
295 if (_latency_flush_frames > nframes) {
296 _latency_flush_frames -= nframes;
298 _latency_flush_frames = 0;
301 return_after_remove_check = true;
304 if (session_remove_pending) {
306 /* perform the actual session removal */
308 if (session_removal_countdown < 0) {
310 /* fade out over 1 second */
311 session_removal_countdown = sample_rate()/2;
312 session_removal_gain = GAIN_COEFF_UNITY;
313 session_removal_gain_step = 1.0/session_removal_countdown;
315 } else if (session_removal_countdown > 0) {
317 /* we'll be fading audio out.
319 if this is the last time we do this as part
320 of session removal, do a MIDI panic now
321 to get MIDI stopped. This relies on the fact
322 that "immediate data" (aka "out of band data") from
323 MIDI tracks is *appended* after any other data,
324 so that it emerges after any outbound note ons, etc.
327 if (session_removal_countdown <= nframes) {
328 _session->midi_panic ();
334 session_removal_countdown = -1; // reset to "not in progress"
335 session_remove_pending = false;
336 session_removed.signal(); // wakes up thread that initiated session removal
340 if (return_after_remove_check) {
346 if (!_freewheeling) {
347 PortManager::cycle_start (nframes);
348 PortManager::cycle_end (nframes);
351 _processed_frames = next_processed_frames;
356 /* tell all relevant objects that we're starting a new cycle */
358 InternalSend::CycleStart (nframes);
360 /* tell all Ports that we're starting a new cycle */
362 PortManager::cycle_start (nframes);
364 /* test if we are freewheeling and there are freewheel signals connected.
365 ardour should act normally even when freewheeling unless /it/ is
366 exporting (which is what Freewheel.empty() tests for).
369 if (_freewheeling && !Freewheel.empty()) {
372 _session->process (nframes);
376 PortManager::cycle_end (nframes);
381 _processed_frames = next_processed_frames;
385 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
387 PortManager::check_monitoring ();
388 last_monitor_check = next_processed_frames;
391 #ifdef SILENCE_AFTER_SECONDS
393 bool was_silent = (_silence_countdown == 0);
395 if (_silence_countdown >= nframes) {
396 _silence_countdown -= nframes;
398 _silence_countdown = 0;
401 if (!was_silent && _silence_countdown == 0) {
403 BecameSilent (); /* EMIT SIGNAL */
406 if (_silence_countdown == 0 || _session->silent()) {
407 PortManager::silence (nframes);
411 if (_session->silent()) {
412 PortManager::silence (nframes);
416 if (session_remove_pending && session_removal_countdown) {
418 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
420 if (session_removal_countdown > nframes) {
421 session_removal_countdown -= nframes;
423 session_removal_countdown = 0;
426 session_removal_gain -= (nframes * session_removal_gain_step);
429 PortManager::cycle_end (nframes);
431 _processed_frames = next_processed_frames;
439 AudioEngine::reset_silence_countdown ()
441 #ifdef SILENCE_AFTER_SECONDS
442 double sr = 48000; /* default in case there is no backend */
446 _silence_countdown = max (60 * sr, /* 60 seconds */
447 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (double) _silence_hit_cnt)));
453 AudioEngine::launch_device_control_app()
455 if (_state_lock.trylock () ) {
456 _backend->launch_control_app ();
457 _state_lock.unlock ();
463 AudioEngine::request_backend_reset()
465 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
466 g_atomic_int_inc (&_hw_reset_request_count);
467 _hw_reset_condition.signal ();
471 AudioEngine::backend_reset_requested()
473 return g_atomic_int_get (&_hw_reset_request_count);
477 AudioEngine::do_reset_backend()
479 SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 1024);
481 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
483 while (!_stop_hw_reset_processing) {
485 if (g_atomic_int_get (&_hw_reset_request_count) != 0 && _backend) {
487 _reset_request_lock.unlock();
489 Glib::Threads::RecMutex::Lock pl (_state_lock);
490 g_atomic_int_dec_and_test (&_hw_reset_request_count);
492 std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
493 DeviceResetStarted(); // notify about device reset to be started
495 // backup the device name
496 std::string name = _backend->device_name ();
498 std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
499 if ( ( 0 == stop () ) &&
500 ( 0 == _backend->reset_device () ) &&
501 ( 0 == start () ) ) {
503 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
505 // inform about possible changes
506 BufferSizeChanged (_backend->buffer_size() );
507 DeviceResetFinished(); // notify about device reset finish
511 DeviceResetFinished(); // notify about device reset finish
512 // we've got an error
516 std::cout << "AudioEngine::RESET::Done." << std::endl;
518 _reset_request_lock.lock();
522 _hw_reset_condition.wait (_reset_request_lock);
528 AudioEngine::request_device_list_update()
530 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
531 g_atomic_int_inc (&_hw_devicelist_update_count);
532 _hw_devicelist_update_condition.signal ();
537 AudioEngine::do_devicelist_update()
539 SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
541 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
543 while (!_stop_hw_devicelist_processing) {
545 if (_hw_devicelist_update_count) {
547 _devicelist_update_lock.unlock();
549 Glib::Threads::RecMutex::Lock pl (_state_lock);
551 g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
552 DeviceListChanged (); /* EMIT SIGNAL */
554 _devicelist_update_lock.lock();
557 _hw_devicelist_update_condition.wait (_devicelist_update_lock);
564 AudioEngine::start_hw_event_processing()
566 if (_hw_reset_event_thread == 0) {
567 g_atomic_int_set(&_hw_reset_request_count, 0);
568 g_atomic_int_set(&_stop_hw_reset_processing, 0);
569 _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
572 if (_hw_devicelist_update_thread == 0) {
573 g_atomic_int_set(&_hw_devicelist_update_count, 0);
574 g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
575 _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
581 AudioEngine::stop_hw_event_processing()
583 if (_hw_reset_event_thread) {
584 g_atomic_int_set(&_stop_hw_reset_processing, 1);
585 g_atomic_int_set(&_hw_reset_request_count, 0);
586 _hw_reset_condition.signal ();
587 _hw_reset_event_thread->join ();
588 _hw_reset_event_thread = 0;
591 if (_hw_devicelist_update_thread) {
592 g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
593 g_atomic_int_set(&_hw_devicelist_update_count, 0);
594 _hw_devicelist_update_condition.signal ();
595 _hw_devicelist_update_thread->join ();
596 _hw_devicelist_update_thread = 0;
603 AudioEngine::set_session (Session *s)
605 Glib::Threads::Mutex::Lock pl (_process_lock);
607 SessionHandlePtr::set_session (s);
611 pframes_t blocksize = samples_per_cycle ();
613 PortManager::cycle_start (blocksize);
615 _session->process (blocksize);
616 _session->process (blocksize);
617 _session->process (blocksize);
618 _session->process (blocksize);
619 _session->process (blocksize);
620 _session->process (blocksize);
621 _session->process (blocksize);
622 _session->process (blocksize);
624 PortManager::cycle_end (blocksize);
629 AudioEngine::remove_session ()
631 Glib::Threads::Mutex::Lock lm (_process_lock);
636 session_remove_pending = true;
637 /* signal the start of the fade out countdown */
638 session_removal_countdown = -1;
639 session_removed.wait(_process_lock);
643 SessionHandlePtr::set_session (0);
651 AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs)
653 #ifdef USE_TRACKS_CODE_FEATURES
655 _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs);
664 /* called from a signal handler for SIGPIPE */
669 AudioEngine::reset_timebase ()
672 if (_session->config.get_jack_time_master()) {
673 _backend->set_time_master (true);
675 _backend->set_time_master (false);
683 AudioEngine::destroy ()
690 AudioEngine::discover_backends ()
692 vector<std::string> backend_modules;
696 Glib::PatternSpec so_extension_pattern("*backend.so");
697 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
699 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
700 #if defined(DEBUG) || defined(_DEBUG)
701 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
703 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
706 Glib::PatternSpec dll_extension_pattern("*backend.dll");
709 find_files_matching_pattern (backend_modules, backend_search_path (),
710 so_extension_pattern);
712 find_files_matching_pattern (backend_modules, backend_search_path (),
713 dylib_extension_pattern);
715 find_files_matching_pattern (backend_modules, backend_search_path (),
716 dll_extension_pattern);
718 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
720 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
722 AudioBackendInfo* info;
724 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
726 if ((info = backend_discover (*i)) != 0) {
727 _backends.insert (make_pair (info->name, info));
731 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
733 return _backends.size();
737 AudioEngine::backend_discover (const string& path)
739 #ifdef PLATFORM_WINDOWS
740 // do not show popup dialog (e.g. missing libjack.dll)
741 // win7+ should use SetThreadErrorMode()
742 SetErrorMode(SEM_FAILCRITICALERRORS);
744 Glib::Module module (path);
745 #ifdef PLATFORM_WINDOWS
746 SetErrorMode(0); // reset to system default
748 AudioBackendInfo* info;
749 AudioBackendInfo* (*dfunc)(void);
753 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
754 Glib::Module::get_last_error()) << endmsg;
758 if (!module.get_symbol ("descriptor", func)) {
759 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
760 error << Glib::Module::get_last_error() << endmsg;
764 dfunc = (AudioBackendInfo* (*)(void))func;
766 if (!info->available()) {
770 module.make_resident ();
775 vector<const AudioBackendInfo*>
776 AudioEngine::available_backends() const
778 vector<const AudioBackendInfo*> r;
780 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
781 r.push_back (i->second);
788 AudioEngine::current_backend_name() const
791 return _backend->name();
797 AudioEngine::drop_backend ()
801 // Stopped is needed for Graph to explicitly terminate threads
802 Stopped (); /* EMIT SIGNAL */
803 _backend->drop_device ();
809 boost::shared_ptr<AudioBackend>
810 AudioEngine::set_default_backend ()
812 if (_backends.empty()) {
813 return boost::shared_ptr<AudioBackend>();
816 return set_backend (_backends.begin()->first, "", "");
819 boost::shared_ptr<AudioBackend>
820 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
822 BackendMap::iterator b = _backends.find (name);
824 if (b == _backends.end()) {
825 return boost::shared_ptr<AudioBackend>();
831 if (b->second->instantiate (arg1, arg2)) {
832 throw failed_constructor ();
835 _backend = b->second->factory (*this);
837 } catch (exception& e) {
838 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
839 return boost::shared_ptr<AudioBackend>();
845 /* BACKEND PROXY WRAPPERS */
848 AudioEngine::start (bool for_latency)
858 _processed_frames = 0;
859 last_monitor_check = 0;
861 int error_code = _backend->start (for_latency);
863 if (error_code != 0) {
864 _last_backend_error_string =
865 AudioBackend::get_error_string((AudioBackend::ErrorCode)error_code);
872 _session->set_frame_rate (_backend->sample_rate());
874 if (_session->config.get_jack_time_master()) {
875 _backend->set_time_master (true);
881 Running(); /* EMIT SIGNAL */
888 AudioEngine::stop (bool for_latency)
890 bool stop_engine = true;
896 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
902 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
905 if (_backend->stop ()) {
915 if (_session && _running && stop_engine &&
916 (_session->state_of_the_state() & Session::Loading) == 0 &&
917 (_session->state_of_the_state() & Session::Deletion) == 0) {
918 // it's not a halt, but should be handled the same way:
919 // disable record, stop transport and I/O processign but save the data.
920 _session->engine_halted ();
926 _processed_frames = 0;
927 _measuring_latency = MeasureNone;
928 _latency_output_port = 0;
929 _latency_input_port = 0;
930 _started_for_latency = false;
936 if (!for_latency && stop_engine) {
937 Stopped (); /* EMIT SIGNAL */
944 AudioEngine::freewheel (bool start_stop)
950 /* _freewheeling will be set when first Freewheel signal occurs */
952 return _backend->freewheel (start_stop);
956 AudioEngine::get_dsp_load() const
958 if (!_backend || !_running) {
961 return _backend->dsp_load ();
965 AudioEngine::is_realtime() const
971 return _backend->is_realtime();
975 AudioEngine::connected() const
981 return _backend->available();
985 AudioEngine::transport_start ()
990 return _backend->transport_start ();
994 AudioEngine::transport_stop ()
999 return _backend->transport_stop ();
1003 AudioEngine::transport_state ()
1006 return TransportStopped;
1008 return _backend->transport_state ();
1012 AudioEngine::transport_locate (framepos_t pos)
1017 return _backend->transport_locate (pos);
1021 AudioEngine::transport_frame()
1026 return _backend->transport_frame ();
1030 AudioEngine::sample_rate () const
1035 return _backend->sample_rate ();
1039 AudioEngine::samples_per_cycle () const
1044 return _backend->buffer_size ();
1048 AudioEngine::usecs_per_cycle () const
1053 return _backend->usecs_per_cycle ();
1057 AudioEngine::raw_buffer_size (DataType t)
1062 return _backend->raw_buffer_size (t);
1066 AudioEngine::sample_time ()
1071 return _backend->sample_time ();
1075 AudioEngine::sample_time_at_cycle_start ()
1080 return _backend->sample_time_at_cycle_start ();
1084 AudioEngine::samples_since_cycle_start ()
1089 return _backend->samples_since_cycle_start ();
1093 AudioEngine::get_sync_offset (pframes_t& offset) const
1098 return _backend->get_sync_offset (offset);
1102 AudioEngine::create_process_thread (boost::function<void()> func)
1107 return _backend->create_process_thread (func);
1111 AudioEngine::join_process_threads ()
1116 return _backend->join_process_threads ();
1120 AudioEngine::in_process_thread ()
1125 return _backend->in_process_thread ();
1129 AudioEngine::process_thread_count ()
1134 return _backend->process_thread_count ();
1138 AudioEngine::set_device_name (const std::string& name)
1143 return _backend->set_device_name (name);
1147 AudioEngine::set_sample_rate (float sr)
1153 return _backend->set_sample_rate (sr);
1157 AudioEngine::set_buffer_size (uint32_t bufsiz)
1162 return _backend->set_buffer_size (bufsiz);
1166 AudioEngine::set_interleaved (bool yn)
1171 return _backend->set_interleaved (yn);
1175 AudioEngine::set_input_channels (uint32_t ic)
1180 return _backend->set_input_channels (ic);
1184 AudioEngine::set_output_channels (uint32_t oc)
1189 return _backend->set_output_channels (oc);
1193 AudioEngine::set_systemic_input_latency (uint32_t il)
1198 return _backend->set_systemic_input_latency (il);
1202 AudioEngine::set_systemic_output_latency (uint32_t ol)
1207 return _backend->set_systemic_output_latency (ol);
1211 AudioEngine::thread_initialised_for_audio_processing ()
1213 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1216 /* END OF BACKEND PROXY API */
1219 AudioEngine::thread_init_callback (void* arg)
1221 /* make sure that anybody who needs to know about this thread
1225 pthread_set_name (X_("audioengine"));
1227 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
1229 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
1230 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
1232 AsyncMIDIPort::set_process_thread (pthread_self());
1235 /* the special thread created/managed by the backend */
1236 AudioEngine::instance()->_main_thread = new ProcessThread;
1241 AudioEngine::sync_callback (TransportState state, framepos_t position)
1244 return _session->backend_sync_callback (state, position);
1250 AudioEngine::freewheel_callback (bool onoff)
1252 _freewheeling = onoff;
1256 AudioEngine::latency_callback (bool for_playback)
1259 _session->update_latency (for_playback);
1264 AudioEngine::update_latencies ()
1267 _backend->update_latencies ();
1272 AudioEngine::halted_callback (const char* why)
1274 if (_in_destructor) {
1275 /* everything is under control */
1281 Port::PortDrop (); /* EMIT SIGNAL */
1283 if (!_started_for_latency) {
1284 Halted (why); /* EMIT SIGNAL */
1289 AudioEngine::setup_required () const
1292 if (_backend->info().already_configured())
1295 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1304 AudioEngine::prepare_for_latency_measurement ()
1310 if (_backend->can_change_systemic_latency_when_running()) {
1314 _backend->set_systemic_input_latency (0);
1315 _backend->set_systemic_output_latency (0);
1320 _stopped_for_latency = true;
1327 _started_for_latency = true;
1333 AudioEngine::start_latency_detection (bool for_midi)
1335 if (prepare_for_latency_measurement ()) {
1339 PortEngine& pe (port_engine());
1347 /* find the ports we will connect to */
1349 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1350 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1357 /* create the ports we will use to read/write data */
1359 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1363 if (pe.connect (_latency_output_port, _latency_output_name)) {
1364 pe.unregister_port (_latency_output_port);
1369 const string portname ("latency_in");
1370 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1371 pe.unregister_port (_latency_input_port);
1372 pe.unregister_port (_latency_output_port);
1376 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1377 pe.unregister_port (_latency_input_port);
1378 pe.unregister_port (_latency_output_port);
1383 _mididm = new MIDIDM (sample_rate());
1387 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1391 if (pe.connect (_latency_output_port, _latency_output_name)) {
1392 pe.unregister_port (_latency_output_port);
1397 const string portname ("latency_in");
1398 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1399 pe.unregister_port (_latency_input_port);
1400 pe.unregister_port (_latency_output_port);
1404 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1405 pe.unregister_port (_latency_input_port);
1406 pe.unregister_port (_latency_output_port);
1411 _mtdm = new MTDM (sample_rate());
1416 _latency_signal_latency = 0;
1417 lr = pe.get_latency_range (in, false);
1418 _latency_signal_latency = lr.max;
1419 lr = pe.get_latency_range (out, true);
1420 _latency_signal_latency += lr.max;
1422 /* all created and connected, lets go */
1423 _latency_flush_frames = samples_per_cycle();
1424 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1430 AudioEngine::stop_latency_detection ()
1432 _measuring_latency = MeasureNone;
1434 if (_latency_output_port) {
1435 port_engine().unregister_port (_latency_output_port);
1436 _latency_output_port = 0;
1438 if (_latency_input_port) {
1439 port_engine().unregister_port (_latency_input_port);
1440 _latency_input_port = 0;
1443 if (!_backend->can_change_systemic_latency_when_running()) {
1447 if (_stopped_for_latency) {
1451 _stopped_for_latency = false;
1452 _started_for_latency = false;
1456 AudioEngine::set_latency_output_port (const string& name)
1458 _latency_output_name = name;
1462 AudioEngine::set_latency_input_port (const string& name)
1464 _latency_input_name = name;