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 <jack/weakjack.h>
39 #include "midi++/port.h"
40 #include "midi++/mmc.h"
42 #include "ardour/async_midi_port.h"
43 #include "ardour/audio_port.h"
44 #include "ardour/audio_backend.h"
45 #include "ardour/audioengine.h"
46 #include "ardour/backend_search_path.h"
47 #include "ardour/buffer.h"
48 #include "ardour/cycle_timer.h"
49 #include "ardour/internal_send.h"
50 #include "ardour/meter.h"
51 #include "ardour/midi_port.h"
52 #include "ardour/midiport_manager.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 gint AudioEngine::m_meter_exit;
65 AudioEngine* AudioEngine::_instance = 0;
67 AudioEngine::AudioEngine ()
68 : session_remove_pending (false)
69 , session_removal_countdown (-1)
71 , _freewheeling (false)
72 , monitor_check_interval (INT32_MAX)
73 , last_monitor_check (0)
74 , _processed_frames (0)
78 , _measuring_latency (false)
79 , _latency_input_port (0)
80 , _latency_output_port (0)
81 , _latency_flush_frames (0)
82 , _latency_signal_latency (0)
83 , _started_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 && _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 (_latency_flush_frames) {
225 /* wait for the appropriate duration for the MTDM signal to
226 * drain from the ports before we revert to normal behaviour.
229 PortManager::cycle_start (nframes);
230 PortManager::silence (nframes);
231 PortManager::cycle_end (nframes);
233 if (_latency_flush_frames > nframes) {
234 _latency_flush_frames -= nframes;
236 _latency_flush_frames = 0;
239 return_after_remove_check = true;
242 if (session_remove_pending) {
244 /* perform the actual session removal */
246 if (session_removal_countdown < 0) {
248 /* fade out over 1 second */
249 session_removal_countdown = sample_rate()/2;
250 session_removal_gain = 1.0;
251 session_removal_gain_step = 1.0/session_removal_countdown;
253 } else if (session_removal_countdown > 0) {
255 /* we'll be fading audio out.
257 if this is the last time we do this as part
258 of session removal, do a MIDI panic now
259 to get MIDI stopped. This relies on the fact
260 that "immediate data" (aka "out of band data") from
261 MIDI tracks is *appended* after any other data,
262 so that it emerges after any outbound note ons, etc.
265 if (session_removal_countdown <= nframes) {
266 _session->midi_panic ();
272 session_removal_countdown = -1; // reset to "not in progress"
273 session_remove_pending = false;
274 session_removed.signal(); // wakes up thread that initiated session removal
278 if (return_after_remove_check) {
284 if (!_freewheeling) {
285 PortManager::cycle_start (nframes);
286 PortManager::cycle_end (nframes);
289 _processed_frames = next_processed_frames;
294 /* tell all relevant objects that we're starting a new cycle */
296 InternalSend::CycleStart (nframes);
298 /* tell all Ports that we're starting a new cycle */
300 PortManager::cycle_start (nframes);
302 /* test if we are freewheeling and there are freewheel signals connected.
303 ardour should act normally even when freewheeling unless /it/ is
304 exporting (which is what Freewheel.empty() tests for).
307 if (_freewheeling && !Freewheel.empty()) {
311 _session->process (nframes);
320 _processed_frames = next_processed_frames;
324 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
326 PortManager::check_monitoring ();
327 last_monitor_check = next_processed_frames;
330 if (_session->silent()) {
331 PortManager::silence (nframes);
334 if (session_remove_pending && session_removal_countdown) {
336 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
338 if (session_removal_countdown > nframes) {
339 session_removal_countdown -= nframes;
341 session_removal_countdown = 0;
344 session_removal_gain -= (nframes * session_removal_gain_step);
347 PortManager::cycle_end (nframes);
349 _processed_frames = next_processed_frames;
358 AudioEngine::stop_metering_thread ()
360 if (m_meter_thread) {
361 g_atomic_int_set (&m_meter_exit, 1);
362 m_meter_thread->join ();
368 AudioEngine::start_metering_thread ()
370 if (m_meter_thread == 0) {
371 g_atomic_int_set (&m_meter_exit, 0);
372 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
377 AudioEngine::meter_thread ()
379 pthread_set_name (X_("meter"));
382 Glib::usleep (10000); /* 1/100th sec interval */
383 if (g_atomic_int_get(&m_meter_exit)) {
391 AudioEngine::set_session (Session *s)
393 Glib::Threads::Mutex::Lock pl (_process_lock);
395 SessionHandlePtr::set_session (s);
399 pframes_t blocksize = samples_per_cycle ();
401 PortManager::cycle_start (blocksize);
403 _session->process (blocksize);
404 _session->process (blocksize);
405 _session->process (blocksize);
406 _session->process (blocksize);
407 _session->process (blocksize);
408 _session->process (blocksize);
409 _session->process (blocksize);
410 _session->process (blocksize);
412 PortManager::cycle_end (blocksize);
417 AudioEngine::remove_session ()
419 Glib::Threads::Mutex::Lock lm (_process_lock);
424 session_remove_pending = true;
425 session_removal_countdown = 0;
426 session_removed.wait(_process_lock);
430 SessionHandlePtr::set_session (0);
440 /* called from a signal handler for SIGPIPE */
442 stop_metering_thread ();
448 AudioEngine::reset_timebase ()
451 if (_session->config.get_jack_time_master()) {
452 _backend->set_time_master (true);
454 _backend->set_time_master (false);
462 AudioEngine::destroy ()
469 AudioEngine::discover_backends ()
471 vector<std::string> backend_modules;
475 Glib::PatternSpec so_extension_pattern("*backend.so");
476 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
478 find_matching_files_in_search_path (backend_search_path (),
479 so_extension_pattern, backend_modules);
481 find_matching_files_in_search_path (backend_search_path (),
482 dylib_extension_pattern, backend_modules);
484 DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
486 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
488 AudioBackendInfo* info;
490 if ((info = backend_discover (*i)) != 0) {
491 _backends.insert (make_pair (info->name, info));
495 return _backends.size();
499 AudioEngine::backend_discover (const string& path)
501 Glib::Module module (path);
502 AudioBackendInfo* info;
503 AudioBackendInfo* (*dfunc)(void);
507 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
508 Glib::Module::get_last_error()) << endmsg;
512 if (!module.get_symbol ("descriptor", func)) {
513 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
514 error << Glib::Module::get_last_error() << endmsg;
518 module.make_resident ();
520 dfunc = (AudioBackendInfo* (*)(void))func;
526 vector<const AudioBackendInfo*>
527 AudioEngine::available_backends() const
529 vector<const AudioBackendInfo*> r;
531 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
532 r.push_back (i->second);
539 AudioEngine::current_backend_name() const
542 return _backend->name();
548 AudioEngine::drop_backend ()
556 boost::shared_ptr<AudioBackend>
557 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
559 BackendMap::iterator b = _backends.find (name);
561 if (b == _backends.end()) {
562 return boost::shared_ptr<AudioBackend>();
568 if (b->second->instantiate (arg1, arg2)) {
569 throw failed_constructor ();
572 _backend = b->second->factory (*this);
574 } catch (exception& e) {
575 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
576 return boost::shared_ptr<AudioBackend>();
582 /* BACKEND PROXY WRAPPERS */
585 AudioEngine::start ()
595 _processed_frames = 0;
596 last_monitor_check = 0;
598 if (_backend->start()) {
605 _session->set_frame_rate (_backend->sample_rate());
607 if (_session->config.get_jack_time_master()) {
608 _backend->set_time_master (true);
612 start_metering_thread ();
614 if (!_started_for_latency) {
615 Running(); /* EMIT SIGNAL */
628 Glib::Threads::Mutex::Lock lm (_process_lock);
630 if (_backend->stop ()) {
635 _processed_frames = 0;
636 _measuring_latency = false;
637 _latency_output_port = 0;
638 _latency_input_port = 0;
639 _started_for_latency = false;
640 stop_metering_thread ();
643 Stopped (); /* EMIT SIGNAL */
649 AudioEngine::pause ()
655 if (_backend->pause ()) {
661 Stopped(); /* EMIT SIGNAL */
666 AudioEngine::freewheel (bool start_stop)
672 /* _freewheeling will be set when first Freewheel signal occurs */
674 return _backend->freewheel (start_stop);
678 AudioEngine::get_cpu_load() const
683 return _backend->cpu_load ();
687 AudioEngine::is_realtime() const
693 return _backend->is_realtime();
697 AudioEngine::connected() const
703 return _backend->available();
707 AudioEngine::transport_start ()
712 return _backend->transport_start ();
716 AudioEngine::transport_stop ()
721 return _backend->transport_stop ();
725 AudioEngine::transport_state ()
728 return TransportStopped;
730 return _backend->transport_state ();
734 AudioEngine::transport_locate (framepos_t pos)
739 return _backend->transport_locate (pos);
743 AudioEngine::transport_frame()
748 return _backend->transport_frame ();
752 AudioEngine::sample_rate () const
757 return _backend->sample_rate ();
761 AudioEngine::samples_per_cycle () const
766 return _backend->buffer_size ();
770 AudioEngine::usecs_per_cycle () const
775 return _backend->usecs_per_cycle ();
779 AudioEngine::raw_buffer_size (DataType t)
784 return _backend->raw_buffer_size (t);
788 AudioEngine::sample_time ()
793 return _backend->sample_time ();
797 AudioEngine::sample_time_at_cycle_start ()
802 return _backend->sample_time_at_cycle_start ();
806 AudioEngine::samples_since_cycle_start ()
811 return _backend->samples_since_cycle_start ();
815 AudioEngine::get_sync_offset (pframes_t& offset) const
820 return _backend->get_sync_offset (offset);
824 AudioEngine::create_process_thread (boost::function<void()> func)
829 return _backend->create_process_thread (func);
833 AudioEngine::join_process_threads ()
838 return _backend->join_process_threads ();
842 AudioEngine::in_process_thread ()
847 return _backend->in_process_thread ();
851 AudioEngine::process_thread_count ()
856 return _backend->process_thread_count ();
860 AudioEngine::set_device_name (const std::string& name)
865 return _backend->set_device_name (name);
869 AudioEngine::set_sample_rate (float sr)
874 return _backend->set_sample_rate (sr);
878 AudioEngine::set_buffer_size (uint32_t bufsiz)
883 return _backend->set_buffer_size (bufsiz);
887 AudioEngine::set_sample_format (SampleFormat sf)
892 return _backend->set_sample_format (sf);
896 AudioEngine::set_interleaved (bool yn)
901 return _backend->set_interleaved (yn);
905 AudioEngine::set_input_channels (uint32_t ic)
910 return _backend->set_input_channels (ic);
914 AudioEngine::set_output_channels (uint32_t oc)
919 return _backend->set_output_channels (oc);
923 AudioEngine::set_systemic_input_latency (uint32_t il)
928 return _backend->set_systemic_input_latency (il);
932 AudioEngine::set_systemic_output_latency (uint32_t ol)
937 return _backend->set_systemic_output_latency (ol);
940 /* END OF BACKEND PROXY API */
943 AudioEngine::thread_init_callback (void* arg)
945 /* make sure that anybody who needs to know about this thread
949 pthread_set_name (X_("audioengine"));
951 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
952 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
954 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
956 AsyncMIDIPort::set_process_thread (pthread_self());
959 /* the special thread created/managed by the backend */
960 AudioEngine::instance()->_main_thread = new ProcessThread;
965 AudioEngine::sync_callback (TransportState state, framepos_t position)
968 return _session->backend_sync_callback (state, position);
974 AudioEngine::freewheel_callback (bool onoff)
976 _freewheeling = onoff;
980 AudioEngine::latency_callback (bool for_playback)
983 _session->update_latency (for_playback);
988 AudioEngine::update_latencies ()
991 _backend->update_latencies ();
996 AudioEngine::halted_callback (const char* why)
998 if (_in_destructor) {
999 /* everything is under control */
1003 stop_metering_thread ();
1006 Port::PortDrop (); /* EMIT SIGNAL */
1007 Halted (why); /* EMIT SIGNAL */
1011 AudioEngine::setup_required () const
1013 /* If there is only a single backend and it claims to be configured
1014 * already there is no setup to be done.
1016 * Primarily for a case where there is only a JACK backend and
1017 * JACK is already running.
1020 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1034 AudioEngine::prepare_for_latency_measurement ()
1037 _started_for_latency = true;
1040 _started_for_latency = false;
1049 AudioEngine::start_latency_detection ()
1051 if (prepare_for_latency_measurement ()) {
1055 PortEngine& pe (port_engine());
1060 /* find the ports we will connect to */
1062 PortEngine::PortHandle* out = pe.get_port_by_name (_latency_output_name);
1063 PortEngine::PortHandle* in = pe.get_port_by_name (_latency_input_name);
1069 /* create the ports we will use to read/write data */
1071 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1074 if (pe.connect (_latency_output_port, _latency_output_name)) {
1075 pe.unregister_port (_latency_output_port);
1079 const string portname ("latency_in");
1080 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1081 pe.unregister_port (_latency_output_port);
1084 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1085 pe.unregister_port (_latency_output_port);
1090 _latency_signal_latency = 0;
1091 lr = pe.get_latency_range (in, false);
1092 _latency_signal_latency = lr.max;
1093 lr = pe.get_latency_range (out, true);
1094 _latency_signal_latency += lr.max;
1096 /* all created and connected, lets go */
1098 _mtdm = new MTDM (sample_rate());
1099 _measuring_latency = true;
1100 _latency_flush_frames = samples_per_cycle();
1105 AudioEngine::stop_latency_detection ()
1107 _measuring_latency = false;
1109 if (_latency_output_port) {
1110 port_engine().unregister_port (_latency_output_port);
1111 _latency_output_port = 0;
1113 if (_latency_input_port) {
1114 port_engine().unregister_port (_latency_input_port);
1115 _latency_input_port = 0;
1117 if (_started_for_latency) {
1123 AudioEngine::set_latency_output_port (const string& name)
1125 _latency_output_name = name;
1129 AudioEngine::set_latency_input_port (const string& name)
1131 _latency_input_name = name;