2 Copyright (C) 2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <glibmm/timer.h>
29 #include <glibmm/pattern.h>
30 #include <glibmm/module.h>
33 #include "pbd/file_utils.h"
34 #include "pbd/pthread_utils.h"
35 #include "pbd/stacktrace.h"
36 #include "pbd/unknown_type.h"
38 #include "midi++/port.h"
39 #include "midi++/mmc.h"
41 #include "ardour/async_midi_port.h"
42 #include "ardour/audio_port.h"
43 #include "ardour/audio_backend.h"
44 #include "ardour/audioengine.h"
45 #include "ardour/search_paths.h"
46 #include "ardour/buffer.h"
47 #include "ardour/cycle_timer.h"
48 #include "ardour/internal_send.h"
49 #include "ardour/meter.h"
50 #include "ardour/midi_port.h"
51 #include "ardour/midiport_manager.h"
52 #include "ardour/mididm.h"
53 #include "ardour/mtdm.h"
54 #include "ardour/port.h"
55 #include "ardour/process_thread.h"
56 #include "ardour/session.h"
61 using namespace ARDOUR;
64 AudioEngine* AudioEngine::_instance = 0;
66 static gint audioengine_thread_cnt = 1;
69 #define SILENCE_AFTER_SECONDS 600
72 AudioEngine::AudioEngine ()
73 : session_remove_pending (false)
74 , session_removal_countdown (-1)
76 , _freewheeling (false)
77 , monitor_check_interval (INT32_MAX)
78 , last_monitor_check (0)
79 , _processed_frames (0)
84 , _measuring_latency (MeasureNone)
85 , _latency_input_port (0)
86 , _latency_output_port (0)
87 , _latency_flush_frames (0)
88 , _latency_signal_latency (0)
89 , _stopped_for_latency (false)
90 , _started_for_latency (false)
91 , _in_destructor (false)
92 , _last_backend_error_string(AudioBackend::get_error_string((AudioBackend::ErrorCode)-1))
93 , _hw_reset_event_thread(0)
94 , _hw_reset_request_count(0)
95 , _stop_hw_reset_processing(0)
96 , _hw_devicelist_update_thread(0)
97 , _hw_devicelist_update_count(0)
98 , _stop_hw_devicelist_processing(0)
99 #ifdef SILENCE_AFTER_SECONDS
100 , _silence_countdown (0)
101 , _silence_hit_cnt (0)
104 reset_silence_countdown ();
105 start_hw_event_processing();
106 discover_backends ();
109 AudioEngine::~AudioEngine ()
111 _in_destructor = true;
112 stop_hw_event_processing();
114 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
115 i->second->deinstantiate();
121 AudioEngine::create ()
127 _instance = new AudioEngine ();
133 AudioEngine::split_cycle (pframes_t offset)
135 /* caller must hold process lock */
137 Port::increment_global_port_buffer_offset (offset);
139 /* tell all Ports that we're going to start a new (split) cycle */
141 boost::shared_ptr<Ports> p = ports.reader();
143 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
144 i->second->cycle_split ();
149 AudioEngine::sample_rate_change (pframes_t nframes)
151 /* check for monitor input change every 1/10th of second */
153 monitor_check_interval = nframes / 10;
154 last_monitor_check = 0;
157 _session->set_frame_rate (nframes);
160 SampleRateChanged (nframes); /* EMIT SIGNAL */
162 #ifdef SILENCE_AFTER_SECONDS
163 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
170 AudioEngine::buffer_size_change (pframes_t bufsiz)
173 _session->set_block_size (bufsiz);
174 last_monitor_check = 0;
177 BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
182 /** Method called by our ::process_thread when there is work to be done.
183 * @param nframes Number of frames to process.
186 __attribute__((annotate("realtime")))
189 AudioEngine::process_callback (pframes_t nframes)
191 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
196 /// The number of frames that will have been processed when we've finished
197 pframes_t next_processed_frames;
199 /* handle wrap around of total frames counter */
201 if (max_framepos - _processed_frames < nframes) {
202 next_processed_frames = nframes - (max_framepos - _processed_frames);
204 next_processed_frames = _processed_frames + nframes;
208 /* return having done nothing */
212 /* really only JACK requires this
213 * (other backends clear the output buffers
214 * before the process_callback. it may even be
215 * jack/alsa only). but better safe than sorry.
217 PortManager::silence_outputs (nframes);
221 /* The coreaudio-backend calls thread_init_callback() if
222 * the hardware changes or pthread_self() changes.
224 * However there are cases when neither holds true, yet
225 * the thread-pool changes: e.g. connect a headphone to
226 * a shared mic/headphone jack.
227 * It's probably related to, or caused by clocksource changes.
229 * For reasons yet unknown Glib::Threads::Private() can
230 * use a different thread-private in the same pthread
231 * (coreaudio render callback).
233 * Coreaudio must set something which influences
234 * pthread_key_t uniqness or reset the key using
235 * pthread_getspecific().
237 if (! SessionEvent::has_per_thread_pool ()) {
238 thread_init_callback (NULL);
241 bool return_after_remove_check = false;
243 if (_measuring_latency == MeasureAudio && _mtdm) {
244 /* run a normal cycle from the perspective of the PortManager
245 so that we get silence on all registered ports.
247 we overwrite the silence on the two ports used for latency
251 PortManager::cycle_start (nframes);
252 PortManager::silence (nframes);
254 if (_latency_input_port && _latency_output_port) {
255 PortEngine& pe (port_engine());
257 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
258 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
260 _mtdm->process (nframes, in, out);
263 PortManager::cycle_end (nframes);
264 return_after_remove_check = true;
266 } else if (_measuring_latency == MeasureMIDI && _mididm) {
267 /* run a normal cycle from the perspective of the PortManager
268 so that we get silence on all registered ports.
270 we overwrite the silence on the two ports used for latency
274 PortManager::cycle_start (nframes);
275 PortManager::silence (nframes);
277 if (_latency_input_port && _latency_output_port) {
278 PortEngine& pe (port_engine());
280 _mididm->process (nframes, pe,
281 pe.get_buffer (_latency_input_port, nframes),
282 pe.get_buffer (_latency_output_port, nframes));
285 PortManager::cycle_end (nframes);
286 return_after_remove_check = true;
288 } else if (_latency_flush_frames) {
290 /* wait for the appropriate duration for the MTDM signal to
291 * drain from the ports before we revert to normal behaviour.
294 PortManager::cycle_start (nframes);
295 PortManager::silence (nframes);
296 PortManager::cycle_end (nframes);
298 if (_latency_flush_frames > nframes) {
299 _latency_flush_frames -= nframes;
301 _latency_flush_frames = 0;
304 return_after_remove_check = true;
307 if (session_remove_pending) {
309 /* perform the actual session removal */
311 if (session_removal_countdown < 0) {
313 /* fade out over 1 second */
314 session_removal_countdown = sample_rate()/2;
315 session_removal_gain = GAIN_COEFF_UNITY;
316 session_removal_gain_step = 1.0/session_removal_countdown;
318 } else if (session_removal_countdown > 0) {
320 /* we'll be fading audio out.
322 if this is the last time we do this as part
323 of session removal, do a MIDI panic now
324 to get MIDI stopped. This relies on the fact
325 that "immediate data" (aka "out of band data") from
326 MIDI tracks is *appended* after any other data,
327 so that it emerges after any outbound note ons, etc.
330 if (session_removal_countdown <= nframes) {
331 _session->midi_panic ();
337 session_removal_countdown = -1; // reset to "not in progress"
338 session_remove_pending = false;
339 session_removed.signal(); // wakes up thread that initiated session removal
343 if (return_after_remove_check) {
349 if (!_freewheeling) {
350 PortManager::cycle_start (nframes);
351 PortManager::cycle_end (nframes);
354 _processed_frames = next_processed_frames;
359 /* tell all relevant objects that we're starting a new cycle */
361 InternalSend::CycleStart (nframes);
363 /* tell all Ports that we're starting a new cycle */
365 PortManager::cycle_start (nframes);
367 /* test if we are freewheeling and there are freewheel signals connected.
368 ardour should act normally even when freewheeling unless /it/ is
369 exporting (which is what Freewheel.empty() tests for).
372 if (_freewheeling && !Freewheel.empty()) {
375 _session->process (nframes);
379 PortManager::cycle_end (nframes);
384 _processed_frames = next_processed_frames;
388 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
390 PortManager::check_monitoring ();
391 last_monitor_check = next_processed_frames;
394 #ifdef SILENCE_AFTER_SECONDS
396 bool was_silent = (_silence_countdown == 0);
398 if (_silence_countdown >= nframes) {
399 _silence_countdown -= nframes;
401 _silence_countdown = 0;
404 if (!was_silent && _silence_countdown == 0) {
406 BecameSilent (); /* EMIT SIGNAL */
409 if (_silence_countdown == 0 || _session->silent()) {
410 PortManager::silence (nframes);
414 if (_session->silent()) {
415 PortManager::silence (nframes, _session);
419 if (session_remove_pending && session_removal_countdown) {
421 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
423 if (session_removal_countdown > nframes) {
424 session_removal_countdown -= nframes;
426 session_removal_countdown = 0;
429 session_removal_gain -= (nframes * session_removal_gain_step);
432 PortManager::cycle_end (nframes);
434 _processed_frames = next_processed_frames;
442 AudioEngine::reset_silence_countdown ()
444 #ifdef SILENCE_AFTER_SECONDS
445 double sr = 48000; /* default in case there is no backend */
449 _silence_countdown = max (60 * sr, /* 60 seconds */
450 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (double) _silence_hit_cnt)));
456 AudioEngine::launch_device_control_app()
458 if (_state_lock.trylock () ) {
459 _backend->launch_control_app ();
460 _state_lock.unlock ();
466 AudioEngine::request_backend_reset()
468 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
469 g_atomic_int_inc (&_hw_reset_request_count);
470 _hw_reset_condition.signal ();
474 AudioEngine::backend_reset_requested()
476 return g_atomic_int_get (&_hw_reset_request_count);
480 AudioEngine::do_reset_backend()
482 SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 1024);
484 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
486 while (!_stop_hw_reset_processing) {
488 if (g_atomic_int_get (&_hw_reset_request_count) != 0 && _backend) {
490 _reset_request_lock.unlock();
492 Glib::Threads::RecMutex::Lock pl (_state_lock);
493 g_atomic_int_dec_and_test (&_hw_reset_request_count);
495 std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
496 DeviceResetStarted(); // notify about device reset to be started
498 // backup the device name
499 std::string name = _backend->device_name ();
501 std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
502 if ( ( 0 == stop () ) &&
503 ( 0 == _backend->reset_device () ) &&
504 ( 0 == start () ) ) {
506 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
508 // inform about possible changes
509 BufferSizeChanged (_backend->buffer_size() );
510 DeviceResetFinished(); // notify about device reset finish
514 DeviceResetFinished(); // notify about device reset finish
515 // we've got an error
519 std::cout << "AudioEngine::RESET::Done." << std::endl;
521 _reset_request_lock.lock();
525 _hw_reset_condition.wait (_reset_request_lock);
531 AudioEngine::request_device_list_update()
533 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
534 g_atomic_int_inc (&_hw_devicelist_update_count);
535 _hw_devicelist_update_condition.signal ();
540 AudioEngine::do_devicelist_update()
542 SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
544 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
546 while (!_stop_hw_devicelist_processing) {
548 if (_hw_devicelist_update_count) {
550 _devicelist_update_lock.unlock();
552 Glib::Threads::RecMutex::Lock pl (_state_lock);
554 g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
555 DeviceListChanged (); /* EMIT SIGNAL */
557 _devicelist_update_lock.lock();
560 _hw_devicelist_update_condition.wait (_devicelist_update_lock);
567 AudioEngine::start_hw_event_processing()
569 if (_hw_reset_event_thread == 0) {
570 g_atomic_int_set(&_hw_reset_request_count, 0);
571 g_atomic_int_set(&_stop_hw_reset_processing, 0);
572 _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
575 if (_hw_devicelist_update_thread == 0) {
576 g_atomic_int_set(&_hw_devicelist_update_count, 0);
577 g_atomic_int_set(&_stop_hw_devicelist_processing, 0);
578 _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
584 AudioEngine::stop_hw_event_processing()
586 if (_hw_reset_event_thread) {
587 g_atomic_int_set(&_stop_hw_reset_processing, 1);
588 g_atomic_int_set(&_hw_reset_request_count, 0);
589 _hw_reset_condition.signal ();
590 _hw_reset_event_thread->join ();
591 _hw_reset_event_thread = 0;
594 if (_hw_devicelist_update_thread) {
595 g_atomic_int_set(&_stop_hw_devicelist_processing, 1);
596 g_atomic_int_set(&_hw_devicelist_update_count, 0);
597 _hw_devicelist_update_condition.signal ();
598 _hw_devicelist_update_thread->join ();
599 _hw_devicelist_update_thread = 0;
606 AudioEngine::set_session (Session *s)
608 Glib::Threads::Mutex::Lock pl (_process_lock);
610 SessionHandlePtr::set_session (s);
614 pframes_t blocksize = samples_per_cycle ();
616 PortManager::cycle_start (blocksize);
618 _session->process (blocksize);
619 _session->process (blocksize);
620 _session->process (blocksize);
621 _session->process (blocksize);
622 _session->process (blocksize);
623 _session->process (blocksize);
624 _session->process (blocksize);
625 _session->process (blocksize);
627 PortManager::cycle_end (blocksize);
632 AudioEngine::remove_session ()
634 Glib::Threads::Mutex::Lock lm (_process_lock);
639 session_remove_pending = true;
640 /* signal the start of the fade out countdown */
641 session_removal_countdown = -1;
642 session_removed.wait(_process_lock);
646 SessionHandlePtr::set_session (0);
654 AudioEngine::reconnect_session_routes (bool reconnect_inputs, bool reconnect_outputs)
656 #ifdef USE_TRACKS_CODE_FEATURES
658 _session->reconnect_existing_routes(true, true, reconnect_inputs, reconnect_outputs);
667 /* called from a signal handler for SIGPIPE */
672 AudioEngine::reset_timebase ()
675 if (_session->config.get_jack_time_master()) {
676 _backend->set_time_master (true);
678 _backend->set_time_master (false);
686 AudioEngine::destroy ()
693 AudioEngine::discover_backends ()
695 vector<std::string> backend_modules;
699 Glib::PatternSpec so_extension_pattern("*backend.so");
700 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
702 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
703 #if defined(DEBUG) || defined(_DEBUG)
704 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
706 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
709 Glib::PatternSpec dll_extension_pattern("*backend.dll");
712 find_files_matching_pattern (backend_modules, backend_search_path (),
713 so_extension_pattern);
715 find_files_matching_pattern (backend_modules, backend_search_path (),
716 dylib_extension_pattern);
718 find_files_matching_pattern (backend_modules, backend_search_path (),
719 dll_extension_pattern);
721 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
723 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
725 AudioBackendInfo* info;
727 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
729 if ((info = backend_discover (*i)) != 0) {
730 _backends.insert (make_pair (info->name, info));
734 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
736 return _backends.size();
740 AudioEngine::backend_discover (const string& path)
742 #ifdef PLATFORM_WINDOWS
743 // do not show popup dialog (e.g. missing libjack.dll)
744 // win7+ should use SetThreadErrorMode()
745 SetErrorMode(SEM_FAILCRITICALERRORS);
747 Glib::Module module (path);
748 #ifdef PLATFORM_WINDOWS
749 SetErrorMode(0); // reset to system default
751 AudioBackendInfo* info;
752 AudioBackendInfo* (*dfunc)(void);
756 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
757 Glib::Module::get_last_error()) << endmsg;
761 if (!module.get_symbol ("descriptor", func)) {
762 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
763 error << Glib::Module::get_last_error() << endmsg;
767 dfunc = (AudioBackendInfo* (*)(void))func;
769 if (!info->available()) {
773 module.make_resident ();
778 static bool running_from_source_tree ()
780 // dup ARDOUR_UI_UTILS::running_from_source_tree ()
781 gchar const *x = g_getenv ("ARDOUR_THEMES_PATH");
782 return x && (string (x).find ("gtk2_ardour") != string::npos);
785 vector<const AudioBackendInfo*>
786 AudioEngine::available_backends() const
788 vector<const AudioBackendInfo*> r;
790 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
792 if (i->first == "None (Dummy)" && !running_from_source_tree ()) {
796 r.push_back (i->second);
803 AudioEngine::current_backend_name() const
806 return _backend->name();
812 AudioEngine::drop_backend ()
816 // Stopped is needed for Graph to explicitly terminate threads
817 Stopped (); /* EMIT SIGNAL */
818 _backend->drop_device ();
824 boost::shared_ptr<AudioBackend>
825 AudioEngine::set_default_backend ()
827 if (_backends.empty()) {
828 return boost::shared_ptr<AudioBackend>();
831 return set_backend (_backends.begin()->first, "", "");
834 boost::shared_ptr<AudioBackend>
835 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
837 BackendMap::iterator b = _backends.find (name);
839 if (b == _backends.end()) {
840 return boost::shared_ptr<AudioBackend>();
846 if (b->second->instantiate (arg1, arg2)) {
847 throw failed_constructor ();
850 _backend = b->second->factory (*this);
852 } catch (exception& e) {
853 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
854 return boost::shared_ptr<AudioBackend>();
860 /* BACKEND PROXY WRAPPERS */
863 AudioEngine::start (bool for_latency)
873 _processed_frames = 0;
874 last_monitor_check = 0;
876 int error_code = _backend->start (for_latency);
878 if (error_code != 0) {
879 _last_backend_error_string = AudioBackend::get_error_string((AudioBackend::ErrorCode) error_code);
886 _session->set_frame_rate (_backend->sample_rate());
888 if (_session->config.get_jack_time_master()) {
889 _backend->set_time_master (true);
894 /* XXX MIDI ports may not actually be available here yet .. */
896 PortManager::fill_midi_port_info ();
899 Running(); /* EMIT SIGNAL */
906 AudioEngine::stop (bool for_latency)
908 bool stop_engine = true;
914 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
920 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
923 if (_backend->stop ()) {
935 if (_session && _running && stop_engine &&
936 (_session->state_of_the_state() & Session::Loading) == 0 &&
937 (_session->state_of_the_state() & Session::Deletion) == 0) {
938 // it's not a halt, but should be handled the same way:
939 // disable record, stop transport and I/O processign but save the data.
940 _session->engine_halted ();
946 _processed_frames = 0;
947 _measuring_latency = MeasureNone;
948 _latency_output_port = 0;
949 _latency_input_port = 0;
950 _started_for_latency = false;
956 if (!for_latency && stop_engine) {
957 Stopped (); /* EMIT SIGNAL */
964 AudioEngine::freewheel (bool start_stop)
970 /* _freewheeling will be set when first Freewheel signal occurs */
972 return _backend->freewheel (start_stop);
976 AudioEngine::get_dsp_load() const
978 if (!_backend || !_running) {
981 return _backend->dsp_load ();
985 AudioEngine::is_realtime() const
991 return _backend->is_realtime();
995 AudioEngine::connected() const
1001 return _backend->available();
1005 AudioEngine::transport_start ()
1010 return _backend->transport_start ();
1014 AudioEngine::transport_stop ()
1019 return _backend->transport_stop ();
1023 AudioEngine::transport_state ()
1026 return TransportStopped;
1028 return _backend->transport_state ();
1032 AudioEngine::transport_locate (framepos_t pos)
1037 return _backend->transport_locate (pos);
1041 AudioEngine::transport_frame()
1046 return _backend->transport_frame ();
1050 AudioEngine::sample_rate () const
1055 return _backend->sample_rate ();
1059 AudioEngine::samples_per_cycle () const
1064 return _backend->buffer_size ();
1068 AudioEngine::usecs_per_cycle () const
1073 return _backend->usecs_per_cycle ();
1077 AudioEngine::raw_buffer_size (DataType t)
1082 return _backend->raw_buffer_size (t);
1086 AudioEngine::sample_time ()
1091 return _backend->sample_time ();
1095 AudioEngine::sample_time_at_cycle_start ()
1100 return _backend->sample_time_at_cycle_start ();
1104 AudioEngine::samples_since_cycle_start ()
1109 return _backend->samples_since_cycle_start ();
1113 AudioEngine::get_sync_offset (pframes_t& offset) const
1118 return _backend->get_sync_offset (offset);
1122 AudioEngine::create_process_thread (boost::function<void()> func)
1127 return _backend->create_process_thread (func);
1131 AudioEngine::join_process_threads ()
1136 return _backend->join_process_threads ();
1140 AudioEngine::in_process_thread ()
1145 return _backend->in_process_thread ();
1149 AudioEngine::process_thread_count ()
1154 return _backend->process_thread_count ();
1158 AudioEngine::set_device_name (const std::string& name)
1163 return _backend->set_device_name (name);
1167 AudioEngine::set_sample_rate (float sr)
1173 return _backend->set_sample_rate (sr);
1177 AudioEngine::set_buffer_size (uint32_t bufsiz)
1182 return _backend->set_buffer_size (bufsiz);
1186 AudioEngine::set_interleaved (bool yn)
1191 return _backend->set_interleaved (yn);
1195 AudioEngine::set_input_channels (uint32_t ic)
1200 return _backend->set_input_channels (ic);
1204 AudioEngine::set_output_channels (uint32_t oc)
1209 return _backend->set_output_channels (oc);
1213 AudioEngine::set_systemic_input_latency (uint32_t il)
1218 return _backend->set_systemic_input_latency (il);
1222 AudioEngine::set_systemic_output_latency (uint32_t ol)
1227 return _backend->set_systemic_output_latency (ol);
1231 AudioEngine::thread_initialised_for_audio_processing ()
1233 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1236 /* END OF BACKEND PROXY API */
1239 AudioEngine::thread_init_callback (void* arg)
1241 /* make sure that anybody who needs to know about this thread
1245 pthread_set_name (X_("audioengine"));
1247 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1248 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1250 SessionEvent::create_per_thread_pool (thread_name, 512);
1251 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1252 AsyncMIDIPort::set_process_thread (pthread_self());
1255 delete AudioEngine::instance()->_main_thread;
1256 /* the special thread created/managed by the backend */
1257 AudioEngine::instance()->_main_thread = new ProcessThread;
1262 AudioEngine::sync_callback (TransportState state, framepos_t position)
1265 return _session->backend_sync_callback (state, position);
1271 AudioEngine::freewheel_callback (bool onoff)
1273 _freewheeling = onoff;
1277 AudioEngine::latency_callback (bool for_playback)
1280 _session->update_latency (for_playback);
1285 AudioEngine::update_latencies ()
1288 _backend->update_latencies ();
1293 AudioEngine::halted_callback (const char* why)
1295 if (_in_destructor) {
1296 /* everything is under control */
1302 Port::PortDrop (); /* EMIT SIGNAL */
1304 if (!_started_for_latency) {
1305 Halted (why); /* EMIT SIGNAL */
1310 AudioEngine::setup_required () const
1313 if (_backend->info().already_configured())
1316 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1325 AudioEngine::prepare_for_latency_measurement ()
1331 if (_backend->can_change_systemic_latency_when_running()) {
1335 _backend->set_systemic_input_latency (0);
1336 _backend->set_systemic_output_latency (0);
1341 _stopped_for_latency = true;
1348 _started_for_latency = true;
1354 AudioEngine::start_latency_detection (bool for_midi)
1356 if (prepare_for_latency_measurement ()) {
1360 PortEngine& pe (port_engine());
1368 /* find the ports we will connect to */
1370 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1371 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1378 /* create the ports we will use to read/write data */
1380 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1384 if (pe.connect (_latency_output_port, _latency_output_name)) {
1385 pe.unregister_port (_latency_output_port);
1390 const string portname ("latency_in");
1391 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1392 pe.unregister_port (_latency_input_port);
1393 pe.unregister_port (_latency_output_port);
1397 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1398 pe.unregister_port (_latency_input_port);
1399 pe.unregister_port (_latency_output_port);
1404 _mididm = new MIDIDM (sample_rate());
1408 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1412 if (pe.connect (_latency_output_port, _latency_output_name)) {
1413 pe.unregister_port (_latency_output_port);
1418 const string portname ("latency_in");
1419 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1420 pe.unregister_port (_latency_input_port);
1421 pe.unregister_port (_latency_output_port);
1425 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1426 pe.unregister_port (_latency_input_port);
1427 pe.unregister_port (_latency_output_port);
1432 _mtdm = new MTDM (sample_rate());
1437 _latency_signal_latency = 0;
1438 lr = pe.get_latency_range (in, false);
1439 _latency_signal_latency = lr.max;
1440 lr = pe.get_latency_range (out, true);
1441 _latency_signal_latency += lr.max;
1443 /* all created and connected, lets go */
1444 _latency_flush_frames = samples_per_cycle();
1445 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1451 AudioEngine::stop_latency_detection ()
1453 _measuring_latency = MeasureNone;
1455 if (_latency_output_port) {
1456 port_engine().unregister_port (_latency_output_port);
1457 _latency_output_port = 0;
1459 if (_latency_input_port) {
1460 port_engine().unregister_port (_latency_input_port);
1461 _latency_input_port = 0;
1464 if (!_backend->can_change_systemic_latency_when_running()) {
1468 if (_stopped_for_latency) {
1472 _stopped_for_latency = false;
1473 _started_for_latency = false;
1477 AudioEngine::set_latency_output_port (const string& name)
1479 _latency_output_name = name;
1483 AudioEngine::set_latency_input_port (const string& name)
1485 _latency_input_name = name;
1489 AudioEngine::add_pending_port_deletion (Port* p)
1492 DEBUG_TRACE (DEBUG::Ports, string_compose ("adding %1 to pending port deletion list\n", p->name()));
1493 if (_port_deletions_pending.write (&p, 1) != 1) {
1494 error << string_compose (_("programming error: port %1 could not be placed on the pending deletion queue\n"), p->name()) << endmsg;
1496 _session->auto_connect_thread_wakeup ();
1498 DEBUG_TRACE (DEBUG::Ports, string_compose ("Directly delete port %1\n", p->name()));