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++/mmc.h"
38 #include "midi++/manager.h"
40 #include "ardour/amp.h"
41 #include "ardour/audio_port.h"
42 #include "ardour/audioengine.h"
43 #include "ardour/buffer.h"
44 #include "ardour/buffer_set.h"
45 #include "ardour/cycle_timer.h"
46 #include "ardour/delivery.h"
47 #include "ardour/event_type_map.h"
48 #include "ardour/internal_return.h"
49 #include "ardour/io.h"
50 #include "ardour/meter.h"
51 #include "ardour/midi_port.h"
52 #include "ardour/process_thread.h"
53 #include "ardour/port.h"
54 #include "ardour/port_set.h"
55 #include "ardour/session.h"
56 #include "ardour/timestamps.h"
57 #include "ardour/utils.h"
62 using namespace ARDOUR;
65 gint AudioEngine::m_meter_exit;
66 AudioEngine* AudioEngine::_instance = 0;
68 #define GET_PRIVATE_JACK_POINTER(j) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return; }
69 #define GET_PRIVATE_JACK_POINTER_RET(j,r) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return r; }
71 AudioEngine::AudioEngine (string client_name, string session_uuid)
74 _instance = this; /* singleton */
76 session_remove_pending = false;
79 last_monitor_check = 0;
80 monitor_check_interval = INT32_MAX;
81 _processed_frames = 0;
86 _freewheeling = false;
88 port_remove_in_progress = false;
91 g_atomic_int_set (&m_meter_exit, 0);
93 if (connect_to_jack (client_name, session_uuid)) {
94 throw NoBackendAvailable ();
97 Port::set_engine (this);
100 AudioEngine::~AudioEngine ()
103 Glib::Mutex::Lock tm (_process_lock);
104 session_removed.signal ();
107 jack_client_close (_jack);
111 stop_metering_thread ();
116 AudioEngine::jack() const
122 _thread_init_callback (void * /*arg*/)
124 /* make sure that anybody who needs to know about this thread
128 pthread_set_name (X_("audioengine"));
130 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
131 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
133 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
135 MIDI::Port::set_process_thread (pthread_self());
139 ardour_jack_error (const char* msg)
141 error << "JACK: " << msg << endmsg;
145 AudioEngine::set_jack_callbacks ()
147 GET_PRIVATE_JACK_POINTER (_jack);
149 if (jack_on_info_shutdown) {
150 jack_on_info_shutdown (_priv_jack, halted_info, this);
152 jack_on_shutdown (_priv_jack, halted, this);
155 jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
156 jack_set_process_thread (_priv_jack, _process_thread, this);
157 jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
158 jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
159 jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
160 jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
161 jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
162 jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
163 jack_set_sync_callback (_priv_jack, _jack_sync_callback, this);
164 jack_set_freewheel_callback (_priv_jack, _freewheel_callback, this);
166 if (_session && _session->config.get_jack_time_master()) {
167 jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
170 #ifdef HAVE_JACK_SESSION
171 if( jack_set_session_callback)
172 jack_set_session_callback (_priv_jack, _session_callback, this);
175 if (jack_set_latency_callback) {
176 jack_set_latency_callback (_priv_jack, _latency_callback, this);
179 jack_set_error_function (ardour_jack_error);
183 AudioEngine::start ()
185 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
189 if (!jack_port_type_get_buffer_size) {
190 warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
194 BootMessage (_("Connect session to engine"));
195 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
198 /* a proxy for whether jack_activate() will definitely call the buffer size
199 * callback. with older versions of JACK, this function symbol will be null.
200 * this is reliable, but not clean.
203 if (!jack_port_type_get_buffer_size) {
204 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
207 _processed_frames = 0;
208 last_monitor_check = 0;
210 set_jack_callbacks ();
212 if (jack_activate (_priv_jack) == 0) {
215 Running(); /* EMIT SIGNAL */
217 // error << _("cannot activate JACK client") << endmsg;
221 return _running ? 0 : -1;
225 AudioEngine::stop (bool forever)
227 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
231 disconnect_from_jack ();
233 jack_deactivate (_priv_jack);
234 Stopped(); /* EMIT SIGNAL */
235 MIDI::Port::JackHalted (); /* EMIT SIGNAL */
240 stop_metering_thread ();
243 return _running ? -1 : 0;
248 AudioEngine::get_sync_offset (pframes_t& offset) const
251 #ifdef HAVE_JACK_VIDEO_SUPPORT
253 GET_PRIVATE_JACK_POINTER_RET (_jack, false);
258 (void) jack_transport_query (_priv_jack, &pos);
260 if (pos.valid & JackVideoFrameOffset) {
261 offset = pos.video_offset;
274 AudioEngine::_jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
275 jack_position_t* pos, int new_position, void *arg)
277 static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
281 AudioEngine::jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
282 jack_position_t* pos, int new_position)
284 if (_jack && _session && _session->synced_to_jack()) {
285 _session->jack_timebase_callback (state, nframes, pos, new_position);
290 AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
292 return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
296 AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
298 if (_jack && _session) {
299 return _session->jack_sync_callback (state, pos);
306 AudioEngine::_xrun_callback (void *arg)
308 AudioEngine* ae = static_cast<AudioEngine*> (arg);
309 if (ae->connected()) {
310 ae->Xrun (); /* EMIT SIGNAL */
315 #ifdef HAVE_JACK_SESSION
317 AudioEngine::_session_callback (jack_session_event_t *event, void *arg)
319 printf( "helo.... " );
320 AudioEngine* ae = static_cast<AudioEngine*> (arg);
321 if (ae->connected()) {
322 ae->JackSessionEvent ( event ); /* EMIT SIGNAL */
327 AudioEngine::_graph_order_callback (void *arg)
329 AudioEngine* ae = static_cast<AudioEngine*> (arg);
331 if (ae->connected() && !ae->port_remove_in_progress) {
332 ae->GraphReordered (); /* EMIT SIGNAL */
338 /** Wrapped which is called by JACK as its process callback. It is just
339 * here to get us back into C++ land by calling AudioEngine::process_callback()
340 * @param nframes Number of frames passed by JACK.
341 * @param arg User argument passed by JACK, which will be the AudioEngine*.
344 AudioEngine::_process_callback (pframes_t nframes, void *arg)
346 return static_cast<AudioEngine *> (arg)->process_callback (nframes);
350 AudioEngine::_process_thread (void *arg)
352 return static_cast<AudioEngine *> (arg)->process_thread ();
356 AudioEngine::_freewheel_callback (int onoff, void *arg)
358 static_cast<AudioEngine*>(arg)->_freewheeling = onoff;
362 AudioEngine::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
364 AudioEngine* ae = static_cast<AudioEngine*> (arg);
366 if (!ae->port_remove_in_progress) {
367 ae->PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
372 AudioEngine::_latency_callback (jack_latency_callback_mode_t mode, void* arg)
374 return static_cast<AudioEngine *> (arg)->jack_latency_callback (mode);
378 AudioEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
380 AudioEngine* ae = static_cast<AudioEngine*> (arg);
382 if (ae->port_remove_in_progress) {
386 GET_PRIVATE_JACK_POINTER (ae->_jack);
388 jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
389 jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
391 boost::shared_ptr<Port> port_a;
392 boost::shared_ptr<Port> port_b;
394 boost::shared_ptr<Ports> pr = ae->ports.reader ();
395 Ports::iterator i = pr->begin ();
396 while (i != pr->end() && (port_a == 0 || port_b == 0)) {
397 if (jack_port_a == (*i)->jack_port()) {
399 } else if (jack_port_b == (*i)->jack_port()) {
405 ae->PortConnectedOrDisconnected (
406 port_a, jack_port_name (jack_port_a),
407 port_b, jack_port_name (jack_port_b),
408 conn == 0 ? false : true
413 AudioEngine::split_cycle (pframes_t offset)
415 /* caller must hold process lock */
417 Port::increment_global_port_buffer_offset (offset);
419 /* tell all Ports that we're going to start a new (split) cycle */
421 boost::shared_ptr<Ports> p = ports.reader();
423 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
424 (*i)->cycle_split ();
429 AudioEngine::process_thread ()
431 /* JACK doesn't do this for us when we use the wait API
434 _thread_init_callback (0);
436 _main_thread = new ProcessThread;
439 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
441 pframes_t nframes = jack_cycle_wait (_priv_jack);
443 if (process_callback (nframes)) {
447 jack_cycle_signal (_priv_jack, 0);
453 /** Method called by JACK (via _process_callback) which says that there
454 * is work to be done.
455 * @param nframes Number of frames to process.
458 AudioEngine::process_callback (pframes_t nframes)
460 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
461 // CycleTimer ct ("AudioEngine::process");
462 Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
464 /// The number of frames that will have been processed when we've finished
465 pframes_t next_processed_frames;
467 /* handle wrap around of total frames counter */
469 if (max_framepos - _processed_frames < nframes) {
470 next_processed_frames = nframes - (max_framepos - _processed_frames);
472 next_processed_frames = _processed_frames + nframes;
475 if (!tm.locked() || _session == 0) {
476 /* return having done nothing */
477 _processed_frames = next_processed_frames;
481 if (session_remove_pending) {
482 /* perform the actual session removal */
484 session_remove_pending = false;
485 session_removed.signal();
486 _processed_frames = next_processed_frames;
490 /* tell all relevant objects that we're starting a new cycle */
492 Delivery::CycleStart (nframes);
493 Port::set_global_port_buffer_offset (0);
494 Port::set_cycle_framecnt (nframes);
496 /* tell all Ports that we're starting a new cycle */
498 boost::shared_ptr<Ports> p = ports.reader();
500 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
501 (*i)->cycle_start (nframes);
504 /* test if we are freewheeling and there are freewheel signals connected.
505 ardour should act normally even when freewheeling unless /it/ is exporting */
508 if (_freewheeling && !Freewheel.empty()) {
509 /* emit the Freewheel signal and stop freewheeling in the event of trouble
511 boost::optional<int> r = Freewheel (nframes);
512 if (r.get_value_or (0)) {
513 jack_set_freewheel (_priv_jack, false);
518 _session->process (nframes);
528 _processed_frames = next_processed_frames;
532 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
534 boost::shared_ptr<Ports> p = ports.reader();
536 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
540 if ((*i)->last_monitor() != (x = (*i)->monitoring_input ())) {
541 (*i)->set_last_monitor (x);
542 /* XXX I think this is dangerous, due to
543 a likely mutex in the signal handlers ...
545 (*i)->MonitorInputChanged (x); /* EMIT SIGNAL */
548 last_monitor_check = next_processed_frames;
551 if (_session->silent()) {
553 boost::shared_ptr<Ports> p = ports.reader();
555 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
557 if ((*i)->sends_output()) {
558 (*i)->get_buffer(nframes).silence(nframes);
565 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
566 (*i)->cycle_end (nframes);
569 _processed_frames = next_processed_frames;
574 AudioEngine::_sample_rate_callback (pframes_t nframes, void *arg)
576 return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
580 AudioEngine::jack_sample_rate_callback (pframes_t nframes)
582 _frame_rate = nframes;
583 _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
585 /* check for monitor input change every 1/10th of second */
587 monitor_check_interval = nframes / 10;
588 last_monitor_check = 0;
591 _session->set_frame_rate (nframes);
594 SampleRateChanged (nframes); /* EMIT SIGNAL */
600 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
603 _session->update_latency (mode == JackPlaybackLatency);
608 AudioEngine::_bufsize_callback (pframes_t nframes, void *arg)
610 return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
614 AudioEngine::jack_bufsize_callback (pframes_t nframes)
616 /* if the size has not changed, this should be a no-op */
618 if (nframes == _buffer_size) {
622 GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
624 _buffer_size = nframes;
625 _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
626 last_monitor_check = 0;
628 if (jack_port_type_get_buffer_size) {
629 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
630 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
633 /* Old version of JACK.
635 These crude guesses, see below where we try to get the right answers.
637 Note that our guess for MIDI deliberatey tries to overestimate
638 by a little. It would be nicer if we could get the actual
639 size from a port, but we have to use this estimate in the
640 event that there are no MIDI ports currently. If there are
641 the value will be adjusted below.
644 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
645 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
649 Glib::Mutex::Lock lm (_process_lock);
651 boost::shared_ptr<Ports> p = ports.reader();
653 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
659 _session->set_block_size (_buffer_size);
666 AudioEngine::stop_metering_thread ()
668 if (m_meter_thread) {
669 g_atomic_int_set (&m_meter_exit, 1);
670 m_meter_thread->join ();
676 AudioEngine::start_metering_thread ()
678 if (m_meter_thread == 0) {
679 g_atomic_int_set (&m_meter_exit, 0);
680 m_meter_thread = Glib::Thread::create (boost::bind (&AudioEngine::meter_thread, this),
681 500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
686 AudioEngine::meter_thread ()
688 pthread_set_name (X_("meter"));
691 Glib::usleep (10000); /* 1/100th sec interval */
692 if (g_atomic_int_get(&m_meter_exit)) {
700 AudioEngine::set_session (Session *s)
702 Glib::Mutex::Lock pl (_process_lock);
704 SessionHandlePtr::set_session (s);
708 start_metering_thread ();
710 pframes_t blocksize = jack_get_buffer_size (_jack);
712 /* page in as much of the session process code as we
713 can before we really start running.
716 boost::shared_ptr<Ports> p = ports.reader();
718 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
719 (*i)->cycle_start (blocksize);
722 _session->process (blocksize);
723 _session->process (blocksize);
724 _session->process (blocksize);
725 _session->process (blocksize);
726 _session->process (blocksize);
727 _session->process (blocksize);
728 _session->process (blocksize);
729 _session->process (blocksize);
731 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
732 (*i)->cycle_end (blocksize);
738 AudioEngine::remove_session ()
740 Glib::Mutex::Lock lm (_process_lock);
744 stop_metering_thread ();
747 session_remove_pending = true;
748 session_removed.wait(_process_lock);
752 SessionHandlePtr::set_session (0);
759 AudioEngine::port_registration_failure (const std::string& portname)
761 GET_PRIVATE_JACK_POINTER (_jack);
762 string full_portname = jack_client_name;
763 full_portname += ':';
764 full_portname += portname;
767 jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
771 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
773 reason = string_compose (_("No more JACK ports are available. You will need to stop %1 and restart JACK with ports if you need this many tracks."), PROGRAM_NAME);
776 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
779 boost::shared_ptr<Port>
780 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
782 boost::shared_ptr<Port> newport;
785 if (dtype == DataType::AUDIO) {
786 newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
787 } else if (dtype == DataType::MIDI) {
788 newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
790 throw PortRegistrationFailure("unable to create port (unknown type)");
793 RCUWriter<Ports> writer (ports);
794 boost::shared_ptr<Ports> ps = writer.get_copy ();
795 ps->insert (ps->begin(), newport);
797 /* writer goes out of scope, forces update */
802 catch (PortRegistrationFailure& err) {
804 } catch (std::exception& e) {
805 throw PortRegistrationFailure(string_compose(
806 _("unable to create port: %1"), e.what()).c_str());
808 throw PortRegistrationFailure("unable to create port (unknown error)");
812 boost::shared_ptr<Port>
813 AudioEngine::register_input_port (DataType type, const string& portname)
815 return register_port (type, portname, true);
818 boost::shared_ptr<Port>
819 AudioEngine::register_output_port (DataType type, const string& portname)
821 return register_port (type, portname, false);
825 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
827 /* caller must hold process lock */
830 /* probably happening when the engine has been halted by JACK,
831 in which case, there is nothing we can do here.
837 RCUWriter<Ports> writer (ports);
838 boost::shared_ptr<Ports> ps = writer.get_copy ();
841 /* writer goes out of scope, forces update */
850 AudioEngine::connect (const string& source, const string& destination)
856 fatal << _("connect called before engine was started") << endmsg;
863 string s = make_port_name_non_relative (source);
864 string d = make_port_name_non_relative (destination);
867 boost::shared_ptr<Port> src = get_port_by_name (s);
868 boost::shared_ptr<Port> dst = get_port_by_name (d);
871 ret = src->connect (d);
873 ret = dst->connect (s);
875 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
880 /* already exists - no error, no warning */
881 } else if (ret < 0) {
882 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
883 source, s, destination, d)
891 AudioEngine::disconnect (const string& source, const string& destination)
897 fatal << _("disconnect called before engine was started") << endmsg;
904 string s = make_port_name_non_relative (source);
905 string d = make_port_name_non_relative (destination);
907 boost::shared_ptr<Port> src = get_port_by_name (s);
908 boost::shared_ptr<Port> dst = get_port_by_name (d);
911 ret = src->disconnect (d);
913 ret = dst->disconnect (s);
915 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
922 AudioEngine::disconnect (boost::shared_ptr<Port> port)
924 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
928 fatal << _("disconnect called before engine was started") << endmsg;
935 return port->disconnect_all ();
939 AudioEngine::frame_rate () const
941 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
942 if (_frame_rate == 0) {
943 return (_frame_rate = jack_get_sample_rate (_priv_jack));
950 AudioEngine::raw_buffer_size (DataType t)
952 std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
953 return (s != _raw_buffer_sizes.end()) ? s->second : 0;
957 AudioEngine::frames_per_cycle () const
959 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
960 if (_buffer_size == 0) {
961 return jack_get_buffer_size (_jack);
967 /** @param name Full or short name of port
968 * @return Corresponding Port or 0.
971 boost::shared_ptr<Port>
972 AudioEngine::get_port_by_name (const string& portname)
976 fatal << _("get_port_by_name() called before engine was started") << endmsg;
979 boost::shared_ptr<Port> ();
983 if (!port_is_mine (portname)) {
984 /* not an ardour port */
985 return boost::shared_ptr<Port> ();
988 std::string const rel = make_port_name_relative (portname);
990 boost::shared_ptr<Ports> pr = ports.reader();
992 for (Ports::iterator i = pr->begin(); i != pr->end(); ++i) {
993 if (rel == (*i)->name()) {
998 return boost::shared_ptr<Port> ();
1002 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1004 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1007 fatal << _("get_ports called before engine was started") << endmsg;
1013 return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1017 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1019 /* called from jack shutdown handler */
1021 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1022 bool was_running = ae->_running;
1024 ae->stop_metering_thread ();
1026 ae->_running = false;
1027 ae->_buffer_size = 0;
1028 ae->_frame_rate = 0;
1032 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1034 case JackBackendError:
1035 ae->Halted(reason); /* EMIT SIGNAL */
1038 ae->Halted(""); /* EMIT SIGNAL */
1041 ae->Halted(""); /* EMIT SIGNAL */
1047 AudioEngine::halted (void *arg)
1049 cerr << "HALTED by JACK\n";
1051 /* called from jack shutdown handler */
1053 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1054 bool was_running = ae->_running;
1056 ae->stop_metering_thread ();
1058 ae->_running = false;
1059 ae->_buffer_size = 0;
1060 ae->_frame_rate = 0;
1064 ae->Halted(""); /* EMIT SIGNAL */
1065 MIDI::Port::JackHalted (); /* EMIT SIGNAL */
1070 AudioEngine::died ()
1072 /* called from a signal handler for SIGPIPE */
1074 stop_metering_thread ();
1083 AudioEngine::can_request_hardware_monitoring ()
1085 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1086 const char ** ports;
1088 if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1098 AudioEngine::n_physical (unsigned long flags) const
1102 GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1104 const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1109 for (uint32_t i = 0; ports[i]; ++i) {
1110 if (!strstr (ports[i], "Midi-Through")) {
1111 DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1112 c.set (t, c.get (t) + 1);
1122 AudioEngine::n_physical_inputs () const
1124 return n_physical (JackPortIsInput);
1128 AudioEngine::n_physical_outputs () const
1130 return n_physical (JackPortIsOutput);
1134 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1136 GET_PRIVATE_JACK_POINTER (_jack);
1137 const char ** ports;
1139 if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1144 for (uint32_t i = 0; ports[i]; ++i) {
1145 if (strstr (ports[i], "Midi-Through")) {
1148 phy.push_back (ports[i]);
1154 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1155 * a physical input connector.
1158 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1160 get_physical (type, JackPortIsOutput, ins);
1163 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1164 * a physical output connector.
1167 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1169 get_physical (type, JackPortIsInput, outs);
1173 AudioEngine::transport_stop ()
1175 GET_PRIVATE_JACK_POINTER (_jack);
1176 jack_transport_stop (_priv_jack);
1180 AudioEngine::transport_start ()
1182 GET_PRIVATE_JACK_POINTER (_jack);
1183 jack_transport_start (_priv_jack);
1187 AudioEngine::transport_locate (framepos_t where)
1189 GET_PRIVATE_JACK_POINTER (_jack);
1190 jack_transport_locate (_priv_jack, where);
1193 AudioEngine::TransportState
1194 AudioEngine::transport_state ()
1196 GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1197 jack_position_t pos;
1198 return (TransportState) jack_transport_query (_priv_jack, &pos);
1202 AudioEngine::reset_timebase ()
1204 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1206 if (_session->config.get_jack_time_master()) {
1207 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1209 return jack_release_timebase (_jack);
1216 AudioEngine::freewheel (bool onoff)
1218 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1220 if (onoff != _freewheeling) {
1221 return jack_set_freewheel (_priv_jack, onoff);
1224 /* already doing what has been asked for */
1230 AudioEngine::remove_all_ports ()
1232 /* make sure that JACK callbacks that will be invoked as we cleanup
1233 * ports know that they have nothing to do.
1236 port_remove_in_progress = true;
1238 /* process lock MUST be held by caller
1242 RCUWriter<Ports> writer (ports);
1243 boost::shared_ptr<Ports> ps = writer.get_copy ();
1247 /* clear dead wood list in RCU */
1251 port_remove_in_progress = false;
1255 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1257 EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1258 boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1259 jack_options_t options = JackNullOption;
1260 jack_status_t status;
1261 const char *server_name = NULL;
1263 /* revert all environment settings back to whatever they were when ardour started
1267 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1268 global_epa->restore ();
1271 jack_client_name = client_name; /* might be reset below */
1272 #ifdef HAVE_JACK_SESSION
1273 if (! session_uuid.empty())
1274 _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1277 _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name);
1279 if (_jack == NULL) {
1280 // error message is not useful here
1284 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1286 if (status & JackNameNotUnique) {
1287 jack_client_name = jack_get_client_name (_priv_jack);
1294 AudioEngine::disconnect_from_jack ()
1296 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1299 stop_metering_thread ();
1303 Glib::Mutex::Lock lm (_process_lock);
1304 jack_client_close (_priv_jack);
1310 _raw_buffer_sizes.clear();
1314 Stopped(); /* EMIT SIGNAL */
1315 MIDI::Port::JackHalted (); /* EMIT SIGNAL */
1322 AudioEngine::reconnect_to_jack ()
1325 disconnect_from_jack ();
1326 /* XXX give jackd a chance */
1327 Glib::usleep (250000);
1330 if (connect_to_jack (jack_client_name, "")) {
1331 error << _("failed to connect to JACK") << endmsg;
1337 boost::shared_ptr<Ports> p = ports.reader ();
1339 for (i = p->begin(); i != p->end(); ++i) {
1340 if ((*i)->reestablish ()) {
1345 if (i != p->end()) {
1347 remove_all_ports ();
1351 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1353 MIDI::Manager::instance()->reestablish (_priv_jack);
1356 _session->reset_jack_connection (_priv_jack);
1357 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1358 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1361 last_monitor_check = 0;
1363 set_jack_callbacks ();
1365 if (jack_activate (_priv_jack) == 0) {
1372 /* re-establish connections */
1374 for (i = p->begin(); i != p->end(); ++i) {
1378 MIDI::Manager::instance()->reconnect ();
1380 Running (); /* EMIT SIGNAL*/
1382 start_metering_thread ();
1388 AudioEngine::request_buffer_size (pframes_t nframes)
1390 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1392 if (nframes == jack_get_buffer_size (_priv_jack)) {
1396 return jack_set_buffer_size (_priv_jack, nframes);
1400 AudioEngine::make_port_name_relative (string portname) const
1402 string::size_type len;
1403 string::size_type n;
1405 len = portname.length();
1407 for (n = 0; n < len; ++n) {
1408 if (portname[n] == ':') {
1413 if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1414 return portname.substr (n+1);
1421 AudioEngine::make_port_name_non_relative (string portname) const
1425 if (portname.find_first_of (':') != string::npos) {
1429 str = jack_client_name;
1437 AudioEngine::port_is_mine (const string& portname) const
1439 if (portname.find_first_of (':') != string::npos) {
1440 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1448 AudioEngine::is_realtime () const
1450 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1451 return jack_is_realtime (_priv_jack);
1455 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1457 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1458 ThreadData* td = new ThreadData (this, f, stacksize);
1460 if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1461 jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1469 AudioEngine::_start_process_thread (void* arg)
1471 ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1472 boost::function<void()> f = td->f;
1481 AudioEngine::port_is_physical (const std::string& portname) const
1483 GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1485 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1491 return jack_port_flags (port) & JackPortIsPhysical;
1495 AudioEngine::ensure_monitor_input (const std::string& portname, bool yn) const
1497 GET_PRIVATE_JACK_POINTER(_jack);
1499 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1505 jack_port_request_monitor (port, yn);
1509 AudioEngine::update_latencies ()
1511 if (jack_recompute_total_latencies) {
1512 GET_PRIVATE_JACK_POINTER (_jack);
1513 jack_recompute_total_latencies (_priv_jack);
1518 AudioEngine::destroy ()