Inrease the export "chunk size" to speed it up over 10% at least in some situations
[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::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::Mutex::Lock tm (_process_lock, Glib::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::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::Thread::create (boost::bind (&AudioEngine::meter_thread, this),
749                                                        500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
750         }
751 }
752
753 void
754 AudioEngine::meter_thread ()
755 {
756         pthread_set_name (X_("meter"));
757
758         while (true) {
759                 Glib::usleep (10000); /* 1/100th sec interval */
760                 if (g_atomic_int_get(&m_meter_exit)) {
761                         break;
762                 }
763                 Metering::Meter ();
764         }
765 }
766
767 void
768 AudioEngine::set_session (Session *s)
769 {
770         Glib::Mutex::Lock pl (_process_lock);
771
772         SessionHandlePtr::set_session (s);
773
774         if (_session) {
775
776                 start_metering_thread ();
777
778                 pframes_t blocksize = jack_get_buffer_size (_jack);
779
780                 /* page in as much of the session process code as we
781                    can before we really start running.
782                 */
783
784                 boost::shared_ptr<Ports> p = ports.reader();
785
786                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
787                         i->second->cycle_start (blocksize);
788                 }
789
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                 _session->process (blocksize);
798
799                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
800                         i->second->cycle_end (blocksize);
801                 }
802         }
803 }
804
805 void
806 AudioEngine::remove_session ()
807 {
808         Glib::Mutex::Lock lm (_process_lock);
809
810         if (_running) {
811
812                 stop_metering_thread ();
813
814                 if (_session) {
815                         session_remove_pending = true;
816                         session_removed.wait(_process_lock);
817                 }
818
819         } else {
820                 SessionHandlePtr::set_session (0);
821         }
822
823         remove_all_ports ();
824 }
825
826 void
827 AudioEngine::port_registration_failure (const std::string& portname)
828 {
829         GET_PRIVATE_JACK_POINTER (_jack);
830         string full_portname = jack_client_name;
831         full_portname += ':';
832         full_portname += portname;
833
834
835         jack_port_t* p = jack_port_by_name (_priv_jack, full_portname.c_str());
836         string reason;
837
838         if (p) {
839                 reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
840         } else {
841                 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);
842         }
843
844         throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
845 }
846
847 boost::shared_ptr<Port>
848 AudioEngine::register_port (DataType dtype, const string& portname, bool input)
849 {
850         boost::shared_ptr<Port> newport;
851
852         try {
853                 if (dtype == DataType::AUDIO) {
854                         newport.reset (new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput)));
855                 } else if (dtype == DataType::MIDI) {
856                         newport.reset (new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput)));
857                 } else {
858                         throw PortRegistrationFailure("unable to create port (unknown type)");
859                 }
860
861                 RCUWriter<Ports> writer (ports);
862                 boost::shared_ptr<Ports> ps = writer.get_copy ();
863                 ps->insert (make_pair (make_port_name_relative (portname), newport));
864
865                 /* writer goes out of scope, forces update */
866
867                 return newport;
868         }
869
870         catch (PortRegistrationFailure& err) {
871                 throw err;
872         } catch (std::exception& e) {
873                 throw PortRegistrationFailure(string_compose(
874                                 _("unable to create port: %1"), e.what()).c_str());
875         } catch (...) {
876                 throw PortRegistrationFailure("unable to create port (unknown error)");
877         }
878 }
879
880 boost::shared_ptr<Port>
881 AudioEngine::register_input_port (DataType type, const string& portname)
882 {
883         return register_port (type, portname, true);
884 }
885
886 boost::shared_ptr<Port>
887 AudioEngine::register_output_port (DataType type, const string& portname)
888 {
889         return register_port (type, portname, false);
890 }
891
892 int
893 AudioEngine::unregister_port (boost::shared_ptr<Port> port)
894 {
895         /* caller must hold process lock */
896
897         if (!_running) {
898                 /* probably happening when the engine has been halted by JACK,
899                    in which case, there is nothing we can do here.
900                    */
901                 return 0;
902         }
903
904         {
905                 RCUWriter<Ports> writer (ports);
906                 boost::shared_ptr<Ports> ps = writer.get_copy ();
907                 Ports::iterator x = ps->find (make_port_name_relative (port->name()));
908
909                 if (x != ps->end()) {
910                         ps->erase (x);
911                 }
912
913                 /* writer goes out of scope, forces update */
914         }
915
916         ports.flush ();
917
918         return 0;
919 }
920
921 int
922 AudioEngine::connect (const string& source, const string& destination)
923 {
924         int ret;
925
926         if (!_running) {
927                 if (!_has_run) {
928                         fatal << _("connect called before engine was started") << endmsg;
929                         /*NOTREACHED*/
930                 } else {
931                         return -1;
932                 }
933         }
934
935         string s = make_port_name_non_relative (source);
936         string d = make_port_name_non_relative (destination);
937
938
939         boost::shared_ptr<Port> src = get_port_by_name (s);
940         boost::shared_ptr<Port> dst = get_port_by_name (d);
941
942         if (src) {
943                 ret = src->connect (d);
944         } else if (dst) {
945                 ret = dst->connect (s);
946         } else {
947                 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
948                 ret = -1;
949         }
950
951         if (ret > 0) {
952                 /* already exists - no error, no warning */
953         } else if (ret < 0) {
954                 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
955                                         source, s, destination, d)
956                       << endmsg;
957         }
958
959         return ret;
960 }
961
962 int
963 AudioEngine::disconnect (const string& source, const string& destination)
964 {
965         int ret;
966
967         if (!_running) {
968                 if (!_has_run) {
969                         fatal << _("disconnect called before engine was started") << endmsg;
970                         /*NOTREACHED*/
971                 } else {
972                         return -1;
973                 }
974         }
975
976         string s = make_port_name_non_relative (source);
977         string d = make_port_name_non_relative (destination);
978
979         boost::shared_ptr<Port> src = get_port_by_name (s);
980         boost::shared_ptr<Port> dst = get_port_by_name (d);
981
982         if (src) {
983                         ret = src->disconnect (d);
984         } else if (dst) {
985                         ret = dst->disconnect (s);
986         } else {
987                 /* neither port is known to us, and this API isn't intended for use as a general patch bay */
988                 ret = -1;
989         }
990         return ret;
991 }
992
993 int
994 AudioEngine::disconnect (boost::shared_ptr<Port> port)
995 {
996         GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
997
998         if (!_running) {
999                 if (!_has_run) {
1000                         fatal << _("disconnect called before engine was started") << endmsg;
1001                         /*NOTREACHED*/
1002                 } else {
1003                         return -1;
1004                 }
1005         }
1006
1007         return port->disconnect_all ();
1008 }
1009
1010 ARDOUR::framecnt_t
1011 AudioEngine::frame_rate () const
1012 {
1013         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1014         if (_frame_rate == 0) {
1015                 return (_frame_rate = jack_get_sample_rate (_priv_jack));
1016         } else {
1017                 return _frame_rate;
1018         }
1019 }
1020
1021 size_t
1022 AudioEngine::raw_buffer_size (DataType t)
1023 {
1024         std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
1025         return (s != _raw_buffer_sizes.end()) ? s->second : 0;
1026 }
1027
1028 ARDOUR::pframes_t
1029 AudioEngine::frames_per_cycle () const
1030 {
1031         GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1032         if (_buffer_size == 0) {
1033                 return jack_get_buffer_size (_jack);
1034         } else {
1035                 return _buffer_size;
1036         }
1037 }
1038
1039 /** @param name Full or short name of port
1040  *  @return Corresponding Port or 0.
1041  */
1042
1043 boost::shared_ptr<Port>
1044 AudioEngine::get_port_by_name (const string& portname)
1045 {
1046         if (!_running) {
1047                 if (!_has_run) {
1048                         fatal << _("get_port_by_name() called before engine was started") << endmsg;
1049                         /*NOTREACHED*/
1050                 } else {
1051                         boost::shared_ptr<Port> ();
1052                 }
1053         }
1054
1055         if (!port_is_mine (portname)) {
1056                 /* not an ardour port */
1057                 return boost::shared_ptr<Port> ();
1058         }
1059
1060         boost::shared_ptr<Ports> pr = ports.reader();
1061         std::string rel = make_port_name_relative (portname);
1062         Ports::iterator x = pr->find (rel);
1063
1064         if (x != pr->end()) {
1065                 /* its possible that the port was renamed by some 3rd party and
1066                    we don't know about it. check for this (the check is quick
1067                    and cheap), and if so, rename the port (which will alter
1068                    the port map as a side effect).
1069                 */
1070                 const std::string check = make_port_name_relative (jack_port_name (x->second->jack_port()));
1071                 if (check != rel) {
1072                         x->second->set_name (check);
1073                 }
1074                 return x->second;
1075         }
1076
1077         return boost::shared_ptr<Port> ();
1078 }
1079
1080 void
1081 AudioEngine::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
1082 {
1083         RCUWriter<Ports> writer (ports);
1084         boost::shared_ptr<Ports> p = writer.get_copy();
1085         Ports::iterator x = p->find (old_relative_name);
1086         
1087         if (x != p->end()) {
1088                 boost::shared_ptr<Port> port = x->second;
1089                 p->erase (x);
1090                 p->insert (make_pair (new_relative_name, port));
1091         }
1092 }
1093
1094 const char **
1095 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
1096 {
1097         GET_PRIVATE_JACK_POINTER_RET (_jack,0);
1098         if (!_running) {
1099                 if (!_has_run) {
1100                         fatal << _("get_ports called before engine was started") << endmsg;
1101                         /*NOTREACHED*/
1102                 } else {
1103                         return 0;
1104                 }
1105         }
1106         return jack_get_ports (_priv_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
1107 }
1108
1109 void
1110 AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
1111 {
1112         /* called from jack shutdown handler  */
1113
1114         AudioEngine* ae = static_cast<AudioEngine *> (arg);
1115         bool was_running = ae->_running;
1116
1117         ae->stop_metering_thread ();
1118
1119         ae->_running = false;
1120         ae->_buffer_size = 0;
1121         ae->_frame_rate = 0;
1122         ae->_jack = 0;
1123
1124         if (was_running) {
1125 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1126                 switch (code) {
1127                 case JackBackendError:
1128                         ae->Halted(reason); /* EMIT SIGNAL */
1129                         break;
1130                 default:
1131                         ae->Halted(""); /* EMIT SIGNAL */
1132                 }
1133 #else
1134                 ae->Halted(""); /* EMIT SIGNAL */
1135 #endif
1136         }
1137 }
1138
1139 void
1140 AudioEngine::halted (void *arg)
1141 {
1142         cerr << "HALTED by JACK\n";
1143
1144         /* called from jack shutdown handler  */
1145
1146         AudioEngine* ae = static_cast<AudioEngine *> (arg);
1147         bool was_running = ae->_running;
1148
1149         ae->stop_metering_thread ();
1150
1151         ae->_running = false;
1152         ae->_buffer_size = 0;
1153         ae->_frame_rate = 0;
1154         ae->_jack = 0;
1155
1156         if (was_running) {
1157                 ae->Halted(""); /* EMIT SIGNAL */
1158                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1159         }
1160 }
1161
1162 void
1163 AudioEngine::died ()
1164 {
1165         /* called from a signal handler for SIGPIPE */
1166
1167         stop_metering_thread ();
1168
1169         _running = false;
1170         _buffer_size = 0;
1171         _frame_rate = 0;
1172         _jack = 0;
1173 }
1174
1175 bool
1176 AudioEngine::can_request_hardware_monitoring ()
1177 {
1178         GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1179         const char ** ports;
1180
1181         if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1182                 return false;
1183         }
1184
1185         free (ports);
1186
1187         return true;
1188 }
1189
1190 ChanCount
1191 AudioEngine::n_physical (unsigned long flags) const
1192 {
1193         ChanCount c;
1194
1195         GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1196
1197         const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1198         if (ports == 0) {
1199                 return c;
1200         }
1201
1202         for (uint32_t i = 0; ports[i]; ++i) {
1203                 if (!strstr (ports[i], "Midi-Through")) {
1204                         DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1205                         c.set (t, c.get (t) + 1);
1206                 }
1207         }
1208
1209         free (ports);
1210
1211         return c;
1212 }
1213
1214 ChanCount
1215 AudioEngine::n_physical_inputs () const
1216 {
1217         return n_physical (JackPortIsInput);
1218 }
1219
1220 ChanCount
1221 AudioEngine::n_physical_outputs () const
1222 {
1223         return n_physical (JackPortIsOutput);
1224 }
1225
1226 void
1227 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1228 {
1229         GET_PRIVATE_JACK_POINTER (_jack);
1230         const char ** ports;
1231
1232         if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1233                 return;
1234         }
1235
1236         if (ports) {
1237                 for (uint32_t i = 0; ports[i]; ++i) {
1238                         if (strstr (ports[i], "Midi-Through")) {
1239                                 continue;
1240                         }
1241                         phy.push_back (ports[i]);
1242                 }
1243                 free (ports);
1244         }
1245 }
1246
1247 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1248  *  a physical input connector.
1249  */
1250 void
1251 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1252 {
1253         get_physical (type, JackPortIsOutput, ins);
1254 }
1255
1256 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1257  *  a physical output connector.
1258  */
1259 void
1260 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1261 {
1262         get_physical (type, JackPortIsInput, outs);
1263 }
1264
1265 void
1266 AudioEngine::transport_stop ()
1267 {
1268         GET_PRIVATE_JACK_POINTER (_jack);
1269         jack_transport_stop (_priv_jack);
1270 }
1271
1272 void
1273 AudioEngine::transport_start ()
1274 {
1275         GET_PRIVATE_JACK_POINTER (_jack);
1276         jack_transport_start (_priv_jack);
1277 }
1278
1279 void
1280 AudioEngine::transport_locate (framepos_t where)
1281 {
1282         GET_PRIVATE_JACK_POINTER (_jack);
1283         jack_transport_locate (_priv_jack, where);
1284 }
1285
1286 AudioEngine::TransportState
1287 AudioEngine::transport_state ()
1288 {
1289         GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1290         jack_position_t pos;
1291         return (TransportState) jack_transport_query (_priv_jack, &pos);
1292 }
1293
1294 int
1295 AudioEngine::reset_timebase ()
1296 {
1297         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1298         if (_session) {
1299                 if (_session->config.get_jack_time_master()) {
1300                         return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1301                 } else {
1302                         return jack_release_timebase (_jack);
1303                 }
1304         }
1305         return 0;
1306 }
1307
1308 int
1309 AudioEngine::freewheel (bool onoff)
1310 {
1311         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1312
1313         if (onoff != _freewheeling) {
1314                 return jack_set_freewheel (_priv_jack, onoff);
1315
1316         } else {
1317                 /* already doing what has been asked for */
1318                 return 0;
1319         }
1320 }
1321
1322 void
1323 AudioEngine::remove_all_ports ()
1324 {
1325         /* make sure that JACK callbacks that will be invoked as we cleanup
1326          * ports know that they have nothing to do.
1327          */
1328
1329         port_remove_in_progress = true;
1330
1331         /* process lock MUST be held by caller
1332         */
1333
1334         {
1335                 RCUWriter<Ports> writer (ports);
1336                 boost::shared_ptr<Ports> ps = writer.get_copy ();
1337                 ps->clear ();
1338         }
1339
1340         /* clear dead wood list in RCU */
1341
1342         ports.flush ();
1343
1344         port_remove_in_progress = false;
1345 }
1346
1347 int
1348 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1349 {
1350         EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1351         boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1352         jack_status_t status;
1353
1354         /* revert all environment settings back to whatever they were when ardour started
1355          */
1356
1357         if (global_epa) {
1358                 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1359                 global_epa->restore ();
1360         }
1361
1362         jack_client_name = client_name; /* might be reset below */
1363 #ifdef HAVE_JACK_SESSION
1364         if (! session_uuid.empty())
1365             _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1366         else
1367 #endif
1368         _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1369
1370         if (_jack == NULL) {
1371                 // error message is not useful here
1372                 return -1;
1373         }
1374
1375         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1376
1377         if (status & JackNameNotUnique) {
1378                 jack_client_name = jack_get_client_name (_priv_jack);
1379         }
1380
1381         return 0;
1382 }
1383
1384 int
1385 AudioEngine::disconnect_from_jack ()
1386 {
1387         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1388
1389         if (_running) {
1390                 stop_metering_thread ();
1391         }
1392
1393         {
1394                 Glib::Mutex::Lock lm (_process_lock);
1395                 jack_client_close (_priv_jack);
1396                 _jack = 0;
1397         }
1398
1399         _buffer_size = 0;
1400         _frame_rate = 0;
1401         _raw_buffer_sizes.clear();
1402
1403         if (_running) {
1404                 _running = false;
1405                 Stopped(); /* EMIT SIGNAL */
1406                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1407         }
1408
1409         return 0;
1410 }
1411
1412 int
1413 AudioEngine::reconnect_to_jack ()
1414 {
1415         if (_running) {
1416                 disconnect_from_jack ();
1417                 /* XXX give jackd a chance */
1418                 Glib::usleep (250000);
1419         }
1420
1421         if (connect_to_jack (jack_client_name, "")) {
1422                 error << _("failed to connect to JACK") << endmsg;
1423                 return -1;
1424         }
1425
1426         Ports::iterator i;
1427
1428         boost::shared_ptr<Ports> p = ports.reader ();
1429
1430         for (i = p->begin(); i != p->end(); ++i) {
1431                 if (i->second->reestablish ()) {
1432                         break;
1433                 }
1434         }
1435
1436         if (i != p->end()) {
1437                 /* failed */
1438                 remove_all_ports ();
1439                 return -1;
1440         }
1441
1442         GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1443
1444         MIDI::Manager::instance()->reestablish (_priv_jack);
1445
1446         if (_session) {
1447                 _session->reset_jack_connection (_priv_jack);
1448                 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1449                 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1450         }
1451
1452         last_monitor_check = 0;
1453
1454         set_jack_callbacks ();
1455
1456         if (jack_activate (_priv_jack) == 0) {
1457                 _running = true;
1458                 _has_run = true;
1459         } else {
1460                 return -1;
1461         }
1462
1463         /* re-establish connections */
1464
1465         for (i = p->begin(); i != p->end(); ++i) {
1466                 i->second->reconnect ();
1467         }
1468
1469         MIDI::Manager::instance()->reconnect ();
1470
1471         Running (); /* EMIT SIGNAL*/
1472
1473         start_metering_thread ();
1474
1475         return 0;
1476 }
1477
1478 int
1479 AudioEngine::request_buffer_size (pframes_t nframes)
1480 {
1481         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1482
1483         if (nframes == jack_get_buffer_size (_priv_jack)) {
1484                 return 0;
1485         }
1486
1487         return jack_set_buffer_size (_priv_jack, nframes);
1488 }
1489
1490 string
1491 AudioEngine::make_port_name_relative (string portname) const
1492 {
1493         string::size_type len;
1494         string::size_type n;
1495
1496         len = portname.length();
1497
1498         for (n = 0; n < len; ++n) {
1499                 if (portname[n] == ':') {
1500                         break;
1501                 }
1502         }
1503
1504         if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1505                 return portname.substr (n+1);
1506         }
1507
1508         return portname;
1509 }
1510
1511 string
1512 AudioEngine::make_port_name_non_relative (string portname) const
1513 {
1514         string str;
1515
1516         if (portname.find_first_of (':') != string::npos) {
1517                 return portname;
1518         }
1519
1520         str  = jack_client_name;
1521         str += ':';
1522         str += portname;
1523
1524         return str;
1525 }
1526
1527 bool
1528 AudioEngine::port_is_mine (const string& portname) const
1529 {
1530         if (portname.find_first_of (':') != string::npos) {
1531                 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1532                         return false;
1533                 }
1534         }
1535         return true;
1536 }
1537
1538 bool
1539 AudioEngine::is_realtime () const
1540 {
1541         GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1542         return jack_is_realtime (_priv_jack);
1543 }
1544
1545 int
1546 AudioEngine::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
1547 {
1548         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1549         ThreadData* td = new ThreadData (this, f, stacksize);
1550
1551         if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1552                                        jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1553                 return -1;
1554         }
1555
1556         return 0;
1557 }
1558
1559 void*
1560 AudioEngine::_start_process_thread (void* arg)
1561 {
1562         ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1563         boost::function<void()> f = td->f;
1564         delete td;
1565
1566         f ();
1567
1568         return 0;
1569 }
1570
1571 bool
1572 AudioEngine::port_is_physical (const std::string& portname) const
1573 {
1574         GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1575
1576         jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1577
1578         if (!port) {
1579                 return false;
1580         }
1581
1582         return jack_port_flags (port) & JackPortIsPhysical;
1583 }
1584
1585 void
1586 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1587 {
1588         GET_PRIVATE_JACK_POINTER(_jack);
1589
1590         jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1591
1592         if (!port) {
1593                 return;
1594         }
1595
1596         jack_port_request_monitor (port, yn);
1597 }
1598
1599 void
1600 AudioEngine::update_latencies ()
1601 {
1602         if (jack_recompute_total_latencies) {
1603                 GET_PRIVATE_JACK_POINTER (_jack);
1604                 jack_recompute_total_latencies (_priv_jack);
1605         }
1606 }
1607
1608 void
1609 AudioEngine::destroy ()
1610 {
1611         delete _instance;
1612         _instance = 0;
1613 }