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)
84 g_atomic_int_set (&m_meter_exit, 0);
88 AudioEngine::~AudioEngine ()
92 config_connection.disconnect ();
95 Glib::Threads::Mutex::Lock tm (_process_lock);
96 session_removed.signal ();
97 stop_metering_thread ();
102 AudioEngine::create ()
108 _instance = new AudioEngine ();
114 _thread_init_callback (void * /*arg*/)
116 /* make sure that anybody who needs to know about this thread
120 pthread_set_name (X_("audioengine"));
122 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
123 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
125 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
127 AsyncMIDIPort::set_process_thread (pthread_self());
131 AudioEngine::split_cycle (pframes_t offset)
133 /* caller must hold process lock */
135 Port::increment_global_port_buffer_offset (offset);
137 /* tell all Ports that we're going to start a new (split) cycle */
139 boost::shared_ptr<Ports> p = ports.reader();
141 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
142 i->second->cycle_split ();
147 AudioEngine::sample_rate_change (pframes_t nframes)
149 /* check for monitor input change every 1/10th of second */
151 monitor_check_interval = nframes / 10;
152 last_monitor_check = 0;
155 _session->set_frame_rate (nframes);
158 SampleRateChanged (nframes); /* EMIT SIGNAL */
164 AudioEngine::buffer_size_change (pframes_t bufsiz)
167 _session->set_block_size (bufsiz);
168 last_monitor_check = 0;
174 /** Method called by our ::process_thread when there is work to be done.
175 * @param nframes Number of frames to process.
178 AudioEngine::process_callback (pframes_t nframes)
180 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
185 /// The number of frames that will have been processed when we've finished
186 pframes_t next_processed_frames;
188 /* handle wrap around of total frames counter */
190 if (max_framepos - _processed_frames < nframes) {
191 next_processed_frames = nframes - (max_framepos - _processed_frames);
193 next_processed_frames = _processed_frames + nframes;
197 /* return having done nothing */
198 _processed_frames = next_processed_frames;
202 bool return_after_remove_check = false;
204 if (_measuring_latency && _mtdm) {
205 PortManager::cycle_start (nframes);
206 PortManager::silence (nframes);
208 if (_latency_input_port && _latency_output_port) {
209 PortEngine& pe (port_engine());
211 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
212 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
214 _mtdm->process (nframes, in, out);
217 PortManager::cycle_end (nframes);
218 return_after_remove_check = true;
220 } else if (_latency_flush_frames) {
222 /* wait for the appropriate duration for the MTDM signal to
223 * drain from the ports before we revert to normal behaviour.
226 PortManager::cycle_start (nframes);
227 PortManager::silence (nframes);
228 PortManager::cycle_end (nframes);
230 if (_latency_flush_frames > nframes) {
231 _latency_flush_frames -= nframes;
233 _latency_flush_frames = 0;
236 return_after_remove_check = true;
239 if (session_remove_pending) {
241 /* perform the actual session removal */
243 if (session_removal_countdown < 0) {
245 /* fade out over 1 second */
246 session_removal_countdown = sample_rate()/2;
247 session_removal_gain = 1.0;
248 session_removal_gain_step = 1.0/session_removal_countdown;
250 } else if (session_removal_countdown > 0) {
252 /* we'll be fading audio out.
254 if this is the last time we do this as part
255 of session removal, do a MIDI panic now
256 to get MIDI stopped. This relies on the fact
257 that "immediate data" (aka "out of band data") from
258 MIDI tracks is *appended* after any other data,
259 so that it emerges after any outbound note ons, etc.
262 if (session_removal_countdown <= nframes) {
263 _session->midi_panic ();
269 session_removal_countdown = -1; // reset to "not in progress"
270 session_remove_pending = false;
271 session_removed.signal(); // wakes up thread that initiated session removal
275 if (return_after_remove_check) {
281 if (!_freewheeling) {
282 PortManager::cycle_start (nframes);
283 PortManager::cycle_end (nframes);
286 _processed_frames = next_processed_frames;
291 /* tell all relevant objects that we're starting a new cycle */
293 InternalSend::CycleStart (nframes);
295 /* tell all Ports that we're starting a new cycle */
297 PortManager::cycle_start (nframes);
299 /* test if we are freewheeling and there are freewheel signals connected.
300 ardour should act normally even when freewheeling unless /it/ is
301 exporting (which is what Freewheel.empty() tests for).
304 if (_freewheeling && !Freewheel.empty()) {
308 _session->process (nframes);
317 _processed_frames = next_processed_frames;
321 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
323 PortManager::check_monitoring ();
324 last_monitor_check = next_processed_frames;
327 if (_session->silent()) {
328 PortManager::silence (nframes);
331 if (session_remove_pending && session_removal_countdown) {
333 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
335 if (session_removal_countdown > nframes) {
336 session_removal_countdown -= nframes;
338 session_removal_countdown = 0;
341 session_removal_gain -= (nframes * session_removal_gain_step);
344 PortManager::cycle_end (nframes);
346 _processed_frames = next_processed_frames;
355 AudioEngine::stop_metering_thread ()
357 if (m_meter_thread) {
358 g_atomic_int_set (&m_meter_exit, 1);
359 m_meter_thread->join ();
365 AudioEngine::start_metering_thread ()
367 if (m_meter_thread == 0) {
368 g_atomic_int_set (&m_meter_exit, 0);
369 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
374 AudioEngine::meter_thread ()
376 pthread_set_name (X_("meter"));
379 Glib::usleep (10000); /* 1/100th sec interval */
380 if (g_atomic_int_get(&m_meter_exit)) {
388 AudioEngine::set_session (Session *s)
390 Glib::Threads::Mutex::Lock pl (_process_lock);
392 SessionHandlePtr::set_session (s);
396 pframes_t blocksize = samples_per_cycle ();
398 PortManager::cycle_start (blocksize);
400 _session->process (blocksize);
401 _session->process (blocksize);
402 _session->process (blocksize);
403 _session->process (blocksize);
404 _session->process (blocksize);
405 _session->process (blocksize);
406 _session->process (blocksize);
407 _session->process (blocksize);
409 PortManager::cycle_end (blocksize);
414 AudioEngine::remove_session ()
416 Glib::Threads::Mutex::Lock lm (_process_lock);
420 stop_metering_thread ();
423 session_remove_pending = true;
424 session_removal_countdown = 0;
425 session_removed.wait(_process_lock);
429 SessionHandlePtr::set_session (0);
439 /* called from a signal handler for SIGPIPE */
441 stop_metering_thread ();
447 AudioEngine::reset_timebase ()
450 if (_session->config.get_jack_time_master()) {
451 _backend->set_time_master (true);
453 _backend->set_time_master (false);
461 AudioEngine::destroy ()
468 AudioEngine::discover_backends ()
470 vector<std::string> backend_modules;
474 Glib::PatternSpec so_extension_pattern("*backend.so");
475 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
477 find_matching_files_in_search_path (backend_search_path (),
478 so_extension_pattern, backend_modules);
480 find_matching_files_in_search_path (backend_search_path (),
481 dylib_extension_pattern, backend_modules);
483 DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
485 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
487 AudioBackendInfo* info;
489 if ((info = backend_discover (*i)) != 0) {
490 _backends.insert (make_pair (info->name, info));
494 return _backends.size();
498 AudioEngine::backend_discover (const string& path)
500 Glib::Module module (path);
501 AudioBackendInfo* info;
505 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
506 Glib::Module::get_last_error()) << endmsg;
510 if (!module.get_symbol ("descriptor", sym)) {
511 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor."), path) << endmsg;
512 error << Glib::Module::get_last_error() << endmsg;
516 module.make_resident ();
518 info = (AudioBackendInfo*) sym;
523 vector<const AudioBackendInfo*>
524 AudioEngine::available_backends() const
526 vector<const AudioBackendInfo*> r;
528 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
529 r.push_back (i->second);
536 AudioEngine::current_backend_name() const
539 return _backend->name();
545 AudioEngine::drop_backend ()
553 boost::shared_ptr<AudioBackend>
554 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
556 BackendMap::iterator b = _backends.find (name);
558 if (b == _backends.end()) {
559 return boost::shared_ptr<AudioBackend>();
565 if (b->second->instantiate (arg1, arg2)) {
566 throw failed_constructor ();
569 _backend = b->second->backend_factory (*this);
570 _impl = b->second->portengine_factory (*this);
572 } catch (exception& e) {
573 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
574 return boost::shared_ptr<AudioBackend>();
580 /* BACKEND PROXY WRAPPERS */
583 AudioEngine::start ()
593 _processed_frames = 0;
594 last_monitor_check = 0;
596 if (_backend->start()) {
603 _session->set_frame_rate (_backend->sample_rate());
605 if (_session->config.get_jack_time_master()) {
606 _backend->set_time_master (true);
610 start_metering_thread ();
612 Running(); /* EMIT SIGNAL */
624 Glib::Threads::Mutex::Lock lm (_process_lock);
626 if (_backend->stop ()) {
631 _processed_frames = 0;
632 _measuring_latency = false;
633 _latency_output_port = 0;
634 _latency_input_port = 0;
635 stop_metering_thread ();
638 Stopped (); /* EMIT SIGNAL */
644 AudioEngine::pause ()
650 if (_backend->pause ()) {
656 Stopped(); /* EMIT SIGNAL */
661 AudioEngine::freewheel (bool start_stop)
667 /* _freewheeling will be set when first Freewheel signal occurs */
669 return _backend->freewheel (start_stop);
673 AudioEngine::get_cpu_load() const
678 return _backend->cpu_load ();
682 AudioEngine::is_realtime() const
688 return _backend->is_realtime();
692 AudioEngine::connected() const
698 return _backend->connected();
702 AudioEngine::transport_start ()
707 return _backend->transport_start ();
711 AudioEngine::transport_stop ()
716 return _backend->transport_stop ();
720 AudioEngine::transport_state ()
723 return TransportStopped;
725 return _backend->transport_state ();
729 AudioEngine::transport_locate (framepos_t pos)
734 return _backend->transport_locate (pos);
738 AudioEngine::transport_frame()
743 return _backend->transport_frame ();
747 AudioEngine::sample_rate () const
752 return _backend->sample_rate ();
756 AudioEngine::samples_per_cycle () const
761 return _backend->buffer_size ();
765 AudioEngine::usecs_per_cycle () const
770 return _backend->usecs_per_cycle ();
774 AudioEngine::raw_buffer_size (DataType t)
779 return _backend->raw_buffer_size (t);
783 AudioEngine::sample_time ()
788 return _backend->sample_time ();
792 AudioEngine::sample_time_at_cycle_start ()
797 return _backend->sample_time_at_cycle_start ();
801 AudioEngine::samples_since_cycle_start ()
806 return _backend->samples_since_cycle_start ();
810 AudioEngine::get_sync_offset (pframes_t& offset) const
815 return _backend->get_sync_offset (offset);
819 AudioEngine::create_process_thread (boost::function<void()> func, pthread_t* thr, size_t stacksize)
824 return _backend->create_process_thread (func, thr, stacksize);
829 AudioEngine::set_device_name (const std::string& name)
834 return _backend->set_device_name (name);
838 AudioEngine::set_sample_rate (float sr)
843 return _backend->set_sample_rate (sr);
847 AudioEngine::set_buffer_size (uint32_t bufsiz)
852 return _backend->set_buffer_size (bufsiz);
856 AudioEngine::set_sample_format (SampleFormat sf)
861 return _backend->set_sample_format (sf);
865 AudioEngine::set_interleaved (bool yn)
870 return _backend->set_interleaved (yn);
874 AudioEngine::set_input_channels (uint32_t ic)
879 return _backend->set_input_channels (ic);
883 AudioEngine::set_output_channels (uint32_t oc)
888 return _backend->set_output_channels (oc);
892 AudioEngine::set_systemic_input_latency (uint32_t il)
897 return _backend->set_systemic_input_latency (il);
901 AudioEngine::set_systemic_output_latency (uint32_t ol)
906 return _backend->set_systemic_output_latency (ol);
909 /* END OF BACKEND PROXY API */
912 AudioEngine::thread_init_callback (void* arg)
914 /* make sure that anybody who needs to know about this thread
918 pthread_set_name (X_("audioengine"));
920 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
921 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
923 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
925 AsyncMIDIPort::set_process_thread (pthread_self());
928 /* the special thread created/managed by the backend */
929 AudioEngine::instance()->_main_thread = new ProcessThread;
934 AudioEngine::sync_callback (TransportState state, framepos_t position)
937 return _session->backend_sync_callback (state, position);
943 AudioEngine::freewheel_callback (bool onoff)
945 _freewheeling = onoff;
949 AudioEngine::latency_callback (bool for_playback)
952 _session->update_latency (for_playback);
957 AudioEngine::update_latencies ()
960 _backend->update_latencies ();
965 AudioEngine::halted_callback (const char* why)
967 stop_metering_thread ();
970 Port::PortDrop (); /* EMIT SIGNAL */
971 Halted (why); /* EMIT SIGNAL */
975 AudioEngine::setup_required () const
977 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
991 AudioEngine::start_latency_detection ()
993 PortEngine& pe (port_engine());
998 /* create the ports we will use to read/write data */
1000 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1003 if (pe.connect (_latency_output_port, _latency_output_name)) {
1007 const string portname ("latency_in");
1008 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1009 pe.unregister_port (_latency_output_port);
1012 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1013 pe.unregister_port (_latency_output_port);
1018 _latency_signal_latency = 0;
1019 lr = pe.get_latency_range (_latency_input_port, false);
1020 _latency_signal_latency = lr.max;
1021 lr = pe.get_latency_range (_latency_output_port, true);
1022 _latency_signal_latency += lr.max;
1024 cerr << "latency signal pathway = " << _latency_signal_latency << endl;
1026 /* all created and connected, lets go */
1028 _mtdm = new MTDM (sample_rate());
1029 _measuring_latency = true;
1030 _latency_flush_frames = samples_per_cycle();
1036 AudioEngine::stop_latency_detection ()
1038 port_engine().unregister_port (_latency_output_port);
1039 port_engine().unregister_port (_latency_input_port);
1040 _measuring_latency = false;
1044 AudioEngine::set_latency_output_port (const string& name)
1046 _latency_output_name = name;
1050 AudioEngine::set_latency_input_port (const string& name)
1052 _latency_input_name = name;