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"));
763 Glib::usleep (10000);
764 if (g_atomic_int_get(&m_meter_exit)) {
772 AudioEngine::set_session (Session *s)
774 Glib::Threads::Mutex::Lock pl (_process_lock);
776 SessionHandlePtr::set_session (s);
780 start_metering_thread ();
782 pframes_t blocksize = jack_get_buffer_size (_jack);
784 /* page in as much of the session process code as we
785 can before we really start running.
788 boost::shared_ptr<Ports> p = ports.reader();
790 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
791 i->second->cycle_start (blocksize);
794 _session->process (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);
803 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
804 i->second->cycle_end (blocksize);
810 AudioEngine::remove_session ()
812 Glib::Threads::Mutex::Lock lm (_process_lock);
816 stop_metering_thread ();
819 session_remove_pending = true;
820 session_removed.wait(_process_lock);
824 SessionHandlePtr::set_session (0);
831 AudioEngine::port_registration_failure (const std::string& portname)
833 GET_PRIVATE_JACK_POINTER (_jack);
834 string full_portname = jack_client_name;
835 full_portname += ':';
836 full_portname += portname;
839 jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
843 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
845 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);
848 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
851 boost::shared_ptr<Port>
852 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
854 boost::shared_ptr<Port> newport;
857 if (dtype == DataType::AUDIO) {
858 newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
859 } else if (dtype == DataType::MIDI) {
860 newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
862 throw PortRegistrationFailure("unable to create port (unknown type)");
865 RCUWriter<Ports> writer (ports);
866 boost::shared_ptr<Ports> ps = writer.get_copy ();
867 ps->insert (make_pair (make_port_name_relative (portname), newport));
869 /* writer goes out of scope, forces update */
874 catch (PortRegistrationFailure& err) {
876 } catch (std::exception& e) {
877 throw PortRegistrationFailure(string_compose(
878 _("unable to create port: %1"), e.what()).c_str());
880 throw PortRegistrationFailure("unable to create port (unknown error)");
884 boost::shared_ptr<Port>
885 AudioEngine::register_input_port (DataType type, const string& portname)
887 return register_port (type, portname, true);
890 boost::shared_ptr<Port>
891 AudioEngine::register_output_port (DataType type, const string& portname)
893 return register_port (type, portname, false);
897 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
899 /* caller must hold process lock */
902 /* probably happening when the engine has been halted by JACK,
903 in which case, there is nothing we can do here.
909 RCUWriter<Ports> writer (ports);
910 boost::shared_ptr<Ports> ps = writer.get_copy ();
911 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
913 if (x != ps->end()) {
917 /* writer goes out of scope, forces update */
926 AudioEngine::connect (const string& source, const string& destination)
932 fatal << _("connect called before engine was started") << endmsg;
939 string s = make_port_name_non_relative (source);
940 string d = make_port_name_non_relative (destination);
943 boost::shared_ptr<Port> src = get_port_by_name (s);
944 boost::shared_ptr<Port> dst = get_port_by_name (d);
947 ret = src->connect (d);
949 ret = dst->connect (s);
951 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
956 /* already exists - no error, no warning */
957 } else if (ret < 0) {
958 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
959 source, s, destination, d)
967 AudioEngine::disconnect (const string& source, const string& destination)
973 fatal << _("disconnect called before engine was started") << endmsg;
980 string s = make_port_name_non_relative (source);
981 string d = make_port_name_non_relative (destination);
983 boost::shared_ptr<Port> src = get_port_by_name (s);
984 boost::shared_ptr<Port> dst = get_port_by_name (d);
987 ret = src->disconnect (d);
989 ret = dst->disconnect (s);
991 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
998 AudioEngine::disconnect (boost::shared_ptr<Port> port)
1000 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1004 fatal << _("disconnect called before engine was started") << endmsg;
1011 return port->disconnect_all ();
1015 AudioEngine::frame_rate () const
1017 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1018 if (_frame_rate == 0) {
1019 return (_frame_rate = jack_get_sample_rate (_priv_jack));
1026 AudioEngine::raw_buffer_size (DataType t)
1028 std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
1029 return (s != _raw_buffer_sizes.end()) ? s->second : 0;
1033 AudioEngine::frames_per_cycle () const
1035 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1036 if (_buffer_size == 0) {
1037 return jack_get_buffer_size (_jack);
1039 return _buffer_size;
1043 /** @param name Full or short name of port
1044 * @return Corresponding Port or 0.
1047 boost::shared_ptr<Port>
1048 AudioEngine::get_port_by_name (const string& portname)
1052 fatal << _("get_port_by_name() called before engine was started") << endmsg;
1055 boost::shared_ptr<Port> ();
1059 if (!port_is_mine (portname)) {
1060 /* not an ardour port */
1061 return boost::shared_ptr<Port> ();
1064 boost::shared_ptr<Ports> pr = ports.reader();
1065 std::string rel = make_port_name_relative (portname);
1066 Ports::iterator x = pr->find (rel);
1068 if (x != pr->end()) {
1069 /* its possible that the port was renamed by some 3rd party and
1070 we don't know about it. check for this (the check is quick
1071 and cheap), and if so, rename the port (which will alter
1072 the port map as a side effect).
1074 const std::string check = make_port_name_relative (jack_port_name (x->second->jack_port()));
1076 x->second->set_name (check);
1081 return boost::shared_ptr<Port> ();
1085 AudioEngine::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
1087 RCUWriter<Ports> writer (ports);
1088 boost::shared_ptr<Ports> p = writer.get_copy();
1089 Ports::iterator x = p->find (old_relative_name);
1091 if (x != p->end()) {
1092 boost::shared_ptr<Port> port = x->second;
1094 p->insert (make_pair (new_relative_name, port));
1099 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1101 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1104 fatal << _("get_ports called before engine was started") << endmsg;
1110 return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1114 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1116 /* called from jack shutdown handler */
1118 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1119 bool was_running = ae->_running;
1121 ae->stop_metering_thread ();
1123 ae->_running = false;
1124 ae->_buffer_size = 0;
1125 ae->_frame_rate = 0;
1129 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1130 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1132 case JackBackendError:
1133 ae->Halted(reason); /* EMIT SIGNAL */
1136 ae->Halted(""); /* EMIT SIGNAL */
1139 ae->Halted(""); /* EMIT SIGNAL */
1145 AudioEngine::halted (void *arg)
1147 cerr << "HALTED by JACK\n";
1149 /* called from jack shutdown handler */
1151 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1152 bool was_running = ae->_running;
1154 ae->stop_metering_thread ();
1156 ae->_running = false;
1157 ae->_buffer_size = 0;
1158 ae->_frame_rate = 0;
1162 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1163 ae->Halted(""); /* EMIT SIGNAL */
1168 AudioEngine::died ()
1170 /* called from a signal handler for SIGPIPE */
1172 stop_metering_thread ();
1181 AudioEngine::can_request_hardware_monitoring ()
1183 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1184 const char ** ports;
1186 if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1196 AudioEngine::n_physical (unsigned long flags) const
1200 GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1202 const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1207 for (uint32_t i = 0; ports[i]; ++i) {
1208 if (!strstr (ports[i], "Midi-Through")) {
1209 DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1210 c.set (t, c.get (t) + 1);
1220 AudioEngine::n_physical_inputs () const
1222 return n_physical (JackPortIsInput);
1226 AudioEngine::n_physical_outputs () const
1228 return n_physical (JackPortIsOutput);
1232 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1234 GET_PRIVATE_JACK_POINTER (_jack);
1235 const char ** ports;
1237 if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1242 for (uint32_t i = 0; ports[i]; ++i) {
1243 if (strstr (ports[i], "Midi-Through")) {
1246 phy.push_back (ports[i]);
1252 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1253 * a physical input connector.
1256 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1258 get_physical (type, JackPortIsOutput, ins);
1261 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1262 * a physical output connector.
1265 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1267 get_physical (type, JackPortIsInput, outs);
1271 AudioEngine::transport_stop ()
1273 GET_PRIVATE_JACK_POINTER (_jack);
1274 jack_transport_stop (_priv_jack);
1278 AudioEngine::transport_start ()
1280 GET_PRIVATE_JACK_POINTER (_jack);
1281 jack_transport_start (_priv_jack);
1285 AudioEngine::transport_locate (framepos_t where)
1287 GET_PRIVATE_JACK_POINTER (_jack);
1288 jack_transport_locate (_priv_jack, where);
1291 AudioEngine::TransportState
1292 AudioEngine::transport_state ()
1294 GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1295 jack_position_t pos;
1296 return (TransportState) jack_transport_query (_priv_jack, &pos);
1300 AudioEngine::reset_timebase ()
1302 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1304 if (_session->config.get_jack_time_master()) {
1305 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1307 return jack_release_timebase (_jack);
1314 AudioEngine::freewheel (bool onoff)
1316 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1318 if (onoff != _freewheeling) {
1319 return jack_set_freewheel (_priv_jack, onoff);
1322 /* already doing what has been asked for */
1328 AudioEngine::remove_all_ports ()
1330 /* make sure that JACK callbacks that will be invoked as we cleanup
1331 * ports know that they have nothing to do.
1334 port_remove_in_progress = true;
1336 /* process lock MUST be held by caller
1340 RCUWriter<Ports> writer (ports);
1341 boost::shared_ptr<Ports> ps = writer.get_copy ();
1345 /* clear dead wood list in RCU */
1349 port_remove_in_progress = false;
1353 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1355 EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1356 boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1357 jack_status_t status;
1359 /* revert all environment settings back to whatever they were when ardour started
1363 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1364 global_epa->restore ();
1367 jack_client_name = client_name; /* might be reset below */
1368 #ifdef HAVE_JACK_SESSION
1369 if (! session_uuid.empty())
1370 _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1373 _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1375 if (_jack == NULL) {
1376 // error message is not useful here
1380 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1382 if (status & JackNameNotUnique) {
1383 jack_client_name = jack_get_client_name (_priv_jack);
1390 AudioEngine::disconnect_from_jack ()
1392 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1395 stop_metering_thread ();
1399 Glib::Threads::Mutex::Lock lm (_process_lock);
1400 jack_client_close (_priv_jack);
1406 _raw_buffer_sizes.clear();
1410 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1411 Stopped(); /* EMIT SIGNAL */
1418 AudioEngine::reconnect_to_jack ()
1421 disconnect_from_jack ();
1422 /* XXX give jackd a chance */
1423 Glib::usleep (250000);
1426 if (connect_to_jack (jack_client_name, "")) {
1427 error << _("failed to connect to JACK") << endmsg;
1433 boost::shared_ptr<Ports> p = ports.reader ();
1435 for (i = p->begin(); i != p->end(); ++i) {
1436 if (i->second->reestablish ()) {
1441 if (i != p->end()) {
1443 remove_all_ports ();
1447 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1449 MIDI::Manager::instance()->reestablish (_priv_jack);
1452 _session->reset_jack_connection (_priv_jack);
1453 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1454 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1457 last_monitor_check = 0;
1459 set_jack_callbacks ();
1461 if (jack_activate (_priv_jack) == 0) {
1468 /* re-establish connections */
1470 for (i = p->begin(); i != p->end(); ++i) {
1471 i->second->reconnect ();
1474 MIDI::Manager::instance()->reconnect ();
1476 Running (); /* EMIT SIGNAL*/
1478 start_metering_thread ();
1484 AudioEngine::request_buffer_size (pframes_t nframes)
1486 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1488 if (nframes == jack_get_buffer_size (_priv_jack)) {
1492 return jack_set_buffer_size (_priv_jack, nframes);
1496 AudioEngine::make_port_name_relative (string portname) const
1498 string::size_type len;
1499 string::size_type n;
1501 len = portname.length();
1503 for (n = 0; n < len; ++n) {
1504 if (portname[n] == ':') {
1509 if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1510 return portname.substr (n+1);
1517 AudioEngine::make_port_name_non_relative (string portname) const
1521 if (portname.find_first_of (':') != string::npos) {
1525 str = jack_client_name;
1533 AudioEngine::port_is_mine (const string& portname) const
1535 if (portname.find_first_of (':') != string::npos) {
1536 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1544 AudioEngine::is_realtime () const
1546 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1547 return jack_is_realtime (_priv_jack);
1551 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1553 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1554 ThreadData* td = new ThreadData (this, f, stacksize);
1556 if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1557 jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1565 AudioEngine::_start_process_thread (void* arg)
1567 ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1568 boost::function<void()> f = td->f;
1577 AudioEngine::port_is_physical (const std::string& portname) const
1579 GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1581 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1587 return jack_port_flags (port) & JackPortIsPhysical;
1591 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1593 GET_PRIVATE_JACK_POINTER(_jack);
1595 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1601 jack_port_request_monitor (port, yn);
1605 AudioEngine::update_latencies ()
1607 if (jack_recompute_total_latencies) {
1608 GET_PRIVATE_JACK_POINTER (_jack);
1609 jack_recompute_total_latencies (_priv_jack);
1614 AudioEngine::destroy ()