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();
120 AudioEngine::create ()
126 _instance = new AudioEngine ();
132 AudioEngine::split_cycle (pframes_t offset)
134 /* caller must hold process lock */
136 Port::increment_global_port_buffer_offset (offset);
138 /* tell all Ports that we're going to start a new (split) cycle */
140 boost::shared_ptr<Ports> p = ports.reader();
142 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
143 i->second->cycle_split ();
148 AudioEngine::sample_rate_change (pframes_t nframes)
150 /* check for monitor input change every 1/10th of second */
152 monitor_check_interval = nframes / 10;
153 last_monitor_check = 0;
156 _session->set_frame_rate (nframes);
159 SampleRateChanged (nframes); /* EMIT SIGNAL */
161 #ifdef SILENCE_AFTER_SECONDS
162 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
169 AudioEngine::buffer_size_change (pframes_t bufsiz)
172 _session->set_block_size (bufsiz);
173 last_monitor_check = 0;
176 BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
181 /** Method called by our ::process_thread when there is work to be done.
182 * @param nframes Number of frames to process.
185 __attribute__((annotate("realtime")))
188 AudioEngine::process_callback (pframes_t nframes)
190 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
195 /// The number of frames that will have been processed when we've finished
196 pframes_t next_processed_frames;
198 /* handle wrap around of total frames counter */
200 if (max_framepos - _processed_frames < nframes) {
201 next_processed_frames = nframes - (max_framepos - _processed_frames);
203 next_processed_frames = _processed_frames + nframes;
207 /* return having done nothing */
211 /* really only JACK requires this
212 * (other backends clear the output buffers
213 * before the process_callback. it may even be
214 * jack/alsa only). but better safe than sorry.
216 PortManager::silence_outputs (nframes);
220 /* The coreaudio-backend calls thread_init_callback() if
221 * the hardware changes or pthread_self() changes.
223 * However there are cases when neither holds true, yet
224 * the thread-pool changes: e.g. connect a headphone to
225 * a shared mic/headphone jack.
226 * It's probably related to, or caused by clocksource changes.
228 * For reasons yet unknown Glib::Threads::Private() can
229 * use a different thread-private in the same pthread
230 * (coreaudio render callback).
232 * Coreaudio must set something which influences
233 * pthread_key_t uniqness or reset the key using
234 * pthread_getspecific().
236 if (! SessionEvent::has_per_thread_pool ()) {
237 thread_init_callback (NULL);
240 bool return_after_remove_check = false;
242 if (_measuring_latency == MeasureAudio && _mtdm) {
243 /* run a normal cycle from the perspective of the PortManager
244 so that we get silence on all registered ports.
246 we overwrite the silence on the two ports used for latency
250 PortManager::cycle_start (nframes);
251 PortManager::silence (nframes);
253 if (_latency_input_port && _latency_output_port) {
254 PortEngine& pe (port_engine());
256 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
257 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
259 _mtdm->process (nframes, in, out);
262 PortManager::cycle_end (nframes);
263 return_after_remove_check = true;
265 } else if (_measuring_latency == MeasureMIDI && _mididm) {
266 /* run a normal cycle from the perspective of the PortManager
267 so that we get silence on all registered ports.
269 we overwrite the silence on the two ports used for latency
273 PortManager::cycle_start (nframes);
274 PortManager::silence (nframes);
276 if (_latency_input_port && _latency_output_port) {
277 PortEngine& pe (port_engine());
279 _mididm->process (nframes, pe,
280 pe.get_buffer (_latency_input_port, nframes),
281 pe.get_buffer (_latency_output_port, nframes));
284 PortManager::cycle_end (nframes);
285 return_after_remove_check = true;
287 } else if (_latency_flush_frames) {
289 /* wait for the appropriate duration for the MTDM signal to
290 * drain from the ports before we revert to normal behaviour.
293 PortManager::cycle_start (nframes);
294 PortManager::silence (nframes);
295 PortManager::cycle_end (nframes);
297 if (_latency_flush_frames > nframes) {
298 _latency_flush_frames -= nframes;
300 _latency_flush_frames = 0;
303 return_after_remove_check = true;
306 if (session_remove_pending) {
308 /* perform the actual session removal */
310 if (session_removal_countdown < 0) {
312 /* fade out over 1 second */
313 session_removal_countdown = sample_rate()/2;
314 session_removal_gain = GAIN_COEFF_UNITY;
315 session_removal_gain_step = 1.0/session_removal_countdown;
317 } else if (session_removal_countdown > 0) {
319 /* we'll be fading audio out.
321 if this is the last time we do this as part
322 of session removal, do a MIDI panic now
323 to get MIDI stopped. This relies on the fact
324 that "immediate data" (aka "out of band data") from
325 MIDI tracks is *appended* after any other data,
326 so that it emerges after any outbound note ons, etc.
329 if (session_removal_countdown <= nframes) {
330 _session->midi_panic ();
336 session_removal_countdown = -1; // reset to "not in progress"
337 session_remove_pending = false;
338 session_removed.signal(); // wakes up thread that initiated session removal
342 if (return_after_remove_check) {
348 if (!_freewheeling) {
349 PortManager::cycle_start (nframes);
350 PortManager::cycle_end (nframes);
353 _processed_frames = next_processed_frames;
358 /* tell all relevant objects that we're starting a new cycle */
360 InternalSend::CycleStart (nframes);
362 /* tell all Ports that we're starting a new cycle */
364 PortManager::cycle_start (nframes);
366 /* test if we are freewheeling and there are freewheel signals connected.
367 ardour should act normally even when freewheeling unless /it/ is
368 exporting (which is what Freewheel.empty() tests for).
371 if (_freewheeling && !Freewheel.empty()) {
374 _session->process (nframes);
378 PortManager::cycle_end (nframes);
383 _processed_frames = next_processed_frames;
387 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
389 PortManager::check_monitoring ();
390 last_monitor_check = next_processed_frames;
393 #ifdef SILENCE_AFTER_SECONDS
395 bool was_silent = (_silence_countdown == 0);
397 if (_silence_countdown >= nframes) {
398 _silence_countdown -= nframes;
400 _silence_countdown = 0;
403 if (!was_silent && _silence_countdown == 0) {
405 BecameSilent (); /* EMIT SIGNAL */
408 if (_silence_countdown == 0 || _session->silent()) {
409 PortManager::silence (nframes);
413 if (_session->silent()) {
414 PortManager::silence (nframes);
418 if (session_remove_pending && session_removal_countdown) {
420 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
422 if (session_removal_countdown > nframes) {
423 session_removal_countdown -= nframes;
425 session_removal_countdown = 0;
428 session_removal_gain -= (nframes * session_removal_gain_step);
431 PortManager::cycle_end (nframes);
433 _processed_frames = next_processed_frames;
441 AudioEngine::reset_silence_countdown ()
443 #ifdef SILENCE_AFTER_SECONDS
444 double sr = 48000; /* default in case there is no backend */
448 _silence_countdown = max (60 * sr, /* 60 seconds */
449 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (double) _silence_hit_cnt)));
455 AudioEngine::launch_device_control_app()
457 if (_state_lock.trylock () ) {
458 _backend->launch_control_app ();
459 _state_lock.unlock ();
465 AudioEngine::request_backend_reset()
467 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
468 g_atomic_int_inc (&_hw_reset_request_count);
469 _hw_reset_condition.signal ();
473 AudioEngine::backend_reset_requested()
475 return g_atomic_int_get (&_hw_reset_request_count);
479 AudioEngine::do_reset_backend()
481 SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 1024);
483 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
485 while (!_stop_hw_reset_processing) {
487 if (g_atomic_int_get (&_hw_reset_request_count) != 0 && _backend) {
489 _reset_request_lock.unlock();
491 Glib::Threads::RecMutex::Lock pl (_state_lock);
492 g_atomic_int_dec_and_test (&_hw_reset_request_count);
494 std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
495 DeviceResetStarted(); // notify about device reset to be started
497 // backup the device name
498 std::string name = _backend->device_name ();
500 std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
501 if ( ( 0 == stop () ) &&
502 ( 0 == _backend->reset_device () ) &&
503 ( 0 == start () ) ) {
505 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
507 // inform about possible changes
508 BufferSizeChanged (_backend->buffer_size() );
509 DeviceResetFinished(); // notify about device reset finish
513 DeviceResetFinished(); // notify about device reset finish
514 // we've got an error
518 std::cout << "AudioEngine::RESET::Done." << std::endl;
520 _reset_request_lock.lock();
524 _hw_reset_condition.wait (_reset_request_lock);
530 AudioEngine::request_device_list_update()
532 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
533 g_atomic_int_inc (&_hw_devicelist_update_count);
534 _hw_devicelist_update_condition.signal ();
539 AudioEngine::do_devicelist_update()
541 SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
543 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
545 while (!_stop_hw_devicelist_processing) {
547 if (_hw_devicelist_update_count) {
549 _devicelist_update_lock.unlock();
551 Glib::Threads::RecMutex::Lock pl (_state_lock);
553 g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
554 DeviceListChanged (); /* EMIT SIGNAL */
556 _devicelist_update_lock.lock();
559 _hw_devicelist_update_condition.wait (_devicelist_update_lock);
566 AudioEngine::start_hw_event_processing()
568 if (_hw_reset_event_thread == 0) {
569 g_atomic_int_set(&_hw_reset_request_count, 0);
570 g_atomic_int_set(&_stop_hw_reset_processing, 0);
571 _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
574 if (_hw_devicelist_update_thread == 0) {
575 g_atomic_int_set(&_hw_devicelist_update_count, 0);
576 g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
577 _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
583 AudioEngine::stop_hw_event_processing()
585 if (_hw_reset_event_thread) {
586 g_atomic_int_set(&_stop_hw_reset_processing, 1);
587 g_atomic_int_set(&_hw_reset_request_count, 0);
588 _hw_reset_condition.signal ();
589 _hw_reset_event_thread->join ();
590 _hw_reset_event_thread = 0;
593 if (_hw_devicelist_update_thread) {
594 g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
595 g_atomic_int_set(&_hw_devicelist_update_count, 0);
596 _hw_devicelist_update_condition.signal ();
597 _hw_devicelist_update_thread->join ();
598 _hw_devicelist_update_thread = 0;
605 AudioEngine::set_session (Session *s)
607 Glib::Threads::Mutex::Lock pl (_process_lock);
609 SessionHandlePtr::set_session (s);
613 pframes_t blocksize = samples_per_cycle ();
615 PortManager::cycle_start (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);
623 _session->process (blocksize);
624 _session->process (blocksize);
626 PortManager::cycle_end (blocksize);
631 AudioEngine::remove_session ()
633 Glib::Threads::Mutex::Lock lm (_process_lock);
638 session_remove_pending = true;
639 /* signal the start of the fade out countdown */
640 session_removal_countdown = -1;
641 session_removed.wait(_process_lock);
645 SessionHandlePtr::set_session (0);
653 AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs)
655 #ifdef USE_TRACKS_CODE_FEATURES
657 _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs);
666 /* called from a signal handler for SIGPIPE */
671 AudioEngine::reset_timebase ()
674 if (_session->config.get_jack_time_master()) {
675 _backend->set_time_master (true);
677 _backend->set_time_master (false);
685 AudioEngine::destroy ()
692 AudioEngine::discover_backends ()
694 vector<std::string> backend_modules;
698 Glib::PatternSpec so_extension_pattern("*backend.so");
699 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
701 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
702 #if defined(DEBUG) || defined(_DEBUG)
703 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
705 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
708 Glib::PatternSpec dll_extension_pattern("*backend.dll");
711 find_files_matching_pattern (backend_modules, backend_search_path (),
712 so_extension_pattern);
714 find_files_matching_pattern (backend_modules, backend_search_path (),
715 dylib_extension_pattern);
717 find_files_matching_pattern (backend_modules, backend_search_path (),
718 dll_extension_pattern);
720 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
722 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
724 AudioBackendInfo* info;
726 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
728 if ((info = backend_discover (*i)) != 0) {
729 _backends.insert (make_pair (info->name, info));
733 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
735 return _backends.size();
739 AudioEngine::backend_discover (const string& path)
741 #ifdef PLATFORM_WINDOWS
742 // do not show popup dialog (e.g. missing libjack.dll)
743 // win7+ should use SetThreadErrorMode()
744 SetErrorMode(SEM_FAILCRITICALERRORS);
746 Glib::Module module (path);
747 #ifdef PLATFORM_WINDOWS
748 SetErrorMode(0); // reset to system default
750 AudioBackendInfo* info;
751 AudioBackendInfo* (*dfunc)(void);
755 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
756 Glib::Module::get_last_error()) << endmsg;
760 if (!module.get_symbol ("descriptor", func)) {
761 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
762 error << Glib::Module::get_last_error() << endmsg;
766 dfunc = (AudioBackendInfo* (*)(void))func;
768 if (!info->available()) {
772 module.make_resident ();
777 vector<const AudioBackendInfo*>
778 AudioEngine::available_backends() const
780 vector<const AudioBackendInfo*> r;
782 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
783 r.push_back (i->second);
790 AudioEngine::current_backend_name() const
793 return _backend->name();
799 AudioEngine::drop_backend ()
803 // Stopped is needed for Graph to explicitly terminate threads
804 Stopped (); /* EMIT SIGNAL */
805 _backend->drop_device ();
811 boost::shared_ptr<AudioBackend>
812 AudioEngine::set_default_backend ()
814 if (_backends.empty()) {
815 return boost::shared_ptr<AudioBackend>();
818 return set_backend (_backends.begin()->first, "", "");
821 boost::shared_ptr<AudioBackend>
822 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
824 BackendMap::iterator b = _backends.find (name);
826 if (b == _backends.end()) {
827 return boost::shared_ptr<AudioBackend>();
833 if (b->second->instantiate (arg1, arg2)) {
834 throw failed_constructor ();
837 _backend = b->second->factory (*this);
839 } catch (exception& e) {
840 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
841 return boost::shared_ptr<AudioBackend>();
847 /* BACKEND PROXY WRAPPERS */
850 AudioEngine::start (bool for_latency)
860 _processed_frames = 0;
861 last_monitor_check = 0;
863 int error_code = _backend->start (for_latency);
865 if (error_code != 0) {
866 _last_backend_error_string =
867 AudioBackend::get_error_string((AudioBackend::ErrorCode)error_code);
874 _session->set_frame_rate (_backend->sample_rate());
876 if (_session->config.get_jack_time_master()) {
877 _backend->set_time_master (true);
883 Running(); /* EMIT SIGNAL */
890 AudioEngine::stop (bool for_latency)
892 bool stop_engine = true;
898 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
904 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
907 if (_backend->stop ()) {
917 if (_session && _running && stop_engine &&
918 (_session->state_of_the_state() & Session::Loading) == 0 &&
919 (_session->state_of_the_state() & Session::Deletion) == 0) {
920 // it's not a halt, but should be handled the same way:
921 // disable record, stop transport and I/O processign but save the data.
922 _session->engine_halted ();
928 _processed_frames = 0;
929 _measuring_latency = MeasureNone;
930 _latency_output_port = 0;
931 _latency_input_port = 0;
932 _started_for_latency = false;
938 if (!for_latency && stop_engine) {
939 Stopped (); /* EMIT SIGNAL */
946 AudioEngine::freewheel (bool start_stop)
952 /* _freewheeling will be set when first Freewheel signal occurs */
954 return _backend->freewheel (start_stop);
958 AudioEngine::get_dsp_load() const
960 if (!_backend || !_running) {
963 return _backend->dsp_load ();
967 AudioEngine::is_realtime() const
973 return _backend->is_realtime();
977 AudioEngine::connected() const
983 return _backend->available();
987 AudioEngine::transport_start ()
992 return _backend->transport_start ();
996 AudioEngine::transport_stop ()
1001 return _backend->transport_stop ();
1005 AudioEngine::transport_state ()
1008 return TransportStopped;
1010 return _backend->transport_state ();
1014 AudioEngine::transport_locate (framepos_t pos)
1019 return _backend->transport_locate (pos);
1023 AudioEngine::transport_frame()
1028 return _backend->transport_frame ();
1032 AudioEngine::sample_rate () const
1037 return _backend->sample_rate ();
1041 AudioEngine::samples_per_cycle () const
1046 return _backend->buffer_size ();
1050 AudioEngine::usecs_per_cycle () const
1055 return _backend->usecs_per_cycle ();
1059 AudioEngine::raw_buffer_size (DataType t)
1064 return _backend->raw_buffer_size (t);
1068 AudioEngine::sample_time ()
1073 return _backend->sample_time ();
1077 AudioEngine::sample_time_at_cycle_start ()
1082 return _backend->sample_time_at_cycle_start ();
1086 AudioEngine::samples_since_cycle_start ()
1091 return _backend->samples_since_cycle_start ();
1095 AudioEngine::get_sync_offset (pframes_t& offset) const
1100 return _backend->get_sync_offset (offset);
1104 AudioEngine::create_process_thread (boost::function<void()> func)
1109 return _backend->create_process_thread (func);
1113 AudioEngine::join_process_threads ()
1118 return _backend->join_process_threads ();
1122 AudioEngine::in_process_thread ()
1127 return _backend->in_process_thread ();
1131 AudioEngine::process_thread_count ()
1136 return _backend->process_thread_count ();
1140 AudioEngine::set_device_name (const std::string& name)
1145 return _backend->set_device_name (name);
1149 AudioEngine::set_sample_rate (float sr)
1155 return _backend->set_sample_rate (sr);
1159 AudioEngine::set_buffer_size (uint32_t bufsiz)
1164 return _backend->set_buffer_size (bufsiz);
1168 AudioEngine::set_interleaved (bool yn)
1173 return _backend->set_interleaved (yn);
1177 AudioEngine::set_input_channels (uint32_t ic)
1182 return _backend->set_input_channels (ic);
1186 AudioEngine::set_output_channels (uint32_t oc)
1191 return _backend->set_output_channels (oc);
1195 AudioEngine::set_systemic_input_latency (uint32_t il)
1200 return _backend->set_systemic_input_latency (il);
1204 AudioEngine::set_systemic_output_latency (uint32_t ol)
1209 return _backend->set_systemic_output_latency (ol);
1213 AudioEngine::thread_initialised_for_audio_processing ()
1215 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1218 /* END OF BACKEND PROXY API */
1221 AudioEngine::thread_init_callback (void* arg)
1223 /* make sure that anybody who needs to know about this thread
1227 pthread_set_name (X_("audioengine"));
1229 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1230 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1232 SessionEvent::create_per_thread_pool (thread_name, 512);
1233 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1234 AsyncMIDIPort::set_process_thread (pthread_self());
1237 /* the special thread created/managed by the backend */
1238 AudioEngine::instance()->_main_thread = new ProcessThread;
1243 AudioEngine::sync_callback (TransportState state, framepos_t position)
1246 return _session->backend_sync_callback (state, position);
1252 AudioEngine::freewheel_callback (bool onoff)
1254 _freewheeling = onoff;
1258 AudioEngine::latency_callback (bool for_playback)
1261 _session->update_latency (for_playback);
1266 AudioEngine::update_latencies ()
1269 _backend->update_latencies ();
1274 AudioEngine::halted_callback (const char* why)
1276 if (_in_destructor) {
1277 /* everything is under control */
1283 Port::PortDrop (); /* EMIT SIGNAL */
1285 if (!_started_for_latency) {
1286 Halted (why); /* EMIT SIGNAL */
1291 AudioEngine::setup_required () const
1294 if (_backend->info().already_configured())
1297 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1306 AudioEngine::prepare_for_latency_measurement ()
1312 if (_backend->can_change_systemic_latency_when_running()) {
1316 _backend->set_systemic_input_latency (0);
1317 _backend->set_systemic_output_latency (0);
1322 _stopped_for_latency = true;
1329 _started_for_latency = true;
1335 AudioEngine::start_latency_detection (bool for_midi)
1337 if (prepare_for_latency_measurement ()) {
1341 PortEngine& pe (port_engine());
1349 /* find the ports we will connect to */
1351 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1352 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1359 /* create the ports we will use to read/write data */
1361 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1365 if (pe.connect (_latency_output_port, _latency_output_name)) {
1366 pe.unregister_port (_latency_output_port);
1371 const string portname ("latency_in");
1372 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1373 pe.unregister_port (_latency_input_port);
1374 pe.unregister_port (_latency_output_port);
1378 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1379 pe.unregister_port (_latency_input_port);
1380 pe.unregister_port (_latency_output_port);
1385 _mididm = new MIDIDM (sample_rate());
1389 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1393 if (pe.connect (_latency_output_port, _latency_output_name)) {
1394 pe.unregister_port (_latency_output_port);
1399 const string portname ("latency_in");
1400 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1401 pe.unregister_port (_latency_input_port);
1402 pe.unregister_port (_latency_output_port);
1406 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1407 pe.unregister_port (_latency_input_port);
1408 pe.unregister_port (_latency_output_port);
1413 _mtdm = new MTDM (sample_rate());
1418 _latency_signal_latency = 0;
1419 lr = pe.get_latency_range (in, false);
1420 _latency_signal_latency = lr.max;
1421 lr = pe.get_latency_range (out, true);
1422 _latency_signal_latency += lr.max;
1424 /* all created and connected, lets go */
1425 _latency_flush_frames = samples_per_cycle();
1426 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1432 AudioEngine::stop_latency_detection ()
1434 _measuring_latency = MeasureNone;
1436 if (_latency_output_port) {
1437 port_engine().unregister_port (_latency_output_port);
1438 _latency_output_port = 0;
1440 if (_latency_input_port) {
1441 port_engine().unregister_port (_latency_input_port);
1442 _latency_input_port = 0;
1445 if (!_backend->can_change_systemic_latency_when_running()) {
1449 if (_stopped_for_latency) {
1453 _stopped_for_latency = false;
1454 _started_for_latency = false;
1458 AudioEngine::set_latency_output_port (const string& name)
1460 _latency_output_name = name;
1464 AudioEngine::set_latency_input_port (const string& name)
1466 _latency_input_name = name;