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.
27 #include <glibmm/timer.h>
28 #include <glibmm/pattern.h>
29 #include <glibmm/module.h>
32 #include "pbd/file_utils.h"
33 #include "pbd/pthread_utils.h"
34 #include "pbd/stacktrace.h"
35 #include "pbd/unknown_type.h"
37 #include "midi++/port.h"
38 #include "midi++/mmc.h"
40 #include "ardour/async_midi_port.h"
41 #include "ardour/audio_port.h"
42 #include "ardour/audio_backend.h"
43 #include "ardour/audioengine.h"
44 #include "ardour/search_paths.h"
45 #include "ardour/buffer.h"
46 #include "ardour/cycle_timer.h"
47 #include "ardour/internal_send.h"
48 #include "ardour/meter.h"
49 #include "ardour/midi_port.h"
50 #include "ardour/midiport_manager.h"
51 #include "ardour/mididm.h"
52 #include "ardour/mtdm.h"
53 #include "ardour/port.h"
54 #include "ardour/process_thread.h"
55 #include "ardour/session.h"
60 using namespace ARDOUR;
63 gint AudioEngine::m_meter_exit;
64 AudioEngine* AudioEngine::_instance = 0;
66 AudioEngine::AudioEngine ()
67 : session_remove_pending (false)
68 , session_removal_countdown (-1)
70 , _freewheeling (false)
71 , monitor_check_interval (INT32_MAX)
72 , last_monitor_check (0)
73 , _processed_frames (0)
78 , _measuring_latency (MeasureNone)
79 , _latency_input_port (0)
80 , _latency_output_port (0)
81 , _latency_flush_frames (0)
82 , _latency_signal_latency (0)
83 , _stopped_for_latency (false)
84 , _in_destructor (false)
86 g_atomic_int_set (&m_meter_exit, 0);
90 AudioEngine::~AudioEngine ()
92 _in_destructor = true;
93 stop_metering_thread ();
98 AudioEngine::create ()
104 _instance = new AudioEngine ();
110 _thread_init_callback (void * /*arg*/)
112 /* make sure that anybody who needs to know about this thread
116 pthread_set_name (X_("audioengine"));
118 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
119 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
121 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
123 AsyncMIDIPort::set_process_thread (pthread_self());
127 AudioEngine::split_cycle (pframes_t offset)
129 /* caller must hold process lock */
131 Port::increment_global_port_buffer_offset (offset);
133 /* tell all Ports that we're going to start a new (split) cycle */
135 boost::shared_ptr<Ports> p = ports.reader();
137 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
138 i->second->cycle_split ();
143 AudioEngine::sample_rate_change (pframes_t nframes)
145 /* check for monitor input change every 1/10th of second */
147 monitor_check_interval = nframes / 10;
148 last_monitor_check = 0;
151 _session->set_frame_rate (nframes);
154 SampleRateChanged (nframes); /* EMIT SIGNAL */
160 AudioEngine::buffer_size_change (pframes_t bufsiz)
163 _session->set_block_size (bufsiz);
164 last_monitor_check = 0;
170 /** Method called by our ::process_thread when there is work to be done.
171 * @param nframes Number of frames to process.
174 __attribute__((annotate("realtime")))
177 AudioEngine::process_callback (pframes_t nframes)
179 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
184 /// The number of frames that will have been processed when we've finished
185 pframes_t next_processed_frames;
187 /* handle wrap around of total frames counter */
189 if (max_framepos - _processed_frames < nframes) {
190 next_processed_frames = nframes - (max_framepos - _processed_frames);
192 next_processed_frames = _processed_frames + nframes;
196 /* return having done nothing */
197 _processed_frames = next_processed_frames;
201 bool return_after_remove_check = false;
203 if (_measuring_latency == MeasureAudio && _mtdm) {
204 /* run a normal cycle from the perspective of the PortManager
205 so that we get silence on all registered ports.
207 we overwrite the silence on the two ports used for latency
211 PortManager::cycle_start (nframes);
212 PortManager::silence (nframes);
214 if (_latency_input_port && _latency_output_port) {
215 PortEngine& pe (port_engine());
217 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
218 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
220 _mtdm->process (nframes, in, out);
223 PortManager::cycle_end (nframes);
224 return_after_remove_check = true;
226 } else if (_measuring_latency == MeasureMIDI && _mididm) {
227 /* run a normal cycle from the perspective of the PortManager
228 so that we get silence on all registered ports.
230 we overwrite the silence on the two ports used for latency
234 PortManager::cycle_start (nframes);
235 PortManager::silence (nframes);
237 if (_latency_input_port && _latency_output_port) {
238 PortEngine& pe (port_engine());
240 _mididm->process (nframes, pe,
241 pe.get_buffer (_latency_input_port, nframes),
242 pe.get_buffer (_latency_output_port, nframes));
245 PortManager::cycle_end (nframes);
246 return_after_remove_check = true;
248 } else if (_latency_flush_frames) {
250 /* wait for the appropriate duration for the MTDM signal to
251 * drain from the ports before we revert to normal behaviour.
254 PortManager::cycle_start (nframes);
255 PortManager::silence (nframes);
256 PortManager::cycle_end (nframes);
258 if (_latency_flush_frames > nframes) {
259 _latency_flush_frames -= nframes;
261 _latency_flush_frames = 0;
264 return_after_remove_check = true;
267 if (session_remove_pending) {
269 /* perform the actual session removal */
271 if (session_removal_countdown < 0) {
273 /* fade out over 1 second */
274 session_removal_countdown = sample_rate()/2;
275 session_removal_gain = 1.0;
276 session_removal_gain_step = 1.0/session_removal_countdown;
278 } else if (session_removal_countdown > 0) {
280 /* we'll be fading audio out.
282 if this is the last time we do this as part
283 of session removal, do a MIDI panic now
284 to get MIDI stopped. This relies on the fact
285 that "immediate data" (aka "out of band data") from
286 MIDI tracks is *appended* after any other data,
287 so that it emerges after any outbound note ons, etc.
290 if (session_removal_countdown <= nframes) {
291 _session->midi_panic ();
297 session_removal_countdown = -1; // reset to "not in progress"
298 session_remove_pending = false;
299 session_removed.signal(); // wakes up thread that initiated session removal
303 if (return_after_remove_check) {
309 if (!_freewheeling) {
310 PortManager::cycle_start (nframes);
311 PortManager::cycle_end (nframes);
314 _processed_frames = next_processed_frames;
319 /* tell all relevant objects that we're starting a new cycle */
321 InternalSend::CycleStart (nframes);
323 /* tell all Ports that we're starting a new cycle */
325 PortManager::cycle_start (nframes);
327 /* test if we are freewheeling and there are freewheel signals connected.
328 ardour should act normally even when freewheeling unless /it/ is
329 exporting (which is what Freewheel.empty() tests for).
332 if (_freewheeling && !Freewheel.empty()) {
336 _session->process (nframes);
345 _processed_frames = next_processed_frames;
349 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
351 PortManager::check_monitoring ();
352 last_monitor_check = next_processed_frames;
355 if (_session->silent()) {
356 PortManager::silence (nframes);
359 if (session_remove_pending && session_removal_countdown) {
361 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
363 if (session_removal_countdown > nframes) {
364 session_removal_countdown -= nframes;
366 session_removal_countdown = 0;
369 session_removal_gain -= (nframes * session_removal_gain_step);
372 PortManager::cycle_end (nframes);
374 _processed_frames = next_processed_frames;
383 AudioEngine::stop_metering_thread ()
385 if (m_meter_thread) {
386 g_atomic_int_set (&m_meter_exit, 1);
387 m_meter_thread->join ();
393 AudioEngine::start_metering_thread ()
395 if (m_meter_thread == 0) {
396 g_atomic_int_set (&m_meter_exit, 0);
397 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
402 AudioEngine::meter_thread ()
404 pthread_set_name (X_("meter"));
407 Glib::usleep (10000); /* 1/100th sec interval */
408 if (g_atomic_int_get(&m_meter_exit)) {
416 AudioEngine::set_session (Session *s)
418 Glib::Threads::Mutex::Lock pl (_process_lock);
420 SessionHandlePtr::set_session (s);
424 pframes_t blocksize = samples_per_cycle ();
426 PortManager::cycle_start (blocksize);
428 _session->process (blocksize);
429 _session->process (blocksize);
430 _session->process (blocksize);
431 _session->process (blocksize);
432 _session->process (blocksize);
433 _session->process (blocksize);
434 _session->process (blocksize);
435 _session->process (blocksize);
437 PortManager::cycle_end (blocksize);
442 AudioEngine::remove_session ()
444 Glib::Threads::Mutex::Lock lm (_process_lock);
449 session_remove_pending = true;
450 session_removal_countdown = 0;
451 session_removed.wait(_process_lock);
455 SessionHandlePtr::set_session (0);
465 /* called from a signal handler for SIGPIPE */
467 stop_metering_thread ();
473 AudioEngine::reset_timebase ()
476 if (_session->config.get_jack_time_master()) {
477 _backend->set_time_master (true);
479 _backend->set_time_master (false);
487 AudioEngine::destroy ()
494 AudioEngine::discover_backends ()
496 vector<std::string> backend_modules;
500 Glib::PatternSpec so_extension_pattern("*backend.so");
501 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
503 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
504 #if defined(DEBUG) || defined(_DEBUG)
505 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
507 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
510 Glib::PatternSpec dll_extension_pattern("*backend.dll");
513 find_files_matching_pattern (backend_modules, backend_search_path (),
514 so_extension_pattern);
516 find_files_matching_pattern (backend_modules, backend_search_path (),
517 dylib_extension_pattern);
519 find_files_matching_pattern (backend_modules, backend_search_path (),
520 dll_extension_pattern);
522 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
524 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
526 AudioBackendInfo* info;
528 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
530 if ((info = backend_discover (*i)) != 0) {
531 _backends.insert (make_pair (info->name, info));
535 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
537 return _backends.size();
541 AudioEngine::backend_discover (const string& path)
543 Glib::Module module (path);
544 AudioBackendInfo* info;
545 AudioBackendInfo* (*dfunc)(void);
549 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
550 Glib::Module::get_last_error()) << endmsg;
554 if (!module.get_symbol ("descriptor", func)) {
555 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
556 error << Glib::Module::get_last_error() << endmsg;
560 module.make_resident ();
562 dfunc = (AudioBackendInfo* (*)(void))func;
568 vector<const AudioBackendInfo*>
569 AudioEngine::available_backends() const
571 vector<const AudioBackendInfo*> r;
573 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
574 r.push_back (i->second);
581 AudioEngine::current_backend_name() const
584 return _backend->name();
590 AudioEngine::drop_backend ()
594 _backend->drop_device();
600 boost::shared_ptr<AudioBackend>
601 AudioEngine::set_default_backend ()
603 if (_backends.empty()) {
604 return boost::shared_ptr<AudioBackend>();
607 return set_backend (_backends.begin()->first, "", "");
610 boost::shared_ptr<AudioBackend>
611 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
613 BackendMap::iterator b = _backends.find (name);
615 if (b == _backends.end()) {
616 return boost::shared_ptr<AudioBackend>();
622 if (b->second->instantiate (arg1, arg2)) {
623 throw failed_constructor ();
626 _backend = b->second->factory (*this);
628 } catch (exception& e) {
629 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
630 return boost::shared_ptr<AudioBackend>();
636 /* BACKEND PROXY WRAPPERS */
639 AudioEngine::start (bool for_latency)
649 _processed_frames = 0;
650 last_monitor_check = 0;
652 if (_backend->start (for_latency)) {
659 _session->set_frame_rate (_backend->sample_rate());
661 if (_session->config.get_jack_time_master()) {
662 _backend->set_time_master (true);
666 start_metering_thread ();
669 Running(); /* EMIT SIGNAL */
676 AudioEngine::stop (bool for_latency)
682 Glib::Threads::Mutex::Lock lm (_process_lock);
684 if (_backend->stop ()) {
689 _processed_frames = 0;
690 _measuring_latency = MeasureNone;
691 _latency_output_port = 0;
692 _latency_input_port = 0;
693 _started_for_latency = false;
694 stop_metering_thread ();
699 Stopped (); /* EMIT SIGNAL */
706 AudioEngine::freewheel (bool start_stop)
712 /* _freewheeling will be set when first Freewheel signal occurs */
714 return _backend->freewheel (start_stop);
718 AudioEngine::get_dsp_load() const
723 return _backend->dsp_load ();
727 AudioEngine::is_realtime() const
733 return _backend->is_realtime();
737 AudioEngine::connected() const
743 return _backend->available();
747 AudioEngine::transport_start ()
752 return _backend->transport_start ();
756 AudioEngine::transport_stop ()
761 return _backend->transport_stop ();
765 AudioEngine::transport_state ()
768 return TransportStopped;
770 return _backend->transport_state ();
774 AudioEngine::transport_locate (framepos_t pos)
779 return _backend->transport_locate (pos);
783 AudioEngine::transport_frame()
788 return _backend->transport_frame ();
792 AudioEngine::sample_rate () const
797 return _backend->sample_rate ();
801 AudioEngine::samples_per_cycle () const
806 return _backend->buffer_size ();
810 AudioEngine::usecs_per_cycle () const
815 return _backend->usecs_per_cycle ();
819 AudioEngine::raw_buffer_size (DataType t)
824 return _backend->raw_buffer_size (t);
828 AudioEngine::sample_time ()
833 return _backend->sample_time ();
837 AudioEngine::sample_time_at_cycle_start ()
842 return _backend->sample_time_at_cycle_start ();
846 AudioEngine::samples_since_cycle_start ()
851 return _backend->samples_since_cycle_start ();
855 AudioEngine::get_sync_offset (pframes_t& offset) const
860 return _backend->get_sync_offset (offset);
864 AudioEngine::create_process_thread (boost::function<void()> func)
869 return _backend->create_process_thread (func);
873 AudioEngine::join_process_threads ()
878 return _backend->join_process_threads ();
882 AudioEngine::in_process_thread ()
887 return _backend->in_process_thread ();
891 AudioEngine::process_thread_count ()
896 return _backend->process_thread_count ();
900 AudioEngine::set_device_name (const std::string& name)
905 return _backend->set_device_name (name);
909 AudioEngine::set_sample_rate (float sr)
914 return _backend->set_sample_rate (sr);
918 AudioEngine::set_buffer_size (uint32_t bufsiz)
923 return _backend->set_buffer_size (bufsiz);
927 AudioEngine::set_interleaved (bool yn)
932 return _backend->set_interleaved (yn);
936 AudioEngine::set_input_channels (uint32_t ic)
941 return _backend->set_input_channels (ic);
945 AudioEngine::set_output_channels (uint32_t oc)
950 return _backend->set_output_channels (oc);
954 AudioEngine::set_systemic_input_latency (uint32_t il)
959 return _backend->set_systemic_input_latency (il);
963 AudioEngine::set_systemic_output_latency (uint32_t ol)
968 return _backend->set_systemic_output_latency (ol);
971 /* END OF BACKEND PROXY API */
974 AudioEngine::thread_init_callback (void* arg)
976 /* make sure that anybody who needs to know about this thread
980 pthread_set_name (X_("audioengine"));
982 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
983 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
985 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
987 AsyncMIDIPort::set_process_thread (pthread_self());
990 /* the special thread created/managed by the backend */
991 AudioEngine::instance()->_main_thread = new ProcessThread;
996 AudioEngine::sync_callback (TransportState state, framepos_t position)
999 return _session->backend_sync_callback (state, position);
1005 AudioEngine::freewheel_callback (bool onoff)
1007 _freewheeling = onoff;
1011 AudioEngine::latency_callback (bool for_playback)
1014 _session->update_latency (for_playback);
1019 AudioEngine::update_latencies ()
1022 _backend->update_latencies ();
1027 AudioEngine::halted_callback (const char* why)
1029 if (_in_destructor) {
1030 /* everything is under control */
1034 stop_metering_thread ();
1037 Port::PortDrop (); /* EMIT SIGNAL */
1039 if (!_started_for_latency) {
1040 Halted (why); /* EMIT SIGNAL */
1045 AudioEngine::setup_required () const
1048 if (_backend->info().already_configured())
1051 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1060 AudioEngine::prepare_for_latency_measurement ()
1063 _stopped_for_latency = true;
1068 _started_for_latency = true;
1076 AudioEngine::start_latency_detection (bool for_midi)
1079 if (prepare_for_latency_measurement ()) {
1084 PortEngine& pe (port_engine());
1092 /* find the ports we will connect to */
1094 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1095 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1102 /* create the ports we will use to read/write data */
1104 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1108 if (pe.connect (_latency_output_port, _latency_output_name)) {
1109 pe.unregister_port (_latency_output_port);
1114 const string portname ("latency_in");
1115 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1116 pe.unregister_port (_latency_input_port);
1117 pe.unregister_port (_latency_output_port);
1121 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1122 pe.unregister_port (_latency_input_port);
1123 pe.unregister_port (_latency_output_port);
1128 _mididm = new MIDIDM (sample_rate());
1132 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1136 if (pe.connect (_latency_output_port, _latency_output_name)) {
1137 pe.unregister_port (_latency_output_port);
1142 const string portname ("latency_in");
1143 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1144 pe.unregister_port (_latency_input_port);
1145 pe.unregister_port (_latency_output_port);
1149 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1150 pe.unregister_port (_latency_input_port);
1151 pe.unregister_port (_latency_output_port);
1156 _mtdm = new MTDM (sample_rate());
1161 _latency_signal_latency = 0;
1162 lr = pe.get_latency_range (in, false);
1163 _latency_signal_latency = lr.max;
1164 lr = pe.get_latency_range (out, true);
1165 _latency_signal_latency += lr.max;
1167 /* all created and connected, lets go */
1168 _latency_flush_frames = samples_per_cycle();
1169 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1175 AudioEngine::stop_latency_detection ()
1177 _measuring_latency = MeasureNone;
1179 if (_latency_output_port) {
1180 port_engine().unregister_port (_latency_output_port);
1181 _latency_output_port = 0;
1183 if (_latency_input_port) {
1184 port_engine().unregister_port (_latency_input_port);
1185 _latency_input_port = 0;
1190 if (_stopped_for_latency) {
1194 _stopped_for_latency = false;
1195 _started_for_latency = false;
1199 AudioEngine::set_latency_output_port (const string& name)
1201 _latency_output_name = name;
1205 AudioEngine::set_latency_input_port (const string& name)
1207 _latency_input_name = name;