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 AudioEngine::process_callback (pframes_t nframes)
176 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
181 /// The number of frames that will have been processed when we've finished
182 pframes_t next_processed_frames;
184 /* handle wrap around of total frames counter */
186 if (max_framepos - _processed_frames < nframes) {
187 next_processed_frames = nframes - (max_framepos - _processed_frames);
189 next_processed_frames = _processed_frames + nframes;
193 /* return having done nothing */
194 _processed_frames = next_processed_frames;
198 bool return_after_remove_check = false;
200 if (_measuring_latency == MeasureAudio && _mtdm) {
201 /* run a normal cycle from the perspective of the PortManager
202 so that we get silence on all registered ports.
204 we overwrite the silence on the two ports used for latency
208 PortManager::cycle_start (nframes);
209 PortManager::silence (nframes);
211 if (_latency_input_port && _latency_output_port) {
212 PortEngine& pe (port_engine());
214 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
215 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
217 _mtdm->process (nframes, in, out);
220 PortManager::cycle_end (nframes);
221 return_after_remove_check = true;
223 } else if (_measuring_latency == MeasureMIDI && _mididm) {
224 /* run a normal cycle from the perspective of the PortManager
225 so that we get silence on all registered ports.
227 we overwrite the silence on the two ports used for latency
231 PortManager::cycle_start (nframes);
232 PortManager::silence (nframes);
234 if (_latency_input_port && _latency_output_port) {
235 PortEngine& pe (port_engine());
237 _mididm->process (nframes, pe,
238 pe.get_buffer (_latency_input_port, nframes),
239 pe.get_buffer (_latency_output_port, nframes));
242 PortManager::cycle_end (nframes);
243 return_after_remove_check = true;
245 } else if (_latency_flush_frames) {
247 /* wait for the appropriate duration for the MTDM signal to
248 * drain from the ports before we revert to normal behaviour.
251 PortManager::cycle_start (nframes);
252 PortManager::silence (nframes);
253 PortManager::cycle_end (nframes);
255 if (_latency_flush_frames > nframes) {
256 _latency_flush_frames -= nframes;
258 _latency_flush_frames = 0;
261 return_after_remove_check = true;
264 if (session_remove_pending) {
266 /* perform the actual session removal */
268 if (session_removal_countdown < 0) {
270 /* fade out over 1 second */
271 session_removal_countdown = sample_rate()/2;
272 session_removal_gain = 1.0;
273 session_removal_gain_step = 1.0/session_removal_countdown;
275 } else if (session_removal_countdown > 0) {
277 /* we'll be fading audio out.
279 if this is the last time we do this as part
280 of session removal, do a MIDI panic now
281 to get MIDI stopped. This relies on the fact
282 that "immediate data" (aka "out of band data") from
283 MIDI tracks is *appended* after any other data,
284 so that it emerges after any outbound note ons, etc.
287 if (session_removal_countdown <= nframes) {
288 _session->midi_panic ();
294 session_removal_countdown = -1; // reset to "not in progress"
295 session_remove_pending = false;
296 session_removed.signal(); // wakes up thread that initiated session removal
300 if (return_after_remove_check) {
306 if (!_freewheeling) {
307 PortManager::cycle_start (nframes);
308 PortManager::cycle_end (nframes);
311 _processed_frames = next_processed_frames;
316 /* tell all relevant objects that we're starting a new cycle */
318 InternalSend::CycleStart (nframes);
320 /* tell all Ports that we're starting a new cycle */
322 PortManager::cycle_start (nframes);
324 /* test if we are freewheeling and there are freewheel signals connected.
325 ardour should act normally even when freewheeling unless /it/ is
326 exporting (which is what Freewheel.empty() tests for).
329 if (_freewheeling && !Freewheel.empty()) {
333 _session->process (nframes);
342 _processed_frames = next_processed_frames;
346 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
348 PortManager::check_monitoring ();
349 last_monitor_check = next_processed_frames;
352 if (_session->silent()) {
353 PortManager::silence (nframes);
356 if (session_remove_pending && session_removal_countdown) {
358 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
360 if (session_removal_countdown > nframes) {
361 session_removal_countdown -= nframes;
363 session_removal_countdown = 0;
366 session_removal_gain -= (nframes * session_removal_gain_step);
369 PortManager::cycle_end (nframes);
371 _processed_frames = next_processed_frames;
380 AudioEngine::stop_metering_thread ()
382 if (m_meter_thread) {
383 g_atomic_int_set (&m_meter_exit, 1);
384 m_meter_thread->join ();
390 AudioEngine::start_metering_thread ()
392 if (m_meter_thread == 0) {
393 g_atomic_int_set (&m_meter_exit, 0);
394 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
399 AudioEngine::meter_thread ()
401 pthread_set_name (X_("meter"));
404 Glib::usleep (10000); /* 1/100th sec interval */
405 if (g_atomic_int_get(&m_meter_exit)) {
413 AudioEngine::set_session (Session *s)
415 Glib::Threads::Mutex::Lock pl (_process_lock);
417 SessionHandlePtr::set_session (s);
421 pframes_t blocksize = samples_per_cycle ();
423 PortManager::cycle_start (blocksize);
425 _session->process (blocksize);
426 _session->process (blocksize);
427 _session->process (blocksize);
428 _session->process (blocksize);
429 _session->process (blocksize);
430 _session->process (blocksize);
431 _session->process (blocksize);
432 _session->process (blocksize);
434 PortManager::cycle_end (blocksize);
439 AudioEngine::remove_session ()
441 Glib::Threads::Mutex::Lock lm (_process_lock);
446 session_remove_pending = true;
447 session_removal_countdown = 0;
448 session_removed.wait(_process_lock);
452 SessionHandlePtr::set_session (0);
462 /* called from a signal handler for SIGPIPE */
464 stop_metering_thread ();
470 AudioEngine::reset_timebase ()
473 if (_session->config.get_jack_time_master()) {
474 _backend->set_time_master (true);
476 _backend->set_time_master (false);
484 AudioEngine::destroy ()
491 AudioEngine::discover_backends ()
493 vector<std::string> backend_modules;
497 Glib::PatternSpec so_extension_pattern("*backend.so");
498 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
500 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
501 #if defined(DEBUG) || defined(_DEBUG)
502 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
504 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
507 Glib::PatternSpec dll_extension_pattern("*backend.dll");
510 find_files_matching_pattern (backend_modules, backend_search_path (),
511 so_extension_pattern);
513 find_files_matching_pattern (backend_modules, backend_search_path (),
514 dylib_extension_pattern);
516 find_files_matching_pattern (backend_modules, backend_search_path (),
517 dll_extension_pattern);
519 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
521 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
523 AudioBackendInfo* info;
525 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
527 if ((info = backend_discover (*i)) != 0) {
528 _backends.insert (make_pair (info->name, info));
532 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
534 return _backends.size();
538 AudioEngine::backend_discover (const string& path)
540 Glib::Module module (path);
541 AudioBackendInfo* info;
542 AudioBackendInfo* (*dfunc)(void);
546 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
547 Glib::Module::get_last_error()) << endmsg;
551 if (!module.get_symbol ("descriptor", func)) {
552 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
553 error << Glib::Module::get_last_error() << endmsg;
557 module.make_resident ();
559 dfunc = (AudioBackendInfo* (*)(void))func;
565 vector<const AudioBackendInfo*>
566 AudioEngine::available_backends() const
568 vector<const AudioBackendInfo*> r;
570 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
571 r.push_back (i->second);
578 AudioEngine::current_backend_name() const
581 return _backend->name();
587 AudioEngine::drop_backend ()
591 _backend->drop_device();
597 boost::shared_ptr<AudioBackend>
598 AudioEngine::set_default_backend ()
600 if (_backends.empty()) {
601 return boost::shared_ptr<AudioBackend>();
604 return set_backend (_backends.begin()->first, "", "");
607 boost::shared_ptr<AudioBackend>
608 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
610 BackendMap::iterator b = _backends.find (name);
612 if (b == _backends.end()) {
613 return boost::shared_ptr<AudioBackend>();
619 if (b->second->instantiate (arg1, arg2)) {
620 throw failed_constructor ();
623 _backend = b->second->factory (*this);
625 } catch (exception& e) {
626 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
627 return boost::shared_ptr<AudioBackend>();
633 /* BACKEND PROXY WRAPPERS */
636 AudioEngine::start (bool for_latency)
646 _processed_frames = 0;
647 last_monitor_check = 0;
649 if (_backend->start (for_latency)) {
656 _session->set_frame_rate (_backend->sample_rate());
658 if (_session->config.get_jack_time_master()) {
659 _backend->set_time_master (true);
663 start_metering_thread ();
666 Running(); /* EMIT SIGNAL */
673 AudioEngine::stop (bool for_latency)
679 Glib::Threads::Mutex::Lock lm (_process_lock);
681 if (_backend->stop ()) {
686 _processed_frames = 0;
687 _measuring_latency = MeasureNone;
688 _latency_output_port = 0;
689 _latency_input_port = 0;
690 _started_for_latency = false;
691 stop_metering_thread ();
696 Stopped (); /* EMIT SIGNAL */
703 AudioEngine::freewheel (bool start_stop)
709 /* _freewheeling will be set when first Freewheel signal occurs */
711 return _backend->freewheel (start_stop);
715 AudioEngine::get_dsp_load() const
720 return _backend->dsp_load ();
724 AudioEngine::is_realtime() const
730 return _backend->is_realtime();
734 AudioEngine::connected() const
740 return _backend->available();
744 AudioEngine::transport_start ()
749 return _backend->transport_start ();
753 AudioEngine::transport_stop ()
758 return _backend->transport_stop ();
762 AudioEngine::transport_state ()
765 return TransportStopped;
767 return _backend->transport_state ();
771 AudioEngine::transport_locate (framepos_t pos)
776 return _backend->transport_locate (pos);
780 AudioEngine::transport_frame()
785 return _backend->transport_frame ();
789 AudioEngine::sample_rate () const
794 return _backend->sample_rate ();
798 AudioEngine::samples_per_cycle () const
803 return _backend->buffer_size ();
807 AudioEngine::usecs_per_cycle () const
812 return _backend->usecs_per_cycle ();
816 AudioEngine::raw_buffer_size (DataType t)
821 return _backend->raw_buffer_size (t);
825 AudioEngine::sample_time ()
830 return _backend->sample_time ();
834 AudioEngine::sample_time_at_cycle_start ()
839 return _backend->sample_time_at_cycle_start ();
843 AudioEngine::samples_since_cycle_start ()
848 return _backend->samples_since_cycle_start ();
852 AudioEngine::get_sync_offset (pframes_t& offset) const
857 return _backend->get_sync_offset (offset);
861 AudioEngine::create_process_thread (boost::function<void()> func)
866 return _backend->create_process_thread (func);
870 AudioEngine::join_process_threads ()
875 return _backend->join_process_threads ();
879 AudioEngine::in_process_thread ()
884 return _backend->in_process_thread ();
888 AudioEngine::process_thread_count ()
893 return _backend->process_thread_count ();
897 AudioEngine::set_device_name (const std::string& name)
902 return _backend->set_device_name (name);
906 AudioEngine::set_sample_rate (float sr)
911 return _backend->set_sample_rate (sr);
915 AudioEngine::set_buffer_size (uint32_t bufsiz)
920 return _backend->set_buffer_size (bufsiz);
924 AudioEngine::set_interleaved (bool yn)
929 return _backend->set_interleaved (yn);
933 AudioEngine::set_input_channels (uint32_t ic)
938 return _backend->set_input_channels (ic);
942 AudioEngine::set_output_channels (uint32_t oc)
947 return _backend->set_output_channels (oc);
951 AudioEngine::set_systemic_input_latency (uint32_t il)
956 return _backend->set_systemic_input_latency (il);
960 AudioEngine::set_systemic_output_latency (uint32_t ol)
965 return _backend->set_systemic_output_latency (ol);
968 /* END OF BACKEND PROXY API */
971 AudioEngine::thread_init_callback (void* arg)
973 /* make sure that anybody who needs to know about this thread
977 pthread_set_name (X_("audioengine"));
979 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
980 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
982 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
984 AsyncMIDIPort::set_process_thread (pthread_self());
987 /* the special thread created/managed by the backend */
988 AudioEngine::instance()->_main_thread = new ProcessThread;
993 AudioEngine::sync_callback (TransportState state, framepos_t position)
996 return _session->backend_sync_callback (state, position);
1002 AudioEngine::freewheel_callback (bool onoff)
1004 _freewheeling = onoff;
1008 AudioEngine::latency_callback (bool for_playback)
1011 _session->update_latency (for_playback);
1016 AudioEngine::update_latencies ()
1019 _backend->update_latencies ();
1024 AudioEngine::halted_callback (const char* why)
1026 if (_in_destructor) {
1027 /* everything is under control */
1031 stop_metering_thread ();
1034 Port::PortDrop (); /* EMIT SIGNAL */
1036 if (!_started_for_latency) {
1037 Halted (why); /* EMIT SIGNAL */
1042 AudioEngine::setup_required () const
1045 if (_backend->info().already_configured())
1048 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1057 AudioEngine::prepare_for_latency_measurement ()
1060 _stopped_for_latency = true;
1065 _started_for_latency = true;
1073 AudioEngine::start_latency_detection (bool for_midi)
1076 if (prepare_for_latency_measurement ()) {
1081 PortEngine& pe (port_engine());
1089 /* find the ports we will connect to */
1091 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1092 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1099 /* create the ports we will use to read/write data */
1101 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1105 if (pe.connect (_latency_output_port, _latency_output_name)) {
1106 pe.unregister_port (_latency_output_port);
1111 const string portname ("latency_in");
1112 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1113 pe.unregister_port (_latency_input_port);
1114 pe.unregister_port (_latency_output_port);
1118 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1119 pe.unregister_port (_latency_input_port);
1120 pe.unregister_port (_latency_output_port);
1125 _mididm = new MIDIDM (sample_rate());
1129 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1133 if (pe.connect (_latency_output_port, _latency_output_name)) {
1134 pe.unregister_port (_latency_output_port);
1139 const string portname ("latency_in");
1140 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1141 pe.unregister_port (_latency_input_port);
1142 pe.unregister_port (_latency_output_port);
1146 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1147 pe.unregister_port (_latency_input_port);
1148 pe.unregister_port (_latency_output_port);
1153 _mtdm = new MTDM (sample_rate());
1158 _latency_signal_latency = 0;
1159 lr = pe.get_latency_range (in, false);
1160 _latency_signal_latency = lr.max;
1161 lr = pe.get_latency_range (out, true);
1162 _latency_signal_latency += lr.max;
1164 /* all created and connected, lets go */
1165 _latency_flush_frames = samples_per_cycle();
1166 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1172 AudioEngine::stop_latency_detection ()
1174 _measuring_latency = MeasureNone;
1176 if (_latency_output_port) {
1177 port_engine().unregister_port (_latency_output_port);
1178 _latency_output_port = 0;
1180 if (_latency_input_port) {
1181 port_engine().unregister_port (_latency_input_port);
1182 _latency_input_port = 0;
1187 if (_stopped_for_latency) {
1191 _stopped_for_latency = false;
1192 _started_for_latency = false;
1196 AudioEngine::set_latency_output_port (const string& name)
1198 _latency_output_name = name;
1202 AudioEngine::set_latency_input_port (const string& name)
1204 _latency_input_name = name;