cleanup confused mess related to jack_port_type_get_buffer_size()
[ardour2.git] / libs / ardour / audioengine.cc
blob791a5d62a3bf29e234a8d135fdb5390864eca504
1 /*
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.
20 #include <unistd.h>
21 #include <cerrno>
22 #include <vector>
23 #include <exception>
24 #include <stdexcept>
25 #include <sstream>
27 #include <glibmm/timer.h>
28 #include <jack/weakjack.h>
29 #include <jack/jack.h>
30 #include <jack/thread.h>
32 #include "pbd/pthread_utils.h"
33 #include "pbd/stacktrace.h"
34 #include "pbd/unknown_type.h"
35 #include "pbd/epa.h"
37 #include "midi++/port.h"
38 #include "midi++/mmc.h"
39 #include "midi++/manager.h"
41 #include "ardour/amp.h"
42 #include "ardour/audio_port.h"
43 #include "ardour/audioengine.h"
44 #include "ardour/buffer.h"
45 #include "ardour/buffer_set.h"
46 #include "ardour/cycle_timer.h"
47 #include "ardour/delivery.h"
48 #include "ardour/event_type_map.h"
49 #include "ardour/internal_return.h"
50 #include "ardour/io.h"
51 #include "ardour/meter.h"
52 #include "ardour/midi_port.h"
53 #include "ardour/process_thread.h"
54 #include "ardour/port.h"
55 #include "ardour/port_set.h"
56 #include "ardour/session.h"
57 #include "ardour/timestamps.h"
58 #include "ardour/utils.h"
60 #include "i18n.h"
62 using namespace std;
63 using namespace ARDOUR;
64 using namespace PBD;
66 gint AudioEngine::m_meter_exit;
67 AudioEngine* AudioEngine::_instance = 0;
69 #define GET_PRIVATE_JACK_POINTER(j) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return; }
70 #define GET_PRIVATE_JACK_POINTER_RET(j,r) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return r; }
72 AudioEngine::AudioEngine (string client_name, string session_uuid)
73 : ports (new Ports)
75 _instance = this; /* singleton */
77 session_remove_pending = false;
78 _running = false;
79 _has_run = false;
80 last_monitor_check = 0;
81 monitor_check_interval = INT32_MAX;
82 _processed_frames = 0;
83 _usecs_per_cycle = 0;
84 _jack = 0;
85 _frame_rate = 0;
86 _buffer_size = 0;
87 _freewheeling = false;
88 _main_thread = 0;
89 port_remove_in_progress = false;
91 m_meter_thread = 0;
92 g_atomic_int_set (&m_meter_exit, 0);
94 if (connect_to_jack (client_name, session_uuid)) {
95 throw NoBackendAvailable ();
98 Port::set_engine (this);
100 // Initialize parameter metadata (e.g. ranges)
101 Evoral::Parameter p(NullAutomation);
102 p = EventTypeMap::instance().new_parameter(NullAutomation);
103 p = EventTypeMap::instance().new_parameter(GainAutomation);
104 p = EventTypeMap::instance().new_parameter(PanAzimuthAutomation);
105 p = EventTypeMap::instance().new_parameter(PanElevationAutomation);
106 p = EventTypeMap::instance().new_parameter(PanWidthAutomation);
107 p = EventTypeMap::instance().new_parameter(PluginAutomation);
108 p = EventTypeMap::instance().new_parameter(SoloAutomation);
109 p = EventTypeMap::instance().new_parameter(MuteAutomation);
110 p = EventTypeMap::instance().new_parameter(MidiCCAutomation);
111 p = EventTypeMap::instance().new_parameter(MidiPgmChangeAutomation);
112 p = EventTypeMap::instance().new_parameter(MidiPitchBenderAutomation);
113 p = EventTypeMap::instance().new_parameter(MidiChannelPressureAutomation);
114 p = EventTypeMap::instance().new_parameter(FadeInAutomation);
115 p = EventTypeMap::instance().new_parameter(FadeOutAutomation);
116 p = EventTypeMap::instance().new_parameter(EnvelopeAutomation);
117 p = EventTypeMap::instance().new_parameter(MidiCCAutomation);
120 AudioEngine::~AudioEngine ()
123 Glib::Mutex::Lock tm (_process_lock);
124 session_removed.signal ();
126 if (_running) {
127 jack_client_close (_jack);
128 _jack = 0;
131 stop_metering_thread ();
135 jack_client_t*
136 AudioEngine::jack() const
138 return _jack;
141 void
142 _thread_init_callback (void * /*arg*/)
144 /* make sure that anybody who needs to know about this thread
145 knows about it.
148 pthread_set_name (X_("audioengine"));
150 PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
151 PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
153 SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
155 MIDI::Port::set_process_thread (pthread_self());
158 static void
159 ardour_jack_error (const char* msg)
161 error << "JACK: " << msg << endmsg;
164 void
165 AudioEngine::set_jack_callbacks ()
167 GET_PRIVATE_JACK_POINTER (_jack);
169 if (jack_on_info_shutdown) {
170 jack_on_info_shutdown (_priv_jack, halted_info, this);
171 } else {
172 jack_on_shutdown (_priv_jack, halted, this);
175 jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
176 jack_set_process_thread (_priv_jack, _process_thread, this);
177 jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
178 jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
179 jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
180 jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
181 jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
182 jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
183 jack_set_sync_callback (_priv_jack, _jack_sync_callback, this);
184 jack_set_freewheel_callback (_priv_jack, _freewheel_callback, this);
186 if (_session && _session->config.get_jack_time_master()) {
187 jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
190 #ifdef HAVE_JACK_SESSION
191 if( jack_set_session_callback)
192 jack_set_session_callback (_priv_jack, _session_callback, this);
193 #endif
195 if (jack_set_latency_callback) {
196 jack_set_latency_callback (_priv_jack, _latency_callback, this);
199 jack_set_error_function (ardour_jack_error);
203 AudioEngine::start ()
205 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
207 if (!_running) {
209 if (!jack_port_type_get_buffer_size) {
210 warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
213 if (_session) {
214 BootMessage (_("Connect session to engine"));
215 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
218 /* a proxy for whether jack_activate() will definitely call the buffer size
219 * callback. with older versions of JACK, this function symbol will be null.
220 * this is reliable, but not clean.
223 if (!jack_port_type_get_buffer_size) {
224 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
227 _processed_frames = 0;
228 last_monitor_check = 0;
230 set_jack_callbacks ();
232 if (jack_activate (_priv_jack) == 0) {
233 _running = true;
234 _has_run = true;
235 Running(); /* EMIT SIGNAL */
236 } else {
237 // error << _("cannot activate JACK client") << endmsg;
241 return _running ? 0 : -1;
245 AudioEngine::stop (bool forever)
247 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
249 if (_priv_jack) {
250 if (forever) {
251 disconnect_from_jack ();
252 } else {
253 jack_deactivate (_priv_jack);
254 Stopped(); /* EMIT SIGNAL */
255 MIDI::Port::JackHalted (); /* EMIT SIGNAL */
259 if (forever) {
260 stop_metering_thread ();
263 return _running ? -1 : 0;
267 bool
268 AudioEngine::get_sync_offset (pframes_t& offset) const
271 #ifdef HAVE_JACK_VIDEO_SUPPORT
273 GET_PRIVATE_JACK_POINTER_RET (_jack, false);
275 jack_position_t pos;
277 if (_priv_jack) {
278 (void) jack_transport_query (_priv_jack, &pos);
280 if (pos.valid & JackVideoFrameOffset) {
281 offset = pos.video_offset;
282 return true;
285 #else
286 /* keep gcc happy */
287 offset = 0;
288 #endif
290 return false;
293 void
294 AudioEngine::_jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
295 jack_position_t* pos, int new_position, void *arg)
297 static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
300 void
301 AudioEngine::jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
302 jack_position_t* pos, int new_position)
304 if (_jack && _session && _session->synced_to_jack()) {
305 _session->jack_timebase_callback (state, nframes, pos, new_position);
310 AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
312 return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
316 AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
318 if (_jack && _session) {
319 return _session->jack_sync_callback (state, pos);
322 return true;
326 AudioEngine::_xrun_callback (void *arg)
328 AudioEngine* ae = static_cast<AudioEngine*> (arg);
329 if (ae->connected()) {
330 ae->Xrun (); /* EMIT SIGNAL */
332 return 0;
335 #ifdef HAVE_JACK_SESSION
336 void
337 AudioEngine::_session_callback (jack_session_event_t *event, void *arg)
339 printf( "helo.... " );
340 AudioEngine* ae = static_cast<AudioEngine*> (arg);
341 if (ae->connected()) {
342 ae->JackSessionEvent ( event ); /* EMIT SIGNAL */
345 #endif
347 AudioEngine::_graph_order_callback (void *arg)
349 AudioEngine* ae = static_cast<AudioEngine*> (arg);
351 if (ae->connected() && !ae->port_remove_in_progress) {
352 ae->GraphReordered (); /* EMIT SIGNAL */
354 return 0;
357 /** Wrapped which is called by JACK as its process callback. It is just
358 * here to get us back into C++ land by calling AudioEngine::process_callback()
359 * @param nframes Number of frames passed by JACK.
360 * @param arg User argument passed by JACK, which will be the AudioEngine*.
363 AudioEngine::_process_callback (pframes_t nframes, void *arg)
365 return static_cast<AudioEngine *> (arg)->process_callback (nframes);
368 void*
369 AudioEngine::_process_thread (void *arg)
371 return static_cast<AudioEngine *> (arg)->process_thread ();
374 void
375 AudioEngine::_freewheel_callback (int onoff, void *arg)
377 static_cast<AudioEngine*>(arg)->_freewheeling = onoff;
380 void
381 AudioEngine::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
383 AudioEngine* ae = static_cast<AudioEngine*> (arg);
385 if (!ae->port_remove_in_progress) {
386 ae->PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
390 void
391 AudioEngine::_latency_callback (jack_latency_callback_mode_t mode, void* arg)
393 return static_cast<AudioEngine *> (arg)->jack_latency_callback (mode);
396 void
397 AudioEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
399 AudioEngine* ae = static_cast<AudioEngine*> (arg);
401 if (ae->port_remove_in_progress) {
402 return;
405 GET_PRIVATE_JACK_POINTER (ae->_jack);
407 jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
408 jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
410 Port* port_a = 0;
411 Port* port_b = 0;
413 boost::shared_ptr<Ports> pr = ae->ports.reader ();
414 Ports::iterator i = pr->begin ();
415 while (i != pr->end() && (port_a == 0 || port_b == 0)) {
416 if (jack_port_a == (*i)->jack_port()) {
417 port_a = *i;
418 } else if (jack_port_b == (*i)->jack_port()) {
419 port_b = *i;
421 ++i;
424 ae->PortConnectedOrDisconnected (port_a, port_b, conn == 0 ? false : true); /* EMIT SIGNAL */
427 void
428 AudioEngine::split_cycle (pframes_t offset)
430 /* caller must hold process lock */
432 Port::increment_global_port_buffer_offset (offset);
434 /* tell all Ports that we're going to start a new (split) cycle */
436 boost::shared_ptr<Ports> p = ports.reader();
438 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
439 (*i)->cycle_split ();
443 void*
444 AudioEngine::process_thread ()
446 /* JACK doesn't do this for us when we use the wait API
449 _thread_init_callback (0);
451 _main_thread = new ProcessThread;
453 while (1) {
454 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
456 pframes_t nframes = jack_cycle_wait (_priv_jack);
458 if (process_callback (nframes)) {
459 return 0;
462 jack_cycle_signal (_priv_jack, 0);
465 return 0;
468 /** Method called by JACK (via _process_callback) which says that there
469 * is work to be done.
470 * @param nframes Number of frames to process.
473 AudioEngine::process_callback (pframes_t nframes)
475 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
476 // CycleTimer ct ("AudioEngine::process");
477 Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
479 /// The number of frames that will have been processed when we've finished
480 pframes_t next_processed_frames;
482 /* handle wrap around of total frames counter */
484 if (max_framepos - _processed_frames < nframes) {
485 next_processed_frames = nframes - (max_framepos - _processed_frames);
486 } else {
487 next_processed_frames = _processed_frames + nframes;
490 if (!tm.locked() || _session == 0) {
491 /* return having done nothing */
492 _processed_frames = next_processed_frames;
493 return 0;
496 if (session_remove_pending) {
497 /* perform the actual session removal */
498 _session = 0;
499 session_remove_pending = false;
500 session_removed.signal();
501 _processed_frames = next_processed_frames;
502 return 0;
505 /* tell all relevant objects that we're starting a new cycle */
507 Delivery::CycleStart (nframes);
508 Port::set_global_port_buffer_offset (0);
509 Port::set_cycle_framecnt (nframes);
510 InternalReturn::CycleStart (nframes);
512 /* tell all Ports that we're starting a new cycle */
514 boost::shared_ptr<Ports> p = ports.reader();
516 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
517 (*i)->cycle_start (nframes);
520 /* test if we are freewheeling and there are freewheel signals connected.
521 ardour should act normally even when freewheeling unless /it/ is exporting */
524 if (_freewheeling && !Freewheel.empty()) {
525 /* emit the Freewheel signal and stop freewheeling in the event of trouble
527 boost::optional<int> r = Freewheel (nframes);
528 if (r.get_value_or (0)) {
529 jack_set_freewheel (_priv_jack, false);
532 } else {
533 if (_session) {
534 _session->process (nframes);
539 if (_freewheeling) {
540 return 0;
543 if (!_running) {
544 _processed_frames = next_processed_frames;
545 return 0;
548 if (last_monitor_check + monitor_check_interval < next_processed_frames) {
550 boost::shared_ptr<Ports> p = ports.reader();
552 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
554 Port *port = (*i);
555 bool x;
557 if (port->last_monitor() != (x = port->monitoring_input ())) {
558 port->set_last_monitor (x);
559 /* XXX I think this is dangerous, due to
560 a likely mutex in the signal handlers ...
562 port->MonitorInputChanged (x); /* EMIT SIGNAL */
565 last_monitor_check = next_processed_frames;
568 if (_session->silent()) {
570 boost::shared_ptr<Ports> p = ports.reader();
572 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
574 Port *port = (*i);
576 if (port->sends_output()) {
577 port->get_buffer(nframes).silence(nframes);
582 // Finalize ports
584 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
585 (*i)->cycle_end (nframes);
588 _processed_frames = next_processed_frames;
589 return 0;
593 AudioEngine::_sample_rate_callback (pframes_t nframes, void *arg)
595 return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
599 AudioEngine::jack_sample_rate_callback (pframes_t nframes)
601 _frame_rate = nframes;
602 _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
604 /* check for monitor input change every 1/10th of second */
606 monitor_check_interval = nframes / 10;
607 last_monitor_check = 0;
609 if (_session) {
610 _session->set_frame_rate (nframes);
613 SampleRateChanged (nframes); /* EMIT SIGNAL */
615 return 0;
618 void
619 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
621 if (_session) {
622 _session->update_latency (mode == JackPlaybackLatency);
627 AudioEngine::_bufsize_callback (pframes_t nframes, void *arg)
629 return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
633 AudioEngine::jack_bufsize_callback (pframes_t nframes)
635 /* if the size has not changed, this should be a no-op */
637 if (nframes == _buffer_size) {
638 return 0;
641 GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
643 _buffer_size = nframes;
644 _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
645 last_monitor_check = 0;
647 if (jack_port_type_get_buffer_size) {
648 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
649 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
650 } else {
652 /* Old version of JACK.
654 These crude guesses, see below where we try to get the right answers.
656 Note that our guess for MIDI deliberatey tries to overestimate
657 by a little. It would be nicer if we could get the actual
658 size from a port, but we have to use this estimate in the
659 event that there are no MIDI ports currently. If there are
660 the value will be adjusted below.
663 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
664 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
668 Glib::Mutex::Lock lm (_process_lock);
670 boost::shared_ptr<Ports> p = ports.reader();
672 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
673 (*i)->reset();
677 if (_session) {
678 _session->set_block_size (_buffer_size);
681 return 0;
684 void
685 AudioEngine::stop_metering_thread ()
687 if (m_meter_thread) {
688 g_atomic_int_set (&m_meter_exit, 1);
689 m_meter_thread->join ();
690 m_meter_thread = 0;
694 void
695 AudioEngine::start_metering_thread ()
697 if (m_meter_thread == 0) {
698 g_atomic_int_set (&m_meter_exit, 0);
699 m_meter_thread = Glib::Thread::create (boost::bind (&AudioEngine::meter_thread, this),
700 500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
704 void
705 AudioEngine::meter_thread ()
707 pthread_set_name (X_("meter"));
709 while (true) {
710 Glib::usleep (10000); /* 1/100th sec interval */
711 if (g_atomic_int_get(&m_meter_exit)) {
712 break;
714 Metering::Meter ();
718 void
719 AudioEngine::set_session (Session *s)
721 Glib::Mutex::Lock pl (_process_lock);
723 SessionHandlePtr::set_session (s);
725 if (_session) {
727 start_metering_thread ();
729 pframes_t blocksize = jack_get_buffer_size (_jack);
731 /* page in as much of the session process code as we
732 can before we really start running.
735 boost::shared_ptr<Ports> p = ports.reader();
737 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
738 (*i)->cycle_start (blocksize);
741 _session->process (blocksize);
742 _session->process (blocksize);
743 _session->process (blocksize);
744 _session->process (blocksize);
745 _session->process (blocksize);
746 _session->process (blocksize);
747 _session->process (blocksize);
748 _session->process (blocksize);
750 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
751 (*i)->cycle_end (blocksize);
756 void
757 AudioEngine::remove_session ()
759 Glib::Mutex::Lock lm (_process_lock);
761 if (_running) {
763 stop_metering_thread ();
765 if (_session) {
766 session_remove_pending = true;
767 session_removed.wait(_process_lock);
770 } else {
771 SessionHandlePtr::set_session (0);
774 remove_all_ports ();
777 void
778 AudioEngine::port_registration_failure (const std::string& portname)
780 GET_PRIVATE_JACK_POINTER (_jack);
781 string full_portname = jack_client_name;
782 full_portname += ':';
783 full_portname += portname;
786 jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
787 string reason;
789 if (p) {
790 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
791 } else {
792 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);
795 throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
798 Port*
799 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
801 Port* newport;
803 try {
804 if (dtype == DataType::AUDIO) {
805 newport = new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
806 } else if (dtype == DataType::MIDI) {
807 newport = new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
808 } else {
809 throw PortRegistrationFailure("unable to create port (unknown type)");
812 RCUWriter<Ports> writer (ports);
813 boost::shared_ptr<Ports> ps = writer.get_copy ();
814 ps->insert (ps->begin(), newport);
816 /* writer goes out of scope, forces update */
818 return newport;
821 catch (PortRegistrationFailure& err) {
822 throw err;
823 } catch (std::exception& e) {
824 throw PortRegistrationFailure(string_compose(
825 _("unable to create port: %1"), e.what()).c_str());
826 } catch (...) {
827 throw PortRegistrationFailure("unable to create port (unknown error)");
831 Port *
832 AudioEngine::register_input_port (DataType type, const string& portname)
834 return register_port (type, portname, true);
837 Port *
838 AudioEngine::register_output_port (DataType type, const string& portname)
840 return register_port (type, portname, false);
844 AudioEngine::unregister_port (Port& port)
846 /* caller must hold process lock */
848 if (!_running) {
849 /* probably happening when the engine has been halted by JACK,
850 in which case, there is nothing we can do here.
852 return 0;
856 RCUWriter<Ports> writer (ports);
857 boost::shared_ptr<Ports> ps = writer.get_copy ();
859 for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) {
860 if ((*i) == &port) {
861 delete *i;
862 ps->erase (i);
863 break;
867 /* writer goes out of scope, forces update */
870 return 0;
874 AudioEngine::connect (const string& source, const string& destination)
876 int ret;
878 if (!_running) {
879 if (!_has_run) {
880 fatal << _("connect called before engine was started") << endmsg;
881 /*NOTREACHED*/
882 } else {
883 return -1;
887 string s = make_port_name_non_relative (source);
888 string d = make_port_name_non_relative (destination);
891 Port* src = get_port_by_name (s);
892 Port* dst = get_port_by_name (d);
894 if (src) {
895 ret = src->connect (d);
896 } else if (dst) {
897 ret = dst->connect (s);
898 } else {
899 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
900 ret = -1;
903 if (ret > 0) {
904 /* already exists - no error, no warning */
905 } else if (ret < 0) {
906 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
907 source, s, destination, d)
908 << endmsg;
911 return ret;
915 AudioEngine::disconnect (const string& source, const string& destination)
917 int ret;
919 if (!_running) {
920 if (!_has_run) {
921 fatal << _("disconnect called before engine was started") << endmsg;
922 /*NOTREACHED*/
923 } else {
924 return -1;
928 string s = make_port_name_non_relative (source);
929 string d = make_port_name_non_relative (destination);
931 Port* src = get_port_by_name (s);
932 Port* dst = get_port_by_name (d);
934 if (src) {
935 ret = src->disconnect (d);
936 } else if (dst) {
937 ret = dst->disconnect (s);
938 } else {
939 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
940 ret = -1;
942 return ret;
946 AudioEngine::disconnect (Port& port)
948 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
950 if (!_running) {
951 if (!_has_run) {
952 fatal << _("disconnect called before engine was started") << endmsg;
953 /*NOTREACHED*/
954 } else {
955 return -1;
959 return port.disconnect_all ();
962 ARDOUR::framecnt_t
963 AudioEngine::frame_rate () const
965 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
966 if (_frame_rate == 0) {
967 return (_frame_rate = jack_get_sample_rate (_priv_jack));
968 } else {
969 return _frame_rate;
973 size_t
974 AudioEngine::raw_buffer_size (DataType t)
976 std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
977 return (s != _raw_buffer_sizes.end()) ? s->second : 0;
980 ARDOUR::pframes_t
981 AudioEngine::frames_per_cycle () const
983 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
984 if (_buffer_size == 0) {
985 return jack_get_buffer_size (_jack);
986 } else {
987 return _buffer_size;
991 /** @param name Full or short name of port
992 * @return Corresponding Port* or 0. This object remains the property of the AudioEngine
993 * so must not be deleted.
995 Port*
996 AudioEngine::get_port_by_name (const string& portname)
998 if (!_running) {
999 if (!_has_run) {
1000 fatal << _("get_port_by_name() called before engine was started") << endmsg;
1001 /*NOTREACHED*/
1002 } else {
1003 return 0;
1007 if (!port_is_mine (portname)) {
1008 /* not an ardour port */
1009 return 0;
1012 std::string const rel = make_port_name_relative (portname);
1014 boost::shared_ptr<Ports> pr = ports.reader();
1016 for (Ports::iterator i = pr->begin(); i != pr->end(); ++i) {
1017 if (rel == (*i)->name()) {
1018 return *i;
1022 return 0;
1025 const char **
1026 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1028 GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1029 if (!_running) {
1030 if (!_has_run) {
1031 fatal << _("get_ports called before engine was started") << endmsg;
1032 /*NOTREACHED*/
1033 } else {
1034 return 0;
1037 return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1040 void
1041 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1043 /* called from jack shutdown handler */
1045 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1046 bool was_running = ae->_running;
1048 ae->stop_metering_thread ();
1050 ae->_running = false;
1051 ae->_buffer_size = 0;
1052 ae->_frame_rate = 0;
1053 ae->_jack = 0;
1055 if (was_running) {
1056 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1057 switch (code) {
1058 case JackBackendError:
1059 ae->Halted(reason); /* EMIT SIGNAL */
1060 break;
1061 default:
1062 ae->Halted(""); /* EMIT SIGNAL */
1064 #else
1065 ae->Halted(""); /* EMIT SIGNAL */
1066 #endif
1070 void
1071 AudioEngine::halted (void *arg)
1073 cerr << "HALTED by JACK\n";
1075 /* called from jack shutdown handler */
1077 AudioEngine* ae = static_cast<AudioEngine *> (arg);
1078 bool was_running = ae->_running;
1080 ae->stop_metering_thread ();
1082 ae->_running = false;
1083 ae->_buffer_size = 0;
1084 ae->_frame_rate = 0;
1085 ae->_jack = 0;
1087 if (was_running) {
1088 ae->Halted(""); /* EMIT SIGNAL */
1089 MIDI::Port::JackHalted (); /* EMIT SIGNAL */
1093 void
1094 AudioEngine::died ()
1096 /* called from a signal handler for SIGPIPE */
1098 stop_metering_thread ();
1100 _running = false;
1101 _buffer_size = 0;
1102 _frame_rate = 0;
1103 _jack = 0;
1106 bool
1107 AudioEngine::can_request_hardware_monitoring ()
1109 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1110 const char ** ports;
1112 if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1113 return false;
1116 free (ports);
1118 return true;
1121 ChanCount
1122 AudioEngine::n_physical (unsigned long flags) const
1124 ChanCount c;
1126 GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1128 const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1129 if (ports == 0) {
1130 return c;
1133 for (uint32_t i = 0; ports[i]; ++i) {
1134 if (!strstr (ports[i], "Midi-Through")) {
1135 DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1136 c.set (t, c.get (t) + 1);
1140 free (ports);
1142 return c;
1145 ChanCount
1146 AudioEngine::n_physical_inputs () const
1148 return n_physical (JackPortIsInput);
1151 ChanCount
1152 AudioEngine::n_physical_outputs () const
1154 return n_physical (JackPortIsOutput);
1157 void
1158 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1160 GET_PRIVATE_JACK_POINTER (_jack);
1161 const char ** ports;
1163 if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1164 return;
1167 if (ports) {
1168 for (uint32_t i = 0; ports[i]; ++i) {
1169 if (strstr (ports[i], "Midi-Through")) {
1170 continue;
1172 phy.push_back (ports[i]);
1174 free (ports);
1178 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1179 * a physical input connector.
1181 void
1182 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1184 get_physical (type, JackPortIsOutput, ins);
1187 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1188 * a physical output connector.
1190 void
1191 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1193 get_physical (type, JackPortIsInput, outs);
1196 void
1197 AudioEngine::transport_stop ()
1199 GET_PRIVATE_JACK_POINTER (_jack);
1200 jack_transport_stop (_priv_jack);
1203 void
1204 AudioEngine::transport_start ()
1206 GET_PRIVATE_JACK_POINTER (_jack);
1207 jack_transport_start (_priv_jack);
1210 void
1211 AudioEngine::transport_locate (framepos_t where)
1213 GET_PRIVATE_JACK_POINTER (_jack);
1214 jack_transport_locate (_priv_jack, where);
1217 AudioEngine::TransportState
1218 AudioEngine::transport_state ()
1220 GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1221 jack_position_t pos;
1222 return (TransportState) jack_transport_query (_priv_jack, &pos);
1226 AudioEngine::reset_timebase ()
1228 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1229 if (_session) {
1230 if (_session->config.get_jack_time_master()) {
1231 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1232 } else {
1233 return jack_release_timebase (_jack);
1236 return 0;
1240 AudioEngine::freewheel (bool onoff)
1242 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1244 if (onoff != _freewheeling) {
1245 return jack_set_freewheel (_priv_jack, onoff);
1247 } else {
1248 /* already doing what has been asked for */
1249 return 0;
1253 void
1254 AudioEngine::remove_all_ports ()
1256 /* make sure that JACK callbacks that will be invoked as we cleanup
1257 * ports know that they have nothing to do.
1260 port_remove_in_progress = true;
1262 /* process lock MUST be held by caller
1265 vector<Port*> to_be_deleted;
1268 RCUWriter<Ports> writer (ports);
1269 boost::shared_ptr<Ports> ps = writer.get_copy ();
1270 for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) {
1271 to_be_deleted.push_back (*i);
1273 ps->clear ();
1276 /* clear dead wood list in RCU */
1278 ports.flush ();
1280 /* now do the actual deletion, given that "ports" is now empty, thus
1281 preventing anyone else from getting a handle on a Port
1284 for (vector<Port*>::iterator p = to_be_deleted.begin(); p != to_be_deleted.end(); ++p) {
1285 delete *p;
1288 port_remove_in_progress = false;
1292 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1294 EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1295 boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1296 jack_options_t options = JackNullOption;
1297 jack_status_t status;
1298 const char *server_name = NULL;
1300 /* revert all environment settings back to whatever they were when ardour started
1303 if (global_epa) {
1304 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1305 global_epa->restore ();
1308 jack_client_name = client_name; /* might be reset below */
1309 #ifdef HAVE_JACK_SESSION
1310 if (! session_uuid.empty())
1311 _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1312 else
1313 #endif
1314 _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name);
1316 if (_jack == NULL) {
1317 // error message is not useful here
1318 return -1;
1321 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1323 if (status & JackNameNotUnique) {
1324 jack_client_name = jack_get_client_name (_priv_jack);
1327 return 0;
1331 AudioEngine::disconnect_from_jack ()
1333 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1335 if (_running) {
1336 stop_metering_thread ();
1340 Glib::Mutex::Lock lm (_process_lock);
1341 jack_client_close (_priv_jack);
1342 _jack = 0;
1345 _buffer_size = 0;
1346 _frame_rate = 0;
1347 _raw_buffer_sizes.clear();
1349 if (_running) {
1350 _running = false;
1351 Stopped(); /* EMIT SIGNAL */
1352 MIDI::Port::JackHalted (); /* EMIT SIGNAL */
1355 return 0;
1359 AudioEngine::reconnect_to_jack ()
1361 if (_running) {
1362 disconnect_from_jack ();
1363 /* XXX give jackd a chance */
1364 Glib::usleep (250000);
1367 if (connect_to_jack (jack_client_name, "")) {
1368 error << _("failed to connect to JACK") << endmsg;
1369 return -1;
1372 Ports::iterator i;
1374 boost::shared_ptr<Ports> p = ports.reader ();
1376 for (i = p->begin(); i != p->end(); ++i) {
1377 if ((*i)->reestablish ()) {
1378 break;
1382 if (i != p->end()) {
1383 /* failed */
1384 remove_all_ports ();
1385 return -1;
1388 GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1390 MIDI::Manager::instance()->reestablish (_priv_jack);
1392 if (_session) {
1393 _session->reset_jack_connection (_priv_jack);
1394 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1395 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1398 last_monitor_check = 0;
1400 set_jack_callbacks ();
1402 if (jack_activate (_priv_jack) == 0) {
1403 _running = true;
1404 _has_run = true;
1405 } else {
1406 return -1;
1409 /* re-establish connections */
1411 for (i = p->begin(); i != p->end(); ++i) {
1412 (*i)->reconnect ();
1415 MIDI::Manager::instance()->reconnect ();
1417 Running (); /* EMIT SIGNAL*/
1419 start_metering_thread ();
1421 return 0;
1425 AudioEngine::request_buffer_size (pframes_t nframes)
1427 GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1429 if (nframes == jack_get_buffer_size (_priv_jack)) {
1430 return 0;
1433 return jack_set_buffer_size (_priv_jack, nframes);
1436 void
1437 AudioEngine::update_total_latencies ()
1439 GET_PRIVATE_JACK_POINTER (_jack);
1440 jack_recompute_total_latencies (_priv_jack);
1443 string
1444 AudioEngine::make_port_name_relative (string portname) const
1446 string::size_type len;
1447 string::size_type n;
1449 len = portname.length();
1451 for (n = 0; n < len; ++n) {
1452 if (portname[n] == ':') {
1453 break;
1457 if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1458 return portname.substr (n+1);
1461 return portname;
1464 string
1465 AudioEngine::make_port_name_non_relative (string portname) const
1467 string str;
1469 if (portname.find_first_of (':') != string::npos) {
1470 return portname;
1473 str = jack_client_name;
1474 str += ':';
1475 str += portname;
1477 return str;
1480 bool
1481 AudioEngine::port_is_mine (const string& portname) const
1483 if (portname.find_first_of (':') != string::npos) {
1484 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1485 return false;
1488 return true;
1491 bool
1492 AudioEngine::is_realtime () const
1494 GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1495 return jack_is_realtime (_priv_jack);
1499 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1501 GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1502 ThreadData* td = new ThreadData (this, f, stacksize);
1504 if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1505 jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1506 return -1;
1509 return 0;
1512 void*
1513 AudioEngine::_start_process_thread (void* arg)
1515 ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1516 boost::function<void()> f = td->f;
1517 delete td;
1519 f ();
1521 return 0;
1524 bool
1525 AudioEngine::port_is_physical (const std::string& portname) const
1527 GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1529 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1531 if (!port) {
1532 return false;
1535 return jack_port_flags (port) & JackPortIsPhysical;
1538 void
1539 AudioEngine::ensure_monitor_input (const std::string& portname, bool yn) const
1541 GET_PRIVATE_JACK_POINTER(_jack);
1543 jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1545 if (!port) {
1546 return;
1549 jack_port_request_monitor (port, yn);