do not add in ticks in the "at" position when computing BBT duration somewhere on...
[ardour.git] / libs / ardour / audioengine.cc
1 /*
2     Copyright (C) 2002 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #include <unistd.h>
21 #include <cerrno>
22 #include <vector>
23 #include <exception>
24 #include <stdexcept>
25 #include <sstream>
26
27 #include <glibmm/timer.h>
28
29 #include "pbd/pthread_utils.h"
30 #include "pbd/stacktrace.h"
31 #include "pbd/unknown_type.h"
32 #include "pbd/epa.h"
33
34 #include <jack/weakjack.h>
35
36 #include "midi++/port.h"
37 #include "midi++/jack_midi_port.h"
38 #include "midi++/mmc.h"
39 #include "midi++/manager.h"
40
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"
51
52 #include "i18n.h"
53
54 using namespace std;
55 using namespace ARDOUR;
56 using namespace PBD;
57
58 gint AudioEngine::m_meter_exit;
59 AudioEngine* AudioEngine::_instance = 0;
60
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; }
63
64 AudioEngine::AudioEngine (string client_name, string session_uuid)
65         : _jack (0)
66         , session_remove_pending (false)
67         , session_removal_countdown (-1)
68         , _running (false)
69         , _has_run (false)
70         , _buffer_size (0)
71         , _frame_rate (0)
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)
79         , m_meter_thread (0)
80         , _main_thread (0)
81         , ports (new Ports)
82 {
83         _instance = this; /* singleton */
84
85         g_atomic_int_set (&m_meter_exit, 0);
86
87         if (connect_to_jack (client_name, session_uuid)) {
88                 throw NoBackendAvailable ();
89         }
90
91         Port::set_engine (this);
92 }
93
94 AudioEngine::~AudioEngine ()
95 {
96         {
97                 Glib::Threads::Mutex::Lock tm (_process_lock);
98                 session_removed.signal ();
99
100                 if (_running) {
101                         jack_client_close (_jack);
102                         _jack = 0;
103                 }
104
105                 stop_metering_thread ();
106         }
107 }
108
109 jack_client_t*
110 AudioEngine::jack() const
111 {
112         return _jack;
113 }
114
115 void
116 _thread_init_callback (void * /*arg*/)
117 {
118         /* make sure that anybody who needs to know about this thread
119            knows about it.
120         */
121
122         pthread_set_name (X_("audioengine"));
123
124         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
125         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
126
127         SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
128
129         MIDI::JackMIDIPort::set_process_thread (pthread_self());
130 }
131
132 static void
133 ardour_jack_error (const char* msg)
134 {
135         error << "JACK: " << msg << endmsg;
136 }
137
138 void
139 AudioEngine::set_jack_callbacks ()
140 {
141         GET_PRIVATE_JACK_POINTER (_jack);
142
143         if (jack_on_info_shutdown) {
144                 jack_on_info_shutdown (_priv_jack, halted_info, this);
145         } else {
146                 jack_on_shutdown (_priv_jack, halted, this);
147         }
148
149         jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
150         jack_set_process_thread (_priv_jack, _process_thread, this);
151         jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
152         jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
153         jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
154         jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
155         jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
156         jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
157         jack_set_sync_callback (_priv_jack, _jack_sync_callback, this);
158         jack_set_freewheel_callback (_priv_jack, _freewheel_callback, this);
159
160         if (_session && _session->config.get_jack_time_master()) {
161                 jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
162         }
163
164 #ifdef HAVE_JACK_SESSION
165         if( jack_set_session_callback)
166                 jack_set_session_callback (_priv_jack, _session_callback, this);
167 #endif
168
169         if (jack_set_latency_callback) {
170                 jack_set_latency_callback (_priv_jack, _latency_callback, this);
171         }
172
173         jack_set_error_function (ardour_jack_error);
174 }
175
176 int
177 AudioEngine::start ()
178 {
179         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
180
181         if (!_running) {
182
183                 if (!jack_port_type_get_buffer_size) {
184                         warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
185                 }
186
187                 if (_session) {
188                         BootMessage (_("Connect session to engine"));
189                         _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
190                 }
191
192                 /* a proxy for whether jack_activate() will definitely call the buffer size
193                  * callback. with older versions of JACK, this function symbol will be null.
194                  * this is reliable, but not clean.
195                  */
196
197                 if (!jack_port_type_get_buffer_size) {
198                         jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
199                 }
200                 
201                 _processed_frames = 0;
202                 last_monitor_check = 0;
203
204                 set_jack_callbacks ();
205
206                 if (jack_activate (_priv_jack) == 0) {
207                         _running = true;
208                         _has_run = true;
209                         Running(); /* EMIT SIGNAL */
210                 } else {
211                         // error << _("cannot activate JACK client") << endmsg;
212                 }
213         }
214                 
215         return _running ? 0 : -1;
216 }
217
218 int
219 AudioEngine::stop (bool forever)
220 {
221         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
222
223         if (_priv_jack) {
224                 if (forever) {
225                         disconnect_from_jack ();
226                 } else {
227                         jack_deactivate (_priv_jack);
228                         Stopped(); /* EMIT SIGNAL */
229                         MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
230                 }
231         }
232
233         if (forever) {
234                 stop_metering_thread ();
235         }
236
237         return _running ? -1 : 0;
238 }
239
240
241 bool
242 AudioEngine::get_sync_offset (pframes_t& offset) const
243 {
244
245 #ifdef HAVE_JACK_VIDEO_SUPPORT
246
247         GET_PRIVATE_JACK_POINTER_RET (_jack, false);
248
249         jack_position_t pos;
250
251         if (_priv_jack) {
252                 (void) jack_transport_query (_priv_jack, &pos);
253
254                 if (pos.valid & JackVideoFrameOffset) {
255                         offset = pos.video_offset;
256                         return true;
257                 }
258         }
259 #else
260         /* keep gcc happy */
261         offset = 0;
262 #endif
263
264         return false;
265 }
266
267 void
268 AudioEngine::_jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
269                                       jack_position_t* pos, int new_position, void *arg)
270 {
271         static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
272 }
273
274 void
275 AudioEngine::jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
276                                      jack_position_t* pos, int new_position)
277 {
278         if (_jack && _session && _session->synced_to_jack()) {
279                 _session->jack_timebase_callback (state, nframes, pos, new_position);
280         }
281 }
282
283 int
284 AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
285 {
286         return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
287 }
288
289 int
290 AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
291 {
292         if (_jack && _session) {
293                 return _session->jack_sync_callback (state, pos);
294         }
295
296         return true;
297 }
298
299 int
300 AudioEngine::_xrun_callback (void *arg)
301 {
302         AudioEngine* ae = static_cast<AudioEngine*> (arg);
303         if (ae->connected()) {
304                 ae->Xrun (); /* EMIT SIGNAL */
305         }
306         return 0;
307 }
308
309 #ifdef HAVE_JACK_SESSION
310 void
311 AudioEngine::_session_callback (jack_session_event_t *event, void *arg)
312 {
313         AudioEngine* ae = static_cast<AudioEngine*> (arg);
314         if (ae->connected()) {
315                 ae->JackSessionEvent ( event ); /* EMIT SIGNAL */
316         }
317 }
318 #endif
319
320 int
321 AudioEngine::_graph_order_callback (void *arg)
322 {
323         AudioEngine* ae = static_cast<AudioEngine*> (arg);
324
325         if (ae->connected() && !ae->port_remove_in_progress) {
326                 ae->GraphReordered (); /* EMIT SIGNAL */
327         }
328         
329         return 0;
330 }
331
332 void*
333 AudioEngine::_process_thread (void *arg)
334 {
335         return static_cast<AudioEngine *> (arg)->process_thread ();
336 }
337
338 void
339 AudioEngine::_freewheel_callback (int onoff, void *arg)
340 {
341         static_cast<AudioEngine*>(arg)->freewheel_callback (onoff);
342 }
343
344 void
345 AudioEngine::freewheel_callback (int onoff)
346 {
347         _freewheeling = onoff;
348
349         if (onoff) {
350                 _pre_freewheel_mmc_enabled = MIDI::Manager::instance()->mmc()->send_enabled ();
351                 MIDI::Manager::instance()->mmc()->enable_send (false);
352         } else {
353                 MIDI::Manager::instance()->mmc()->enable_send (_pre_freewheel_mmc_enabled);
354         }
355 }
356
357 void
358 AudioEngine::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
359 {
360         AudioEngine* ae = static_cast<AudioEngine*> (arg);
361
362         if (!ae->port_remove_in_progress) {
363                 ae->PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
364         }
365 }
366
367 void
368 AudioEngine::_latency_callback (jack_latency_callback_mode_t mode, void* arg)
369 {
370         return static_cast<AudioEngine *> (arg)->jack_latency_callback (mode);
371 }
372
373 void
374 AudioEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
375 {
376         AudioEngine* ae = static_cast<AudioEngine*> (arg);
377
378         if (ae->port_remove_in_progress) {
379                 return;
380         }
381
382         GET_PRIVATE_JACK_POINTER (ae->_jack);
383
384         jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
385         jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
386
387         boost::shared_ptr<Port> port_a;
388         boost::shared_ptr<Port> port_b;
389
390         boost::shared_ptr<Ports> pr = ae->ports.reader ();
391         Ports::iterator i = pr->begin ();
392         while (i != pr->end() && (port_a == 0 || port_b == 0)) {
393                 if (jack_port_a == i->second->jack_port()) {
394                         port_a = i->second;
395                 } else if (jack_port_b == i->second->jack_port()) {
396                         port_b = i->second;
397                 }
398                 ++i;
399         }
400
401         ae->PortConnectedOrDisconnected (
402                 port_a, jack_port_name (jack_port_a),
403                 port_b, jack_port_name (jack_port_b),
404                 conn == 0 ? false : true
405                 ); /* EMIT SIGNAL */
406 }
407
408 void
409 AudioEngine::split_cycle (pframes_t offset)
410 {
411         /* caller must hold process lock */
412
413         Port::increment_global_port_buffer_offset (offset);
414
415         /* tell all Ports that we're going to start a new (split) cycle */
416
417         boost::shared_ptr<Ports> p = ports.reader();
418
419         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
420                 i->second->cycle_split ();
421         }
422 }
423
424 void*
425 AudioEngine::process_thread ()
426 {
427         /* JACK doesn't do this for us when we use the wait API
428          */
429
430         _thread_init_callback (0);
431
432         _main_thread = new ProcessThread;
433
434         while (1) {
435                 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
436
437                 pframes_t nframes = jack_cycle_wait (_priv_jack);
438
439                 if (process_callback (nframes)) {
440                         return 0;
441                 }
442
443                 jack_cycle_signal (_priv_jack, 0);
444         }
445
446         return 0;
447 }
448
449 /** Method called by our ::process_thread when there is work to be done.
450  *  @param nframes Number of frames to process.
451  */
452 int
453 AudioEngine::process_callback (pframes_t nframes)
454 {
455         GET_PRIVATE_JACK_POINTER_RET(_jack,0);
456         Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
457
458         PT_TIMING_REF;
459         PT_TIMING_CHECK (1);
460
461         /// The number of frames that will have been processed when we've finished
462         pframes_t next_processed_frames;
463
464         /* handle wrap around of total frames counter */
465
466         if (max_framepos - _processed_frames < nframes) {
467                 next_processed_frames = nframes - (max_framepos - _processed_frames);
468         } else {
469                 next_processed_frames = _processed_frames + nframes;
470         }
471
472         if (!tm.locked()) {
473                 /* return having done nothing */
474                 _processed_frames = next_processed_frames;
475                 return 0;
476         }
477
478         if (session_remove_pending) {
479
480                 /* perform the actual session removal */
481
482                 if (session_removal_countdown < 0) {
483
484                         /* fade out over 1 second */
485                         session_removal_countdown = _frame_rate/2;
486                         session_removal_gain = 1.0;
487                         session_removal_gain_step = 1.0/session_removal_countdown;
488
489                 } else if (session_removal_countdown > 0) {
490
491                         /* we'll be fading audio out.
492                            
493                            if this is the last time we do this as part 
494                            of session removal, do a MIDI panic now
495                            to get MIDI stopped. This relies on the fact
496                            that "immediate data" (aka "out of band data") from
497                            MIDI tracks is *appended* after any other data, 
498                            so that it emerges after any outbound note ons, etc.
499                         */
500
501                         if (session_removal_countdown <= nframes) {
502                                 _session->midi_panic ();
503                         }
504
505                 } else {
506                         /* fade out done */
507                         _session = 0;
508                         session_removal_countdown = -1; // reset to "not in progress"
509                         session_remove_pending = false;
510                         session_removed.signal(); // wakes up thread that initiated session removal
511                 }
512         }
513
514         if (_session == 0) {
515
516                 if (!_freewheeling) {
517                         MIDI::Manager::instance()->cycle_start(nframes);
518                         MIDI::Manager::instance()->cycle_end();
519                 }
520
521                 _processed_frames = next_processed_frames;
522
523                 return 0;
524         }
525
526         /* tell all relevant objects that we're starting a new cycle */
527
528         InternalSend::CycleStart (nframes);
529         Port::set_global_port_buffer_offset (0);
530         Port::set_cycle_framecnt (nframes);
531
532         /* tell all Ports that we're starting a new cycle */
533
534         boost::shared_ptr<Ports> p = ports.reader();
535
536         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
537                 i->second->cycle_start (nframes);
538         }
539
540         /* test if we are freewheeling and there are freewheel signals connected.
541            ardour should act normally even when freewheeling unless /it/ is exporting */
542
543
544         if (_freewheeling && !Freewheel.empty()) {
545                 /* emit the Freewheel signal and stop freewheeling in the event of trouble
546                  */
547                 boost::optional<int> r = Freewheel (nframes);
548                 if (r.get_value_or (0)) {
549                         jack_set_freewheel (_priv_jack, false);
550                 }
551
552         } else {
553                 MIDI::Manager::instance()->cycle_start(nframes);
554
555                 if (_session) {
556                         _session->process (nframes);
557                 }
558
559                 MIDI::Manager::instance()->cycle_end();
560         }
561
562         if (_freewheeling) {
563                 return 0;
564         }
565
566         if (!_running) {
567                 _processed_frames = next_processed_frames;
568                 return 0;
569         }
570
571         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
572
573                 boost::shared_ptr<Ports> p = ports.reader();
574
575                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
576
577                         bool x;
578
579                         if (i->second->last_monitor() != (x = i->second->jack_monitoring_input ())) {
580                                 i->second->set_last_monitor (x);
581                                 /* XXX I think this is dangerous, due to
582                                    a likely mutex in the signal handlers ...
583                                 */
584                                 i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
585                         }
586                 }
587                 last_monitor_check = next_processed_frames;
588         }
589
590         if (_session->silent()) {
591
592                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
593
594                         if (i->second->sends_output()) {
595                                 i->second->get_buffer(nframes).silence(nframes);
596                         }
597                 }
598         }
599
600         if (session_remove_pending && session_removal_countdown) {
601
602                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
603
604                         if (i->second->sends_output()) {
605
606                                 boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
607                                 if (ap) {
608                                         Sample* s = ap->engine_get_whole_audio_buffer ();
609                                         gain_t g = session_removal_gain;
610                                         
611                                         for (pframes_t n = 0; n < nframes; ++n) {
612                                                 *s++ *= g;
613                                                 g -= session_removal_gain_step;
614                                         }
615                                 }
616                         }
617                 }
618                 
619                 if (session_removal_countdown > nframes) {
620                         session_removal_countdown -= nframes;
621                 } else {
622                         session_removal_countdown = 0;
623                 }
624
625                 session_removal_gain -= (nframes * session_removal_gain_step);
626         }
627
628         // Finalize ports
629
630         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
631                 i->second->cycle_end (nframes);
632         }
633
634         _processed_frames = next_processed_frames;
635
636         PT_TIMING_CHECK (2);
637         
638         return 0;
639 }
640
641 int
642 AudioEngine::_sample_rate_callback (pframes_t nframes, void *arg)
643 {
644         return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
645 }
646
647 int
648 AudioEngine::jack_sample_rate_callback (pframes_t nframes)
649 {
650         _frame_rate = nframes;
651         _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
652
653         /* check for monitor input change every 1/10th of second */
654
655         monitor_check_interval = nframes / 10;
656         last_monitor_check = 0;
657
658         if (_session) {
659                 _session->set_frame_rate (nframes);
660         }
661
662         SampleRateChanged (nframes); /* EMIT SIGNAL */
663
664         return 0;
665 }
666
667 void
668 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
669 {
670         if (_session) {
671                 _session->update_latency (mode == JackPlaybackLatency);
672         }
673 }
674
675 int
676 AudioEngine::_bufsize_callback (pframes_t nframes, void *arg)
677 {
678         return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
679 }
680
681 int
682 AudioEngine::jack_bufsize_callback (pframes_t nframes)
683 {
684         /* if the size has not changed, this should be a no-op */
685
686         if (nframes == _buffer_size) {
687                 return 0;
688         }
689
690         GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
691
692         _buffer_size = nframes;
693         _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
694         last_monitor_check = 0;
695
696         if (jack_port_type_get_buffer_size) {
697                 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
698                 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
699         } else {
700
701                 /* Old version of JACK.
702
703                    These crude guesses, see below where we try to get the right answers.
704
705                    Note that our guess for MIDI deliberatey tries to overestimate
706                    by a little. It would be nicer if we could get the actual
707                    size from a port, but we have to use this estimate in the
708                    event that there are no MIDI ports currently. If there are
709                    the value will be adjusted below.
710                 */
711
712                 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
713                 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
714         }
715
716         {
717                 Glib::Threads::Mutex::Lock lm (_process_lock);
718
719                 boost::shared_ptr<Ports> p = ports.reader();
720
721                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
722                         i->second->reset();
723                 }
724         }
725
726         if (_session) {
727                 _session->set_block_size (_buffer_size);
728         }
729
730         return 0;
731 }
732
733 void
734 AudioEngine::stop_metering_thread ()
735 {
736         if (m_meter_thread) {
737                 g_atomic_int_set (&m_meter_exit, 1);
738                 m_meter_thread->join ();
739                 m_meter_thread = 0;
740         }
741 }
742
743 void
744 AudioEngine::start_metering_thread ()
745 {
746         if (m_meter_thread == 0) {
747                 g_atomic_int_set (&m_meter_exit, 0);
748                 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
749         }
750 }
751
752 void
753 AudioEngine::meter_thread ()
754 {
755         pthread_set_name (X_("meter"));
756
757         while (true) {
758                 Glib::usleep (10000); /* 1/100th sec interval */
759                 if (g_atomic_int_get(&m_meter_exit)) {
760                         break;
761                 }
762                 Metering::Meter ();
763         }
764 }
765
766 void
767 AudioEngine::set_session (Session *s)
768 {
769         Glib::Threads::Mutex::Lock pl (_process_lock);
770
771         SessionHandlePtr::set_session (s);
772
773         if (_session) {
774
775                 start_metering_thread ();
776
777                 pframes_t blocksize = jack_get_buffer_size (_jack);
778
779                 /* page in as much of the session process code as we
780                    can before we really start running.
781                 */
782
783                 boost::shared_ptr<Ports> p = ports.reader();
784
785                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
786                         i->second->cycle_start (blocksize);
787                 }
788
789                 _session->process (blocksize);
790                 _session->process (blocksize);
791                 _session->process (blocksize);
792                 _session->process (blocksize);
793                 _session->process (blocksize);
794                 _session->process (blocksize);
795                 _session->process (blocksize);
796                 _session->process (blocksize);
797
798                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
799                         i->second->cycle_end (blocksize);
800                 }
801         }
802 }
803
804 void
805 AudioEngine::remove_session ()
806 {
807         Glib::Threads::Mutex::Lock lm (_process_lock);
808
809         if (_running) {
810
811                 stop_metering_thread ();
812
813                 if (_session) {
814                         session_remove_pending = true;
815                         session_removed.wait(_process_lock);
816                 }
817
818         } else {
819                 SessionHandlePtr::set_session (0);
820         }
821
822         remove_all_ports ();
823 }
824
825 void
826 AudioEngine::port_registration_failure (const std::string& portname)
827 {
828         GET_PRIVATE_JACK_POINTER (_jack);
829         string full_portname = jack_client_name;
830         full_portname += ':';
831         full_portname += portname;
832
833
834         jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
835         string reason;
836
837         if (p) {
838                 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
839         } else {
840                 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);
841         }
842
843         throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
844 }
845
846 boost::shared_ptr<Port>
847 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
848 {
849         boost::shared_ptr<Port> newport;
850
851         try {
852                 if (dtype == DataType::AUDIO) {
853                         newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
854                 } else if (dtype == DataType::MIDI) {
855                         newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
856                 } else {
857                         throw PortRegistrationFailure("unable to create port (unknown type)");
858                 }
859
860                 RCUWriter<Ports> writer (ports);
861                 boost::shared_ptr<Ports> ps = writer.get_copy ();
862                 ps->insert (make_pair (make_port_name_relative (portname), newport));
863
864                 /* writer goes out of scope, forces update */
865
866                 return newport;
867         }
868
869         catch (PortRegistrationFailure& err) {
870                 throw err;
871         } catch (std::exception& e) {
872                 throw PortRegistrationFailure(string_compose(
873                                 _("unable to create port: %1"), e.what()).c_str());
874         } catch (...) {
875                 throw PortRegistrationFailure("unable to create port (unknown error)");
876         }
877 }
878
879 boost::shared_ptr<Port>
880 AudioEngine::register_input_port (DataType type, const string& portname)
881 {
882         return register_port (type, portname, true);
883 }
884
885 boost::shared_ptr<Port>
886 AudioEngine::register_output_port (DataType type, const string& portname)
887 {
888         return register_port (type, portname, false);
889 }
890
891 int
892 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
893 {
894         /* caller must hold process lock */
895
896         if (!_running) {
897                 /* probably happening when the engine has been halted by JACK,
898                    in which case, there is nothing we can do here.
899                    */
900                 return 0;
901         }
902
903         {
904                 RCUWriter<Ports> writer (ports);
905                 boost::shared_ptr<Ports> ps = writer.get_copy ();
906                 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
907
908                 if (x != ps->end()) {
909                         ps->erase (x);
910                 }
911
912                 /* writer goes out of scope, forces update */
913         }
914
915         ports.flush ();
916
917         return 0;
918 }
919
920 int
921 AudioEngine::connect (const string& source, const string& destination)
922 {
923         int ret;
924
925         if (!_running) {
926                 if (!_has_run) {
927                         fatal << _("connect called before engine was started") << endmsg;
928                         /*NOTREACHED*/
929                 } else {
930                         return -1;
931                 }
932         }
933
934         string s = make_port_name_non_relative (source);
935         string d = make_port_name_non_relative (destination);
936
937
938         boost::shared_ptr<Port> src = get_port_by_name (s);
939         boost::shared_ptr<Port> dst = get_port_by_name (d);
940
941         if (src) {
942                 ret = src->connect (d);
943         } else if (dst) {
944                 ret = dst->connect (s);
945         } else {
946                 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
947                 ret = -1;
948         }
949
950         if (ret > 0) {
951                 /* already exists - no error, no warning */
952         } else if (ret < 0) {
953                 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
954                                         source, s, destination, d)
955                       << endmsg;
956         }
957
958         return ret;
959 }
960
961 int
962 AudioEngine::disconnect (const string& source, const string& destination)
963 {
964         int ret;
965
966         if (!_running) {
967                 if (!_has_run) {
968                         fatal << _("disconnect called before engine was started") << endmsg;
969                         /*NOTREACHED*/
970                 } else {
971                         return -1;
972                 }
973         }
974
975         string s = make_port_name_non_relative (source);
976         string d = make_port_name_non_relative (destination);
977
978         boost::shared_ptr<Port> src = get_port_by_name (s);
979         boost::shared_ptr<Port> dst = get_port_by_name (d);
980
981         if (src) {
982                         ret = src->disconnect (d);
983         } else if (dst) {
984                         ret = dst->disconnect (s);
985         } else {
986                 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
987                 ret = -1;
988         }
989         return ret;
990 }
991
992 int
993 AudioEngine::disconnect (boost::shared_ptr<Port> port)
994 {
995         GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
996
997         if (!_running) {
998                 if (!_has_run) {
999                         fatal << _("disconnect called before engine was started") << endmsg;
1000                         /*NOTREACHED*/
1001                 } else {
1002                         return -1;
1003                 }
1004         }
1005
1006         return port->disconnect_all ();
1007 }
1008
1009 ARDOUR::framecnt_t
1010 AudioEngine::frame_rate () const
1011 {
1012         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1013         if (_frame_rate == 0) {
1014                 return (_frame_rate = jack_get_sample_rate (_priv_jack));
1015         } else {
1016                 return _frame_rate;
1017         }
1018 }
1019
1020 size_t
1021 AudioEngine::raw_buffer_size (DataType t)
1022 {
1023         std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
1024         return (s != _raw_buffer_sizes.end()) ? s->second : 0;
1025 }
1026
1027 ARDOUR::pframes_t
1028 AudioEngine::frames_per_cycle () const
1029 {
1030         GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1031         if (_buffer_size == 0) {
1032                 return jack_get_buffer_size (_jack);
1033         } else {
1034                 return _buffer_size;
1035         }
1036 }
1037
1038 /** @param name Full or short name of port
1039  *  @return Corresponding Port or 0.
1040  */
1041
1042 boost::shared_ptr<Port>
1043 AudioEngine::get_port_by_name (const string& portname)
1044 {
1045         if (!_running) {
1046                 if (!_has_run) {
1047                         fatal << _("get_port_by_name() called before engine was started") << endmsg;
1048                         /*NOTREACHED*/
1049                 } else {
1050                         boost::shared_ptr<Port> ();
1051                 }
1052         }
1053
1054         if (!port_is_mine (portname)) {
1055                 /* not an ardour port */
1056                 return boost::shared_ptr<Port> ();
1057         }
1058
1059         boost::shared_ptr<Ports> pr = ports.reader();
1060         std::string rel = make_port_name_relative (portname);
1061         Ports::iterator x = pr->find (rel);
1062
1063         if (x != pr->end()) {
1064                 /* its possible that the port was renamed by some 3rd party and
1065                    we don't know about it. check for this (the check is quick
1066                    and cheap), and if so, rename the port (which will alter
1067                    the port map as a side effect).
1068                 */
1069                 const std::string check = make_port_name_relative (jack_port_name (x->second->jack_port()));
1070                 if (check != rel) {
1071                         x->second->set_name (check);
1072                 }
1073                 return x->second;
1074         }
1075
1076         return boost::shared_ptr<Port> ();
1077 }
1078
1079 void
1080 AudioEngine::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
1081 {
1082         RCUWriter<Ports> writer (ports);
1083         boost::shared_ptr<Ports> p = writer.get_copy();
1084         Ports::iterator x = p->find (old_relative_name);
1085         
1086         if (x != p->end()) {
1087                 boost::shared_ptr<Port> port = x->second;
1088                 p->erase (x);
1089                 p->insert (make_pair (new_relative_name, port));
1090         }
1091 }
1092
1093 const char **
1094 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1095 {
1096         GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1097         if (!_running) {
1098                 if (!_has_run) {
1099                         fatal << _("get_ports called before engine was started") << endmsg;
1100                         /*NOTREACHED*/
1101                 } else {
1102                         return 0;
1103                 }
1104         }
1105         return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1106 }
1107
1108 void
1109 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1110 {
1111         /* called from jack shutdown handler  */
1112
1113         AudioEngine* ae = static_cast<AudioEngine *> (arg);
1114         bool was_running = ae->_running;
1115
1116         ae->stop_metering_thread ();
1117
1118         ae->_running = false;
1119         ae->_buffer_size = 0;
1120         ae->_frame_rate = 0;
1121         ae->_jack = 0;
1122
1123         if (was_running) {
1124 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1125                 switch (code) {
1126                 case JackBackendError:
1127                         ae->Halted(reason); /* EMIT SIGNAL */
1128                         break;
1129                 default:
1130                         ae->Halted(""); /* EMIT SIGNAL */
1131                 }
1132 #else
1133                 ae->Halted(""); /* EMIT SIGNAL */
1134 #endif
1135         }
1136 }
1137
1138 void
1139 AudioEngine::halted (void *arg)
1140 {
1141         cerr << "HALTED by JACK\n";
1142
1143         /* called from jack shutdown handler  */
1144
1145         AudioEngine* ae = static_cast<AudioEngine *> (arg);
1146         bool was_running = ae->_running;
1147
1148         ae->stop_metering_thread ();
1149
1150         ae->_running = false;
1151         ae->_buffer_size = 0;
1152         ae->_frame_rate = 0;
1153         ae->_jack = 0;
1154
1155         if (was_running) {
1156                 ae->Halted(""); /* EMIT SIGNAL */
1157                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1158         }
1159 }
1160
1161 void
1162 AudioEngine::died ()
1163 {
1164         /* called from a signal handler for SIGPIPE */
1165
1166         stop_metering_thread ();
1167
1168         _running = false;
1169         _buffer_size = 0;
1170         _frame_rate = 0;
1171         _jack = 0;
1172 }
1173
1174 bool
1175 AudioEngine::can_request_hardware_monitoring ()
1176 {
1177         GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1178         const char ** ports;
1179
1180         if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1181                 return false;
1182         }
1183
1184         free (ports);
1185
1186         return true;
1187 }
1188
1189 ChanCount
1190 AudioEngine::n_physical (unsigned long flags) const
1191 {
1192         ChanCount c;
1193
1194         GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1195
1196         const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1197         if (ports == 0) {
1198                 return c;
1199         }
1200
1201         for (uint32_t i = 0; ports[i]; ++i) {
1202                 if (!strstr (ports[i], "Midi-Through")) {
1203                         DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1204                         c.set (t, c.get (t) + 1);
1205                 }
1206         }
1207
1208         free (ports);
1209
1210         return c;
1211 }
1212
1213 ChanCount
1214 AudioEngine::n_physical_inputs () const
1215 {
1216         return n_physical (JackPortIsInput);
1217 }
1218
1219 ChanCount
1220 AudioEngine::n_physical_outputs () const
1221 {
1222         return n_physical (JackPortIsOutput);
1223 }
1224
1225 void
1226 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1227 {
1228         GET_PRIVATE_JACK_POINTER (_jack);
1229         const char ** ports;
1230
1231         if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1232                 return;
1233         }
1234
1235         if (ports) {
1236                 for (uint32_t i = 0; ports[i]; ++i) {
1237                         if (strstr (ports[i], "Midi-Through")) {
1238                                 continue;
1239                         }
1240                         phy.push_back (ports[i]);
1241                 }
1242                 free (ports);
1243         }
1244 }
1245
1246 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1247  *  a physical input connector.
1248  */
1249 void
1250 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1251 {
1252         get_physical (type, JackPortIsOutput, ins);
1253 }
1254
1255 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1256  *  a physical output connector.
1257  */
1258 void
1259 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1260 {
1261         get_physical (type, JackPortIsInput, outs);
1262 }
1263
1264 void
1265 AudioEngine::transport_stop ()
1266 {
1267         GET_PRIVATE_JACK_POINTER (_jack);
1268         jack_transport_stop (_priv_jack);
1269 }
1270
1271 void
1272 AudioEngine::transport_start ()
1273 {
1274         GET_PRIVATE_JACK_POINTER (_jack);
1275         jack_transport_start (_priv_jack);
1276 }
1277
1278 void
1279 AudioEngine::transport_locate (framepos_t where)
1280 {
1281         GET_PRIVATE_JACK_POINTER (_jack);
1282         jack_transport_locate (_priv_jack, where);
1283 }
1284
1285 AudioEngine::TransportState
1286 AudioEngine::transport_state ()
1287 {
1288         GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1289         jack_position_t pos;
1290         return (TransportState) jack_transport_query (_priv_jack, &pos);
1291 }
1292
1293 int
1294 AudioEngine::reset_timebase ()
1295 {
1296         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1297         if (_session) {
1298                 if (_session->config.get_jack_time_master()) {
1299                         return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1300                 } else {
1301                         return jack_release_timebase (_jack);
1302                 }
1303         }
1304         return 0;
1305 }
1306
1307 int
1308 AudioEngine::freewheel (bool onoff)
1309 {
1310         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1311
1312         if (onoff != _freewheeling) {
1313                 return jack_set_freewheel (_priv_jack, onoff);
1314
1315         } else {
1316                 /* already doing what has been asked for */
1317                 return 0;
1318         }
1319 }
1320
1321 void
1322 AudioEngine::remove_all_ports ()
1323 {
1324         /* make sure that JACK callbacks that will be invoked as we cleanup
1325          * ports know that they have nothing to do.
1326          */
1327
1328         port_remove_in_progress = true;
1329
1330         /* process lock MUST be held by caller
1331         */
1332
1333         {
1334                 RCUWriter<Ports> writer (ports);
1335                 boost::shared_ptr<Ports> ps = writer.get_copy ();
1336                 ps->clear ();
1337         }
1338
1339         /* clear dead wood list in RCU */
1340
1341         ports.flush ();
1342
1343         port_remove_in_progress = false;
1344 }
1345
1346 int
1347 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1348 {
1349         EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1350         boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1351         jack_status_t status;
1352
1353         /* revert all environment settings back to whatever they were when ardour started
1354          */
1355
1356         if (global_epa) {
1357                 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1358                 global_epa->restore ();
1359         }
1360
1361         jack_client_name = client_name; /* might be reset below */
1362 #ifdef HAVE_JACK_SESSION
1363         if (! session_uuid.empty())
1364             _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1365         else
1366 #endif
1367         _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1368
1369         if (_jack == NULL) {
1370                 // error message is not useful here
1371                 return -1;
1372         }
1373
1374         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1375
1376         if (status & JackNameNotUnique) {
1377                 jack_client_name = jack_get_client_name (_priv_jack);
1378         }
1379
1380         return 0;
1381 }
1382
1383 int
1384 AudioEngine::disconnect_from_jack ()
1385 {
1386         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1387
1388         if (_running) {
1389                 stop_metering_thread ();
1390         }
1391
1392         {
1393                 Glib::Threads::Mutex::Lock lm (_process_lock);
1394                 jack_client_close (_priv_jack);
1395                 _jack = 0;
1396         }
1397
1398         _buffer_size = 0;
1399         _frame_rate = 0;
1400         _raw_buffer_sizes.clear();
1401
1402         if (_running) {
1403                 _running = false;
1404                 Stopped(); /* EMIT SIGNAL */
1405                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1406         }
1407
1408         return 0;
1409 }
1410
1411 int
1412 AudioEngine::reconnect_to_jack ()
1413 {
1414         if (_running) {
1415                 disconnect_from_jack ();
1416                 /* XXX give jackd a chance */
1417                 Glib::usleep (250000);
1418         }
1419
1420         if (connect_to_jack (jack_client_name, "")) {
1421                 error << _("failed to connect to JACK") << endmsg;
1422                 return -1;
1423         }
1424
1425         Ports::iterator i;
1426
1427         boost::shared_ptr<Ports> p = ports.reader ();
1428
1429         for (i = p->begin(); i != p->end(); ++i) {
1430                 if (i->second->reestablish ()) {
1431                         break;
1432                 }
1433         }
1434
1435         if (i != p->end()) {
1436                 /* failed */
1437                 remove_all_ports ();
1438                 return -1;
1439         }
1440
1441         GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1442
1443         MIDI::Manager::instance()->reestablish (_priv_jack);
1444
1445         if (_session) {
1446                 _session->reset_jack_connection (_priv_jack);
1447                 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1448                 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1449         }
1450
1451         last_monitor_check = 0;
1452
1453         set_jack_callbacks ();
1454
1455         if (jack_activate (_priv_jack) == 0) {
1456                 _running = true;
1457                 _has_run = true;
1458         } else {
1459                 return -1;
1460         }
1461
1462         /* re-establish connections */
1463
1464         for (i = p->begin(); i != p->end(); ++i) {
1465                 i->second->reconnect ();
1466         }
1467
1468         MIDI::Manager::instance()->reconnect ();
1469
1470         Running (); /* EMIT SIGNAL*/
1471
1472         start_metering_thread ();
1473
1474         return 0;
1475 }
1476
1477 int
1478 AudioEngine::request_buffer_size (pframes_t nframes)
1479 {
1480         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1481
1482         if (nframes == jack_get_buffer_size (_priv_jack)) {
1483                 return 0;
1484         }
1485
1486         return jack_set_buffer_size (_priv_jack, nframes);
1487 }
1488
1489 string
1490 AudioEngine::make_port_name_relative (string portname) const
1491 {
1492         string::size_type len;
1493         string::size_type n;
1494
1495         len = portname.length();
1496
1497         for (n = 0; n < len; ++n) {
1498                 if (portname[n] == ':') {
1499                         break;
1500                 }
1501         }
1502
1503         if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1504                 return portname.substr (n+1);
1505         }
1506
1507         return portname;
1508 }
1509
1510 string
1511 AudioEngine::make_port_name_non_relative (string portname) const
1512 {
1513         string str;
1514
1515         if (portname.find_first_of (':') != string::npos) {
1516                 return portname;
1517         }
1518
1519         str  = jack_client_name;
1520         str += ':';
1521         str += portname;
1522
1523         return str;
1524 }
1525
1526 bool
1527 AudioEngine::port_is_mine (const string& portname) const
1528 {
1529         if (portname.find_first_of (':') != string::npos) {
1530                 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1531                         return false;
1532                 }
1533         }
1534         return true;
1535 }
1536
1537 bool
1538 AudioEngine::is_realtime () const
1539 {
1540         GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1541         return jack_is_realtime (_priv_jack);
1542 }
1543
1544 int
1545 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1546 {
1547         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1548         ThreadData* td = new ThreadData (this, f, stacksize);
1549
1550         if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1551                                        jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1552                 return -1;
1553         }
1554
1555         return 0;
1556 }
1557
1558 void*
1559 AudioEngine::_start_process_thread (void* arg)
1560 {
1561         ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1562         boost::function<void()> f = td->f;
1563         delete td;
1564
1565         f ();
1566
1567         return 0;
1568 }
1569
1570 bool
1571 AudioEngine::port_is_physical (const std::string& portname) const
1572 {
1573         GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1574
1575         jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1576
1577         if (!port) {
1578                 return false;
1579         }
1580
1581         return jack_port_flags (port) & JackPortIsPhysical;
1582 }
1583
1584 void
1585 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1586 {
1587         GET_PRIVATE_JACK_POINTER(_jack);
1588
1589         jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1590
1591         if (!port) {
1592                 return;
1593         }
1594
1595         jack_port_request_monitor (port, yn);
1596 }
1597
1598 void
1599 AudioEngine::update_latencies ()
1600 {
1601         if (jack_recompute_total_latencies) {
1602                 GET_PRIVATE_JACK_POINTER (_jack);
1603                 jack_recompute_total_latencies (_priv_jack);
1604         }
1605 }
1606
1607 void
1608 AudioEngine::destroy ()
1609 {
1610         delete _instance;
1611         _instance = 0;
1612 }