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)
67 _instance = this; /* singleton */
69 session_remove_pending = false;
72 last_monitor_check = 0;
73 monitor_check_interval = INT32_MAX;
74 _processed_frames = 0;
79 _freewheeling = false;
80 _pre_freewheel_mmc_enabled = false;
82 port_remove_in_progress = false;
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;
479 if (!_freewheeling) {
480 MIDI::Manager::instance()->cycle_start(nframes);
481 MIDI::Manager::instance()->cycle_end();
483 _processed_frames = next_processed_frames;
487 if (session_remove_pending) {
488 /* perform the actual session removal */
490 session_remove_pending = false;
491 session_removed.signal();
492 _processed_frames = next_processed_frames;
496 /* tell all relevant objects that we're starting a new cycle */
498 InternalSend::CycleStart (nframes);
499 Port::set_global_port_buffer_offset (0);
500 Port::set_cycle_framecnt (nframes);
502 /* tell all Ports that we're starting a new cycle */
504 boost::shared_ptr<Ports> p = ports.reader();
506 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
507 i->second->cycle_start (nframes);
510 /* test if we are freewheeling and there are freewheel signals connected.
511 ardour should act normally even when freewheeling unless /it/ is exporting */
514 if (_freewheeling && !Freewheel.empty()) {
515 /* emit the Freewheel signal and stop freewheeling in the event of trouble
517 boost::optional<int> r = Freewheel (nframes);
518 if (r.get_value_or (0)) {
519 jack_set_freewheel (_priv_jack, false);
523 MIDI::Manager::instance()->cycle_start(nframes);
526 _session->process (nframes);
529 MIDI::Manager::instance()->cycle_end();
537 _processed_frames = next_processed_frames;
541 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
543 boost::shared_ptr<Ports> p = ports.reader();
545 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
549 if (i->second->last_monitor() != (x = i->second->jack_monitoring_input ())) {
550 i->second->set_last_monitor (x);
551 /* XXX I think this is dangerous, due to
552 a likely mutex in the signal handlers ...
554 i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
557 last_monitor_check = next_processed_frames;
560 if (_session->silent()) {
562 boost::shared_ptr<Ports> p = ports.reader();
564 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
566 if (i->second->sends_output()) {
567 i->second->get_buffer(nframes).silence(nframes);
574 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
575 i->second->cycle_end (nframes);
578 _processed_frames = next_processed_frames;
586 AudioEngine::_sample_rate_callback (pframes_t nframes, void *arg)
588 return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
592 AudioEngine::jack_sample_rate_callback (pframes_t nframes)
594 _frame_rate = nframes;
595 _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
597 /* check for monitor input change every 1/10th of second */
599 monitor_check_interval = nframes / 10;
600 last_monitor_check = 0;
603 _session->set_frame_rate (nframes);
606 SampleRateChanged (nframes); /* EMIT SIGNAL */
612 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
615 _session->update_latency (mode == JackPlaybackLatency);
620 AudioEngine::_bufsize_callback (pframes_t nframes, void *arg)
622 return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
626 AudioEngine::jack_bufsize_callback (pframes_t nframes)
628 /* if the size has not changed, this should be a no-op */
630 if (nframes == _buffer_size) {
634 GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
636 _buffer_size = nframes;
637 _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
638 last_monitor_check = 0;
640 if (jack_port_type_get_buffer_size) {
641 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
642 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
645 /* Old version of JACK.
647 These crude guesses, see below where we try to get the right answers.
649 Note that our guess for MIDI deliberatey tries to overestimate
650 by a little. It would be nicer if we could get the actual
651 size from a port, but we have to use this estimate in the
652 event that there are no MIDI ports currently. If there are
653 the value will be adjusted below.
656 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
657 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
661 Glib::Mutex::Lock lm (_process_lock);
663 boost::shared_ptr<Ports> p = ports.reader();
665 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
671 _session->set_block_size (_buffer_size);
678 AudioEngine::stop_metering_thread ()
680 if (m_meter_thread) {
681 g_atomic_int_set (&m_meter_exit, 1);
682 m_meter_thread->join ();
688 AudioEngine::start_metering_thread ()
690 if (m_meter_thread == 0) {
691 g_atomic_int_set (&m_meter_exit, 0);
692 m_meter_thread = Glib::Thread::create (boost::bind (&AudioEngine::meter_thread, this),
693 500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
698 AudioEngine::meter_thread ()
700 pthread_set_name (X_("meter"));
703 Glib::usleep (10000); /* 1/100th sec interval */
704 if (g_atomic_int_get(&m_meter_exit)) {
712 AudioEngine::set_session (Session *s)
714 Glib::Mutex::Lock pl (_process_lock);
716 SessionHandlePtr::set_session (s);
720 start_metering_thread ();
722 pframes_t blocksize = jack_get_buffer_size (_jack);
724 /* page in as much of the session process code as we
725 can before we really start running.
728 boost::shared_ptr<Ports> p = ports.reader();
730 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
731 i->second->cycle_start (blocksize);
734 _session->process (blocksize);
735 _session->process (blocksize);
736 _session->process (blocksize);
737 _session->process (blocksize);
738 _session->process (blocksize);
739 _session->process (blocksize);
740 _session->process (blocksize);
741 _session->process (blocksize);
743 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
744 i->second->cycle_end (blocksize);
750 AudioEngine::remove_session ()
752 Glib::Mutex::Lock lm (_process_lock);
756 stop_metering_thread ();
759 session_remove_pending = true;
760 session_removed.wait(_process_lock);
764 SessionHandlePtr::set_session (0);
771 AudioEngine::port_registration_failure (const std::string& portname)
773 GET_PRIVATE_JACK_POINTER (_jack);
774 string full_portname = jack_client_name;
775 full_portname += ':';
776 full_portname += portname;
779 jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
783 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
785 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);
788 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
791 boost::shared_ptr<Port>
792 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
794 boost::shared_ptr<Port> newport;
797 if (dtype == DataType::AUDIO) {
798 newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
799 } else if (dtype == DataType::MIDI) {
800 newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
802 throw PortRegistrationFailure("unable to create port (unknown type)");
805 RCUWriter<Ports> writer (ports);
806 boost::shared_ptr<Ports> ps = writer.get_copy ();
807 ps->insert (make_pair (make_port_name_relative (portname), newport));
809 /* writer goes out of scope, forces update */
814 catch (PortRegistrationFailure& err) {
816 } catch (std::exception& e) {
817 throw PortRegistrationFailure(string_compose(
818 _("unable to create port: %1"), e.what()).c_str());
820 throw PortRegistrationFailure("unable to create port (unknown error)");
824 boost::shared_ptr<Port>
825 AudioEngine::register_input_port (DataType type, const string& portname)
827 return register_port (type, portname, true);
830 boost::shared_ptr<Port>
831 AudioEngine::register_output_port (DataType type, const string& portname)
833 return register_port (type, portname, false);
837 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
839 /* caller must hold process lock */
842 /* probably happening when the engine has been halted by JACK,
843 in which case, there is nothing we can do here.
849 RCUWriter<Ports> writer (ports);
850 boost::shared_ptr<Ports> ps = writer.get_copy ();
851 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
853 if (x != ps->end()) {
857 /* writer goes out of scope, forces update */
866 AudioEngine::connect (const string& source, const string& destination)
872 fatal << _("connect called before engine was started") << endmsg;
879 string s = make_port_name_non_relative (source);
880 string d = make_port_name_non_relative (destination);
883 boost::shared_ptr<Port> src = get_port_by_name (s);
884 boost::shared_ptr<Port> dst = get_port_by_name (d);
887 ret = src->connect (d);
889 ret = dst->connect (s);
891 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
896 /* already exists - no error, no warning */
897 } else if (ret < 0) {
898 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
899 source, s, destination, d)
907 AudioEngine::disconnect (const string& source, const string& destination)
913 fatal << _("disconnect called before engine was started") << endmsg;
920 string s = make_port_name_non_relative (source);
921 string d = make_port_name_non_relative (destination);
923 boost::shared_ptr<Port> src = get_port_by_name (s);
924 boost::shared_ptr<Port> dst = get_port_by_name (d);
927 ret = src->disconnect (d);
929 ret = dst->disconnect (s);
931 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
938 AudioEngine::disconnect (boost::shared_ptr<Port> port)
940 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
944 fatal << _("disconnect called before engine was started") << endmsg;
951 return port->disconnect_all ();
955 AudioEngine::frame_rate () const
957 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
958 if (_frame_rate == 0) {
959 return (_frame_rate = jack_get_sample_rate (_priv_jack));
966 AudioEngine::raw_buffer_size (DataType t)
968 std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
969 return (s != _raw_buffer_sizes.end()) ? s->second : 0;
973 AudioEngine::frames_per_cycle () const
975 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
976 if (_buffer_size == 0) {
977 return jack_get_buffer_size (_jack);
983 /** @param name Full or short name of port
984 * @return Corresponding Port or 0.
987 boost::shared_ptr<Port>
988 AudioEngine::get_port_by_name (const string& portname)
992 fatal << _("get_port_by_name() called before engine was started") << endmsg;
995 boost::shared_ptr<Port> ();
999 if (!port_is_mine (portname)) {
1000 /* not an ardour port */
1001 return boost::shared_ptr<Port> ();
1004 boost::shared_ptr<Ports> pr = ports.reader();
1005 std::string rel = make_port_name_relative (portname);
1006 Ports::iterator x = pr->find (rel);
1008 if (x != pr->end()) {
1009 /* its possible that the port was renamed by some 3rd party and
1010 we don't know about it. check for this (the check is quick
1011 and cheap), and if so, rename the port (which will alter
1012 the port map as a side effect).
1014 const std::string check = make_port_name_relative (jack_port_name (x->second->jack_port()));
1016 x->second->set_name (check);
1021 return boost::shared_ptr<Port> ();
1025 AudioEngine::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
1027 RCUWriter<Ports> writer (ports);
1028 boost::shared_ptr<Ports> p = writer.get_copy();
1029 Ports::iterator x = p->find (old_relative_name);
1031 if (x != p->end()) {
1032 boost::shared_ptr<Port> port = x->second;
1034 p->insert (make_pair (new_relative_name, port));
1039 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1041 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1044 fatal << _("get_ports called before engine was started") << endmsg;
1050 return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1054 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1056 /* called from jack shutdown handler */
1058 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1059 bool was_running = ae->_running;
1061 ae->stop_metering_thread ();
1063 ae->_running = false;
1064 ae->_buffer_size = 0;
1065 ae->_frame_rate = 0;
1069 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1071 case JackBackendError:
1072 ae->Halted(reason); /* EMIT SIGNAL */
1075 ae->Halted(""); /* EMIT SIGNAL */
1078 ae->Halted(""); /* EMIT SIGNAL */
1084 AudioEngine::halted (void *arg)
1086 cerr << "HALTED by JACK\n";
1088 /* called from jack shutdown handler */
1090 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1091 bool was_running = ae->_running;
1093 ae->stop_metering_thread ();
1095 ae->_running = false;
1096 ae->_buffer_size = 0;
1097 ae->_frame_rate = 0;
1101 ae->Halted(""); /* EMIT SIGNAL */
1102 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1107 AudioEngine::died ()
1109 /* called from a signal handler for SIGPIPE */
1111 stop_metering_thread ();
1120 AudioEngine::can_request_hardware_monitoring ()
1122 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1123 const char ** ports;
1125 if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1135 AudioEngine::n_physical (unsigned long flags) const
1139 GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1141 const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1146 for (uint32_t i = 0; ports[i]; ++i) {
1147 if (!strstr (ports[i], "Midi-Through")) {
1148 DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1149 c.set (t, c.get (t) + 1);
1159 AudioEngine::n_physical_inputs () const
1161 return n_physical (JackPortIsInput);
1165 AudioEngine::n_physical_outputs () const
1167 return n_physical (JackPortIsOutput);
1171 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1173 GET_PRIVATE_JACK_POINTER (_jack);
1174 const char ** ports;
1176 if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1181 for (uint32_t i = 0; ports[i]; ++i) {
1182 if (strstr (ports[i], "Midi-Through")) {
1185 phy.push_back (ports[i]);
1191 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1192 * a physical input connector.
1195 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1197 get_physical (type, JackPortIsOutput, ins);
1200 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1201 * a physical output connector.
1204 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1206 get_physical (type, JackPortIsInput, outs);
1210 AudioEngine::transport_stop ()
1212 GET_PRIVATE_JACK_POINTER (_jack);
1213 jack_transport_stop (_priv_jack);
1217 AudioEngine::transport_start ()
1219 GET_PRIVATE_JACK_POINTER (_jack);
1220 jack_transport_start (_priv_jack);
1224 AudioEngine::transport_locate (framepos_t where)
1226 GET_PRIVATE_JACK_POINTER (_jack);
1227 jack_transport_locate (_priv_jack, where);
1230 AudioEngine::TransportState
1231 AudioEngine::transport_state ()
1233 GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1234 jack_position_t pos;
1235 return (TransportState) jack_transport_query (_priv_jack, &pos);
1239 AudioEngine::reset_timebase ()
1241 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1243 if (_session->config.get_jack_time_master()) {
1244 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1246 return jack_release_timebase (_jack);
1253 AudioEngine::freewheel (bool onoff)
1255 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1257 if (onoff != _freewheeling) {
1258 return jack_set_freewheel (_priv_jack, onoff);
1261 /* already doing what has been asked for */
1267 AudioEngine::remove_all_ports ()
1269 /* make sure that JACK callbacks that will be invoked as we cleanup
1270 * ports know that they have nothing to do.
1273 port_remove_in_progress = true;
1275 /* process lock MUST be held by caller
1279 RCUWriter<Ports> writer (ports);
1280 boost::shared_ptr<Ports> ps = writer.get_copy ();
1284 /* clear dead wood list in RCU */
1288 port_remove_in_progress = false;
1292 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1294 EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1295 boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1296 jack_status_t status;
1298 /* revert all environment settings back to whatever they were when ardour started
1302 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1303 global_epa->restore ();
1306 jack_client_name = client_name; /* might be reset below */
1307 #ifdef HAVE_JACK_SESSION
1308 if (! session_uuid.empty())
1309 _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1312 _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1314 if (_jack == NULL) {
1315 // error message is not useful here
1319 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1321 if (status & JackNameNotUnique) {
1322 jack_client_name = jack_get_client_name (_priv_jack);
1329 AudioEngine::disconnect_from_jack ()
1331 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1334 stop_metering_thread ();
1338 Glib::Mutex::Lock lm (_process_lock);
1339 jack_client_close (_priv_jack);
1345 _raw_buffer_sizes.clear();
1349 Stopped(); /* EMIT SIGNAL */
1350 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1357 AudioEngine::reconnect_to_jack ()
1360 disconnect_from_jack ();
1361 /* XXX give jackd a chance */
1362 Glib::usleep (250000);
1365 if (connect_to_jack (jack_client_name, "")) {
1366 error << _("failed to connect to JACK") << endmsg;
1372 boost::shared_ptr<Ports> p = ports.reader ();
1374 for (i = p->begin(); i != p->end(); ++i) {
1375 if (i->second->reestablish ()) {
1380 if (i != p->end()) {
1382 remove_all_ports ();
1386 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1388 MIDI::Manager::instance()->reestablish (_priv_jack);
1391 _session->reset_jack_connection (_priv_jack);
1392 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1393 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1396 last_monitor_check = 0;
1398 set_jack_callbacks ();
1400 if (jack_activate (_priv_jack) == 0) {
1407 /* re-establish connections */
1409 for (i = p->begin(); i != p->end(); ++i) {
1410 i->second->reconnect ();
1413 MIDI::Manager::instance()->reconnect ();
1415 Running (); /* EMIT SIGNAL*/
1417 start_metering_thread ();
1423 AudioEngine::request_buffer_size (pframes_t nframes)
1425 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1427 if (nframes == jack_get_buffer_size (_priv_jack)) {
1431 return jack_set_buffer_size (_priv_jack, nframes);
1435 AudioEngine::make_port_name_relative (string portname) const
1437 string::size_type len;
1438 string::size_type n;
1440 len = portname.length();
1442 for (n = 0; n < len; ++n) {
1443 if (portname[n] == ':') {
1448 if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1449 return portname.substr (n+1);
1456 AudioEngine::make_port_name_non_relative (string portname) const
1460 if (portname.find_first_of (':') != string::npos) {
1464 str = jack_client_name;
1472 AudioEngine::port_is_mine (const string& portname) const
1474 if (portname.find_first_of (':') != string::npos) {
1475 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1483 AudioEngine::is_realtime () const
1485 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1486 return jack_is_realtime (_priv_jack);
1490 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1492 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1493 ThreadData* td = new ThreadData (this, f, stacksize);
1495 if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1496 jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1504 AudioEngine::_start_process_thread (void* arg)
1506 ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1507 boost::function<void()> f = td->f;
1516 AudioEngine::port_is_physical (const std::string& portname) const
1518 GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1520 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1526 return jack_port_flags (port) & JackPortIsPhysical;
1530 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1532 GET_PRIVATE_JACK_POINTER(_jack);
1534 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1540 jack_port_request_monitor (port, yn);
1544 AudioEngine::update_latencies ()
1546 if (jack_recompute_total_latencies) {
1547 GET_PRIVATE_JACK_POINTER (_jack);
1548 jack_recompute_total_latencies (_priv_jack);
1553 AudioEngine::destroy ()