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)
85 g_atomic_int_set (&m_meter_exit, 0);
89 AudioEngine::~AudioEngine ()
93 config_connection.disconnect ();
96 Glib::Threads::Mutex::Lock tm (_process_lock);
97 session_removed.signal ();
98 stop_metering_thread ();
103 AudioEngine::create ()
109 _instance = new AudioEngine ();
115 _thread_init_callback (void * /*arg*/)
117 /* make sure that anybody who needs to know about this thread
121 pthread_set_name (X_("audioengine"));
123 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
124 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
126 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
128 AsyncMIDIPort::set_process_thread (pthread_self());
132 AudioEngine::split_cycle (pframes_t offset)
134 /* caller must hold process lock */
136 Port::increment_global_port_buffer_offset (offset);
138 /* tell all Ports that we're going to start a new (split) cycle */
140 boost::shared_ptr<Ports> p = ports.reader();
142 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
143 i->second->cycle_split ();
148 AudioEngine::sample_rate_change (pframes_t nframes)
150 /* check for monitor input change every 1/10th of second */
152 monitor_check_interval = nframes / 10;
153 last_monitor_check = 0;
156 _session->set_frame_rate (nframes);
159 SampleRateChanged (nframes); /* EMIT SIGNAL */
165 AudioEngine::buffer_size_change (pframes_t bufsiz)
168 _session->set_block_size (bufsiz);
169 last_monitor_check = 0;
175 /** Method called by our ::process_thread when there is work to be done.
176 * @param nframes Number of frames to process.
179 AudioEngine::process_callback (pframes_t nframes)
181 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
186 /// The number of frames that will have been processed when we've finished
187 pframes_t next_processed_frames;
189 /* handle wrap around of total frames counter */
191 if (max_framepos - _processed_frames < nframes) {
192 next_processed_frames = nframes - (max_framepos - _processed_frames);
194 next_processed_frames = _processed_frames + nframes;
198 /* return having done nothing */
199 _processed_frames = next_processed_frames;
203 bool return_after_remove_check = false;
205 if (_measuring_latency && _mtdm) {
206 /* run a normal cycle from the perspective of the PortManager
207 so that we get silence on all registered ports.
209 we overwrite the silence on the two ports used for latency
213 PortManager::cycle_start (nframes);
214 PortManager::silence (nframes);
216 if (_latency_input_port && _latency_output_port) {
217 PortEngine& pe (port_engine());
219 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
220 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
222 _mtdm->process (nframes, in, out);
225 PortManager::cycle_end (nframes);
226 return_after_remove_check = true;
228 } else if (_latency_flush_frames) {
230 /* wait for the appropriate duration for the MTDM signal to
231 * drain from the ports before we revert to normal behaviour.
234 PortManager::cycle_start (nframes);
235 PortManager::silence (nframes);
236 PortManager::cycle_end (nframes);
238 if (_latency_flush_frames > nframes) {
239 _latency_flush_frames -= nframes;
241 _latency_flush_frames = 0;
244 return_after_remove_check = true;
247 if (session_remove_pending) {
249 /* perform the actual session removal */
251 if (session_removal_countdown < 0) {
253 /* fade out over 1 second */
254 session_removal_countdown = sample_rate()/2;
255 session_removal_gain = 1.0;
256 session_removal_gain_step = 1.0/session_removal_countdown;
258 } else if (session_removal_countdown > 0) {
260 /* we'll be fading audio out.
262 if this is the last time we do this as part
263 of session removal, do a MIDI panic now
264 to get MIDI stopped. This relies on the fact
265 that "immediate data" (aka "out of band data") from
266 MIDI tracks is *appended* after any other data,
267 so that it emerges after any outbound note ons, etc.
270 if (session_removal_countdown <= nframes) {
271 _session->midi_panic ();
277 session_removal_countdown = -1; // reset to "not in progress"
278 session_remove_pending = false;
279 session_removed.signal(); // wakes up thread that initiated session removal
283 if (return_after_remove_check) {
289 if (!_freewheeling) {
290 PortManager::cycle_start (nframes);
291 PortManager::cycle_end (nframes);
294 _processed_frames = next_processed_frames;
299 /* tell all relevant objects that we're starting a new cycle */
301 InternalSend::CycleStart (nframes);
303 /* tell all Ports that we're starting a new cycle */
305 PortManager::cycle_start (nframes);
307 /* test if we are freewheeling and there are freewheel signals connected.
308 ardour should act normally even when freewheeling unless /it/ is
309 exporting (which is what Freewheel.empty() tests for).
312 if (_freewheeling && !Freewheel.empty()) {
316 _session->process (nframes);
325 _processed_frames = next_processed_frames;
329 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
331 PortManager::check_monitoring ();
332 last_monitor_check = next_processed_frames;
335 if (_session->silent()) {
336 PortManager::silence (nframes);
339 if (session_remove_pending && session_removal_countdown) {
341 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
343 if (session_removal_countdown > nframes) {
344 session_removal_countdown -= nframes;
346 session_removal_countdown = 0;
349 session_removal_gain -= (nframes * session_removal_gain_step);
352 PortManager::cycle_end (nframes);
354 _processed_frames = next_processed_frames;
363 AudioEngine::stop_metering_thread ()
365 if (m_meter_thread) {
366 g_atomic_int_set (&m_meter_exit, 1);
367 m_meter_thread->join ();
373 AudioEngine::start_metering_thread ()
375 if (m_meter_thread == 0) {
376 g_atomic_int_set (&m_meter_exit, 0);
377 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
382 AudioEngine::meter_thread ()
384 pthread_set_name (X_("meter"));
387 Glib::usleep (10000); /* 1/100th sec interval */
388 if (g_atomic_int_get(&m_meter_exit)) {
396 AudioEngine::set_session (Session *s)
398 Glib::Threads::Mutex::Lock pl (_process_lock);
400 SessionHandlePtr::set_session (s);
404 pframes_t blocksize = samples_per_cycle ();
406 PortManager::cycle_start (blocksize);
408 _session->process (blocksize);
409 _session->process (blocksize);
410 _session->process (blocksize);
411 _session->process (blocksize);
412 _session->process (blocksize);
413 _session->process (blocksize);
414 _session->process (blocksize);
415 _session->process (blocksize);
417 PortManager::cycle_end (blocksize);
422 AudioEngine::remove_session ()
424 Glib::Threads::Mutex::Lock lm (_process_lock);
429 session_remove_pending = true;
430 session_removal_countdown = 0;
431 session_removed.wait(_process_lock);
435 SessionHandlePtr::set_session (0);
445 /* called from a signal handler for SIGPIPE */
447 stop_metering_thread ();
453 AudioEngine::reset_timebase ()
456 if (_session->config.get_jack_time_master()) {
457 _backend->set_time_master (true);
459 _backend->set_time_master (false);
467 AudioEngine::destroy ()
474 AudioEngine::discover_backends ()
476 vector<std::string> backend_modules;
480 Glib::PatternSpec so_extension_pattern("*backend.so");
481 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
483 find_matching_files_in_search_path (backend_search_path (),
484 so_extension_pattern, backend_modules);
486 find_matching_files_in_search_path (backend_search_path (),
487 dylib_extension_pattern, backend_modules);
489 DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
491 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
493 AudioBackendInfo* info;
495 if ((info = backend_discover (*i)) != 0) {
496 _backends.insert (make_pair (info->name, info));
500 return _backends.size();
504 AudioEngine::backend_discover (const string& path)
506 Glib::Module module (path);
507 AudioBackendInfo* info;
508 AudioBackendInfo* (*dfunc)(void);
512 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
513 Glib::Module::get_last_error()) << endmsg;
517 if (!module.get_symbol ("descriptor", func)) {
518 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
519 error << Glib::Module::get_last_error() << endmsg;
523 module.make_resident ();
525 dfunc = (AudioBackendInfo* (*)(void))func;
531 vector<const AudioBackendInfo*>
532 AudioEngine::available_backends() const
534 vector<const AudioBackendInfo*> r;
536 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
537 r.push_back (i->second);
544 AudioEngine::current_backend_name() const
547 return _backend->name();
553 AudioEngine::drop_backend ()
561 boost::shared_ptr<AudioBackend>
562 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
564 BackendMap::iterator b = _backends.find (name);
566 if (b == _backends.end()) {
567 return boost::shared_ptr<AudioBackend>();
573 if (b->second->instantiate (arg1, arg2)) {
574 throw failed_constructor ();
577 _backend = b->second->factory (*this);
579 } catch (exception& e) {
580 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
581 return boost::shared_ptr<AudioBackend>();
587 /* BACKEND PROXY WRAPPERS */
590 AudioEngine::start ()
600 _processed_frames = 0;
601 last_monitor_check = 0;
603 if (_backend->start()) {
610 _session->set_frame_rate (_backend->sample_rate());
612 if (_session->config.get_jack_time_master()) {
613 _backend->set_time_master (true);
617 start_metering_thread ();
619 if (!_started_for_latency) {
620 Running(); /* EMIT SIGNAL */
633 Glib::Threads::Mutex::Lock lm (_process_lock);
635 if (_backend->stop ()) {
640 _processed_frames = 0;
641 _measuring_latency = false;
642 _latency_output_port = 0;
643 _latency_input_port = 0;
644 _started_for_latency = false;
645 stop_metering_thread ();
648 Stopped (); /* EMIT SIGNAL */
654 AudioEngine::pause ()
660 if (_backend->pause ()) {
666 Stopped(); /* EMIT SIGNAL */
671 AudioEngine::freewheel (bool start_stop)
677 /* _freewheeling will be set when first Freewheel signal occurs */
679 return _backend->freewheel (start_stop);
683 AudioEngine::get_cpu_load() const
688 return _backend->cpu_load ();
692 AudioEngine::is_realtime() const
698 return _backend->is_realtime();
702 AudioEngine::connected() const
708 return _backend->available();
712 AudioEngine::transport_start ()
717 return _backend->transport_start ();
721 AudioEngine::transport_stop ()
726 return _backend->transport_stop ();
730 AudioEngine::transport_state ()
733 return TransportStopped;
735 return _backend->transport_state ();
739 AudioEngine::transport_locate (framepos_t pos)
744 return _backend->transport_locate (pos);
748 AudioEngine::transport_frame()
753 return _backend->transport_frame ();
757 AudioEngine::sample_rate () const
762 return _backend->sample_rate ();
766 AudioEngine::samples_per_cycle () const
771 return _backend->buffer_size ();
775 AudioEngine::usecs_per_cycle () const
780 return _backend->usecs_per_cycle ();
784 AudioEngine::raw_buffer_size (DataType t)
789 return _backend->raw_buffer_size (t);
793 AudioEngine::sample_time ()
798 return _backend->sample_time ();
802 AudioEngine::sample_time_at_cycle_start ()
807 return _backend->sample_time_at_cycle_start ();
811 AudioEngine::samples_since_cycle_start ()
816 return _backend->samples_since_cycle_start ();
820 AudioEngine::get_sync_offset (pframes_t& offset) const
825 return _backend->get_sync_offset (offset);
829 AudioEngine::create_process_thread (boost::function<void()> func, AudioBackendNativeThread* thr, size_t stacksize)
834 return _backend->create_process_thread (func, thr, stacksize);
838 AudioEngine::wait_for_process_thread_exit (AudioBackendNativeThread thr)
843 return _backend->wait_for_process_thread_exit (thr);
847 AudioEngine::set_device_name (const std::string& name)
852 return _backend->set_device_name (name);
856 AudioEngine::set_sample_rate (float sr)
861 return _backend->set_sample_rate (sr);
865 AudioEngine::set_buffer_size (uint32_t bufsiz)
870 return _backend->set_buffer_size (bufsiz);
874 AudioEngine::set_sample_format (SampleFormat sf)
879 return _backend->set_sample_format (sf);
883 AudioEngine::set_interleaved (bool yn)
888 return _backend->set_interleaved (yn);
892 AudioEngine::set_input_channels (uint32_t ic)
897 return _backend->set_input_channels (ic);
901 AudioEngine::set_output_channels (uint32_t oc)
906 return _backend->set_output_channels (oc);
910 AudioEngine::set_systemic_input_latency (uint32_t il)
915 return _backend->set_systemic_input_latency (il);
919 AudioEngine::set_systemic_output_latency (uint32_t ol)
924 return _backend->set_systemic_output_latency (ol);
927 /* END OF BACKEND PROXY API */
930 AudioEngine::thread_init_callback (void* arg)
932 /* make sure that anybody who needs to know about this thread
936 pthread_set_name (X_("audioengine"));
938 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
939 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
941 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
943 AsyncMIDIPort::set_process_thread (pthread_self());
946 /* the special thread created/managed by the backend */
947 AudioEngine::instance()->_main_thread = new ProcessThread;
952 AudioEngine::sync_callback (TransportState state, framepos_t position)
955 return _session->backend_sync_callback (state, position);
961 AudioEngine::freewheel_callback (bool onoff)
963 _freewheeling = onoff;
967 AudioEngine::latency_callback (bool for_playback)
970 _session->update_latency (for_playback);
975 AudioEngine::update_latencies ()
978 _backend->update_latencies ();
983 AudioEngine::halted_callback (const char* why)
985 stop_metering_thread ();
988 Port::PortDrop (); /* EMIT SIGNAL */
989 Halted (why); /* EMIT SIGNAL */
993 AudioEngine::setup_required () const
995 /* If there is only a single backend and it claims to be configured
996 * already there is no setup to be done.
998 * Primarily for a case where there is only a JACK backend and
999 * JACK is already running.
1002 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1016 AudioEngine::prepare_for_latency_measurement ()
1019 _started_for_latency = true;
1022 _started_for_latency = false;
1031 AudioEngine::start_latency_detection ()
1033 if (prepare_for_latency_measurement ()) {
1037 PortEngine& pe (port_engine());
1042 /* find the ports we will connect to */
1044 PortEngine::PortHandle* out = pe.get_port_by_name (_latency_output_name);
1045 PortEngine::PortHandle* in = pe.get_port_by_name (_latency_input_name);
1051 /* create the ports we will use to read/write data */
1053 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1056 if (pe.connect (_latency_output_port, _latency_output_name)) {
1057 pe.unregister_port (_latency_output_port);
1061 const string portname ("latency_in");
1062 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1063 pe.unregister_port (_latency_output_port);
1066 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1067 pe.unregister_port (_latency_output_port);
1072 _latency_signal_latency = 0;
1073 lr = pe.get_latency_range (in, false);
1074 _latency_signal_latency = lr.max;
1075 lr = pe.get_latency_range (out, true);
1076 _latency_signal_latency += lr.max;
1078 /* all created and connected, lets go */
1080 _mtdm = new MTDM (sample_rate());
1081 _measuring_latency = true;
1082 _latency_flush_frames = samples_per_cycle();
1087 AudioEngine::stop_latency_detection ()
1089 _measuring_latency = false;
1091 if (_latency_output_port) {
1092 port_engine().unregister_port (_latency_output_port);
1093 _latency_output_port = 0;
1095 if (_latency_input_port) {
1096 port_engine().unregister_port (_latency_input_port);
1097 _latency_input_port = 0;
1099 if (_started_for_latency) {
1105 AudioEngine::set_latency_output_port (const string& name)
1107 _latency_output_name = name;
1111 AudioEngine::set_latency_input_port (const string& name)
1113 _latency_input_name = name;