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 ();
780 static bool running_from_source_tree ()
782 // dup ARDOUR_UI_UTILS::running_from_source_tree ()
783 gchar const *x = g_getenv ("ARDOUR_THEMES_PATH");
784 return x && (string (x).find ("gtk2_ardour") != string::npos);
788 vector<const AudioBackendInfo*>
789 AudioEngine::available_backends() const
791 vector<const AudioBackendInfo*> r;
793 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
795 if (i->first == "None (Dummy)" && !running_from_source_tree () && Config->get_hide_dummy_backend ()) {
799 r.push_back (i->second);
806 AudioEngine::current_backend_name() const
809 return _backend->name();
815 AudioEngine::drop_backend ()
819 // Stopped is needed for Graph to explicitly terminate threads
820 Stopped (); /* EMIT SIGNAL */
821 _backend->drop_device ();
827 boost::shared_ptr<AudioBackend>
828 AudioEngine::set_default_backend ()
830 if (_backends.empty()) {
831 return boost::shared_ptr<AudioBackend>();
834 return set_backend (_backends.begin()->first, "", "");
837 boost::shared_ptr<AudioBackend>
838 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
840 BackendMap::iterator b = _backends.find (name);
842 if (b == _backends.end()) {
843 return boost::shared_ptr<AudioBackend>();
849 if (b->second->instantiate (arg1, arg2)) {
850 throw failed_constructor ();
853 _backend = b->second->factory (*this);
855 } catch (exception& e) {
856 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
857 return boost::shared_ptr<AudioBackend>();
863 /* BACKEND PROXY WRAPPERS */
866 AudioEngine::start (bool for_latency)
876 _processed_frames = 0;
877 last_monitor_check = 0;
879 int error_code = _backend->start (for_latency);
881 if (error_code != 0) {
882 _last_backend_error_string = AudioBackend::get_error_string((AudioBackend::ErrorCode) error_code);
889 _session->set_frame_rate (_backend->sample_rate());
891 if (_session->config.get_jack_time_master()) {
892 _backend->set_time_master (true);
897 /* XXX MIDI ports may not actually be available here yet .. */
899 PortManager::fill_midi_port_info ();
902 Running(); /* EMIT SIGNAL */
909 AudioEngine::stop (bool for_latency)
911 bool stop_engine = true;
917 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
923 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
926 if (_backend->stop ()) {
938 if (_session && _running && stop_engine &&
939 (_session->state_of_the_state() & Session::Loading) == 0 &&
940 (_session->state_of_the_state() & Session::Deletion) == 0) {
941 // it's not a halt, but should be handled the same way:
942 // disable record, stop transport and I/O processign but save the data.
943 _session->engine_halted ();
949 _processed_frames = 0;
950 _measuring_latency = MeasureNone;
951 _latency_output_port = 0;
952 _latency_input_port = 0;
953 _started_for_latency = false;
959 if (!for_latency && stop_engine) {
960 Stopped (); /* EMIT SIGNAL */
967 AudioEngine::freewheel (bool start_stop)
973 /* _freewheeling will be set when first Freewheel signal occurs */
975 return _backend->freewheel (start_stop);
979 AudioEngine::get_dsp_load() const
981 if (!_backend || !_running) {
984 return _backend->dsp_load ();
988 AudioEngine::is_realtime() const
994 return _backend->is_realtime();
998 AudioEngine::connected() const
1004 return _backend->available();
1008 AudioEngine::transport_start ()
1013 return _backend->transport_start ();
1017 AudioEngine::transport_stop ()
1022 return _backend->transport_stop ();
1026 AudioEngine::transport_state ()
1029 return TransportStopped;
1031 return _backend->transport_state ();
1035 AudioEngine::transport_locate (framepos_t pos)
1040 return _backend->transport_locate (pos);
1044 AudioEngine::transport_frame()
1049 return _backend->transport_frame ();
1053 AudioEngine::sample_rate () const
1058 return _backend->sample_rate ();
1062 AudioEngine::samples_per_cycle () const
1067 return _backend->buffer_size ();
1071 AudioEngine::usecs_per_cycle () const
1076 return _backend->usecs_per_cycle ();
1080 AudioEngine::raw_buffer_size (DataType t)
1085 return _backend->raw_buffer_size (t);
1089 AudioEngine::sample_time ()
1094 return _backend->sample_time ();
1098 AudioEngine::sample_time_at_cycle_start ()
1103 return _backend->sample_time_at_cycle_start ();
1107 AudioEngine::samples_since_cycle_start ()
1112 return _backend->samples_since_cycle_start ();
1116 AudioEngine::get_sync_offset (pframes_t& offset) const
1121 return _backend->get_sync_offset (offset);
1125 AudioEngine::create_process_thread (boost::function<void()> func)
1130 return _backend->create_process_thread (func);
1134 AudioEngine::join_process_threads ()
1139 return _backend->join_process_threads ();
1143 AudioEngine::in_process_thread ()
1148 return _backend->in_process_thread ();
1152 AudioEngine::process_thread_count ()
1157 return _backend->process_thread_count ();
1161 AudioEngine::set_device_name (const std::string& name)
1166 return _backend->set_device_name (name);
1170 AudioEngine::set_sample_rate (float sr)
1176 return _backend->set_sample_rate (sr);
1180 AudioEngine::set_buffer_size (uint32_t bufsiz)
1185 return _backend->set_buffer_size (bufsiz);
1189 AudioEngine::set_interleaved (bool yn)
1194 return _backend->set_interleaved (yn);
1198 AudioEngine::set_input_channels (uint32_t ic)
1203 return _backend->set_input_channels (ic);
1207 AudioEngine::set_output_channels (uint32_t oc)
1212 return _backend->set_output_channels (oc);
1216 AudioEngine::set_systemic_input_latency (uint32_t il)
1221 return _backend->set_systemic_input_latency (il);
1225 AudioEngine::set_systemic_output_latency (uint32_t ol)
1230 return _backend->set_systemic_output_latency (ol);
1234 AudioEngine::thread_initialised_for_audio_processing ()
1236 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1239 /* END OF BACKEND PROXY API */
1242 AudioEngine::thread_init_callback (void* arg)
1244 /* make sure that anybody who needs to know about this thread
1248 pthread_set_name (X_("audioengine"));
1250 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1251 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1253 SessionEvent::create_per_thread_pool (thread_name, 512);
1254 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1255 AsyncMIDIPort::set_process_thread (pthread_self());
1258 delete AudioEngine::instance()->_main_thread;
1259 /* the special thread created/managed by the backend */
1260 AudioEngine::instance()->_main_thread = new ProcessThread;
1265 AudioEngine::sync_callback (TransportState state, framepos_t position)
1268 return _session->backend_sync_callback (state, position);
1274 AudioEngine::freewheel_callback (bool onoff)
1276 _freewheeling = onoff;
1280 AudioEngine::latency_callback (bool for_playback)
1283 _session->update_latency (for_playback);
1288 AudioEngine::update_latencies ()
1291 _backend->update_latencies ();
1296 AudioEngine::halted_callback (const char* why)
1298 if (_in_destructor) {
1299 /* everything is under control */
1305 Port::PortDrop (); /* EMIT SIGNAL */
1307 if (!_started_for_latency) {
1308 Halted (why); /* EMIT SIGNAL */
1313 AudioEngine::setup_required () const
1316 if (_backend->info().already_configured())
1319 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1328 AudioEngine::prepare_for_latency_measurement ()
1334 if (_backend->can_change_systemic_latency_when_running()) {
1338 _backend->set_systemic_input_latency (0);
1339 _backend->set_systemic_output_latency (0);
1344 _stopped_for_latency = true;
1351 _started_for_latency = true;
1357 AudioEngine::start_latency_detection (bool for_midi)
1359 if (prepare_for_latency_measurement ()) {
1363 PortEngine& pe (port_engine());
1371 /* find the ports we will connect to */
1373 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1374 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1381 /* create the ports we will use to read/write data */
1383 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1387 if (pe.connect (_latency_output_port, _latency_output_name)) {
1388 pe.unregister_port (_latency_output_port);
1393 const string portname ("latency_in");
1394 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1395 pe.unregister_port (_latency_input_port);
1396 pe.unregister_port (_latency_output_port);
1400 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1401 pe.unregister_port (_latency_input_port);
1402 pe.unregister_port (_latency_output_port);
1407 _mididm = new MIDIDM (sample_rate());
1411 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1415 if (pe.connect (_latency_output_port, _latency_output_name)) {
1416 pe.unregister_port (_latency_output_port);
1421 const string portname ("latency_in");
1422 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1423 pe.unregister_port (_latency_input_port);
1424 pe.unregister_port (_latency_output_port);
1428 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1429 pe.unregister_port (_latency_input_port);
1430 pe.unregister_port (_latency_output_port);
1435 _mtdm = new MTDM (sample_rate());
1440 _latency_signal_latency = 0;
1441 lr = pe.get_latency_range (in, false);
1442 _latency_signal_latency = lr.max;
1443 lr = pe.get_latency_range (out, true);
1444 _latency_signal_latency += lr.max;
1446 /* all created and connected, lets go */
1447 _latency_flush_frames = samples_per_cycle();
1448 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1454 AudioEngine::stop_latency_detection ()
1456 _measuring_latency = MeasureNone;
1458 if (_latency_output_port) {
1459 port_engine().unregister_port (_latency_output_port);
1460 _latency_output_port = 0;
1462 if (_latency_input_port) {
1463 port_engine().unregister_port (_latency_input_port);
1464 _latency_input_port = 0;
1467 if (!_backend->can_change_systemic_latency_when_running()) {
1471 if (_stopped_for_latency) {
1475 _stopped_for_latency = false;
1476 _started_for_latency = false;
1480 AudioEngine::set_latency_output_port (const string& name)
1482 _latency_output_name = name;
1486 AudioEngine::set_latency_input_port (const string& name)
1488 _latency_input_name = name;
1492 AudioEngine::add_pending_port_deletion (Port* p)
1495 DEBUG_TRACE (DEBUG::Ports, string_compose ("adding %1 to pending port deletion list\n", p->name()));
1496 if (_port_deletions_pending.write (&p, 1) != 1) {
1497 error << string_compose (_("programming error: port %1 could not be placed on the pending deletion queue\n"), p->name()) << endmsg;
1499 _session->auto_connect_thread_wakeup ();
1501 DEBUG_TRACE (DEBUG::Ports, string_compose ("Directly delete port %1\n", p->name()));