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