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;
511 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
512 Glib::Module::get_last_error()) << endmsg;
516 if (!module.get_symbol ("descriptor", sym)) {
517 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor."), path) << endmsg;
518 error << Glib::Module::get_last_error() << endmsg;
522 module.make_resident ();
524 info = (AudioBackendInfo*) sym;
529 vector<const AudioBackendInfo*>
530 AudioEngine::available_backends() const
532 vector<const AudioBackendInfo*> r;
534 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
535 r.push_back (i->second);
542 AudioEngine::current_backend_name() const
545 return _backend->name();
551 AudioEngine::drop_backend ()
559 boost::shared_ptr<AudioBackend>
560 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
562 BackendMap::iterator b = _backends.find (name);
564 if (b == _backends.end()) {
565 return boost::shared_ptr<AudioBackend>();
571 if (b->second->instantiate (arg1, arg2)) {
572 throw failed_constructor ();
575 _backend = b->second->factory (*this);
577 } catch (exception& e) {
578 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
579 return boost::shared_ptr<AudioBackend>();
585 /* BACKEND PROXY WRAPPERS */
588 AudioEngine::start ()
598 _processed_frames = 0;
599 last_monitor_check = 0;
601 if (_backend->start()) {
608 _session->set_frame_rate (_backend->sample_rate());
610 if (_session->config.get_jack_time_master()) {
611 _backend->set_time_master (true);
615 start_metering_thread ();
617 if (!_started_for_latency) {
618 Running(); /* EMIT SIGNAL */
631 Glib::Threads::Mutex::Lock lm (_process_lock);
633 if (_backend->stop ()) {
638 _processed_frames = 0;
639 _measuring_latency = false;
640 _latency_output_port = 0;
641 _latency_input_port = 0;
642 _started_for_latency = false;
643 stop_metering_thread ();
646 Stopped (); /* EMIT SIGNAL */
652 AudioEngine::pause ()
658 if (_backend->pause ()) {
664 Stopped(); /* EMIT SIGNAL */
669 AudioEngine::freewheel (bool start_stop)
675 /* _freewheeling will be set when first Freewheel signal occurs */
677 return _backend->freewheel (start_stop);
681 AudioEngine::get_cpu_load() const
686 return _backend->cpu_load ();
690 AudioEngine::is_realtime() const
696 return _backend->is_realtime();
700 AudioEngine::connected() const
706 return _backend->available();
710 AudioEngine::transport_start ()
715 return _backend->transport_start ();
719 AudioEngine::transport_stop ()
724 return _backend->transport_stop ();
728 AudioEngine::transport_state ()
731 return TransportStopped;
733 return _backend->transport_state ();
737 AudioEngine::transport_locate (framepos_t pos)
742 return _backend->transport_locate (pos);
746 AudioEngine::transport_frame()
751 return _backend->transport_frame ();
755 AudioEngine::sample_rate () const
760 return _backend->sample_rate ();
764 AudioEngine::samples_per_cycle () const
769 return _backend->buffer_size ();
773 AudioEngine::usecs_per_cycle () const
778 return _backend->usecs_per_cycle ();
782 AudioEngine::raw_buffer_size (DataType t)
787 return _backend->raw_buffer_size (t);
791 AudioEngine::sample_time ()
796 return _backend->sample_time ();
800 AudioEngine::sample_time_at_cycle_start ()
805 return _backend->sample_time_at_cycle_start ();
809 AudioEngine::samples_since_cycle_start ()
814 return _backend->samples_since_cycle_start ();
818 AudioEngine::get_sync_offset (pframes_t& offset) const
823 return _backend->get_sync_offset (offset);
827 AudioEngine::create_process_thread (boost::function<void()> func, AudioBackendNativeThread* thr, size_t stacksize)
832 return _backend->create_process_thread (func, thr, stacksize);
836 AudioEngine::wait_for_process_thread_exit (AudioBackendNativeThread thr)
841 return _backend->wait_for_process_thread_exit (thr);
845 AudioEngine::set_device_name (const std::string& name)
850 return _backend->set_device_name (name);
854 AudioEngine::set_sample_rate (float sr)
859 return _backend->set_sample_rate (sr);
863 AudioEngine::set_buffer_size (uint32_t bufsiz)
868 return _backend->set_buffer_size (bufsiz);
872 AudioEngine::set_sample_format (SampleFormat sf)
877 return _backend->set_sample_format (sf);
881 AudioEngine::set_interleaved (bool yn)
886 return _backend->set_interleaved (yn);
890 AudioEngine::set_input_channels (uint32_t ic)
895 return _backend->set_input_channels (ic);
899 AudioEngine::set_output_channels (uint32_t oc)
904 return _backend->set_output_channels (oc);
908 AudioEngine::set_systemic_input_latency (uint32_t il)
913 return _backend->set_systemic_input_latency (il);
917 AudioEngine::set_systemic_output_latency (uint32_t ol)
922 return _backend->set_systemic_output_latency (ol);
925 /* END OF BACKEND PROXY API */
928 AudioEngine::thread_init_callback (void* arg)
930 /* make sure that anybody who needs to know about this thread
934 pthread_set_name (X_("audioengine"));
936 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
937 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
939 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
941 AsyncMIDIPort::set_process_thread (pthread_self());
944 /* the special thread created/managed by the backend */
945 AudioEngine::instance()->_main_thread = new ProcessThread;
950 AudioEngine::sync_callback (TransportState state, framepos_t position)
953 return _session->backend_sync_callback (state, position);
959 AudioEngine::freewheel_callback (bool onoff)
961 _freewheeling = onoff;
965 AudioEngine::latency_callback (bool for_playback)
968 _session->update_latency (for_playback);
973 AudioEngine::update_latencies ()
976 _backend->update_latencies ();
981 AudioEngine::halted_callback (const char* why)
983 stop_metering_thread ();
986 Port::PortDrop (); /* EMIT SIGNAL */
987 Halted (why); /* EMIT SIGNAL */
991 AudioEngine::setup_required () const
993 /* If there is only a single backend and it claims to be configured
994 * already there is no setup to be done.
996 * Primarily for a case where there is only a JACK backend and
997 * JACK is already running.
1000 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1014 AudioEngine::prepare_for_latency_measurement ()
1017 _started_for_latency = true;
1020 _started_for_latency = false;
1029 AudioEngine::start_latency_detection ()
1031 if (prepare_for_latency_measurement ()) {
1035 PortEngine& pe (port_engine());
1040 /* create the ports we will use to read/write data */
1042 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1045 if (pe.connect (_latency_output_port, _latency_output_name)) {
1049 const string portname ("latency_in");
1050 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1051 pe.unregister_port (_latency_output_port);
1054 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1055 pe.unregister_port (_latency_output_port);
1060 _latency_signal_latency = 0;
1061 lr = pe.get_latency_range (_latency_input_port, false);
1062 _latency_signal_latency = lr.max;
1063 lr = pe.get_latency_range (_latency_output_port, true);
1064 _latency_signal_latency += lr.max;
1066 /* all created and connected, lets go */
1068 _mtdm = new MTDM (sample_rate());
1069 _measuring_latency = true;
1070 _latency_flush_frames = samples_per_cycle();
1075 AudioEngine::stop_latency_detection ()
1077 _measuring_latency = false;
1079 port_engine().unregister_port (_latency_output_port);
1080 port_engine().unregister_port (_latency_input_port);
1082 if (_started_for_latency) {
1088 AudioEngine::set_latency_output_port (const string& name)
1090 _latency_output_name = name;
1094 AudioEngine::set_latency_input_port (const string& name)
1096 _latency_input_name = name;