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::Threads::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::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::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::Threads::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::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
753 AudioEngine::meter_thread ()
755 pthread_set_name (X_("meter"));
758 Glib::usleep (10000); /* 1/100th sec interval */
759 if (g_atomic_int_get(&m_meter_exit)) {
767 AudioEngine::set_session (Session *s)
769 Glib::Threads::Mutex::Lock pl (_process_lock);
771 SessionHandlePtr::set_session (s);
775 start_metering_thread ();
777 pframes_t blocksize = jack_get_buffer_size (_jack);
779 /* page in as much of the session process code as we
780 can before we really start running.
783 boost::shared_ptr<Ports> p = ports.reader();
785 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
786 i->second->cycle_start (blocksize);
789 _session->process (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);
798 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
799 i->second->cycle_end (blocksize);
805 AudioEngine::remove_session ()
807 Glib::Threads::Mutex::Lock lm (_process_lock);
811 stop_metering_thread ();
814 session_remove_pending = true;
815 session_removed.wait(_process_lock);
819 SessionHandlePtr::set_session (0);
826 AudioEngine::port_registration_failure (const std::string& portname)
828 GET_PRIVATE_JACK_POINTER (_jack);
829 string full_portname = jack_client_name;
830 full_portname += ':';
831 full_portname += portname;
834 jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
838 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
840 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);
843 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
846 boost::shared_ptr<Port>
847 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
849 boost::shared_ptr<Port> newport;
852 if (dtype == DataType::AUDIO) {
853 newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
854 } else if (dtype == DataType::MIDI) {
855 newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
857 throw PortRegistrationFailure("unable to create port (unknown type)");
860 RCUWriter<Ports> writer (ports);
861 boost::shared_ptr<Ports> ps = writer.get_copy ();
862 ps->insert (make_pair (make_port_name_relative (portname), newport));
864 /* writer goes out of scope, forces update */
869 catch (PortRegistrationFailure& err) {
871 } catch (std::exception& e) {
872 throw PortRegistrationFailure(string_compose(
873 _("unable to create port: %1"), e.what()).c_str());
875 throw PortRegistrationFailure("unable to create port (unknown error)");
879 boost::shared_ptr<Port>
880 AudioEngine::register_input_port (DataType type, const string& portname)
882 return register_port (type, portname, true);
885 boost::shared_ptr<Port>
886 AudioEngine::register_output_port (DataType type, const string& portname)
888 return register_port (type, portname, false);
892 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
894 /* caller must hold process lock */
897 /* probably happening when the engine has been halted by JACK,
898 in which case, there is nothing we can do here.
904 RCUWriter<Ports> writer (ports);
905 boost::shared_ptr<Ports> ps = writer.get_copy ();
906 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
908 if (x != ps->end()) {
912 /* writer goes out of scope, forces update */
921 AudioEngine::connect (const string& source, const string& destination)
927 fatal << _("connect called before engine was started") << endmsg;
934 string s = make_port_name_non_relative (source);
935 string d = make_port_name_non_relative (destination);
938 boost::shared_ptr<Port> src = get_port_by_name (s);
939 boost::shared_ptr<Port> dst = get_port_by_name (d);
942 ret = src->connect (d);
944 ret = dst->connect (s);
946 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
951 /* already exists - no error, no warning */
952 } else if (ret < 0) {
953 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
954 source, s, destination, d)
962 AudioEngine::disconnect (const string& source, const string& destination)
968 fatal << _("disconnect called before engine was started") << endmsg;
975 string s = make_port_name_non_relative (source);
976 string d = make_port_name_non_relative (destination);
978 boost::shared_ptr<Port> src = get_port_by_name (s);
979 boost::shared_ptr<Port> dst = get_port_by_name (d);
982 ret = src->disconnect (d);
984 ret = dst->disconnect (s);
986 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
993 AudioEngine::disconnect (boost::shared_ptr<Port> port)
995 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
999 fatal << _("disconnect called before engine was started") << endmsg;
1006 return port->disconnect_all ();
1010 AudioEngine::frame_rate () const
1012 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1013 if (_frame_rate == 0) {
1014 return (_frame_rate = jack_get_sample_rate (_priv_jack));
1021 AudioEngine::raw_buffer_size (DataType t)
1023 std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
1024 return (s != _raw_buffer_sizes.end()) ? s->second : 0;
1028 AudioEngine::frames_per_cycle () const
1030 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1031 if (_buffer_size == 0) {
1032 return jack_get_buffer_size (_jack);
1034 return _buffer_size;
1038 /** @param name Full or short name of port
1039 * @return Corresponding Port or 0.
1042 boost::shared_ptr<Port>
1043 AudioEngine::get_port_by_name (const string& portname)
1047 fatal << _("get_port_by_name() called before engine was started") << endmsg;
1050 boost::shared_ptr<Port> ();
1054 if (!port_is_mine (portname)) {
1055 /* not an ardour port */
1056 return boost::shared_ptr<Port> ();
1059 boost::shared_ptr<Ports> pr = ports.reader();
1060 std::string rel = make_port_name_relative (portname);
1061 Ports::iterator x = pr->find (rel);
1063 if (x != pr->end()) {
1064 /* its possible that the port was renamed by some 3rd party and
1065 we don't know about it. check for this (the check is quick
1066 and cheap), and if so, rename the port (which will alter
1067 the port map as a side effect).
1069 const std::string check = make_port_name_relative (jack_port_name (x->second->jack_port()));
1071 x->second->set_name (check);
1076 return boost::shared_ptr<Port> ();
1080 AudioEngine::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
1082 RCUWriter<Ports> writer (ports);
1083 boost::shared_ptr<Ports> p = writer.get_copy();
1084 Ports::iterator x = p->find (old_relative_name);
1086 if (x != p->end()) {
1087 boost::shared_ptr<Port> port = x->second;
1089 p->insert (make_pair (new_relative_name, port));
1094 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1096 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1099 fatal << _("get_ports called before engine was started") << endmsg;
1105 return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1109 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1111 /* called from jack shutdown handler */
1113 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1114 bool was_running = ae->_running;
1116 ae->stop_metering_thread ();
1118 ae->_running = false;
1119 ae->_buffer_size = 0;
1120 ae->_frame_rate = 0;
1124 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1126 case JackBackendError:
1127 ae->Halted(reason); /* EMIT SIGNAL */
1130 ae->Halted(""); /* EMIT SIGNAL */
1133 ae->Halted(""); /* EMIT SIGNAL */
1139 AudioEngine::halted (void *arg)
1141 cerr << "HALTED by JACK\n";
1143 /* called from jack shutdown handler */
1145 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1146 bool was_running = ae->_running;
1148 ae->stop_metering_thread ();
1150 ae->_running = false;
1151 ae->_buffer_size = 0;
1152 ae->_frame_rate = 0;
1156 ae->Halted(""); /* EMIT SIGNAL */
1157 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1162 AudioEngine::died ()
1164 /* called from a signal handler for SIGPIPE */
1166 stop_metering_thread ();
1175 AudioEngine::can_request_hardware_monitoring ()
1177 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1178 const char ** ports;
1180 if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1190 AudioEngine::n_physical (unsigned long flags) const
1194 GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1196 const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1201 for (uint32_t i = 0; ports[i]; ++i) {
1202 if (!strstr (ports[i], "Midi-Through")) {
1203 DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1204 c.set (t, c.get (t) + 1);
1214 AudioEngine::n_physical_inputs () const
1216 return n_physical (JackPortIsInput);
1220 AudioEngine::n_physical_outputs () const
1222 return n_physical (JackPortIsOutput);
1226 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1228 GET_PRIVATE_JACK_POINTER (_jack);
1229 const char ** ports;
1231 if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1236 for (uint32_t i = 0; ports[i]; ++i) {
1237 if (strstr (ports[i], "Midi-Through")) {
1240 phy.push_back (ports[i]);
1246 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1247 * a physical input connector.
1250 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1252 get_physical (type, JackPortIsOutput, ins);
1255 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1256 * a physical output connector.
1259 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1261 get_physical (type, JackPortIsInput, outs);
1265 AudioEngine::transport_stop ()
1267 GET_PRIVATE_JACK_POINTER (_jack);
1268 jack_transport_stop (_priv_jack);
1272 AudioEngine::transport_start ()
1274 GET_PRIVATE_JACK_POINTER (_jack);
1275 jack_transport_start (_priv_jack);
1279 AudioEngine::transport_locate (framepos_t where)
1281 GET_PRIVATE_JACK_POINTER (_jack);
1282 jack_transport_locate (_priv_jack, where);
1285 AudioEngine::TransportState
1286 AudioEngine::transport_state ()
1288 GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1289 jack_position_t pos;
1290 return (TransportState) jack_transport_query (_priv_jack, &pos);
1294 AudioEngine::reset_timebase ()
1296 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1298 if (_session->config.get_jack_time_master()) {
1299 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1301 return jack_release_timebase (_jack);
1308 AudioEngine::freewheel (bool onoff)
1310 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1312 if (onoff != _freewheeling) {
1313 return jack_set_freewheel (_priv_jack, onoff);
1316 /* already doing what has been asked for */
1322 AudioEngine::remove_all_ports ()
1324 /* make sure that JACK callbacks that will be invoked as we cleanup
1325 * ports know that they have nothing to do.
1328 port_remove_in_progress = true;
1330 /* process lock MUST be held by caller
1334 RCUWriter<Ports> writer (ports);
1335 boost::shared_ptr<Ports> ps = writer.get_copy ();
1339 /* clear dead wood list in RCU */
1343 port_remove_in_progress = false;
1347 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1349 EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1350 boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1351 jack_status_t status;
1353 /* revert all environment settings back to whatever they were when ardour started
1357 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1358 global_epa->restore ();
1361 jack_client_name = client_name; /* might be reset below */
1362 #ifdef HAVE_JACK_SESSION
1363 if (! session_uuid.empty())
1364 _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1367 _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1369 if (_jack == NULL) {
1370 // error message is not useful here
1374 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1376 if (status & JackNameNotUnique) {
1377 jack_client_name = jack_get_client_name (_priv_jack);
1384 AudioEngine::disconnect_from_jack ()
1386 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1389 stop_metering_thread ();
1393 Glib::Threads::Mutex::Lock lm (_process_lock);
1394 jack_client_close (_priv_jack);
1400 _raw_buffer_sizes.clear();
1404 Stopped(); /* EMIT SIGNAL */
1405 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1412 AudioEngine::reconnect_to_jack ()
1415 disconnect_from_jack ();
1416 /* XXX give jackd a chance */
1417 Glib::usleep (250000);
1420 if (connect_to_jack (jack_client_name, "")) {
1421 error << _("failed to connect to JACK") << endmsg;
1427 boost::shared_ptr<Ports> p = ports.reader ();
1429 for (i = p->begin(); i != p->end(); ++i) {
1430 if (i->second->reestablish ()) {
1435 if (i != p->end()) {
1437 remove_all_ports ();
1441 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1443 MIDI::Manager::instance()->reestablish (_priv_jack);
1446 _session->reset_jack_connection (_priv_jack);
1447 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1448 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1451 last_monitor_check = 0;
1453 set_jack_callbacks ();
1455 if (jack_activate (_priv_jack) == 0) {
1462 /* re-establish connections */
1464 for (i = p->begin(); i != p->end(); ++i) {
1465 i->second->reconnect ();
1468 MIDI::Manager::instance()->reconnect ();
1470 Running (); /* EMIT SIGNAL*/
1472 start_metering_thread ();
1478 AudioEngine::request_buffer_size (pframes_t nframes)
1480 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1482 if (nframes == jack_get_buffer_size (_priv_jack)) {
1486 return jack_set_buffer_size (_priv_jack, nframes);
1490 AudioEngine::make_port_name_relative (string portname) const
1492 string::size_type len;
1493 string::size_type n;
1495 len = portname.length();
1497 for (n = 0; n < len; ++n) {
1498 if (portname[n] == ':') {
1503 if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1504 return portname.substr (n+1);
1511 AudioEngine::make_port_name_non_relative (string portname) const
1515 if (portname.find_first_of (':') != string::npos) {
1519 str = jack_client_name;
1527 AudioEngine::port_is_mine (const string& portname) const
1529 if (portname.find_first_of (':') != string::npos) {
1530 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1538 AudioEngine::is_realtime () const
1540 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1541 return jack_is_realtime (_priv_jack);
1545 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1547 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1548 ThreadData* td = new ThreadData (this, f, stacksize);
1550 if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1551 jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1559 AudioEngine::_start_process_thread (void* arg)
1561 ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1562 boost::function<void()> f = td->f;
1571 AudioEngine::port_is_physical (const std::string& portname) const
1573 GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1575 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1581 return jack_port_flags (port) & JackPortIsPhysical;
1585 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1587 GET_PRIVATE_JACK_POINTER(_jack);
1589 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1595 jack_port_request_monitor (port, yn);
1599 AudioEngine::update_latencies ()
1601 if (jack_recompute_total_latencies) {
1602 GET_PRIVATE_JACK_POINTER (_jack);
1603 jack_recompute_total_latencies (_priv_jack);
1608 AudioEngine::destroy ()