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/port.h"
54 #include "ardour/process_thread.h"
55 #include "ardour/session.h"
60 using namespace ARDOUR;
63 gint AudioEngine::m_meter_exit;
64 AudioEngine* AudioEngine::_instance = 0;
66 AudioEngine::AudioEngine ()
67 : session_remove_pending (false)
68 , session_removal_countdown (-1)
70 , _freewheeling (false)
71 , monitor_check_interval (INT32_MAX)
72 , last_monitor_check (0)
73 , _processed_frames (0)
74 , _pre_freewheel_mmc_enabled (false)
78 g_atomic_int_set (&m_meter_exit, 0);
82 AudioEngine::~AudioEngine ()
86 config_connection.disconnect ();
89 Glib::Threads::Mutex::Lock tm (_process_lock);
90 session_removed.signal ();
91 stop_metering_thread ();
96 AudioEngine::create ()
102 _instance = new AudioEngine ();
108 _thread_init_callback (void * /*arg*/)
110 /* make sure that anybody who needs to know about this thread
114 pthread_set_name (X_("audioengine"));
116 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
117 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
119 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
121 AsyncMIDIPort::set_process_thread (pthread_self());
125 AudioEngine::split_cycle (pframes_t offset)
127 /* caller must hold process lock */
129 Port::increment_global_port_buffer_offset (offset);
131 /* tell all Ports that we're going to start a new (split) cycle */
133 boost::shared_ptr<Ports> p = ports.reader();
135 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
136 i->second->cycle_split ();
141 AudioEngine::sample_rate_change (pframes_t nframes)
143 /* check for monitor input change every 1/10th of second */
145 monitor_check_interval = nframes / 10;
146 last_monitor_check = 0;
149 _session->set_frame_rate (nframes);
152 SampleRateChanged (nframes); /* EMIT SIGNAL */
158 AudioEngine::buffer_size_change (pframes_t bufsiz)
161 _session->set_block_size (bufsiz);
162 last_monitor_check = 0;
168 /** Method called by our ::process_thread when there is work to be done.
169 * @param nframes Number of frames to process.
172 AudioEngine::process_callback (pframes_t nframes)
174 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
179 /// The number of frames that will have been processed when we've finished
180 pframes_t next_processed_frames;
182 /* handle wrap around of total frames counter */
184 if (max_framepos - _processed_frames < nframes) {
185 next_processed_frames = nframes - (max_framepos - _processed_frames);
187 next_processed_frames = _processed_frames + nframes;
191 /* return having done nothing */
192 _processed_frames = next_processed_frames;
196 if (session_remove_pending) {
198 /* perform the actual session removal */
200 if (session_removal_countdown < 0) {
202 /* fade out over 1 second */
203 session_removal_countdown = sample_rate()/2;
204 session_removal_gain = 1.0;
205 session_removal_gain_step = 1.0/session_removal_countdown;
207 } else if (session_removal_countdown > 0) {
209 /* we'll be fading audio out.
211 if this is the last time we do this as part
212 of session removal, do a MIDI panic now
213 to get MIDI stopped. This relies on the fact
214 that "immediate data" (aka "out of band data") from
215 MIDI tracks is *appended* after any other data,
216 so that it emerges after any outbound note ons, etc.
219 if (session_removal_countdown <= nframes) {
220 _session->midi_panic ();
226 session_removal_countdown = -1; // reset to "not in progress"
227 session_remove_pending = false;
228 session_removed.signal(); // wakes up thread that initiated session removal
234 if (!_freewheeling) {
235 PortManager::cycle_start (nframes);
236 PortManager::cycle_end (nframes);
239 _processed_frames = next_processed_frames;
244 /* tell all relevant objects that we're starting a new cycle */
246 InternalSend::CycleStart (nframes);
248 /* tell all Ports that we're starting a new cycle */
250 PortManager::cycle_start (nframes);
252 /* test if we are freewheeling and there are freewheel signals connected.
253 ardour should act normally even when freewheeling unless /it/ is
254 exporting (which is what Freewheel.empty() tests for).
257 if (_freewheeling && !Freewheel.empty()) {
261 _session->process (nframes);
270 _processed_frames = next_processed_frames;
274 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
276 PortManager::check_monitoring ();
277 last_monitor_check = next_processed_frames;
280 if (_session->silent()) {
281 PortManager::silence (nframes);
284 if (session_remove_pending && session_removal_countdown) {
286 PortManager::fade_out (session_removal_gain, session_removal_gain_step, nframes);
288 if (session_removal_countdown > nframes) {
289 session_removal_countdown -= nframes;
291 session_removal_countdown = 0;
294 session_removal_gain -= (nframes * session_removal_gain_step);
297 PortManager::cycle_end (nframes);
299 _processed_frames = next_processed_frames;
308 AudioEngine::stop_metering_thread ()
310 if (m_meter_thread) {
311 g_atomic_int_set (&m_meter_exit, 1);
312 m_meter_thread->join ();
318 AudioEngine::start_metering_thread ()
320 if (m_meter_thread == 0) {
321 g_atomic_int_set (&m_meter_exit, 0);
322 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
327 AudioEngine::meter_thread ()
329 pthread_set_name (X_("meter"));
332 Glib::usleep (10000); /* 1/100th sec interval */
333 if (g_atomic_int_get(&m_meter_exit)) {
341 AudioEngine::set_session (Session *s)
343 Glib::Threads::Mutex::Lock pl (_process_lock);
345 SessionHandlePtr::set_session (s);
349 pframes_t blocksize = samples_per_cycle ();
351 PortManager::cycle_start (blocksize);
353 _session->process (blocksize);
354 _session->process (blocksize);
355 _session->process (blocksize);
356 _session->process (blocksize);
357 _session->process (blocksize);
358 _session->process (blocksize);
359 _session->process (blocksize);
360 _session->process (blocksize);
362 PortManager::cycle_end (blocksize);
367 AudioEngine::remove_session ()
369 Glib::Threads::Mutex::Lock lm (_process_lock);
373 stop_metering_thread ();
376 session_remove_pending = true;
377 session_removal_countdown = 0;
378 session_removed.wait(_process_lock);
382 SessionHandlePtr::set_session (0);
392 /* called from a signal handler for SIGPIPE */
394 stop_metering_thread ();
400 AudioEngine::reset_timebase ()
403 if (_session->config.get_jack_time_master()) {
404 _backend->set_time_master (true);
406 _backend->set_time_master (false);
414 AudioEngine::destroy ()
421 AudioEngine::discover_backends ()
423 vector<std::string> backend_modules;
427 Glib::PatternSpec so_extension_pattern("*backend.so");
428 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
430 find_matching_files_in_search_path (backend_search_path (),
431 so_extension_pattern, backend_modules);
433 find_matching_files_in_search_path (backend_search_path (),
434 dylib_extension_pattern, backend_modules);
436 DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
438 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
440 AudioBackendInfo* info;
442 if ((info = backend_discover (*i)) != 0) {
443 _backends.insert (make_pair (info->name, info));
447 return _backends.size();
451 AudioEngine::backend_discover (const string& path)
453 Glib::Module module (path);
454 AudioBackendInfo* info;
458 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
459 Glib::Module::get_last_error()) << endmsg;
463 if (!module.get_symbol ("descriptor", sym)) {
464 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor."), path) << endmsg;
465 error << Glib::Module::get_last_error() << endmsg;
469 module.make_resident ();
471 info = (AudioBackendInfo*) sym;
476 vector<const AudioBackendInfo*>
477 AudioEngine::available_backends() const
479 vector<const AudioBackendInfo*> r;
481 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
482 r.push_back (i->second);
489 AudioEngine::current_backend_name() const
492 return _backend->name();
498 AudioEngine::drop_backend ()
506 boost::shared_ptr<AudioBackend>
507 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
509 BackendMap::iterator b = _backends.find (name);
511 if (b == _backends.end()) {
512 return boost::shared_ptr<AudioBackend>();
518 if (b->second->instantiate (arg1, arg2)) {
519 throw failed_constructor ();
522 _backend = b->second->backend_factory (*this);
523 _impl = b->second->portengine_factory (*this);
525 } catch (exception& e) {
526 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
527 return boost::shared_ptr<AudioBackend>();
533 /* BACKEND PROXY WRAPPERS */
536 AudioEngine::start ()
546 /* if we're still connected (i.e. previously paused), no need to
550 bool have_ports = (!ports.reader()->empty());
552 _processed_frames = 0;
553 last_monitor_check = 0;
555 if (_backend->start()) {
562 _session->set_frame_rate (_backend->sample_rate());
564 if (_session->config.get_jack_time_master()) {
565 _backend->set_time_master (true);
570 PortManager::create_ports ();
571 _mmc.set_ports (mmc_input_port(), mmc_output_port());
574 start_metering_thread ();
576 Running(); /* EMIT SIGNAL */
588 Glib::Threads::Mutex::Lock lm (_process_lock);
590 if (_backend->stop ()) {
595 _processed_frames = 0;
596 stop_metering_thread ();
599 Stopped (); /* EMIT SIGNAL */
605 AudioEngine::pause ()
611 if (_backend->pause ()) {
617 Stopped(); /* EMIT SIGNAL */
622 AudioEngine::freewheel (bool start_stop)
628 /* _freewheeling will be set when first Freewheel signal occurs */
630 return _backend->freewheel (start_stop);
634 AudioEngine::get_cpu_load() const
639 return _backend->cpu_load ();
643 AudioEngine::is_realtime() const
649 return _backend->is_realtime();
653 AudioEngine::connected() const
659 return _backend->connected();
663 AudioEngine::transport_start ()
668 return _backend->transport_start ();
672 AudioEngine::transport_stop ()
677 return _backend->transport_stop ();
681 AudioEngine::transport_state ()
684 return TransportStopped;
686 return _backend->transport_state ();
690 AudioEngine::transport_locate (framepos_t pos)
695 return _backend->transport_locate (pos);
699 AudioEngine::transport_frame()
704 return _backend->transport_frame ();
708 AudioEngine::sample_rate () const
713 return _backend->sample_rate ();
717 AudioEngine::samples_per_cycle () const
722 return _backend->buffer_size ();
726 AudioEngine::usecs_per_cycle () const
731 return _backend->usecs_per_cycle ();
735 AudioEngine::raw_buffer_size (DataType t)
740 return _backend->raw_buffer_size (t);
744 AudioEngine::sample_time ()
749 return _backend->sample_time ();
753 AudioEngine::sample_time_at_cycle_start ()
758 return _backend->sample_time_at_cycle_start ();
762 AudioEngine::samples_since_cycle_start ()
767 return _backend->samples_since_cycle_start ();
771 AudioEngine::get_sync_offset (pframes_t& offset) const
776 return _backend->get_sync_offset (offset);
780 AudioEngine::create_process_thread (boost::function<void()> func, pthread_t* thr, size_t stacksize)
785 return _backend->create_process_thread (func, thr, stacksize);
790 AudioEngine::set_device_name (const std::string& name)
795 return _backend->set_device_name (name);
799 AudioEngine::set_sample_rate (float sr)
804 return _backend->set_sample_rate (sr);
808 AudioEngine::set_buffer_size (uint32_t bufsiz)
813 return _backend->set_buffer_size (bufsiz);
817 AudioEngine::set_sample_format (SampleFormat sf)
822 return _backend->set_sample_format (sf);
826 AudioEngine::set_interleaved (bool yn)
831 return _backend->set_interleaved (yn);
835 AudioEngine::set_input_channels (uint32_t ic)
840 return _backend->set_input_channels (ic);
844 AudioEngine::set_output_channels (uint32_t oc)
849 return _backend->set_output_channels (oc);
853 AudioEngine::set_systemic_input_latency (uint32_t il)
858 return _backend->set_systemic_input_latency (il);
862 AudioEngine::set_systemic_output_latency (uint32_t ol)
867 return _backend->set_systemic_output_latency (ol);
870 /* END OF BACKEND PROXY API */
873 AudioEngine::thread_init_callback (void* arg)
875 /* make sure that anybody who needs to know about this thread
879 pthread_set_name (X_("audioengine"));
881 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
882 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
884 SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
886 AsyncMIDIPort::set_process_thread (pthread_self());
889 /* the special thread created/managed by the backend */
890 AudioEngine::instance()->_main_thread = new ProcessThread;
895 AudioEngine::sync_callback (TransportState state, framepos_t position)
898 return _session->backend_sync_callback (state, position);
904 AudioEngine::freewheel_callback (bool onoff)
907 _pre_freewheel_mmc_enabled = _mmc.send_enabled ();
908 _mmc.enable_send (false);
910 _mmc.enable_send (_pre_freewheel_mmc_enabled);
913 _freewheeling = onoff;
917 AudioEngine::latency_callback (bool for_playback)
920 _session->update_latency (for_playback);
925 AudioEngine::update_latencies ()
928 _backend->update_latencies ();
933 AudioEngine::halted_callback (const char* why)
935 stop_metering_thread ();
938 Port::PortDrop (); /* EMIT SIGNAL */
939 Halted (why); /* EMIT SIGNAL */
943 AudioEngine::setup_required () const
945 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {