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)
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 /* If measuring latency, do it now and get out of here */
203 if (_measuring_latency && _mtdm) {
204 // PortManager::cycle_start (nframes);
205 // PortManager::silence (nframes);
207 if (_latency_input_port && _latency_output_port) {
208 PortEngine& pe (port_engine());
210 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
211 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
213 _mtdm->process (nframes, in, out);
216 // PortManager::cycle_end (nframes);
219 } else if (_latency_flush_frames) {
221 /* wait for the appropriate duration for the MTDM signal to
222 * drain from the ports before we revert to normal behaviour.
225 PortManager::cycle_start (nframes);
226 PortManager::silence (nframes);
227 PortManager::cycle_end (nframes);
229 if (_latency_flush_frames > nframes) {
230 _latency_flush_frames -= nframes;
232 _latency_flush_frames = 0;
238 if (session_remove_pending) {
240 /* perform the actual session removal */
242 if (session_removal_countdown < 0) {
244 /* fade out over 1 second */
245 session_removal_countdown = sample_rate()/2;
246 session_removal_gain = 1.0;
247 session_removal_gain_step = 1.0/session_removal_countdown;
249 } else if (session_removal_countdown > 0) {
251 /* we'll be fading audio out.
253 if this is the last time we do this as part
254 of session removal, do a MIDI panic now
255 to get MIDI stopped. This relies on the fact
256 that "immediate data" (aka "out of band data") from
257 MIDI tracks is *appended* after any other data,
258 so that it emerges after any outbound note ons, etc.
261 if (session_removal_countdown <= nframes) {
262 _session->midi_panic ();
268 session_removal_countdown = -1; // reset to "not in progress"
269 session_remove_pending = false;
270 session_removed.signal(); // wakes up thread that initiated session removal
276 if (!_freewheeling) {
277 PortManager::cycle_start (nframes);
278 PortManager::cycle_end (nframes);
281 _processed_frames = next_processed_frames;
286 /* tell all relevant objects that we're starting a new cycle */
288 InternalSend::CycleStart (nframes);
290 /* tell all Ports that we're starting a new cycle */
292 PortManager::cycle_start (nframes);
294 /* test if we are freewheeling and there are freewheel signals connected.
295 ardour should act normally even when freewheeling unless /it/ is
296 exporting (which is what Freewheel.empty() tests for).
299 if (_freewheeling && !Freewheel.empty()) {
303 _session->process (nframes);
312 _processed_frames = next_processed_frames;
316 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
318 PortManager::check_monitoring ();
319 last_monitor_check = next_processed_frames;
322 if (_session->silent()) {
323 PortManager::silence (nframes);
326 if (session_remove_pending && session_removal_countdown) {
328 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
330 if (session_removal_countdown > nframes) {
331 session_removal_countdown -= nframes;
333 session_removal_countdown = 0;
336 session_removal_gain -= (nframes * session_removal_gain_step);
339 PortManager::cycle_end (nframes);
341 _processed_frames = next_processed_frames;
350 AudioEngine::stop_metering_thread ()
352 if (m_meter_thread) {
353 g_atomic_int_set (&m_meter_exit, 1);
354 m_meter_thread->join ();
360 AudioEngine::start_metering_thread ()
362 if (m_meter_thread == 0) {
363 g_atomic_int_set (&m_meter_exit, 0);
364 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
369 AudioEngine::meter_thread ()
371 pthread_set_name (X_("meter"));
374 Glib::usleep (10000); /* 1/100th sec interval */
375 if (g_atomic_int_get(&m_meter_exit)) {
383 AudioEngine::set_session (Session *s)
385 Glib::Threads::Mutex::Lock pl (_process_lock);
387 SessionHandlePtr::set_session (s);
391 pframes_t blocksize = samples_per_cycle ();
393 PortManager::cycle_start (blocksize);
395 _session->process (blocksize);
396 _session->process (blocksize);
397 _session->process (blocksize);
398 _session->process (blocksize);
399 _session->process (blocksize);
400 _session->process (blocksize);
401 _session->process (blocksize);
402 _session->process (blocksize);
404 PortManager::cycle_end (blocksize);
409 AudioEngine::remove_session ()
411 Glib::Threads::Mutex::Lock lm (_process_lock);
415 stop_metering_thread ();
418 session_remove_pending = true;
419 session_removal_countdown = 0;
420 session_removed.wait(_process_lock);
424 SessionHandlePtr::set_session (0);
434 /* called from a signal handler for SIGPIPE */
436 stop_metering_thread ();
442 AudioEngine::reset_timebase ()
445 if (_session->config.get_jack_time_master()) {
446 _backend->set_time_master (true);
448 _backend->set_time_master (false);
456 AudioEngine::destroy ()
463 AudioEngine::discover_backends ()
465 vector<std::string> backend_modules;
469 Glib::PatternSpec so_extension_pattern("*backend.so");
470 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
472 find_matching_files_in_search_path (backend_search_path (),
473 so_extension_pattern, backend_modules);
475 find_matching_files_in_search_path (backend_search_path (),
476 dylib_extension_pattern, backend_modules);
478 DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
480 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
482 AudioBackendInfo* info;
484 if ((info = backend_discover (*i)) != 0) {
485 _backends.insert (make_pair (info->name, info));
489 return _backends.size();
493 AudioEngine::backend_discover (const string& path)
495 Glib::Module module (path);
496 AudioBackendInfo* info;
500 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
501 Glib::Module::get_last_error()) << endmsg;
505 if (!module.get_symbol ("descriptor", sym)) {
506 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor."), path) << endmsg;
507 error << Glib::Module::get_last_error() << endmsg;
511 module.make_resident ();
513 info = (AudioBackendInfo*) sym;
518 vector<const AudioBackendInfo*>
519 AudioEngine::available_backends() const
521 vector<const AudioBackendInfo*> r;
523 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
524 r.push_back (i->second);
531 AudioEngine::current_backend_name() const
534 return _backend->name();
540 AudioEngine::drop_backend ()
548 boost::shared_ptr<AudioBackend>
549 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
551 BackendMap::iterator b = _backends.find (name);
553 if (b == _backends.end()) {
554 return boost::shared_ptr<AudioBackend>();
560 if (b->second->instantiate (arg1, arg2)) {
561 throw failed_constructor ();
564 _backend = b->second->backend_factory (*this);
565 _impl = b->second->portengine_factory (*this);
567 } catch (exception& e) {
568 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
569 return boost::shared_ptr<AudioBackend>();
575 /* BACKEND PROXY WRAPPERS */
578 AudioEngine::start ()
588 _processed_frames = 0;
589 last_monitor_check = 0;
591 if (_backend->start()) {
598 _session->set_frame_rate (_backend->sample_rate());
600 if (_session->config.get_jack_time_master()) {
601 _backend->set_time_master (true);
605 start_metering_thread ();
607 Running(); /* EMIT SIGNAL */
619 Glib::Threads::Mutex::Lock lm (_process_lock);
621 if (_backend->stop ()) {
626 _processed_frames = 0;
627 _measuring_latency = false;
628 _latency_output_port = 0;
629 _latency_input_port = 0;
630 stop_metering_thread ();
633 Stopped (); /* EMIT SIGNAL */
639 AudioEngine::pause ()
645 if (_backend->pause ()) {
651 Stopped(); /* EMIT SIGNAL */
656 AudioEngine::freewheel (bool start_stop)
662 /* _freewheeling will be set when first Freewheel signal occurs */
664 return _backend->freewheel (start_stop);
668 AudioEngine::get_cpu_load() const
673 return _backend->cpu_load ();
677 AudioEngine::is_realtime() const
683 return _backend->is_realtime();
687 AudioEngine::connected() const
693 return _backend->connected();
697 AudioEngine::transport_start ()
702 return _backend->transport_start ();
706 AudioEngine::transport_stop ()
711 return _backend->transport_stop ();
715 AudioEngine::transport_state ()
718 return TransportStopped;
720 return _backend->transport_state ();
724 AudioEngine::transport_locate (framepos_t pos)
729 return _backend->transport_locate (pos);
733 AudioEngine::transport_frame()
738 return _backend->transport_frame ();
742 AudioEngine::sample_rate () const
747 return _backend->sample_rate ();
751 AudioEngine::samples_per_cycle () const
756 return _backend->buffer_size ();
760 AudioEngine::usecs_per_cycle () const
765 return _backend->usecs_per_cycle ();
769 AudioEngine::raw_buffer_size (DataType t)
774 return _backend->raw_buffer_size (t);
778 AudioEngine::sample_time ()
783 return _backend->sample_time ();
787 AudioEngine::sample_time_at_cycle_start ()
792 return _backend->sample_time_at_cycle_start ();
796 AudioEngine::samples_since_cycle_start ()
801 return _backend->samples_since_cycle_start ();
805 AudioEngine::get_sync_offset (pframes_t& offset) const
810 return _backend->get_sync_offset (offset);
814 AudioEngine::create_process_thread (boost::function<void()> func, pthread_t* thr, size_t stacksize)
819 return _backend->create_process_thread (func, thr, stacksize);
824 AudioEngine::set_device_name (const std::string& name)
829 return _backend->set_device_name (name);
833 AudioEngine::set_sample_rate (float sr)
838 return _backend->set_sample_rate (sr);
842 AudioEngine::set_buffer_size (uint32_t bufsiz)
847 return _backend->set_buffer_size (bufsiz);
851 AudioEngine::set_sample_format (SampleFormat sf)
856 return _backend->set_sample_format (sf);
860 AudioEngine::set_interleaved (bool yn)
865 return _backend->set_interleaved (yn);
869 AudioEngine::set_input_channels (uint32_t ic)
874 return _backend->set_input_channels (ic);
878 AudioEngine::set_output_channels (uint32_t oc)
883 return _backend->set_output_channels (oc);
887 AudioEngine::set_systemic_input_latency (uint32_t il)
892 return _backend->set_systemic_input_latency (il);
896 AudioEngine::set_systemic_output_latency (uint32_t ol)
901 return _backend->set_systemic_output_latency (ol);
904 /* END OF BACKEND PROXY API */
907 AudioEngine::thread_init_callback (void* arg)
909 /* make sure that anybody who needs to know about this thread
913 pthread_set_name (X_("audioengine"));
915 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
916 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
918 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
920 AsyncMIDIPort::set_process_thread (pthread_self());
923 /* the special thread created/managed by the backend */
924 AudioEngine::instance()->_main_thread = new ProcessThread;
929 AudioEngine::sync_callback (TransportState state, framepos_t position)
932 return _session->backend_sync_callback (state, position);
938 AudioEngine::freewheel_callback (bool onoff)
940 _freewheeling = onoff;
944 AudioEngine::latency_callback (bool for_playback)
947 _session->update_latency (for_playback);
952 AudioEngine::update_latencies ()
955 _backend->update_latencies ();
960 AudioEngine::halted_callback (const char* why)
962 stop_metering_thread ();
965 Port::PortDrop (); /* EMIT SIGNAL */
966 Halted (why); /* EMIT SIGNAL */
970 AudioEngine::setup_required () const
972 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
986 AudioEngine::start_latency_detection ()
988 PortEngine& pe (port_engine());
993 /* create the ports we will use to read/write data */
995 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
998 if (pe.connect (_latency_output_port, _latency_output_name)) {
1002 const string portname ("latency_in");
1003 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1004 pe.unregister_port (_latency_output_port);
1007 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1008 pe.unregister_port (_latency_output_port);
1012 /* all created and connected, lets go */
1014 _mtdm = new MTDM (sample_rate());
1015 _measuring_latency = true;
1016 _latency_flush_frames = samples_per_cycle();
1022 AudioEngine::stop_latency_detection ()
1024 port_engine().unregister_port (_latency_output_port);
1025 port_engine().unregister_port (_latency_input_port);
1026 _measuring_latency = false;
1030 AudioEngine::set_latency_output_port (const string& name)
1032 _latency_output_name = name;
1036 AudioEngine::set_latency_input_port (const string& name)
1038 _latency_input_name = name;