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>
29 #include "pbd/pthread_utils.h"
30 #include "pbd/stacktrace.h"
31 #include "pbd/unknown_type.h"
34 #include <jack/weakjack.h>
36 #include "midi++/port.h"
37 #include "midi++/jack_midi_port.h"
38 #include "midi++/mmc.h"
39 #include "midi++/manager.h"
41 #include "ardour/audio_port.h"
42 #include "ardour/audioengine.h"
43 #include "ardour/buffer.h"
44 #include "ardour/cycle_timer.h"
45 #include "ardour/internal_send.h"
46 #include "ardour/meter.h"
47 #include "ardour/midi_port.h"
48 #include "ardour/port.h"
49 #include "ardour/process_thread.h"
50 #include "ardour/session.h"
55 using namespace ARDOUR;
58 gint AudioEngine::m_meter_exit;
59 AudioEngine* AudioEngine::_instance = 0;
61 #define GET_PRIVATE_JACK_POINTER(j) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return; }
62 #define GET_PRIVATE_JACK_POINTER_RET(j,r) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return r; }
64 AudioEngine::AudioEngine (string client_name, string session_uuid)
66 , session_remove_pending (false)
67 , session_removal_countdown (-1)
72 , monitor_check_interval (INT32_MAX)
73 , last_monitor_check (0)
74 , _processed_frames (0)
75 , _freewheeling (false)
76 , _pre_freewheel_mmc_enabled (false)
77 , _usecs_per_cycle (0)
78 , port_remove_in_progress (false)
83 _instance = this; /* singleton */
85 g_atomic_int_set (&m_meter_exit, 0);
87 if (connect_to_jack (client_name, session_uuid)) {
88 throw NoBackendAvailable ();
91 Port::set_engine (this);
94 AudioEngine::~AudioEngine ()
97 Glib::Mutex::Lock tm (_process_lock);
98 session_removed.signal ();
101 jack_client_close (_jack);
105 stop_metering_thread ();
110 AudioEngine::jack() const
116 _thread_init_callback (void * /*arg*/)
118 /* make sure that anybody who needs to know about this thread
122 pthread_set_name (X_("audioengine"));
124 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
125 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
127 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
129 MIDI::JackMIDIPort::set_process_thread (pthread_self());
133 ardour_jack_error (const char* msg)
135 error << "JACK: " << msg << endmsg;
139 AudioEngine::set_jack_callbacks ()
141 GET_PRIVATE_JACK_POINTER (_jack);
143 if (jack_on_info_shutdown) {
144 jack_on_info_shutdown (_priv_jack, halted_info, this);
146 jack_on_shutdown (_priv_jack, halted, this);
149 jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
150 jack_set_process_thread (_priv_jack, _process_thread, this);
151 jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
152 jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
153 jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
154 jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
155 jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
156 jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
157 jack_set_sync_callback (_priv_jack, _jack_sync_callback, this);
158 jack_set_freewheel_callback (_priv_jack, _freewheel_callback, this);
160 if (_session && _session->config.get_jack_time_master()) {
161 jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
164 #ifdef HAVE_JACK_SESSION
165 if( jack_set_session_callback)
166 jack_set_session_callback (_priv_jack, _session_callback, this);
169 if (jack_set_latency_callback) {
170 jack_set_latency_callback (_priv_jack, _latency_callback, this);
173 jack_set_error_function (ardour_jack_error);
177 AudioEngine::start ()
179 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
183 if (!jack_port_type_get_buffer_size) {
184 warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
188 BootMessage (_("Connect session to engine"));
189 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
192 /* a proxy for whether jack_activate() will definitely call the buffer size
193 * callback. with older versions of JACK, this function symbol will be null.
194 * this is reliable, but not clean.
197 if (!jack_port_type_get_buffer_size) {
198 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
201 _processed_frames = 0;
202 last_monitor_check = 0;
204 set_jack_callbacks ();
206 if (jack_activate (_priv_jack) == 0) {
209 Running(); /* EMIT SIGNAL */
211 // error << _("cannot activate JACK client") << endmsg;
215 return _running ? 0 : -1;
219 AudioEngine::stop (bool forever)
221 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
225 disconnect_from_jack ();
227 jack_deactivate (_priv_jack);
228 Stopped(); /* EMIT SIGNAL */
229 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
234 stop_metering_thread ();
237 return _running ? -1 : 0;
242 AudioEngine::get_sync_offset (pframes_t& offset) const
245 #ifdef HAVE_JACK_VIDEO_SUPPORT
247 GET_PRIVATE_JACK_POINTER_RET (_jack, false);
252 (void) jack_transport_query (_priv_jack, &pos);
254 if (pos.valid & JackVideoFrameOffset) {
255 offset = pos.video_offset;
268 AudioEngine::_jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
269 jack_position_t* pos, int new_position, void *arg)
271 static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
275 AudioEngine::jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
276 jack_position_t* pos, int new_position)
278 if (_jack && _session && _session->synced_to_jack()) {
279 _session->jack_timebase_callback (state, nframes, pos, new_position);
284 AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
286 return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
290 AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
292 if (_jack && _session) {
293 return _session->jack_sync_callback (state, pos);
300 AudioEngine::_xrun_callback (void *arg)
302 AudioEngine* ae = static_cast<AudioEngine*> (arg);
303 if (ae->connected()) {
304 ae->Xrun (); /* EMIT SIGNAL */
309 #ifdef HAVE_JACK_SESSION
311 AudioEngine::_session_callback (jack_session_event_t *event, void *arg)
313 AudioEngine* ae = static_cast<AudioEngine*> (arg);
314 if (ae->connected()) {
315 ae->JackSessionEvent ( event ); /* EMIT SIGNAL */
321 AudioEngine::_graph_order_callback (void *arg)
323 AudioEngine* ae = static_cast<AudioEngine*> (arg);
325 if (ae->connected() && !ae->port_remove_in_progress) {
326 ae->GraphReordered (); /* EMIT SIGNAL */
333 AudioEngine::_process_thread (void *arg)
335 return static_cast<AudioEngine *> (arg)->process_thread ();
339 AudioEngine::_freewheel_callback (int onoff, void *arg)
341 static_cast<AudioEngine*>(arg)->freewheel_callback (onoff);
345 AudioEngine::freewheel_callback (int onoff)
347 _freewheeling = onoff;
350 _pre_freewheel_mmc_enabled = MIDI::Manager::instance()->mmc()->send_enabled ();
351 MIDI::Manager::instance()->mmc()->enable_send (false);
353 MIDI::Manager::instance()->mmc()->enable_send (_pre_freewheel_mmc_enabled);
358 AudioEngine::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
360 AudioEngine* ae = static_cast<AudioEngine*> (arg);
362 if (!ae->port_remove_in_progress) {
363 ae->PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
368 AudioEngine::_latency_callback (jack_latency_callback_mode_t mode, void* arg)
370 return static_cast<AudioEngine *> (arg)->jack_latency_callback (mode);
374 AudioEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
376 AudioEngine* ae = static_cast<AudioEngine*> (arg);
378 if (ae->port_remove_in_progress) {
382 GET_PRIVATE_JACK_POINTER (ae->_jack);
384 jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
385 jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
387 boost::shared_ptr<Port> port_a;
388 boost::shared_ptr<Port> port_b;
390 boost::shared_ptr<Ports> pr = ae->ports.reader ();
391 Ports::iterator i = pr->begin ();
392 while (i != pr->end() && (port_a == 0 || port_b == 0)) {
393 if (jack_port_a == i->second->jack_port()) {
395 } else if (jack_port_b == i->second->jack_port()) {
401 ae->PortConnectedOrDisconnected (
402 port_a, jack_port_name (jack_port_a),
403 port_b, jack_port_name (jack_port_b),
404 conn == 0 ? false : true
409 AudioEngine::split_cycle (pframes_t offset)
411 /* caller must hold process lock */
413 Port::increment_global_port_buffer_offset (offset);
415 /* tell all Ports that we're going to start a new (split) cycle */
417 boost::shared_ptr<Ports> p = ports.reader();
419 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
420 i->second->cycle_split ();
425 AudioEngine::process_thread ()
427 /* JACK doesn't do this for us when we use the wait API
430 _thread_init_callback (0);
432 _main_thread = new ProcessThread;
435 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
437 pframes_t nframes = jack_cycle_wait (_priv_jack);
439 if (process_callback (nframes)) {
443 jack_cycle_signal (_priv_jack, 0);
449 /** Method called by our ::process_thread when there is work to be done.
450 * @param nframes Number of frames to process.
453 AudioEngine::process_callback (pframes_t nframes)
455 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
456 Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
461 /// The number of frames that will have been processed when we've finished
462 pframes_t next_processed_frames;
464 /* handle wrap around of total frames counter */
466 if (max_framepos - _processed_frames < nframes) {
467 next_processed_frames = nframes - (max_framepos - _processed_frames);
469 next_processed_frames = _processed_frames + nframes;
473 /* return having done nothing */
474 _processed_frames = next_processed_frames;
478 if (session_remove_pending) {
480 /* perform the actual session removal */
482 if (session_removal_countdown < 0) {
484 /* fade out over 1 second */
485 session_removal_countdown = _frame_rate/2;
486 session_removal_gain = 1.0;
487 session_removal_gain_step = 1.0/session_removal_countdown;
489 } else if (session_removal_countdown > 0) {
491 /* we'll be fading audio out.
493 if this is the last time we do this as part
494 of session removal, do a MIDI panic now
495 to get MIDI stopped. This relies on the fact
496 that "immediate data" (aka "out of band data") from
497 MIDI tracks is *appended* after any other data,
498 so that it emerges after any outbound note ons, etc.
501 if (session_removal_countdown <= nframes) {
502 _session->midi_panic ();
508 session_removal_countdown = -1; // reset to "not in progress"
509 session_remove_pending = false;
510 session_removed.signal(); // wakes up thread that initiated session removal
516 if (!_freewheeling) {
517 MIDI::Manager::instance()->cycle_start(nframes);
518 MIDI::Manager::instance()->cycle_end();
521 _processed_frames = next_processed_frames;
526 /* tell all relevant objects that we're starting a new cycle */
528 InternalSend::CycleStart (nframes);
529 Port::set_global_port_buffer_offset (0);
530 Port::set_cycle_framecnt (nframes);
532 /* tell all Ports that we're starting a new cycle */
534 boost::shared_ptr<Ports> p = ports.reader();
536 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
537 i->second->cycle_start (nframes);
540 /* test if we are freewheeling and there are freewheel signals connected.
541 ardour should act normally even when freewheeling unless /it/ is exporting */
544 if (_freewheeling && !Freewheel.empty()) {
545 /* emit the Freewheel signal and stop freewheeling in the event of trouble
547 boost::optional<int> r = Freewheel (nframes);
548 if (r.get_value_or (0)) {
549 jack_set_freewheel (_priv_jack, false);
553 MIDI::Manager::instance()->cycle_start(nframes);
556 _session->process (nframes);
559 MIDI::Manager::instance()->cycle_end();
567 _processed_frames = next_processed_frames;
571 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
573 boost::shared_ptr<Ports> p = ports.reader();
575 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
579 if (i->second->last_monitor() != (x = i->second->jack_monitoring_input ())) {
580 i->second->set_last_monitor (x);
581 /* XXX I think this is dangerous, due to
582 a likely mutex in the signal handlers ...
584 i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
587 last_monitor_check = next_processed_frames;
590 if (_session->silent()) {
592 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
594 if (i->second->sends_output()) {
595 i->second->get_buffer(nframes).silence(nframes);
600 if (session_remove_pending && session_removal_countdown) {
602 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
604 if (i->second->sends_output()) {
606 boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
608 Sample* s = ap->engine_get_whole_audio_buffer ();
609 gain_t g = session_removal_gain;
611 for (pframes_t n = 0; n < nframes; ++n) {
613 g -= session_removal_gain_step;
619 if (session_removal_countdown > nframes) {
620 session_removal_countdown -= nframes;
622 session_removal_countdown = 0;
625 session_removal_gain -= (nframes * session_removal_gain_step);
630 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
631 i->second->cycle_end (nframes);
634 _processed_frames = next_processed_frames;
642 AudioEngine::_sample_rate_callback (pframes_t nframes, void *arg)
644 return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
648 AudioEngine::jack_sample_rate_callback (pframes_t nframes)
650 _frame_rate = nframes;
651 _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
653 /* check for monitor input change every 1/10th of second */
655 monitor_check_interval = nframes / 10;
656 last_monitor_check = 0;
659 _session->set_frame_rate (nframes);
662 SampleRateChanged (nframes); /* EMIT SIGNAL */
668 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
671 _session->update_latency (mode == JackPlaybackLatency);
676 AudioEngine::_bufsize_callback (pframes_t nframes, void *arg)
678 return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
682 AudioEngine::jack_bufsize_callback (pframes_t nframes)
684 /* if the size has not changed, this should be a no-op */
686 if (nframes == _buffer_size) {
690 GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
692 _buffer_size = nframes;
693 _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
694 last_monitor_check = 0;
696 if (jack_port_type_get_buffer_size) {
697 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
698 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
701 /* Old version of JACK.
703 These crude guesses, see below where we try to get the right answers.
705 Note that our guess for MIDI deliberatey tries to overestimate
706 by a little. It would be nicer if we could get the actual
707 size from a port, but we have to use this estimate in the
708 event that there are no MIDI ports currently. If there are
709 the value will be adjusted below.
712 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
713 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
717 Glib::Mutex::Lock lm (_process_lock);
719 boost::shared_ptr<Ports> p = ports.reader();
721 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
727 _session->set_block_size (_buffer_size);
734 AudioEngine::stop_metering_thread ()
736 if (m_meter_thread) {
737 g_atomic_int_set (&m_meter_exit, 1);
738 m_meter_thread->join ();
744 AudioEngine::start_metering_thread ()
746 if (m_meter_thread == 0) {
747 g_atomic_int_set (&m_meter_exit, 0);
748 m_meter_thread = Glib::Thread::create (boost::bind (&AudioEngine::meter_thread, this),
749 500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
754 AudioEngine::meter_thread ()
756 pthread_set_name (X_("meter"));
759 Glib::usleep (10000); /* 1/100th sec interval */
760 if (g_atomic_int_get(&m_meter_exit)) {
768 AudioEngine::set_session (Session *s)
770 Glib::Mutex::Lock pl (_process_lock);
772 SessionHandlePtr::set_session (s);
776 start_metering_thread ();
778 pframes_t blocksize = jack_get_buffer_size (_jack);
780 /* page in as much of the session process code as we
781 can before we really start running.
784 boost::shared_ptr<Ports> p = ports.reader();
786 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
787 i->second->cycle_start (blocksize);
790 _session->process (blocksize);
791 _session->process (blocksize);
792 _session->process (blocksize);
793 _session->process (blocksize);
794 _session->process (blocksize);
795 _session->process (blocksize);
796 _session->process (blocksize);
797 _session->process (blocksize);
799 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
800 i->second->cycle_end (blocksize);
806 AudioEngine::remove_session ()
808 Glib::Mutex::Lock lm (_process_lock);
812 stop_metering_thread ();
815 session_remove_pending = true;
816 session_removed.wait(_process_lock);
820 SessionHandlePtr::set_session (0);
827 AudioEngine::port_registration_failure (const std::string& portname)
829 GET_PRIVATE_JACK_POINTER (_jack);
830 string full_portname = jack_client_name;
831 full_portname += ':';
832 full_portname += portname;
835 jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
839 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
841 reason = string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with more ports if you need this many tracks."), PROGRAM_NAME);
844 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
847 boost::shared_ptr<Port>
848 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
850 boost::shared_ptr<Port> newport;
853 if (dtype == DataType::AUDIO) {
854 newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
855 } else if (dtype == DataType::MIDI) {
856 newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
858 throw PortRegistrationFailure("unable to create port (unknown type)");
861 RCUWriter<Ports> writer (ports);
862 boost::shared_ptr<Ports> ps = writer.get_copy ();
863 ps->insert (make_pair (make_port_name_relative (portname), newport));
865 /* writer goes out of scope, forces update */
870 catch (PortRegistrationFailure& err) {
872 } catch (std::exception& e) {
873 throw PortRegistrationFailure(string_compose(
874 _("unable to create port: %1"), e.what()).c_str());
876 throw PortRegistrationFailure("unable to create port (unknown error)");
880 boost::shared_ptr<Port>
881 AudioEngine::register_input_port (DataType type, const string& portname)
883 return register_port (type, portname, true);
886 boost::shared_ptr<Port>
887 AudioEngine::register_output_port (DataType type, const string& portname)
889 return register_port (type, portname, false);
893 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
895 /* caller must hold process lock */
898 /* probably happening when the engine has been halted by JACK,
899 in which case, there is nothing we can do here.
905 RCUWriter<Ports> writer (ports);
906 boost::shared_ptr<Ports> ps = writer.get_copy ();
907 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
909 if (x != ps->end()) {
913 /* writer goes out of scope, forces update */
922 AudioEngine::connect (const string& source, const string& destination)
928 fatal << _("connect called before engine was started") << endmsg;
935 string s = make_port_name_non_relative (source);
936 string d = make_port_name_non_relative (destination);
939 boost::shared_ptr<Port> src = get_port_by_name (s);
940 boost::shared_ptr<Port> dst = get_port_by_name (d);
943 ret = src->connect (d);
945 ret = dst->connect (s);
947 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
952 /* already exists - no error, no warning */
953 } else if (ret < 0) {
954 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
955 source, s, destination, d)
963 AudioEngine::disconnect (const string& source, const string& destination)
969 fatal << _("disconnect called before engine was started") << endmsg;
976 string s = make_port_name_non_relative (source);
977 string d = make_port_name_non_relative (destination);
979 boost::shared_ptr<Port> src = get_port_by_name (s);
980 boost::shared_ptr<Port> dst = get_port_by_name (d);
983 ret = src->disconnect (d);
985 ret = dst->disconnect (s);
987 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
994 AudioEngine::disconnect (boost::shared_ptr<Port> port)
996 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1000 fatal << _("disconnect called before engine was started") << endmsg;
1007 return port->disconnect_all ();
1011 AudioEngine::frame_rate () const
1013 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1014 if (_frame_rate == 0) {
1015 return (_frame_rate = jack_get_sample_rate (_priv_jack));
1022 AudioEngine::raw_buffer_size (DataType t)
1024 std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
1025 return (s != _raw_buffer_sizes.end()) ? s->second : 0;
1029 AudioEngine::frames_per_cycle () const
1031 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1032 if (_buffer_size == 0) {
1033 return jack_get_buffer_size (_jack);
1035 return _buffer_size;
1039 /** @param name Full or short name of port
1040 * @return Corresponding Port or 0.
1043 boost::shared_ptr<Port>
1044 AudioEngine::get_port_by_name (const string& portname)
1048 fatal << _("get_port_by_name() called before engine was started") << endmsg;
1051 boost::shared_ptr<Port> ();
1055 if (!port_is_mine (portname)) {
1056 /* not an ardour port */
1057 return boost::shared_ptr<Port> ();
1060 boost::shared_ptr<Ports> pr = ports.reader();
1061 std::string rel = make_port_name_relative (portname);
1062 Ports::iterator x = pr->find (rel);
1064 if (x != pr->end()) {
1065 /* its possible that the port was renamed by some 3rd party and
1066 we don't know about it. check for this (the check is quick
1067 and cheap), and if so, rename the port (which will alter
1068 the port map as a side effect).
1070 const std::string check = make_port_name_relative (jack_port_name (x->second->jack_port()));
1072 x->second->set_name (check);
1077 return boost::shared_ptr<Port> ();
1081 AudioEngine::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
1083 RCUWriter<Ports> writer (ports);
1084 boost::shared_ptr<Ports> p = writer.get_copy();
1085 Ports::iterator x = p->find (old_relative_name);
1087 if (x != p->end()) {
1088 boost::shared_ptr<Port> port = x->second;
1090 p->insert (make_pair (new_relative_name, port));
1095 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1097 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1100 fatal << _("get_ports called before engine was started") << endmsg;
1106 return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1110 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1112 /* called from jack shutdown handler */
1114 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1115 bool was_running = ae->_running;
1117 ae->stop_metering_thread ();
1119 ae->_running = false;
1120 ae->_buffer_size = 0;
1121 ae->_frame_rate = 0;
1125 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1127 case JackBackendError:
1128 ae->Halted(reason); /* EMIT SIGNAL */
1131 ae->Halted(""); /* EMIT SIGNAL */
1134 ae->Halted(""); /* EMIT SIGNAL */
1140 AudioEngine::halted (void *arg)
1142 cerr << "HALTED by JACK\n";
1144 /* called from jack shutdown handler */
1146 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1147 bool was_running = ae->_running;
1149 ae->stop_metering_thread ();
1151 ae->_running = false;
1152 ae->_buffer_size = 0;
1153 ae->_frame_rate = 0;
1157 ae->Halted(""); /* EMIT SIGNAL */
1158 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1163 AudioEngine::died ()
1165 /* called from a signal handler for SIGPIPE */
1167 stop_metering_thread ();
1176 AudioEngine::can_request_hardware_monitoring ()
1178 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1179 const char ** ports;
1181 if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1191 AudioEngine::n_physical (unsigned long flags) const
1195 GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1197 const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1202 for (uint32_t i = 0; ports[i]; ++i) {
1203 if (!strstr (ports[i], "Midi-Through")) {
1204 DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1205 c.set (t, c.get (t) + 1);
1215 AudioEngine::n_physical_inputs () const
1217 return n_physical (JackPortIsInput);
1221 AudioEngine::n_physical_outputs () const
1223 return n_physical (JackPortIsOutput);
1227 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1229 GET_PRIVATE_JACK_POINTER (_jack);
1230 const char ** ports;
1232 if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1237 for (uint32_t i = 0; ports[i]; ++i) {
1238 if (strstr (ports[i], "Midi-Through")) {
1241 phy.push_back (ports[i]);
1247 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1248 * a physical input connector.
1251 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1253 get_physical (type, JackPortIsOutput, ins);
1256 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1257 * a physical output connector.
1260 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1262 get_physical (type, JackPortIsInput, outs);
1266 AudioEngine::transport_stop ()
1268 GET_PRIVATE_JACK_POINTER (_jack);
1269 jack_transport_stop (_priv_jack);
1273 AudioEngine::transport_start ()
1275 GET_PRIVATE_JACK_POINTER (_jack);
1276 jack_transport_start (_priv_jack);
1280 AudioEngine::transport_locate (framepos_t where)
1282 GET_PRIVATE_JACK_POINTER (_jack);
1283 jack_transport_locate (_priv_jack, where);
1286 AudioEngine::TransportState
1287 AudioEngine::transport_state ()
1289 GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1290 jack_position_t pos;
1291 return (TransportState) jack_transport_query (_priv_jack, &pos);
1295 AudioEngine::reset_timebase ()
1297 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1299 if (_session->config.get_jack_time_master()) {
1300 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1302 return jack_release_timebase (_jack);
1309 AudioEngine::freewheel (bool onoff)
1311 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1313 if (onoff != _freewheeling) {
1314 return jack_set_freewheel (_priv_jack, onoff);
1317 /* already doing what has been asked for */
1323 AudioEngine::remove_all_ports ()
1325 /* make sure that JACK callbacks that will be invoked as we cleanup
1326 * ports know that they have nothing to do.
1329 port_remove_in_progress = true;
1331 /* process lock MUST be held by caller
1335 RCUWriter<Ports> writer (ports);
1336 boost::shared_ptr<Ports> ps = writer.get_copy ();
1340 /* clear dead wood list in RCU */
1344 port_remove_in_progress = false;
1348 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1350 EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1351 boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1352 jack_status_t status;
1354 /* revert all environment settings back to whatever they were when ardour started
1358 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1359 global_epa->restore ();
1362 jack_client_name = client_name; /* might be reset below */
1363 #ifdef HAVE_JACK_SESSION
1364 if (! session_uuid.empty())
1365 _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1368 _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1370 if (_jack == NULL) {
1371 // error message is not useful here
1375 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1377 if (status & JackNameNotUnique) {
1378 jack_client_name = jack_get_client_name (_priv_jack);
1385 AudioEngine::disconnect_from_jack ()
1387 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1390 stop_metering_thread ();
1394 Glib::Mutex::Lock lm (_process_lock);
1395 jack_client_close (_priv_jack);
1401 _raw_buffer_sizes.clear();
1405 Stopped(); /* EMIT SIGNAL */
1406 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1413 AudioEngine::reconnect_to_jack ()
1416 disconnect_from_jack ();
1417 /* XXX give jackd a chance */
1418 Glib::usleep (250000);
1421 if (connect_to_jack (jack_client_name, "")) {
1422 error << _("failed to connect to JACK") << endmsg;
1428 boost::shared_ptr<Ports> p = ports.reader ();
1430 for (i = p->begin(); i != p->end(); ++i) {
1431 if (i->second->reestablish ()) {
1436 if (i != p->end()) {
1438 remove_all_ports ();
1442 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1444 MIDI::Manager::instance()->reestablish (_priv_jack);
1447 _session->reset_jack_connection (_priv_jack);
1448 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1449 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1452 last_monitor_check = 0;
1454 set_jack_callbacks ();
1456 if (jack_activate (_priv_jack) == 0) {
1463 /* re-establish connections */
1465 for (i = p->begin(); i != p->end(); ++i) {
1466 i->second->reconnect ();
1469 MIDI::Manager::instance()->reconnect ();
1471 Running (); /* EMIT SIGNAL*/
1473 start_metering_thread ();
1479 AudioEngine::request_buffer_size (pframes_t nframes)
1481 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1483 if (nframes == jack_get_buffer_size (_priv_jack)) {
1487 return jack_set_buffer_size (_priv_jack, nframes);
1491 AudioEngine::make_port_name_relative (string portname) const
1493 string::size_type len;
1494 string::size_type n;
1496 len = portname.length();
1498 for (n = 0; n < len; ++n) {
1499 if (portname[n] == ':') {
1504 if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1505 return portname.substr (n+1);
1512 AudioEngine::make_port_name_non_relative (string portname) const
1516 if (portname.find_first_of (':') != string::npos) {
1520 str = jack_client_name;
1528 AudioEngine::port_is_mine (const string& portname) const
1530 if (portname.find_first_of (':') != string::npos) {
1531 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1539 AudioEngine::is_realtime () const
1541 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1542 return jack_is_realtime (_priv_jack);
1546 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1548 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1549 ThreadData* td = new ThreadData (this, f, stacksize);
1551 if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1552 jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1560 AudioEngine::_start_process_thread (void* arg)
1562 ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1563 boost::function<void()> f = td->f;
1572 AudioEngine::port_is_physical (const std::string& portname) const
1574 GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1576 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1582 return jack_port_flags (port) & JackPortIsPhysical;
1586 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1588 GET_PRIVATE_JACK_POINTER(_jack);
1590 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1596 jack_port_request_monitor (port, yn);
1600 AudioEngine::update_latencies ()
1602 if (jack_recompute_total_latencies) {
1603 GET_PRIVATE_JACK_POINTER (_jack);
1604 jack_recompute_total_latencies (_priv_jack);
1609 AudioEngine::destroy ()