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 ()
96 config_connection.disconnect ();
99 Glib::Threads::Mutex::Lock tm (_process_lock);
100 session_removed.signal ();
103 jack_client_close (_jack);
107 stop_metering_thread ();
112 AudioEngine::jack() const
118 _thread_init_callback (void * /*arg*/)
120 /* make sure that anybody who needs to know about this thread
124 pthread_set_name (X_("audioengine"));
126 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
127 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
129 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
131 MIDI::JackMIDIPort::set_process_thread (pthread_self());
135 ardour_jack_error (const char* msg)
137 error << "JACK: " << msg << endmsg;
141 AudioEngine::set_jack_callbacks ()
143 GET_PRIVATE_JACK_POINTER (_jack);
145 if (jack_on_info_shutdown) {
146 jack_on_info_shutdown (_priv_jack, halted_info, this);
148 jack_on_shutdown (_priv_jack, halted, this);
151 jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
152 jack_set_process_thread (_priv_jack, _process_thread, this);
153 jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
154 jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
155 jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
156 jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
157 jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
158 jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
159 jack_set_sync_callback (_priv_jack, _jack_sync_callback, this);
160 jack_set_freewheel_callback (_priv_jack, _freewheel_callback, this);
162 if (_session && _session->config.get_jack_time_master()) {
163 jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
166 #ifdef HAVE_JACK_SESSION
167 if( jack_set_session_callback)
168 jack_set_session_callback (_priv_jack, _session_callback, this);
171 if (jack_set_latency_callback) {
172 jack_set_latency_callback (_priv_jack, _latency_callback, this);
175 jack_set_error_function (ardour_jack_error);
179 AudioEngine::start ()
181 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
185 if (!jack_port_type_get_buffer_size) {
186 warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
190 BootMessage (_("Connect session to engine"));
191 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
194 /* a proxy for whether jack_activate() will definitely call the buffer size
195 * callback. with older versions of JACK, this function symbol will be null.
196 * this is reliable, but not clean.
199 if (!jack_port_type_get_buffer_size) {
200 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
203 _processed_frames = 0;
204 last_monitor_check = 0;
206 set_jack_callbacks ();
208 if (jack_activate (_priv_jack) == 0) {
211 Running(); /* EMIT SIGNAL */
213 // error << _("cannot activate JACK client") << endmsg;
217 return _running ? 0 : -1;
221 AudioEngine::stop (bool forever)
223 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
227 disconnect_from_jack ();
229 jack_deactivate (_priv_jack);
230 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
231 Stopped(); /* EMIT SIGNAL */
236 stop_metering_thread ();
239 return _running ? -1 : 0;
244 AudioEngine::get_sync_offset (pframes_t& offset) const
247 #ifdef HAVE_JACK_VIDEO_SUPPORT
249 GET_PRIVATE_JACK_POINTER_RET (_jack, false);
254 (void) jack_transport_query (_priv_jack, &pos);
256 if (pos.valid & JackVideoFrameOffset) {
257 offset = pos.video_offset;
270 AudioEngine::_jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
271 jack_position_t* pos, int new_position, void *arg)
273 static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
277 AudioEngine::jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
278 jack_position_t* pos, int new_position)
280 if (_jack && _session && _session->synced_to_jack()) {
281 _session->jack_timebase_callback (state, nframes, pos, new_position);
286 AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
288 return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
292 AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
294 if (_jack && _session) {
295 return _session->jack_sync_callback (state, pos);
302 AudioEngine::_xrun_callback (void *arg)
304 AudioEngine* ae = static_cast<AudioEngine*> (arg);
305 if (ae->connected()) {
306 ae->Xrun (); /* EMIT SIGNAL */
311 #ifdef HAVE_JACK_SESSION
313 AudioEngine::_session_callback (jack_session_event_t *event, void *arg)
315 AudioEngine* ae = static_cast<AudioEngine*> (arg);
316 if (ae->connected()) {
317 ae->JackSessionEvent ( event ); /* EMIT SIGNAL */
323 AudioEngine::_graph_order_callback (void *arg)
325 AudioEngine* ae = static_cast<AudioEngine*> (arg);
327 if (ae->connected() && !ae->port_remove_in_progress) {
328 ae->GraphReordered (); /* EMIT SIGNAL */
335 AudioEngine::_process_thread (void *arg)
337 return static_cast<AudioEngine *> (arg)->process_thread ();
341 AudioEngine::_freewheel_callback (int onoff, void *arg)
343 static_cast<AudioEngine*>(arg)->freewheel_callback (onoff);
347 AudioEngine::freewheel_callback (int onoff)
349 _freewheeling = onoff;
352 _pre_freewheel_mmc_enabled = MIDI::Manager::instance()->mmc()->send_enabled ();
353 MIDI::Manager::instance()->mmc()->enable_send (false);
355 MIDI::Manager::instance()->mmc()->enable_send (_pre_freewheel_mmc_enabled);
360 AudioEngine::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
362 AudioEngine* ae = static_cast<AudioEngine*> (arg);
364 if (!ae->port_remove_in_progress) {
365 ae->PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
370 AudioEngine::_latency_callback (jack_latency_callback_mode_t mode, void* arg)
372 return static_cast<AudioEngine *> (arg)->jack_latency_callback (mode);
376 AudioEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
378 AudioEngine* ae = static_cast<AudioEngine*> (arg);
379 ae->connect_callback (id_a, id_b, conn);
383 AudioEngine::connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn)
385 if (port_remove_in_progress) {
389 GET_PRIVATE_JACK_POINTER (_jack);
391 jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
392 jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
394 boost::shared_ptr<Port> port_a;
395 boost::shared_ptr<Port> port_b;
397 boost::shared_ptr<Ports> pr = ports.reader ();
400 x = pr->find (make_port_name_relative (jack_port_name (jack_port_a)));
401 if (x != pr->end()) {
405 x = pr->find (make_port_name_relative (jack_port_name (jack_port_b)));
406 if (x != pr->end()) {
410 PortConnectedOrDisconnected (
411 port_a, jack_port_name (jack_port_a),
412 port_b, jack_port_name (jack_port_b),
413 conn == 0 ? false : true
418 AudioEngine::split_cycle (pframes_t offset)
420 /* caller must hold process lock */
422 Port::increment_global_port_buffer_offset (offset);
424 /* tell all Ports that we're going to start a new (split) cycle */
426 boost::shared_ptr<Ports> p = ports.reader();
428 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
429 i->second->cycle_split ();
434 AudioEngine::process_thread ()
436 /* JACK doesn't do this for us when we use the wait API
439 _thread_init_callback (0);
441 _main_thread = new ProcessThread;
444 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
446 pframes_t nframes = jack_cycle_wait (_priv_jack);
448 if (process_callback (nframes)) {
452 jack_cycle_signal (_priv_jack, 0);
458 /** Method called by our ::process_thread when there is work to be done.
459 * @param nframes Number of frames to process.
462 AudioEngine::process_callback (pframes_t nframes)
464 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
465 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
470 /// The number of frames that will have been processed when we've finished
471 pframes_t next_processed_frames;
473 /* handle wrap around of total frames counter */
475 if (max_framepos - _processed_frames < nframes) {
476 next_processed_frames = nframes - (max_framepos - _processed_frames);
478 next_processed_frames = _processed_frames + nframes;
482 /* return having done nothing */
483 _processed_frames = next_processed_frames;
487 if (session_remove_pending) {
489 /* perform the actual session removal */
491 if (session_removal_countdown < 0) {
493 /* fade out over 1 second */
494 session_removal_countdown = _frame_rate/2;
495 session_removal_gain = 1.0;
496 session_removal_gain_step = 1.0/session_removal_countdown;
498 } else if (session_removal_countdown > 0) {
500 /* we'll be fading audio out.
502 if this is the last time we do this as part
503 of session removal, do a MIDI panic now
504 to get MIDI stopped. This relies on the fact
505 that "immediate data" (aka "out of band data") from
506 MIDI tracks is *appended* after any other data,
507 so that it emerges after any outbound note ons, etc.
510 if (session_removal_countdown <= nframes) {
511 _session->midi_panic ();
517 session_removal_countdown = -1; // reset to "not in progress"
518 session_remove_pending = false;
519 session_removed.signal(); // wakes up thread that initiated session removal
525 if (!_freewheeling) {
526 MIDI::Manager::instance()->cycle_start(nframes);
527 MIDI::Manager::instance()->cycle_end();
530 _processed_frames = next_processed_frames;
535 /* tell all relevant objects that we're starting a new cycle */
537 InternalSend::CycleStart (nframes);
538 Port::set_global_port_buffer_offset (0);
539 Port::set_cycle_framecnt (nframes);
541 /* tell all Ports that we're starting a new cycle */
543 boost::shared_ptr<Ports> p = ports.reader();
545 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
546 i->second->cycle_start (nframes);
549 /* test if we are freewheeling and there are freewheel signals connected.
550 ardour should act normally even when freewheeling unless /it/ is
554 if (_freewheeling && !Freewheel.empty()) {
559 MIDI::Manager::instance()->cycle_start(nframes);
562 _session->process (nframes);
565 MIDI::Manager::instance()->cycle_end();
573 _processed_frames = next_processed_frames;
577 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
579 boost::shared_ptr<Ports> p = ports.reader();
581 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
585 if (i->second->last_monitor() != (x = i->second->jack_monitoring_input ())) {
586 i->second->set_last_monitor (x);
587 /* XXX I think this is dangerous, due to
588 a likely mutex in the signal handlers ...
590 i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
593 last_monitor_check = next_processed_frames;
596 if (_session->silent()) {
598 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
600 if (i->second->sends_output()) {
601 i->second->get_buffer(nframes).silence(nframes);
606 if (session_remove_pending && session_removal_countdown) {
608 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
610 if (i->second->sends_output()) {
612 boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
614 Sample* s = ap->engine_get_whole_audio_buffer ();
615 gain_t g = session_removal_gain;
617 for (pframes_t n = 0; n < nframes; ++n) {
619 g -= session_removal_gain_step;
625 if (session_removal_countdown > nframes) {
626 session_removal_countdown -= nframes;
628 session_removal_countdown = 0;
631 session_removal_gain -= (nframes * session_removal_gain_step);
636 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
637 i->second->cycle_end (nframes);
640 _processed_frames = next_processed_frames;
648 AudioEngine::_sample_rate_callback (pframes_t nframes, void *arg)
650 return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
654 AudioEngine::jack_sample_rate_callback (pframes_t nframes)
656 _frame_rate = nframes;
657 _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
659 /* check for monitor input change every 1/10th of second */
661 monitor_check_interval = nframes / 10;
662 last_monitor_check = 0;
665 _session->set_frame_rate (nframes);
668 SampleRateChanged (nframes); /* EMIT SIGNAL */
674 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
677 _session->update_latency (mode == JackPlaybackLatency);
682 AudioEngine::_bufsize_callback (pframes_t nframes, void *arg)
684 return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
688 AudioEngine::jack_bufsize_callback (pframes_t nframes)
690 /* if the size has not changed, this should be a no-op */
692 if (nframes == _buffer_size) {
696 GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
698 _buffer_size = nframes;
699 _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
700 last_monitor_check = 0;
702 if (jack_port_type_get_buffer_size) {
703 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
704 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
707 /* Old version of JACK.
709 These crude guesses, see below where we try to get the right answers.
711 Note that our guess for MIDI deliberatey tries to overestimate
712 by a little. It would be nicer if we could get the actual
713 size from a port, but we have to use this estimate in the
714 event that there are no MIDI ports currently. If there are
715 the value will be adjusted below.
718 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
719 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
723 Glib::Threads::Mutex::Lock lm (_process_lock);
725 boost::shared_ptr<Ports> p = ports.reader();
727 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
733 _session->set_block_size (_buffer_size);
740 AudioEngine::stop_metering_thread ()
742 if (m_meter_thread) {
743 g_atomic_int_set (&m_meter_exit, 1);
744 m_meter_thread->join ();
750 AudioEngine::start_metering_thread ()
752 if (m_meter_thread == 0) {
753 g_atomic_int_set (&m_meter_exit, 0);
754 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
759 AudioEngine::meter_thread ()
761 pthread_set_name (X_("meter"));
764 Glib::usleep (10000); /* 1/100th sec interval */
765 if (g_atomic_int_get(&m_meter_exit)) {
773 AudioEngine::set_session (Session *s)
775 Glib::Threads::Mutex::Lock pl (_process_lock);
777 SessionHandlePtr::set_session (s);
781 start_metering_thread ();
783 pframes_t blocksize = jack_get_buffer_size (_jack);
785 /* page in as much of the session process code as we
786 can before we really start running.
789 boost::shared_ptr<Ports> p = ports.reader();
791 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
792 i->second->cycle_start (blocksize);
795 _session->process (blocksize);
796 _session->process (blocksize);
797 _session->process (blocksize);
798 _session->process (blocksize);
799 _session->process (blocksize);
800 _session->process (blocksize);
801 _session->process (blocksize);
802 _session->process (blocksize);
804 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
805 i->second->cycle_end (blocksize);
811 AudioEngine::remove_session ()
813 Glib::Threads::Mutex::Lock lm (_process_lock);
817 stop_metering_thread ();
820 session_remove_pending = true;
821 session_removed.wait(_process_lock);
825 SessionHandlePtr::set_session (0);
832 AudioEngine::port_registration_failure (const std::string& portname)
834 GET_PRIVATE_JACK_POINTER (_jack);
835 string full_portname = jack_client_name;
836 full_portname += ':';
837 full_portname += portname;
840 jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
844 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
846 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);
849 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
852 boost::shared_ptr<Port>
853 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
855 boost::shared_ptr<Port> newport;
858 if (dtype == DataType::AUDIO) {
859 newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
860 } else if (dtype == DataType::MIDI) {
861 newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
863 throw PortRegistrationFailure("unable to create port (unknown type)");
866 RCUWriter<Ports> writer (ports);
867 boost::shared_ptr<Ports> ps = writer.get_copy ();
868 ps->insert (make_pair (make_port_name_relative (portname), newport));
870 /* writer goes out of scope, forces update */
875 catch (PortRegistrationFailure& err) {
877 } catch (std::exception& e) {
878 throw PortRegistrationFailure(string_compose(
879 _("unable to create port: %1"), e.what()).c_str());
881 throw PortRegistrationFailure("unable to create port (unknown error)");
885 boost::shared_ptr<Port>
886 AudioEngine::register_input_port (DataType type, const string& portname)
888 return register_port (type, portname, true);
891 boost::shared_ptr<Port>
892 AudioEngine::register_output_port (DataType type, const string& portname)
894 return register_port (type, portname, false);
898 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
900 /* caller must hold process lock */
903 /* probably happening when the engine has been halted by JACK,
904 in which case, there is nothing we can do here.
910 RCUWriter<Ports> writer (ports);
911 boost::shared_ptr<Ports> ps = writer.get_copy ();
912 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
914 if (x != ps->end()) {
918 /* writer goes out of scope, forces update */
927 AudioEngine::connect (const string& source, const string& destination)
933 fatal << _("connect called before engine was started") << endmsg;
940 string s = make_port_name_non_relative (source);
941 string d = make_port_name_non_relative (destination);
944 boost::shared_ptr<Port> src = get_port_by_name (s);
945 boost::shared_ptr<Port> dst = get_port_by_name (d);
948 ret = src->connect (d);
950 ret = dst->connect (s);
952 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
957 /* already exists - no error, no warning */
958 } else if (ret < 0) {
959 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
960 source, s, destination, d)
968 AudioEngine::disconnect (const string& source, const string& destination)
974 fatal << _("disconnect called before engine was started") << endmsg;
981 string s = make_port_name_non_relative (source);
982 string d = make_port_name_non_relative (destination);
984 boost::shared_ptr<Port> src = get_port_by_name (s);
985 boost::shared_ptr<Port> dst = get_port_by_name (d);
988 ret = src->disconnect (d);
990 ret = dst->disconnect (s);
992 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
999 AudioEngine::disconnect (boost::shared_ptr<Port> port)
1001 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1005 fatal << _("disconnect called before engine was started") << endmsg;
1012 return port->disconnect_all ();
1016 AudioEngine::frame_rate () const
1018 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1019 if (_frame_rate == 0) {
1020 return (_frame_rate = jack_get_sample_rate (_priv_jack));
1027 AudioEngine::raw_buffer_size (DataType t)
1029 std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
1030 return (s != _raw_buffer_sizes.end()) ? s->second : 0;
1034 AudioEngine::frames_per_cycle () const
1036 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1037 if (_buffer_size == 0) {
1038 return jack_get_buffer_size (_jack);
1040 return _buffer_size;
1044 /** @param name Full or short name of port
1045 * @return Corresponding Port or 0.
1048 boost::shared_ptr<Port>
1049 AudioEngine::get_port_by_name (const string& portname)
1053 fatal << _("get_port_by_name() called before engine was started") << endmsg;
1056 boost::shared_ptr<Port> ();
1060 if (!port_is_mine (portname)) {
1061 /* not an ardour port */
1062 return boost::shared_ptr<Port> ();
1065 boost::shared_ptr<Ports> pr = ports.reader();
1066 std::string rel = make_port_name_relative (portname);
1067 Ports::iterator x = pr->find (rel);
1069 if (x != pr->end()) {
1070 /* its possible that the port was renamed by some 3rd party and
1071 we don't know about it. check for this (the check is quick
1072 and cheap), and if so, rename the port (which will alter
1073 the port map as a side effect).
1075 const std::string check = make_port_name_relative (jack_port_name (x->second->jack_port()));
1077 x->second->set_name (check);
1082 return boost::shared_ptr<Port> ();
1086 AudioEngine::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
1088 RCUWriter<Ports> writer (ports);
1089 boost::shared_ptr<Ports> p = writer.get_copy();
1090 Ports::iterator x = p->find (old_relative_name);
1092 if (x != p->end()) {
1093 boost::shared_ptr<Port> port = x->second;
1095 p->insert (make_pair (new_relative_name, port));
1100 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1102 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1105 fatal << _("get_ports called before engine was started") << endmsg;
1111 return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1115 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1117 /* called from jack shutdown handler */
1119 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1120 bool was_running = ae->_running;
1122 ae->stop_metering_thread ();
1124 ae->_running = false;
1125 ae->_buffer_size = 0;
1126 ae->_frame_rate = 0;
1130 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1131 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1133 case JackBackendError:
1134 ae->Halted(reason); /* EMIT SIGNAL */
1137 ae->Halted(""); /* EMIT SIGNAL */
1140 ae->Halted(""); /* EMIT SIGNAL */
1146 AudioEngine::halted (void *arg)
1148 cerr << "HALTED by JACK\n";
1150 /* called from jack shutdown handler */
1152 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1153 bool was_running = ae->_running;
1155 ae->stop_metering_thread ();
1157 ae->_running = false;
1158 ae->_buffer_size = 0;
1159 ae->_frame_rate = 0;
1163 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1164 ae->Halted(""); /* EMIT SIGNAL */
1169 AudioEngine::died ()
1171 /* called from a signal handler for SIGPIPE */
1173 stop_metering_thread ();
1182 AudioEngine::can_request_hardware_monitoring ()
1184 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1185 const char ** ports;
1187 if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1197 AudioEngine::n_physical (unsigned long flags) const
1201 GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1203 const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1208 for (uint32_t i = 0; ports[i]; ++i) {
1209 if (!strstr (ports[i], "Midi-Through")) {
1210 DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1211 c.set (t, c.get (t) + 1);
1221 AudioEngine::n_physical_inputs () const
1223 return n_physical (JackPortIsInput);
1227 AudioEngine::n_physical_outputs () const
1229 return n_physical (JackPortIsOutput);
1233 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1235 GET_PRIVATE_JACK_POINTER (_jack);
1236 const char ** ports;
1238 if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1243 for (uint32_t i = 0; ports[i]; ++i) {
1244 if (strstr (ports[i], "Midi-Through")) {
1247 phy.push_back (ports[i]);
1253 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1254 * a physical input connector.
1257 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1259 get_physical (type, JackPortIsOutput, ins);
1262 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1263 * a physical output connector.
1266 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1268 get_physical (type, JackPortIsInput, outs);
1272 AudioEngine::transport_stop ()
1274 GET_PRIVATE_JACK_POINTER (_jack);
1275 jack_transport_stop (_priv_jack);
1279 AudioEngine::transport_start ()
1281 GET_PRIVATE_JACK_POINTER (_jack);
1282 jack_transport_start (_priv_jack);
1286 AudioEngine::transport_locate (framepos_t where)
1288 GET_PRIVATE_JACK_POINTER (_jack);
1289 jack_transport_locate (_priv_jack, where);
1292 AudioEngine::TransportState
1293 AudioEngine::transport_state ()
1295 GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1296 jack_position_t pos;
1297 return (TransportState) jack_transport_query (_priv_jack, &pos);
1301 AudioEngine::reset_timebase ()
1303 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1305 if (_session->config.get_jack_time_master()) {
1306 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1308 return jack_release_timebase (_jack);
1315 AudioEngine::freewheel (bool onoff)
1317 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1319 if (onoff != _freewheeling) {
1320 return jack_set_freewheel (_priv_jack, onoff);
1323 /* already doing what has been asked for */
1329 AudioEngine::remove_all_ports ()
1331 /* make sure that JACK callbacks that will be invoked as we cleanup
1332 * ports know that they have nothing to do.
1335 port_remove_in_progress = true;
1337 /* process lock MUST be held by caller
1341 RCUWriter<Ports> writer (ports);
1342 boost::shared_ptr<Ports> ps = writer.get_copy ();
1346 /* clear dead wood list in RCU */
1350 port_remove_in_progress = false;
1354 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1356 EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1357 boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1358 jack_status_t status;
1360 /* revert all environment settings back to whatever they were when ardour started
1364 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1365 global_epa->restore ();
1368 jack_client_name = client_name; /* might be reset below */
1369 #ifdef HAVE_JACK_SESSION
1370 if (! session_uuid.empty())
1371 _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1374 _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1376 if (_jack == NULL) {
1377 // error message is not useful here
1381 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1383 if (status & JackNameNotUnique) {
1384 jack_client_name = jack_get_client_name (_priv_jack);
1391 AudioEngine::disconnect_from_jack ()
1393 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1396 stop_metering_thread ();
1400 Glib::Threads::Mutex::Lock lm (_process_lock);
1401 jack_client_close (_priv_jack);
1407 _raw_buffer_sizes.clear();
1411 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1412 Stopped(); /* EMIT SIGNAL */
1419 AudioEngine::reconnect_to_jack ()
1422 disconnect_from_jack ();
1423 /* XXX give jackd a chance */
1424 Glib::usleep (250000);
1427 if (connect_to_jack (jack_client_name, "")) {
1428 error << _("failed to connect to JACK") << endmsg;
1434 boost::shared_ptr<Ports> p = ports.reader ();
1436 for (i = p->begin(); i != p->end(); ++i) {
1437 if (i->second->reestablish ()) {
1442 if (i != p->end()) {
1444 remove_all_ports ();
1448 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1450 MIDI::Manager::instance()->reestablish (_priv_jack);
1453 _session->reset_jack_connection (_priv_jack);
1454 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1455 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1458 last_monitor_check = 0;
1460 set_jack_callbacks ();
1462 if (jack_activate (_priv_jack) == 0) {
1469 /* re-establish connections */
1471 for (i = p->begin(); i != p->end(); ++i) {
1472 i->second->reconnect ();
1475 MIDI::Manager::instance()->reconnect ();
1477 Running (); /* EMIT SIGNAL*/
1479 start_metering_thread ();
1485 AudioEngine::request_buffer_size (pframes_t nframes)
1487 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1489 if (nframes == jack_get_buffer_size (_priv_jack)) {
1493 return jack_set_buffer_size (_priv_jack, nframes);
1497 AudioEngine::make_port_name_relative (string portname) const
1499 string::size_type len;
1500 string::size_type n;
1502 len = portname.length();
1504 for (n = 0; n < len; ++n) {
1505 if (portname[n] == ':') {
1510 if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1511 return portname.substr (n+1);
1518 AudioEngine::make_port_name_non_relative (string portname) const
1522 if (portname.find_first_of (':') != string::npos) {
1526 str = jack_client_name;
1534 AudioEngine::port_is_mine (const string& portname) const
1536 if (portname.find_first_of (':') != string::npos) {
1537 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1545 AudioEngine::is_realtime () const
1547 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1548 return jack_is_realtime (_priv_jack);
1552 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1554 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1555 ThreadData* td = new ThreadData (this, f, stacksize);
1557 if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1558 jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1566 AudioEngine::_start_process_thread (void* arg)
1568 ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1569 boost::function<void()> f = td->f;
1578 AudioEngine::port_is_physical (const std::string& portname) const
1580 GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1582 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1588 return jack_port_flags (port) & JackPortIsPhysical;
1592 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1594 GET_PRIVATE_JACK_POINTER(_jack);
1596 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1602 jack_port_request_monitor (port, yn);
1606 AudioEngine::update_latencies ()
1608 if (jack_recompute_total_latencies) {
1609 GET_PRIVATE_JACK_POINTER (_jack);
1610 jack_recompute_total_latencies (_priv_jack);
1615 AudioEngine::destroy ()