2 Copyright (C) 2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <glibmm/timer.h>
29 #include <glibmm/pattern.h>
30 #include <glibmm/module.h>
33 #include "pbd/file_utils.h"
34 #include "pbd/pthread_utils.h"
35 #include "pbd/stacktrace.h"
36 #include "pbd/unknown_type.h"
38 #include "midi++/port.h"
39 #include "midi++/mmc.h"
41 #include "ardour/async_midi_port.h"
42 #include "ardour/audio_port.h"
43 #include "ardour/audio_backend.h"
44 #include "ardour/audioengine.h"
45 #include "ardour/search_paths.h"
46 #include "ardour/buffer.h"
47 #include "ardour/cycle_timer.h"
48 #include "ardour/internal_send.h"
49 #include "ardour/meter.h"
50 #include "ardour/midi_port.h"
51 #include "ardour/midiport_manager.h"
52 #include "ardour/mididm.h"
53 #include "ardour/mtdm.h"
54 #include "ardour/port.h"
55 #include "ardour/process_thread.h"
56 #include "ardour/rc_configuration.h"
57 #include "ardour/session.h"
62 using namespace ARDOUR;
65 AudioEngine* AudioEngine::_instance = 0;
67 static gint audioengine_thread_cnt = 1;
70 #define SILENCE_AFTER_SECONDS 600
73 AudioEngine::AudioEngine ()
74 : session_remove_pending (false)
75 , session_removal_countdown (-1)
77 , _freewheeling (false)
78 , monitor_check_interval (INT32_MAX)
79 , last_monitor_check (0)
80 , _processed_frames (0)
85 , _measuring_latency (MeasureNone)
86 , _latency_input_port (0)
87 , _latency_output_port (0)
88 , _latency_flush_frames (0)
89 , _latency_signal_latency (0)
90 , _stopped_for_latency (false)
91 , _started_for_latency (false)
92 , _in_destructor (false)
93 , _last_backend_error_string(AudioBackend::get_error_string((AudioBackend::ErrorCode)-1))
94 , _hw_reset_event_thread(0)
95 , _hw_reset_request_count(0)
96 , _stop_hw_reset_processing(0)
97 , _hw_devicelist_update_thread(0)
98 , _hw_devicelist_update_count(0)
99 , _stop_hw_devicelist_processing(0)
100 #ifdef SILENCE_AFTER_SECONDS
101 , _silence_countdown (0)
102 , _silence_hit_cnt (0)
105 reset_silence_countdown ();
106 start_hw_event_processing();
107 discover_backends ();
110 AudioEngine::~AudioEngine ()
112 _in_destructor = true;
113 stop_hw_event_processing();
115 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
116 i->second->deinstantiate();
122 AudioEngine::create ()
128 _instance = new AudioEngine ();
134 AudioEngine::split_cycle (pframes_t offset)
136 /* caller must hold process lock */
138 Port::increment_global_port_buffer_offset (offset);
140 /* tell all Ports that we're going to start a new (split) cycle */
142 boost::shared_ptr<Ports> p = ports.reader();
144 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
145 i->second->cycle_split ();
150 AudioEngine::sample_rate_change (pframes_t nframes)
152 /* check for monitor input change every 1/10th of second */
154 monitor_check_interval = nframes / 10;
155 last_monitor_check = 0;
158 _session->set_frame_rate (nframes);
161 SampleRateChanged (nframes); /* EMIT SIGNAL */
163 #ifdef SILENCE_AFTER_SECONDS
164 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
171 AudioEngine::buffer_size_change (pframes_t bufsiz)
174 _session->set_block_size (bufsiz);
175 last_monitor_check = 0;
178 BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
183 /** Method called by our ::process_thread when there is work to be done.
184 * @param nframes Number of frames to process.
187 __attribute__((annotate("realtime")))
190 AudioEngine::process_callback (pframes_t nframes)
192 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
197 /// The number of frames that will have been processed when we've finished
198 pframes_t next_processed_frames;
200 /* handle wrap around of total frames counter */
202 if (max_framepos - _processed_frames < nframes) {
203 next_processed_frames = nframes - (max_framepos - _processed_frames);
205 next_processed_frames = _processed_frames + nframes;
209 /* return having done nothing */
213 /* really only JACK requires this
214 * (other backends clear the output buffers
215 * before the process_callback. it may even be
216 * jack/alsa only). but better safe than sorry.
218 PortManager::silence_outputs (nframes);
222 /* The coreaudio-backend calls thread_init_callback() if
223 * the hardware changes or pthread_self() changes.
225 * However there are cases when neither holds true, yet
226 * the thread-pool changes: e.g. connect a headphone to
227 * a shared mic/headphone jack.
228 * It's probably related to, or caused by clocksource changes.
230 * For reasons yet unknown Glib::Threads::Private() can
231 * use a different thread-private in the same pthread
232 * (coreaudio render callback).
234 * Coreaudio must set something which influences
235 * pthread_key_t uniqness or reset the key using
236 * pthread_getspecific().
238 if (! SessionEvent::has_per_thread_pool ()) {
239 thread_init_callback (NULL);
242 bool return_after_remove_check = false;
244 if (_measuring_latency == MeasureAudio && _mtdm) {
245 /* run a normal cycle from the perspective of the PortManager
246 so that we get silence on all registered ports.
248 we overwrite the silence on the two ports used for latency
252 PortManager::cycle_start (nframes);
253 PortManager::silence (nframes);
255 if (_latency_input_port && _latency_output_port) {
256 PortEngine& pe (port_engine());
258 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
259 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
261 _mtdm->process (nframes, in, out);
264 PortManager::cycle_end (nframes);
265 return_after_remove_check = true;
267 } else if (_measuring_latency == MeasureMIDI && _mididm) {
268 /* run a normal cycle from the perspective of the PortManager
269 so that we get silence on all registered ports.
271 we overwrite the silence on the two ports used for latency
275 PortManager::cycle_start (nframes);
276 PortManager::silence (nframes);
278 if (_latency_input_port && _latency_output_port) {
279 PortEngine& pe (port_engine());
281 _mididm->process (nframes, pe,
282 pe.get_buffer (_latency_input_port, nframes),
283 pe.get_buffer (_latency_output_port, nframes));
286 PortManager::cycle_end (nframes);
287 return_after_remove_check = true;
289 } else if (_latency_flush_frames) {
291 /* wait for the appropriate duration for the MTDM signal to
292 * drain from the ports before we revert to normal behaviour.
295 PortManager::cycle_start (nframes);
296 PortManager::silence (nframes);
297 PortManager::cycle_end (nframes);
299 if (_latency_flush_frames > nframes) {
300 _latency_flush_frames -= nframes;
302 _latency_flush_frames = 0;
305 return_after_remove_check = true;
308 if (session_remove_pending) {
310 /* perform the actual session removal */
312 if (session_removal_countdown < 0) {
314 /* fade out over 1 second */
315 session_removal_countdown = sample_rate()/2;
316 session_removal_gain = GAIN_COEFF_UNITY;
317 session_removal_gain_step = 1.0/session_removal_countdown;
319 } else if (session_removal_countdown > 0) {
321 /* we'll be fading audio out.
323 if this is the last time we do this as part
324 of session removal, do a MIDI panic now
325 to get MIDI stopped. This relies on the fact
326 that "immediate data" (aka "out of band data") from
327 MIDI tracks is *appended* after any other data,
328 so that it emerges after any outbound note ons, etc.
331 if (session_removal_countdown <= nframes) {
332 _session->midi_panic ();
338 session_removal_countdown = -1; // reset to "not in progress"
339 session_remove_pending = false;
340 session_removed.signal(); // wakes up thread that initiated session removal
344 if (return_after_remove_check) {
350 if (!_freewheeling) {
351 PortManager::cycle_start (nframes);
352 PortManager::cycle_end (nframes);
355 _processed_frames = next_processed_frames;
360 /* tell all relevant objects that we're starting a new cycle */
362 InternalSend::CycleStart (nframes);
364 /* tell all Ports that we're starting a new cycle */
366 PortManager::cycle_start (nframes);
368 /* test if we are freewheeling and there are freewheel signals connected.
369 ardour should act normally even when freewheeling unless /it/ is
370 exporting (which is what Freewheel.empty() tests for).
373 if (_freewheeling && !Freewheel.empty()) {
376 _session->process (nframes);
380 PortManager::cycle_end (nframes);
385 _processed_frames = next_processed_frames;
389 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
391 PortManager::check_monitoring ();
392 last_monitor_check = next_processed_frames;
395 #ifdef SILENCE_AFTER_SECONDS
397 bool was_silent = (_silence_countdown == 0);
399 if (_silence_countdown >= nframes) {
400 _silence_countdown -= nframes;
402 _silence_countdown = 0;
405 if (!was_silent && _silence_countdown == 0) {
407 BecameSilent (); /* EMIT SIGNAL */
410 if (_silence_countdown == 0 || _session->silent()) {
411 PortManager::silence (nframes);
415 if (_session->silent()) {
416 PortManager::silence (nframes, _session);
420 if (session_remove_pending && session_removal_countdown) {
422 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
424 if (session_removal_countdown > nframes) {
425 session_removal_countdown -= nframes;
427 session_removal_countdown = 0;
430 session_removal_gain -= (nframes * session_removal_gain_step);
433 PortManager::cycle_end (nframes);
435 _processed_frames = next_processed_frames;
443 AudioEngine::reset_silence_countdown ()
445 #ifdef SILENCE_AFTER_SECONDS
446 double sr = 48000; /* default in case there is no backend */
450 _silence_countdown = max (60 * sr, /* 60 seconds */
451 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (double) _silence_hit_cnt)));
457 AudioEngine::launch_device_control_app()
459 if (_state_lock.trylock () ) {
460 _backend->launch_control_app ();
461 _state_lock.unlock ();
467 AudioEngine::request_backend_reset()
469 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
470 g_atomic_int_inc (&_hw_reset_request_count);
471 _hw_reset_condition.signal ();
475 AudioEngine::backend_reset_requested()
477 return g_atomic_int_get (&_hw_reset_request_count);
481 AudioEngine::do_reset_backend()
483 SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 1024);
485 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
487 while (!_stop_hw_reset_processing) {
489 if (g_atomic_int_get (&_hw_reset_request_count) != 0 && _backend) {
491 _reset_request_lock.unlock();
493 Glib::Threads::RecMutex::Lock pl (_state_lock);
494 g_atomic_int_dec_and_test (&_hw_reset_request_count);
496 std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
497 DeviceResetStarted(); // notify about device reset to be started
499 // backup the device name
500 std::string name = _backend->device_name ();
502 std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
503 if ( ( 0 == stop () ) &&
504 ( 0 == _backend->reset_device () ) &&
505 ( 0 == start () ) ) {
507 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
509 // inform about possible changes
510 BufferSizeChanged (_backend->buffer_size() );
511 DeviceResetFinished(); // notify about device reset finish
515 DeviceResetFinished(); // notify about device reset finish
516 // we've got an error
520 std::cout << "AudioEngine::RESET::Done." << std::endl;
522 _reset_request_lock.lock();
526 _hw_reset_condition.wait (_reset_request_lock);
532 AudioEngine::request_device_list_update()
534 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
535 g_atomic_int_inc (&_hw_devicelist_update_count);
536 _hw_devicelist_update_condition.signal ();
541 AudioEngine::do_devicelist_update()
543 SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
545 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
547 while (!_stop_hw_devicelist_processing) {
549 if (_hw_devicelist_update_count) {
551 _devicelist_update_lock.unlock();
553 Glib::Threads::RecMutex::Lock pl (_state_lock);
555 g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
556 DeviceListChanged (); /* EMIT SIGNAL */
558 _devicelist_update_lock.lock();
561 _hw_devicelist_update_condition.wait (_devicelist_update_lock);
568 AudioEngine::start_hw_event_processing()
570 if (_hw_reset_event_thread == 0) {
571 g_atomic_int_set(&_hw_reset_request_count, 0);
572 g_atomic_int_set(&_stop_hw_reset_processing, 0);
573 _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
576 if (_hw_devicelist_update_thread == 0) {
577 g_atomic_int_set(&_hw_devicelist_update_count, 0);
578 g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
579 _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
585 AudioEngine::stop_hw_event_processing()
587 if (_hw_reset_event_thread) {
588 g_atomic_int_set(&_stop_hw_reset_processing, 1);
589 g_atomic_int_set(&_hw_reset_request_count, 0);
590 _hw_reset_condition.signal ();
591 _hw_reset_event_thread->join ();
592 _hw_reset_event_thread = 0;
595 if (_hw_devicelist_update_thread) {
596 g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
597 g_atomic_int_set(&_hw_devicelist_update_count, 0);
598 _hw_devicelist_update_condition.signal ();
599 _hw_devicelist_update_thread->join ();
600 _hw_devicelist_update_thread = 0;
607 AudioEngine::set_session (Session *s)
609 Glib::Threads::Mutex::Lock pl (_process_lock);
611 SessionHandlePtr::set_session (s);
615 pframes_t blocksize = samples_per_cycle ();
617 PortManager::cycle_start (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);
626 _session->process (blocksize);
628 PortManager::cycle_end (blocksize);
633 AudioEngine::remove_session ()
635 Glib::Threads::Mutex::Lock lm (_process_lock);
640 session_remove_pending = true;
641 /* signal the start of the fade out countdown */
642 session_removal_countdown = -1;
643 session_removed.wait(_process_lock);
647 SessionHandlePtr::set_session (0);
655 AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs)
657 #ifdef USE_TRACKS_CODE_FEATURES
659 _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs);
668 /* called from a signal handler for SIGPIPE */
673 AudioEngine::reset_timebase ()
676 if (_session->config.get_jack_time_master()) {
677 _backend->set_time_master (true);
679 _backend->set_time_master (false);
687 AudioEngine::destroy ()
694 AudioEngine::discover_backends ()
696 vector<std::string> backend_modules;
700 Glib::PatternSpec so_extension_pattern("*backend.so");
701 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
703 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
704 #if defined(DEBUG) || defined(_DEBUG)
705 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
707 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
710 Glib::PatternSpec dll_extension_pattern("*backend.dll");
713 find_files_matching_pattern (backend_modules, backend_search_path (),
714 so_extension_pattern);
716 find_files_matching_pattern (backend_modules, backend_search_path (),
717 dylib_extension_pattern);
719 find_files_matching_pattern (backend_modules, backend_search_path (),
720 dll_extension_pattern);
722 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
724 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
726 AudioBackendInfo* info;
728 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
730 if ((info = backend_discover (*i)) != 0) {
731 _backends.insert (make_pair (info->name, info));
735 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
737 return _backends.size();
741 AudioEngine::backend_discover (const string& path)
743 #ifdef PLATFORM_WINDOWS
744 // do not show popup dialog (e.g. missing libjack.dll)
745 // win7+ should use SetThreadErrorMode()
746 SetErrorMode(SEM_FAILCRITICALERRORS);
748 Glib::Module module (path);
749 #ifdef PLATFORM_WINDOWS
750 SetErrorMode(0); // reset to system default
752 AudioBackendInfo* info;
753 AudioBackendInfo* (*dfunc)(void);
757 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
758 Glib::Module::get_last_error()) << endmsg;
762 if (!module.get_symbol ("descriptor", func)) {
763 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
764 error << Glib::Module::get_last_error() << endmsg;
768 dfunc = (AudioBackendInfo* (*)(void))func;
770 if (!info->available()) {
774 module.make_resident ();
779 static bool running_from_source_tree ()
781 // dup ARDOUR_UI_UTILS::running_from_source_tree ()
782 gchar const *x = g_getenv ("ARDOUR_THEMES_PATH");
783 return x && (string (x).find ("gtk2_ardour") != string::npos);
786 vector<const AudioBackendInfo*>
787 AudioEngine::available_backends() const
789 vector<const AudioBackendInfo*> r;
791 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
793 if (i->first == "None (Dummy)" && !running_from_source_tree () && Config->get_hide_dummy_backend ()) {
797 r.push_back (i->second);
804 AudioEngine::current_backend_name() const
807 return _backend->name();
813 AudioEngine::drop_backend ()
817 // Stopped is needed for Graph to explicitly terminate threads
818 Stopped (); /* EMIT SIGNAL */
819 _backend->drop_device ();
825 boost::shared_ptr<AudioBackend>
826 AudioEngine::set_default_backend ()
828 if (_backends.empty()) {
829 return boost::shared_ptr<AudioBackend>();
832 return set_backend (_backends.begin()->first, "", "");
835 boost::shared_ptr<AudioBackend>
836 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
838 BackendMap::iterator b = _backends.find (name);
840 if (b == _backends.end()) {
841 return boost::shared_ptr<AudioBackend>();
847 if (b->second->instantiate (arg1, arg2)) {
848 throw failed_constructor ();
851 _backend = b->second->factory (*this);
853 } catch (exception& e) {
854 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
855 return boost::shared_ptr<AudioBackend>();
861 /* BACKEND PROXY WRAPPERS */
864 AudioEngine::start (bool for_latency)
874 _processed_frames = 0;
875 last_monitor_check = 0;
877 int error_code = _backend->start (for_latency);
879 if (error_code != 0) {
880 _last_backend_error_string = AudioBackend::get_error_string((AudioBackend::ErrorCode) error_code);
887 _session->set_frame_rate (_backend->sample_rate());
889 if (_session->config.get_jack_time_master()) {
890 _backend->set_time_master (true);
895 /* XXX MIDI ports may not actually be available here yet .. */
897 PortManager::fill_midi_port_info ();
900 Running(); /* EMIT SIGNAL */
907 AudioEngine::stop (bool for_latency)
909 bool stop_engine = true;
915 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
921 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
924 if (_backend->stop ()) {
936 if (_session && _running && stop_engine &&
937 (_session->state_of_the_state() & Session::Loading) == 0 &&
938 (_session->state_of_the_state() & Session::Deletion) == 0) {
939 // it's not a halt, but should be handled the same way:
940 // disable record, stop transport and I/O processign but save the data.
941 _session->engine_halted ();
947 _processed_frames = 0;
948 _measuring_latency = MeasureNone;
949 _latency_output_port = 0;
950 _latency_input_port = 0;
951 _started_for_latency = false;
957 if (!for_latency && stop_engine) {
958 Stopped (); /* EMIT SIGNAL */
965 AudioEngine::freewheel (bool start_stop)
971 /* _freewheeling will be set when first Freewheel signal occurs */
973 return _backend->freewheel (start_stop);
977 AudioEngine::get_dsp_load() const
979 if (!_backend || !_running) {
982 return _backend->dsp_load ();
986 AudioEngine::is_realtime() const
992 return _backend->is_realtime();
996 AudioEngine::connected() const
1002 return _backend->available();
1006 AudioEngine::transport_start ()
1011 return _backend->transport_start ();
1015 AudioEngine::transport_stop ()
1020 return _backend->transport_stop ();
1024 AudioEngine::transport_state ()
1027 return TransportStopped;
1029 return _backend->transport_state ();
1033 AudioEngine::transport_locate (framepos_t pos)
1038 return _backend->transport_locate (pos);
1042 AudioEngine::transport_frame()
1047 return _backend->transport_frame ();
1051 AudioEngine::sample_rate () const
1056 return _backend->sample_rate ();
1060 AudioEngine::samples_per_cycle () const
1065 return _backend->buffer_size ();
1069 AudioEngine::usecs_per_cycle () const
1074 return _backend->usecs_per_cycle ();
1078 AudioEngine::raw_buffer_size (DataType t)
1083 return _backend->raw_buffer_size (t);
1087 AudioEngine::sample_time ()
1092 return _backend->sample_time ();
1096 AudioEngine::sample_time_at_cycle_start ()
1101 return _backend->sample_time_at_cycle_start ();
1105 AudioEngine::samples_since_cycle_start ()
1110 return _backend->samples_since_cycle_start ();
1114 AudioEngine::get_sync_offset (pframes_t& offset) const
1119 return _backend->get_sync_offset (offset);
1123 AudioEngine::create_process_thread (boost::function<void()> func)
1128 return _backend->create_process_thread (func);
1132 AudioEngine::join_process_threads ()
1137 return _backend->join_process_threads ();
1141 AudioEngine::in_process_thread ()
1146 return _backend->in_process_thread ();
1150 AudioEngine::process_thread_count ()
1155 return _backend->process_thread_count ();
1159 AudioEngine::set_device_name (const std::string& name)
1164 return _backend->set_device_name (name);
1168 AudioEngine::set_sample_rate (float sr)
1174 return _backend->set_sample_rate (sr);
1178 AudioEngine::set_buffer_size (uint32_t bufsiz)
1183 return _backend->set_buffer_size (bufsiz);
1187 AudioEngine::set_interleaved (bool yn)
1192 return _backend->set_interleaved (yn);
1196 AudioEngine::set_input_channels (uint32_t ic)
1201 return _backend->set_input_channels (ic);
1205 AudioEngine::set_output_channels (uint32_t oc)
1210 return _backend->set_output_channels (oc);
1214 AudioEngine::set_systemic_input_latency (uint32_t il)
1219 return _backend->set_systemic_input_latency (il);
1223 AudioEngine::set_systemic_output_latency (uint32_t ol)
1228 return _backend->set_systemic_output_latency (ol);
1232 AudioEngine::thread_initialised_for_audio_processing ()
1234 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1237 /* END OF BACKEND PROXY API */
1240 AudioEngine::thread_init_callback (void* arg)
1242 /* make sure that anybody who needs to know about this thread
1246 pthread_set_name (X_("audioengine"));
1248 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1249 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1251 SessionEvent::create_per_thread_pool (thread_name, 512);
1252 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1253 AsyncMIDIPort::set_process_thread (pthread_self());
1256 delete AudioEngine::instance()->_main_thread;
1257 /* the special thread created/managed by the backend */
1258 AudioEngine::instance()->_main_thread = new ProcessThread;
1263 AudioEngine::sync_callback (TransportState state, framepos_t position)
1266 return _session->backend_sync_callback (state, position);
1272 AudioEngine::freewheel_callback (bool onoff)
1274 _freewheeling = onoff;
1278 AudioEngine::latency_callback (bool for_playback)
1281 _session->update_latency (for_playback);
1286 AudioEngine::update_latencies ()
1289 _backend->update_latencies ();
1294 AudioEngine::halted_callback (const char* why)
1296 if (_in_destructor) {
1297 /* everything is under control */
1303 Port::PortDrop (); /* EMIT SIGNAL */
1305 if (!_started_for_latency) {
1306 Halted (why); /* EMIT SIGNAL */
1311 AudioEngine::setup_required () const
1314 if (_backend->info().already_configured())
1317 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1326 AudioEngine::prepare_for_latency_measurement ()
1332 if (_backend->can_change_systemic_latency_when_running()) {
1336 _backend->set_systemic_input_latency (0);
1337 _backend->set_systemic_output_latency (0);
1342 _stopped_for_latency = true;
1349 _started_for_latency = true;
1355 AudioEngine::start_latency_detection (bool for_midi)
1357 if (prepare_for_latency_measurement ()) {
1361 PortEngine& pe (port_engine());
1369 /* find the ports we will connect to */
1371 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1372 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1379 /* create the ports we will use to read/write data */
1381 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1385 if (pe.connect (_latency_output_port, _latency_output_name)) {
1386 pe.unregister_port (_latency_output_port);
1391 const string portname ("latency_in");
1392 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1393 pe.unregister_port (_latency_input_port);
1394 pe.unregister_port (_latency_output_port);
1398 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1399 pe.unregister_port (_latency_input_port);
1400 pe.unregister_port (_latency_output_port);
1405 _mididm = new MIDIDM (sample_rate());
1409 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1413 if (pe.connect (_latency_output_port, _latency_output_name)) {
1414 pe.unregister_port (_latency_output_port);
1419 const string portname ("latency_in");
1420 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1421 pe.unregister_port (_latency_input_port);
1422 pe.unregister_port (_latency_output_port);
1426 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1427 pe.unregister_port (_latency_input_port);
1428 pe.unregister_port (_latency_output_port);
1433 _mtdm = new MTDM (sample_rate());
1438 _latency_signal_latency = 0;
1439 lr = pe.get_latency_range (in, false);
1440 _latency_signal_latency = lr.max;
1441 lr = pe.get_latency_range (out, true);
1442 _latency_signal_latency += lr.max;
1444 /* all created and connected, lets go */
1445 _latency_flush_frames = samples_per_cycle();
1446 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1452 AudioEngine::stop_latency_detection ()
1454 _measuring_latency = MeasureNone;
1456 if (_latency_output_port) {
1457 port_engine().unregister_port (_latency_output_port);
1458 _latency_output_port = 0;
1460 if (_latency_input_port) {
1461 port_engine().unregister_port (_latency_input_port);
1462 _latency_input_port = 0;
1465 if (!_backend->can_change_systemic_latency_when_running()) {
1469 if (_stopped_for_latency) {
1473 _stopped_for_latency = false;
1474 _started_for_latency = false;
1478 AudioEngine::set_latency_output_port (const string& name)
1480 _latency_output_name = name;
1484 AudioEngine::set_latency_input_port (const string& name)
1486 _latency_input_name = name;
1490 AudioEngine::add_pending_port_deletion (Port* p)
1493 DEBUG_TRACE (DEBUG::Ports, string_compose ("adding %1 to pending port deletion list\n", p->name()));
1494 if (_port_deletions_pending.write (&p, 1) != 1) {
1495 error << string_compose (_("programming error: port %1 could not be placed on the pending deletion queue\n"), p->name()) << endmsg;
1497 _session->auto_connect_thread_wakeup ();
1499 DEBUG_TRACE (DEBUG::Ports, string_compose ("Directly delete port %1\n", p->name()));