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;
478 if (session_remove_pending) {
479 /* perform the actual session removal */
481 session_remove_pending = false;
483 /* pump one cycle of silence into the ports
484 before the session tears them all down
488 boost::shared_ptr<Ports> p = ports.reader();
490 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
492 if (i->second->sends_output()) {
493 i->second->get_buffer (nframes).silence (nframes);
497 session_removed.signal();
501 if (!_freewheeling) {
502 MIDI::Manager::instance()->cycle_start(nframes);
503 MIDI::Manager::instance()->cycle_end();
506 _processed_frames = next_processed_frames;
511 /* tell all relevant objects that we're starting a new cycle */
513 InternalSend::CycleStart (nframes);
514 Port::set_global_port_buffer_offset (0);
515 Port::set_cycle_framecnt (nframes);
517 /* tell all Ports that we're starting a new cycle */
519 boost::shared_ptr<Ports> p = ports.reader();
521 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
522 i->second->cycle_start (nframes);
525 /* test if we are freewheeling and there are freewheel signals connected.
526 ardour should act normally even when freewheeling unless /it/ is exporting */
529 if (_freewheeling && !Freewheel.empty()) {
530 /* emit the Freewheel signal and stop freewheeling in the event of trouble
532 boost::optional<int> r = Freewheel (nframes);
533 if (r.get_value_or (0)) {
534 jack_set_freewheel (_priv_jack, false);
538 MIDI::Manager::instance()->cycle_start(nframes);
541 _session->process (nframes);
544 MIDI::Manager::instance()->cycle_end();
552 _processed_frames = next_processed_frames;
556 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
558 boost::shared_ptr<Ports> p = ports.reader();
560 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
564 if (i->second->last_monitor() != (x = i->second->jack_monitoring_input ())) {
565 i->second->set_last_monitor (x);
566 /* XXX I think this is dangerous, due to
567 a likely mutex in the signal handlers ...
569 i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
572 last_monitor_check = next_processed_frames;
575 if (_session->silent()) {
577 boost::shared_ptr<Ports> p = ports.reader();
579 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
581 if (i->second->sends_output()) {
582 i->second->get_buffer(nframes).silence(nframes);
589 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
590 i->second->cycle_end (nframes);
593 _processed_frames = next_processed_frames;
601 AudioEngine::_sample_rate_callback (pframes_t nframes, void *arg)
603 return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
607 AudioEngine::jack_sample_rate_callback (pframes_t nframes)
609 _frame_rate = nframes;
610 _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
612 /* check for monitor input change every 1/10th of second */
614 monitor_check_interval = nframes / 10;
615 last_monitor_check = 0;
618 _session->set_frame_rate (nframes);
621 SampleRateChanged (nframes); /* EMIT SIGNAL */
627 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
630 _session->update_latency (mode == JackPlaybackLatency);
635 AudioEngine::_bufsize_callback (pframes_t nframes, void *arg)
637 return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
641 AudioEngine::jack_bufsize_callback (pframes_t nframes)
643 /* if the size has not changed, this should be a no-op */
645 if (nframes == _buffer_size) {
649 GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
651 _buffer_size = nframes;
652 _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
653 last_monitor_check = 0;
655 if (jack_port_type_get_buffer_size) {
656 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
657 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
660 /* Old version of JACK.
662 These crude guesses, see below where we try to get the right answers.
664 Note that our guess for MIDI deliberatey tries to overestimate
665 by a little. It would be nicer if we could get the actual
666 size from a port, but we have to use this estimate in the
667 event that there are no MIDI ports currently. If there are
668 the value will be adjusted below.
671 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
672 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
676 Glib::Mutex::Lock lm (_process_lock);
678 boost::shared_ptr<Ports> p = ports.reader();
680 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
686 _session->set_block_size (_buffer_size);
693 AudioEngine::stop_metering_thread ()
695 if (m_meter_thread) {
696 g_atomic_int_set (&m_meter_exit, 1);
697 m_meter_thread->join ();
703 AudioEngine::start_metering_thread ()
705 if (m_meter_thread == 0) {
706 g_atomic_int_set (&m_meter_exit, 0);
707 m_meter_thread = Glib::Thread::create (boost::bind (&AudioEngine::meter_thread, this),
708 500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
713 AudioEngine::meter_thread ()
715 pthread_set_name (X_("meter"));
718 Glib::usleep (10000); /* 1/100th sec interval */
719 if (g_atomic_int_get(&m_meter_exit)) {
727 AudioEngine::set_session (Session *s)
729 Glib::Mutex::Lock pl (_process_lock);
731 SessionHandlePtr::set_session (s);
735 start_metering_thread ();
737 pframes_t blocksize = jack_get_buffer_size (_jack);
739 /* page in as much of the session process code as we
740 can before we really start running.
743 boost::shared_ptr<Ports> p = ports.reader();
745 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
746 i->second->cycle_start (blocksize);
749 _session->process (blocksize);
750 _session->process (blocksize);
751 _session->process (blocksize);
752 _session->process (blocksize);
753 _session->process (blocksize);
754 _session->process (blocksize);
755 _session->process (blocksize);
756 _session->process (blocksize);
758 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
759 i->second->cycle_end (blocksize);
765 AudioEngine::remove_session ()
767 Glib::Mutex::Lock lm (_process_lock);
771 stop_metering_thread ();
774 session_remove_pending = true;
775 session_removed.wait(_process_lock);
779 SessionHandlePtr::set_session (0);
786 AudioEngine::port_registration_failure (const std::string& portname)
788 GET_PRIVATE_JACK_POINTER (_jack);
789 string full_portname = jack_client_name;
790 full_portname += ':';
791 full_portname += portname;
794 jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
798 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
800 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);
803 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
806 boost::shared_ptr<Port>
807 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
809 boost::shared_ptr<Port> newport;
812 if (dtype == DataType::AUDIO) {
813 newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
814 } else if (dtype == DataType::MIDI) {
815 newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
817 throw PortRegistrationFailure("unable to create port (unknown type)");
820 RCUWriter<Ports> writer (ports);
821 boost::shared_ptr<Ports> ps = writer.get_copy ();
822 ps->insert (make_pair (make_port_name_relative (portname), newport));
824 /* writer goes out of scope, forces update */
829 catch (PortRegistrationFailure& err) {
831 } catch (std::exception& e) {
832 throw PortRegistrationFailure(string_compose(
833 _("unable to create port: %1"), e.what()).c_str());
835 throw PortRegistrationFailure("unable to create port (unknown error)");
839 boost::shared_ptr<Port>
840 AudioEngine::register_input_port (DataType type, const string& portname)
842 return register_port (type, portname, true);
845 boost::shared_ptr<Port>
846 AudioEngine::register_output_port (DataType type, const string& portname)
848 return register_port (type, portname, false);
852 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
854 /* caller must hold process lock */
857 /* probably happening when the engine has been halted by JACK,
858 in which case, there is nothing we can do here.
864 RCUWriter<Ports> writer (ports);
865 boost::shared_ptr<Ports> ps = writer.get_copy ();
866 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
868 if (x != ps->end()) {
872 /* writer goes out of scope, forces update */
881 AudioEngine::connect (const string& source, const string& destination)
887 fatal << _("connect called before engine was started") << endmsg;
894 string s = make_port_name_non_relative (source);
895 string d = make_port_name_non_relative (destination);
898 boost::shared_ptr<Port> src = get_port_by_name (s);
899 boost::shared_ptr<Port> dst = get_port_by_name (d);
902 ret = src->connect (d);
904 ret = dst->connect (s);
906 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
911 /* already exists - no error, no warning */
912 } else if (ret < 0) {
913 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
914 source, s, destination, d)
922 AudioEngine::disconnect (const string& source, const string& destination)
928 fatal << _("disconnect called before engine was started") << endmsg;
935 string s = make_port_name_non_relative (source);
936 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->disconnect (d);
944 ret = dst->disconnect (s);
946 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
953 AudioEngine::disconnect (boost::shared_ptr<Port> port)
955 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
959 fatal << _("disconnect called before engine was started") << endmsg;
966 return port->disconnect_all ();
970 AudioEngine::frame_rate () const
972 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
973 if (_frame_rate == 0) {
974 return (_frame_rate = jack_get_sample_rate (_priv_jack));
981 AudioEngine::raw_buffer_size (DataType t)
983 std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
984 return (s != _raw_buffer_sizes.end()) ? s->second : 0;
988 AudioEngine::frames_per_cycle () const
990 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
991 if (_buffer_size == 0) {
992 return jack_get_buffer_size (_jack);
998 /** @param name Full or short name of port
999 * @return Corresponding Port or 0.
1002 boost::shared_ptr<Port>
1003 AudioEngine::get_port_by_name (const string& portname)
1007 fatal << _("get_port_by_name() called before engine was started") << endmsg;
1010 boost::shared_ptr<Port> ();
1014 if (!port_is_mine (portname)) {
1015 /* not an ardour port */
1016 return boost::shared_ptr<Port> ();
1019 boost::shared_ptr<Ports> pr = ports.reader();
1020 std::string rel = make_port_name_relative (portname);
1021 Ports::iterator x = pr->find (rel);
1023 if (x != pr->end()) {
1024 /* its possible that the port was renamed by some 3rd party and
1025 we don't know about it. check for this (the check is quick
1026 and cheap), and if so, rename the port (which will alter
1027 the port map as a side effect).
1029 const std::string check = make_port_name_relative (jack_port_name (x->second->jack_port()));
1031 x->second->set_name (check);
1036 return boost::shared_ptr<Port> ();
1040 AudioEngine::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
1042 RCUWriter<Ports> writer (ports);
1043 boost::shared_ptr<Ports> p = writer.get_copy();
1044 Ports::iterator x = p->find (old_relative_name);
1046 if (x != p->end()) {
1047 boost::shared_ptr<Port> port = x->second;
1049 p->insert (make_pair (new_relative_name, port));
1054 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1056 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1059 fatal << _("get_ports called before engine was started") << endmsg;
1065 return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1069 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1071 /* called from jack shutdown handler */
1073 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1074 bool was_running = ae->_running;
1076 ae->stop_metering_thread ();
1078 ae->_running = false;
1079 ae->_buffer_size = 0;
1080 ae->_frame_rate = 0;
1084 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1086 case JackBackendError:
1087 ae->Halted(reason); /* EMIT SIGNAL */
1090 ae->Halted(""); /* EMIT SIGNAL */
1093 ae->Halted(""); /* EMIT SIGNAL */
1099 AudioEngine::halted (void *arg)
1101 cerr << "HALTED by JACK\n";
1103 /* called from jack shutdown handler */
1105 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1106 bool was_running = ae->_running;
1108 ae->stop_metering_thread ();
1110 ae->_running = false;
1111 ae->_buffer_size = 0;
1112 ae->_frame_rate = 0;
1116 ae->Halted(""); /* EMIT SIGNAL */
1117 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1122 AudioEngine::died ()
1124 /* called from a signal handler for SIGPIPE */
1126 stop_metering_thread ();
1135 AudioEngine::can_request_hardware_monitoring ()
1137 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1138 const char ** ports;
1140 if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1150 AudioEngine::n_physical (unsigned long flags) const
1154 GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1156 const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1161 for (uint32_t i = 0; ports[i]; ++i) {
1162 if (!strstr (ports[i], "Midi-Through")) {
1163 DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1164 c.set (t, c.get (t) + 1);
1174 AudioEngine::n_physical_inputs () const
1176 return n_physical (JackPortIsInput);
1180 AudioEngine::n_physical_outputs () const
1182 return n_physical (JackPortIsOutput);
1186 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1188 GET_PRIVATE_JACK_POINTER (_jack);
1189 const char ** ports;
1191 if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1196 for (uint32_t i = 0; ports[i]; ++i) {
1197 if (strstr (ports[i], "Midi-Through")) {
1200 phy.push_back (ports[i]);
1206 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1207 * a physical input connector.
1210 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1212 get_physical (type, JackPortIsOutput, ins);
1215 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1216 * a physical output connector.
1219 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1221 get_physical (type, JackPortIsInput, outs);
1225 AudioEngine::transport_stop ()
1227 GET_PRIVATE_JACK_POINTER (_jack);
1228 jack_transport_stop (_priv_jack);
1232 AudioEngine::transport_start ()
1234 GET_PRIVATE_JACK_POINTER (_jack);
1235 jack_transport_start (_priv_jack);
1239 AudioEngine::transport_locate (framepos_t where)
1241 GET_PRIVATE_JACK_POINTER (_jack);
1242 jack_transport_locate (_priv_jack, where);
1245 AudioEngine::TransportState
1246 AudioEngine::transport_state ()
1248 GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1249 jack_position_t pos;
1250 return (TransportState) jack_transport_query (_priv_jack, &pos);
1254 AudioEngine::reset_timebase ()
1256 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1258 if (_session->config.get_jack_time_master()) {
1259 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1261 return jack_release_timebase (_jack);
1268 AudioEngine::freewheel (bool onoff)
1270 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1272 if (onoff != _freewheeling) {
1273 return jack_set_freewheel (_priv_jack, onoff);
1276 /* already doing what has been asked for */
1282 AudioEngine::remove_all_ports ()
1284 /* make sure that JACK callbacks that will be invoked as we cleanup
1285 * ports know that they have nothing to do.
1288 port_remove_in_progress = true;
1290 /* process lock MUST be held by caller
1294 RCUWriter<Ports> writer (ports);
1295 boost::shared_ptr<Ports> ps = writer.get_copy ();
1299 /* clear dead wood list in RCU */
1303 port_remove_in_progress = false;
1307 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1309 EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1310 boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1311 jack_status_t status;
1313 /* revert all environment settings back to whatever they were when ardour started
1317 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1318 global_epa->restore ();
1321 jack_client_name = client_name; /* might be reset below */
1322 #ifdef HAVE_JACK_SESSION
1323 if (! session_uuid.empty())
1324 _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1327 _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1329 if (_jack == NULL) {
1330 // error message is not useful here
1334 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1336 if (status & JackNameNotUnique) {
1337 jack_client_name = jack_get_client_name (_priv_jack);
1344 AudioEngine::disconnect_from_jack ()
1346 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1349 stop_metering_thread ();
1353 Glib::Mutex::Lock lm (_process_lock);
1354 jack_client_close (_priv_jack);
1360 _raw_buffer_sizes.clear();
1364 Stopped(); /* EMIT SIGNAL */
1365 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1372 AudioEngine::reconnect_to_jack ()
1375 disconnect_from_jack ();
1376 /* XXX give jackd a chance */
1377 Glib::usleep (250000);
1380 if (connect_to_jack (jack_client_name, "")) {
1381 error << _("failed to connect to JACK") << endmsg;
1387 boost::shared_ptr<Ports> p = ports.reader ();
1389 for (i = p->begin(); i != p->end(); ++i) {
1390 if (i->second->reestablish ()) {
1395 if (i != p->end()) {
1397 remove_all_ports ();
1401 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1403 MIDI::Manager::instance()->reestablish (_priv_jack);
1406 _session->reset_jack_connection (_priv_jack);
1407 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1408 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1411 last_monitor_check = 0;
1413 set_jack_callbacks ();
1415 if (jack_activate (_priv_jack) == 0) {
1422 /* re-establish connections */
1424 for (i = p->begin(); i != p->end(); ++i) {
1425 i->second->reconnect ();
1428 MIDI::Manager::instance()->reconnect ();
1430 Running (); /* EMIT SIGNAL*/
1432 start_metering_thread ();
1438 AudioEngine::request_buffer_size (pframes_t nframes)
1440 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1442 if (nframes == jack_get_buffer_size (_priv_jack)) {
1446 return jack_set_buffer_size (_priv_jack, nframes);
1450 AudioEngine::make_port_name_relative (string portname) const
1452 string::size_type len;
1453 string::size_type n;
1455 len = portname.length();
1457 for (n = 0; n < len; ++n) {
1458 if (portname[n] == ':') {
1463 if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1464 return portname.substr (n+1);
1471 AudioEngine::make_port_name_non_relative (string portname) const
1475 if (portname.find_first_of (':') != string::npos) {
1479 str = jack_client_name;
1487 AudioEngine::port_is_mine (const string& portname) const
1489 if (portname.find_first_of (':') != string::npos) {
1490 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1498 AudioEngine::is_realtime () const
1500 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1501 return jack_is_realtime (_priv_jack);
1505 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1507 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1508 ThreadData* td = new ThreadData (this, f, stacksize);
1510 if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1511 jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1519 AudioEngine::_start_process_thread (void* arg)
1521 ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1522 boost::function<void()> f = td->f;
1531 AudioEngine::port_is_physical (const std::string& portname) const
1533 GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1535 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1541 return jack_port_flags (port) & JackPortIsPhysical;
1545 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1547 GET_PRIVATE_JACK_POINTER(_jack);
1549 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1555 jack_port_request_monitor (port, yn);
1559 AudioEngine::update_latencies ()
1561 if (jack_recompute_total_latencies) {
1562 GET_PRIVATE_JACK_POINTER (_jack);
1563 jack_recompute_total_latencies (_priv_jack);
1568 AudioEngine::destroy ()