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/backend_search_path.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/mtdm.h"
52 #include "ardour/port.h"
53 #include "ardour/process_thread.h"
54 #include "ardour/session.h"
59 using namespace ARDOUR;
62 gint AudioEngine::m_meter_exit;
63 AudioEngine* AudioEngine::_instance = 0;
65 AudioEngine::AudioEngine ()
66 : session_remove_pending (false)
67 , session_removal_countdown (-1)
69 , _freewheeling (false)
70 , monitor_check_interval (INT32_MAX)
71 , last_monitor_check (0)
72 , _processed_frames (0)
76 , _measuring_latency (false)
77 , _latency_input_port (0)
78 , _latency_output_port (0)
79 , _latency_flush_frames (0)
80 , _latency_signal_latency (0)
81 , _started_for_latency (false)
83 g_atomic_int_set (&m_meter_exit, 0);
87 AudioEngine::~AudioEngine ()
91 config_connection.disconnect ();
94 Glib::Threads::Mutex::Lock tm (_process_lock);
95 session_removed.signal ();
96 stop_metering_thread ();
101 AudioEngine::create ()
107 _instance = new AudioEngine ();
113 _thread_init_callback (void * /*arg*/)
115 /* make sure that anybody who needs to know about this thread
119 pthread_set_name (X_("audioengine"));
121 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
122 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
124 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
126 AsyncMIDIPort::set_process_thread (pthread_self());
130 AudioEngine::split_cycle (pframes_t offset)
132 /* caller must hold process lock */
134 Port::increment_global_port_buffer_offset (offset);
136 /* tell all Ports that we're going to start a new (split) cycle */
138 boost::shared_ptr<Ports> p = ports.reader();
140 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
141 i->second->cycle_split ();
146 AudioEngine::sample_rate_change (pframes_t nframes)
148 /* check for monitor input change every 1/10th of second */
150 monitor_check_interval = nframes / 10;
151 last_monitor_check = 0;
154 _session->set_frame_rate (nframes);
157 SampleRateChanged (nframes); /* EMIT SIGNAL */
163 AudioEngine::buffer_size_change (pframes_t bufsiz)
166 _session->set_block_size (bufsiz);
167 last_monitor_check = 0;
173 /** Method called by our ::process_thread when there is work to be done.
174 * @param nframes Number of frames to process.
177 AudioEngine::process_callback (pframes_t nframes)
179 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
184 /// The number of frames that will have been processed when we've finished
185 pframes_t next_processed_frames;
187 /* handle wrap around of total frames counter */
189 if (max_framepos - _processed_frames < nframes) {
190 next_processed_frames = nframes - (max_framepos - _processed_frames);
192 next_processed_frames = _processed_frames + nframes;
196 /* return having done nothing */
197 _processed_frames = next_processed_frames;
201 bool return_after_remove_check = false;
203 if (_measuring_latency && _mtdm) {
204 /* run a normal cycle from the perspective of the PortManager
205 so that we get silence on all registered ports.
207 we overwrite the silence on the two ports used for latency
211 PortManager::cycle_start (nframes);
212 PortManager::silence (nframes);
214 if (_latency_input_port && _latency_output_port) {
215 PortEngine& pe (port_engine());
217 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
218 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
220 _mtdm->process (nframes, in, out);
223 PortManager::cycle_end (nframes);
224 return_after_remove_check = true;
226 } else if (_latency_flush_frames) {
228 /* wait for the appropriate duration for the MTDM signal to
229 * drain from the ports before we revert to normal behaviour.
232 PortManager::cycle_start (nframes);
233 PortManager::silence (nframes);
234 PortManager::cycle_end (nframes);
236 if (_latency_flush_frames > nframes) {
237 _latency_flush_frames -= nframes;
239 _latency_flush_frames = 0;
242 return_after_remove_check = true;
245 if (session_remove_pending) {
247 /* perform the actual session removal */
249 if (session_removal_countdown < 0) {
251 /* fade out over 1 second */
252 session_removal_countdown = sample_rate()/2;
253 session_removal_gain = 1.0;
254 session_removal_gain_step = 1.0/session_removal_countdown;
256 } else if (session_removal_countdown > 0) {
258 /* we'll be fading audio out.
260 if this is the last time we do this as part
261 of session removal, do a MIDI panic now
262 to get MIDI stopped. This relies on the fact
263 that "immediate data" (aka "out of band data") from
264 MIDI tracks is *appended* after any other data,
265 so that it emerges after any outbound note ons, etc.
268 if (session_removal_countdown <= nframes) {
269 _session->midi_panic ();
275 session_removal_countdown = -1; // reset to "not in progress"
276 session_remove_pending = false;
277 session_removed.signal(); // wakes up thread that initiated session removal
281 if (return_after_remove_check) {
287 if (!_freewheeling) {
288 PortManager::cycle_start (nframes);
289 PortManager::cycle_end (nframes);
292 _processed_frames = next_processed_frames;
297 /* tell all relevant objects that we're starting a new cycle */
299 InternalSend::CycleStart (nframes);
301 /* tell all Ports that we're starting a new cycle */
303 PortManager::cycle_start (nframes);
305 /* test if we are freewheeling and there are freewheel signals connected.
306 ardour should act normally even when freewheeling unless /it/ is
307 exporting (which is what Freewheel.empty() tests for).
310 if (_freewheeling && !Freewheel.empty()) {
314 _session->process (nframes);
323 _processed_frames = next_processed_frames;
327 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
329 PortManager::check_monitoring ();
330 last_monitor_check = next_processed_frames;
333 if (_session->silent()) {
334 PortManager::silence (nframes);
337 if (session_remove_pending && session_removal_countdown) {
339 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
341 if (session_removal_countdown > nframes) {
342 session_removal_countdown -= nframes;
344 session_removal_countdown = 0;
347 session_removal_gain -= (nframes * session_removal_gain_step);
350 PortManager::cycle_end (nframes);
352 _processed_frames = next_processed_frames;
361 AudioEngine::stop_metering_thread ()
363 if (m_meter_thread) {
364 g_atomic_int_set (&m_meter_exit, 1);
365 m_meter_thread->join ();
371 AudioEngine::start_metering_thread ()
373 if (m_meter_thread == 0) {
374 g_atomic_int_set (&m_meter_exit, 0);
375 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
380 AudioEngine::meter_thread ()
382 pthread_set_name (X_("meter"));
385 Glib::usleep (10000); /* 1/100th sec interval */
386 if (g_atomic_int_get(&m_meter_exit)) {
394 AudioEngine::set_session (Session *s)
396 Glib::Threads::Mutex::Lock pl (_process_lock);
398 SessionHandlePtr::set_session (s);
402 pframes_t blocksize = samples_per_cycle ();
404 PortManager::cycle_start (blocksize);
406 _session->process (blocksize);
407 _session->process (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);
415 PortManager::cycle_end (blocksize);
420 AudioEngine::remove_session ()
422 Glib::Threads::Mutex::Lock lm (_process_lock);
427 session_remove_pending = true;
428 session_removal_countdown = 0;
429 session_removed.wait(_process_lock);
433 SessionHandlePtr::set_session (0);
443 /* called from a signal handler for SIGPIPE */
445 stop_metering_thread ();
451 AudioEngine::reset_timebase ()
454 if (_session->config.get_jack_time_master()) {
455 _backend->set_time_master (true);
457 _backend->set_time_master (false);
465 AudioEngine::destroy ()
472 AudioEngine::discover_backends ()
474 vector<std::string> backend_modules;
478 Glib::PatternSpec so_extension_pattern("*backend.so");
479 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
481 find_matching_files_in_search_path (backend_search_path (),
482 so_extension_pattern, backend_modules);
484 find_matching_files_in_search_path (backend_search_path (),
485 dylib_extension_pattern, backend_modules);
487 DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
489 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
491 AudioBackendInfo* info;
493 if ((info = backend_discover (*i)) != 0) {
494 _backends.insert (make_pair (info->name, info));
498 return _backends.size();
502 AudioEngine::backend_discover (const string& path)
504 Glib::Module module (path);
505 AudioBackendInfo* info;
506 AudioBackendInfo* (*dfunc)(void);
510 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
511 Glib::Module::get_last_error()) << endmsg;
515 if (!module.get_symbol ("descriptor", func)) {
516 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
517 error << Glib::Module::get_last_error() << endmsg;
521 module.make_resident ();
523 dfunc = (AudioBackendInfo* (*)(void))func;
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 /* find the ports we will connect to */
1042 PortEngine::PortHandle* out = pe.get_port_by_name (_latency_output_name);
1043 PortEngine::PortHandle* in = pe.get_port_by_name (_latency_input_name);
1049 /* create the ports we will use to read/write data */
1051 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1054 if (pe.connect (_latency_output_port, _latency_output_name)) {
1055 pe.unregister_port (_latency_output_port);
1059 const string portname ("latency_in");
1060 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1061 pe.unregister_port (_latency_output_port);
1064 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1065 pe.unregister_port (_latency_output_port);
1070 _latency_signal_latency = 0;
1071 lr = pe.get_latency_range (in, false);
1072 _latency_signal_latency = lr.max;
1073 lr = pe.get_latency_range (out, true);
1074 _latency_signal_latency += lr.max;
1076 /* all created and connected, lets go */
1078 _mtdm = new MTDM (sample_rate());
1079 _measuring_latency = true;
1080 _latency_flush_frames = samples_per_cycle();
1085 AudioEngine::stop_latency_detection ()
1087 _measuring_latency = false;
1089 if (_latency_output_port) {
1090 port_engine().unregister_port (_latency_output_port);
1091 _latency_output_port = 0;
1093 if (_latency_input_port) {
1094 port_engine().unregister_port (_latency_input_port);
1095 _latency_input_port = 0;
1097 if (_started_for_latency) {
1103 AudioEngine::set_latency_output_port (const string& name)
1105 _latency_output_name = name;
1109 AudioEngine::set_latency_input_port (const string& name)
1111 _latency_input_name = name;