Merge branch 'windows' of git.ardour.org:ardour/ardour into windows
[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 "midi++/port.h"
35 #include "midi++/jack_midi_port.h"
36 #include "midi++/mmc.h"
37 #include "midi++/manager.h"
38
39 #include "ardour/audio_port.h"
40 #include "ardour/audioengine.h"
41 #include "ardour/buffer.h"
42 #include "ardour/cycle_timer.h"
43 #include "ardour/internal_send.h"
44 #include "ardour/meter.h"
45 #include "ardour/midi_port.h"
46 #include "ardour/port.h"
47 #include "ardour/process_thread.h"
48 #include "ardour/session.h"
49
50 #include "i18n.h"
51
52 using namespace std;
53 using namespace ARDOUR;
54 using namespace PBD;
55
56 gint AudioEngine::m_meter_exit;
57 AudioEngine* AudioEngine::_instance = 0;
58
59 #define GET_PRIVATE_JACK_POINTER(j)  jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return; }
60 #define GET_PRIVATE_JACK_POINTER_RET(j,r) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return r; }
61
62 AudioEngine::AudioEngine (string client_name, string session_uuid)
63         : _jack (0)
64         , session_remove_pending (false)
65         , session_removal_countdown (-1)
66         , _running (false)
67         , _has_run (false)
68         , _buffer_size (0)
69         , _frame_rate (0)
70         , monitor_check_interval (INT32_MAX)
71         , last_monitor_check (0)
72         , _processed_frames (0)
73         , _freewheeling (false)
74         , _pre_freewheel_mmc_enabled (false)
75         , _usecs_per_cycle (0)
76         , port_remove_in_progress (false)
77         , m_meter_thread (0)
78         , _main_thread (0)
79         , ports (new Ports)
80 {
81         _instance = this; /* singleton */
82
83         g_atomic_int_set (&m_meter_exit, 0);
84
85         if (connect_to_jack (client_name, session_uuid)) {
86                 throw NoBackendAvailable ();
87         }
88
89         Port::set_engine (this);
90 }
91
92 AudioEngine::~AudioEngine ()
93 {
94         config_connection.disconnect ();
95
96         {
97                 Glib::Threads::Mutex::Lock tm (_process_lock);
98                 session_removed.signal ();
99
100                 if (_running) {
101                         jack_client_close (_jack);
102                         _jack = 0;
103                 }
104
105                 stop_metering_thread ();
106         }
107 }
108
109 jack_client_t*
110 AudioEngine::jack() const
111 {
112         return _jack;
113 }
114
115 void
116 _thread_init_callback (void * /*arg*/)
117 {
118         /* make sure that anybody who needs to know about this thread
119            knows about it.
120         */
121
122         pthread_set_name (X_("audioengine"));
123
124         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
125         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
126
127         SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
128
129         MIDI::JackMIDIPort::set_process_thread (pthread_self());
130 }
131
132 static void
133 ardour_jack_error (const char* msg)
134 {
135         error << "JACK: " << msg << endmsg;
136 }
137
138 void
139 AudioEngine::set_jack_callbacks ()
140 {
141         GET_PRIVATE_JACK_POINTER (_jack);
142
143         if (jack_on_info_shutdown) {
144                 jack_on_info_shutdown (_priv_jack, halted_info, this);
145         } else {
146                 jack_on_shutdown (_priv_jack, halted, this);
147         }
148
149         jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
150         jack_set_process_thread (_priv_jack, _process_thread, this);
151         jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
152         jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
153         jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
154         jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
155         jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
156         jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
157         jack_set_sync_callback (_priv_jack, _jack_sync_callback, this);
158         jack_set_freewheel_callback (_priv_jack, _freewheel_callback, this);
159
160         if (_session && _session->config.get_jack_time_master()) {
161                 jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
162         }
163
164 #ifdef HAVE_JACK_SESSION
165         if( jack_set_session_callback)
166                 jack_set_session_callback (_priv_jack, _session_callback, this);
167 #endif
168
169         if (jack_set_latency_callback) {
170                 jack_set_latency_callback (_priv_jack, _latency_callback, this);
171         }
172
173         jack_set_error_function (ardour_jack_error);
174 }
175
176 int
177 AudioEngine::start ()
178 {
179         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
180
181         if (!_running) {
182
183                 if (!jack_port_type_get_buffer_size) {
184                         warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
185                 }
186
187                 if (_session) {
188                         BootMessage (_("Connect session to engine"));
189                         _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
190                 }
191
192                 /* a proxy for whether jack_activate() will definitely call the buffer size
193                  * callback. with older versions of JACK, this function symbol will be null.
194                  * this is reliable, but not clean.
195                  */
196
197                 if (!jack_port_type_get_buffer_size) {
198                         jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
199                 }
200                 
201                 _processed_frames = 0;
202                 last_monitor_check = 0;
203
204                 set_jack_callbacks ();
205
206                 if (jack_activate (_priv_jack) == 0) {
207                         _running = true;
208                         _has_run = true;
209                         Running(); /* EMIT SIGNAL */
210                 } else {
211                         // error << _("cannot activate JACK client") << endmsg;
212                 }
213         }
214                 
215         return _running ? 0 : -1;
216 }
217
218 int
219 AudioEngine::stop (bool forever)
220 {
221         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
222
223         if (_priv_jack) {
224                 if (forever) {
225                         disconnect_from_jack ();
226                 } else {
227                         jack_deactivate (_priv_jack);
228                         MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
229                         Stopped(); /* 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         ae->connect_callback (id_a, id_b, conn);
378 }
379
380 void
381 AudioEngine::connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn)
382 {
383         if (port_remove_in_progress) {
384                 return;
385         }
386
387         GET_PRIVATE_JACK_POINTER (_jack);
388
389         jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
390         jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
391
392         boost::shared_ptr<Port> port_a;
393         boost::shared_ptr<Port> port_b;
394         Ports::iterator x;
395         boost::shared_ptr<Ports> pr = ports.reader ();
396
397
398         x = pr->find (make_port_name_relative (jack_port_name (jack_port_a)));
399         if (x != pr->end()) {
400                 port_a = x->second;
401         }
402
403         x = pr->find (make_port_name_relative (jack_port_name (jack_port_b)));
404         if (x != pr->end()) {
405                 port_b = x->second;
406         }
407
408         PortConnectedOrDisconnected (
409                 port_a, jack_port_name (jack_port_a),
410                 port_b, jack_port_name (jack_port_b),
411                 conn == 0 ? false : true
412                 ); /* EMIT SIGNAL */
413 }
414
415 void
416 AudioEngine::split_cycle (pframes_t offset)
417 {
418         /* caller must hold process lock */
419
420         Port::increment_global_port_buffer_offset (offset);
421
422         /* tell all Ports that we're going to start a new (split) cycle */
423
424         boost::shared_ptr<Ports> p = ports.reader();
425
426         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
427                 i->second->cycle_split ();
428         }
429 }
430
431 void*
432 AudioEngine::process_thread ()
433 {
434         /* JACK doesn't do this for us when we use the wait API
435          */
436
437         _thread_init_callback (0);
438
439         _main_thread = new ProcessThread;
440
441         while (1) {
442                 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
443
444                 pframes_t nframes = jack_cycle_wait (_priv_jack);
445
446                 if (process_callback (nframes)) {
447                         return 0;
448                 }
449
450                 jack_cycle_signal (_priv_jack, 0);
451         }
452
453         return 0;
454 }
455
456 /** Method called by our ::process_thread when there is work to be done.
457  *  @param nframes Number of frames to process.
458  */
459 int
460 AudioEngine::process_callback (pframes_t nframes)
461 {
462         GET_PRIVATE_JACK_POINTER_RET(_jack,0);
463         Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
464
465         PT_TIMING_REF;
466         PT_TIMING_CHECK (1);
467
468         /// The number of frames that will have been processed when we've finished
469         pframes_t next_processed_frames;
470
471         /* handle wrap around of total frames counter */
472
473         if (max_framepos - _processed_frames < nframes) {
474                 next_processed_frames = nframes - (max_framepos - _processed_frames);
475         } else {
476                 next_processed_frames = _processed_frames + nframes;
477         }
478
479         if (!tm.locked()) {
480                 /* return having done nothing */
481                 _processed_frames = next_processed_frames;
482                 return 0;
483         }
484
485         if (session_remove_pending) {
486
487                 /* perform the actual session removal */
488
489                 if (session_removal_countdown < 0) {
490
491                         /* fade out over 1 second */
492                         session_removal_countdown = _frame_rate/2;
493                         session_removal_gain = 1.0;
494                         session_removal_gain_step = 1.0/session_removal_countdown;
495
496                 } else if (session_removal_countdown > 0) {
497
498                         /* we'll be fading audio out.
499                            
500                            if this is the last time we do this as part 
501                            of session removal, do a MIDI panic now
502                            to get MIDI stopped. This relies on the fact
503                            that "immediate data" (aka "out of band data") from
504                            MIDI tracks is *appended* after any other data, 
505                            so that it emerges after any outbound note ons, etc.
506                         */
507
508                         if (session_removal_countdown <= nframes) {
509                                 _session->midi_panic ();
510                         }
511
512                 } else {
513                         /* fade out done */
514                         _session = 0;
515                         session_removal_countdown = -1; // reset to "not in progress"
516                         session_remove_pending = false;
517                         session_removed.signal(); // wakes up thread that initiated session removal
518                 }
519         }
520
521         if (_session == 0) {
522
523                 if (!_freewheeling) {
524                         MIDI::Manager::instance()->cycle_start(nframes);
525                         MIDI::Manager::instance()->cycle_end();
526                 }
527
528                 _processed_frames = next_processed_frames;
529
530                 return 0;
531         }
532
533         /* tell all relevant objects that we're starting a new cycle */
534
535         InternalSend::CycleStart (nframes);
536         Port::set_global_port_buffer_offset (0);
537         Port::set_cycle_framecnt (nframes);
538
539         /* tell all Ports that we're starting a new cycle */
540
541         boost::shared_ptr<Ports> p = ports.reader();
542
543         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
544                 i->second->cycle_start (nframes);
545         }
546
547         /* test if we are freewheeling and there are freewheel signals connected.
548            ardour should act normally even when freewheeling unless /it/ is
549            exporting 
550         */
551
552         if (_freewheeling && !Freewheel.empty()) {
553
554                 Freewheel (nframes);
555
556         } else {
557                 MIDI::Manager::instance()->cycle_start(nframes);
558
559                 if (_session) {
560                         _session->process (nframes);
561                 }
562
563                 MIDI::Manager::instance()->cycle_end();
564         }
565
566         if (_freewheeling) {
567                 return 0;
568         }
569
570         if (!_running) {
571                 _processed_frames = next_processed_frames;
572                 return 0;
573         }
574
575         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
576
577                 boost::shared_ptr<Ports> p = ports.reader();
578
579                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
580
581                         bool x;
582
583                         if (i->second->last_monitor() != (x = i->second->jack_monitoring_input ())) {
584                                 i->second->set_last_monitor (x);
585                                 /* XXX I think this is dangerous, due to
586                                    a likely mutex in the signal handlers ...
587                                 */
588                                 i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
589                         }
590                 }
591                 last_monitor_check = next_processed_frames;
592         }
593
594         if (_session->silent()) {
595
596                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
597
598                         if (i->second->sends_output()) {
599                                 i->second->get_buffer(nframes).silence(nframes);
600                         }
601                 }
602         }
603
604         if (session_remove_pending && session_removal_countdown) {
605
606                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
607
608                         if (i->second->sends_output()) {
609
610                                 boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
611                                 if (ap) {
612                                         Sample* s = ap->engine_get_whole_audio_buffer ();
613                                         gain_t g = session_removal_gain;
614                                         
615                                         for (pframes_t n = 0; n < nframes; ++n) {
616                                                 *s++ *= g;
617                                                 g -= session_removal_gain_step;
618                                         }
619                                 }
620                         }
621                 }
622                 
623                 if (session_removal_countdown > nframes) {
624                         session_removal_countdown -= nframes;
625                 } else {
626                         session_removal_countdown = 0;
627                 }
628
629                 session_removal_gain -= (nframes * session_removal_gain_step);
630         }
631
632         // Finalize ports
633
634         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
635                 i->second->cycle_end (nframes);
636         }
637
638         _processed_frames = next_processed_frames;
639
640         PT_TIMING_CHECK (2);
641         
642         return 0;
643 }
644
645 int
646 AudioEngine::_sample_rate_callback (pframes_t nframes, void *arg)
647 {
648         return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
649 }
650
651 int
652 AudioEngine::jack_sample_rate_callback (pframes_t nframes)
653 {
654         _frame_rate = nframes;
655         _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
656
657         /* check for monitor input change every 1/10th of second */
658
659         monitor_check_interval = nframes / 10;
660         last_monitor_check = 0;
661
662         if (_session) {
663                 _session->set_frame_rate (nframes);
664         }
665
666         SampleRateChanged (nframes); /* EMIT SIGNAL */
667
668         return 0;
669 }
670
671 void
672 AudioEngine::jack_latency_callback (jack_latency_callback_mode_t mode)
673 {
674         if (_session) {
675                 _session->update_latency (mode == JackPlaybackLatency);
676         }
677 }
678
679 int
680 AudioEngine::_bufsize_callback (pframes_t nframes, void *arg)
681 {
682         return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
683 }
684
685 int
686 AudioEngine::jack_bufsize_callback (pframes_t nframes)
687 {
688         /* if the size has not changed, this should be a no-op */
689
690         if (nframes == _buffer_size) {
691                 return 0;
692         }
693
694         GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
695
696         _buffer_size = nframes;
697         _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
698         last_monitor_check = 0;
699
700         if (jack_port_type_get_buffer_size) {
701                 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
702                 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
703         } else {
704
705                 /* Old version of JACK.
706
707                    These crude guesses, see below where we try to get the right answers.
708
709                    Note that our guess for MIDI deliberatey tries to overestimate
710                    by a little. It would be nicer if we could get the actual
711                    size from a port, but we have to use this estimate in the
712                    event that there are no MIDI ports currently. If there are
713                    the value will be adjusted below.
714                 */
715
716                 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
717                 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
718         }
719
720         {
721                 Glib::Threads::Mutex::Lock lm (_process_lock);
722
723                 boost::shared_ptr<Ports> p = ports.reader();
724
725                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
726                         i->second->reset();
727                 }
728         }
729
730         if (_session) {
731                 _session->set_block_size (_buffer_size);
732         }
733
734         return 0;
735 }
736
737 void
738 AudioEngine::stop_metering_thread ()
739 {
740         if (m_meter_thread) {
741                 g_atomic_int_set (&m_meter_exit, 1);
742                 m_meter_thread->join ();
743                 m_meter_thread = 0;
744         }
745 }
746
747 void
748 AudioEngine::start_metering_thread ()
749 {
750         if (m_meter_thread == 0) {
751                 g_atomic_int_set (&m_meter_exit, 0);
752                 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
753         }
754 }
755
756 void
757 AudioEngine::meter_thread ()
758 {
759         pthread_set_name (X_("meter"));
760         while (true) {
761                 Glib::usleep (10000);
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                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1128 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
1129                 switch (code) {
1130                 case JackBackendError:
1131                         ae->Halted(reason); /* EMIT SIGNAL */
1132                         break;
1133                 default:
1134                         ae->Halted(""); /* EMIT SIGNAL */
1135                 }
1136 #else
1137                 ae->Halted(""); /* EMIT SIGNAL */
1138 #endif
1139         }
1140 }
1141
1142 void
1143 AudioEngine::halted (void *arg)
1144 {
1145         cerr << "HALTED by JACK\n";
1146
1147         /* called from jack shutdown handler  */
1148
1149         AudioEngine* ae = static_cast<AudioEngine *> (arg);
1150         bool was_running = ae->_running;
1151
1152         ae->stop_metering_thread ();
1153
1154         ae->_running = false;
1155         ae->_buffer_size = 0;
1156         ae->_frame_rate = 0;
1157         ae->_jack = 0;
1158
1159         if (was_running) {
1160                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1161                 ae->Halted(""); /* EMIT SIGNAL */
1162         }
1163 }
1164
1165 void
1166 AudioEngine::died ()
1167 {
1168         /* called from a signal handler for SIGPIPE */
1169
1170         stop_metering_thread ();
1171
1172         _running = false;
1173         _buffer_size = 0;
1174         _frame_rate = 0;
1175         _jack = 0;
1176 }
1177
1178 bool
1179 AudioEngine::can_request_hardware_monitoring ()
1180 {
1181         GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1182         const char ** ports;
1183
1184         if ((ports = jack_get_ports (_priv_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) {
1185                 return false;
1186         }
1187
1188         free (ports);
1189
1190         return true;
1191 }
1192
1193 ChanCount
1194 AudioEngine::n_physical (unsigned long flags) const
1195 {
1196         ChanCount c;
1197
1198         GET_PRIVATE_JACK_POINTER_RET (_jack, c);
1199
1200         const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
1201         if (ports == 0) {
1202                 return c;
1203         }
1204
1205         for (uint32_t i = 0; ports[i]; ++i) {
1206                 if (!strstr (ports[i], "Midi-Through")) {
1207                         DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
1208                         c.set (t, c.get (t) + 1);
1209                 }
1210         }
1211
1212         free (ports);
1213
1214         return c;
1215 }
1216
1217 ChanCount
1218 AudioEngine::n_physical_inputs () const
1219 {
1220         return n_physical (JackPortIsInput);
1221 }
1222
1223 ChanCount
1224 AudioEngine::n_physical_outputs () const
1225 {
1226         return n_physical (JackPortIsOutput);
1227 }
1228
1229 void
1230 AudioEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
1231 {
1232         GET_PRIVATE_JACK_POINTER (_jack);
1233         const char ** ports;
1234
1235         if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
1236                 return;
1237         }
1238
1239         if (ports) {
1240                 for (uint32_t i = 0; ports[i]; ++i) {
1241                         if (strstr (ports[i], "Midi-Through")) {
1242                                 continue;
1243                         }
1244                         phy.push_back (ports[i]);
1245                 }
1246                 free (ports);
1247         }
1248 }
1249
1250 /** Get physical ports for which JackPortIsOutput is set; ie those that correspond to
1251  *  a physical input connector.
1252  */
1253 void
1254 AudioEngine::get_physical_inputs (DataType type, vector<string>& ins)
1255 {
1256         get_physical (type, JackPortIsOutput, ins);
1257 }
1258
1259 /** Get physical ports for which JackPortIsInput is set; ie those that correspond to
1260  *  a physical output connector.
1261  */
1262 void
1263 AudioEngine::get_physical_outputs (DataType type, vector<string>& outs)
1264 {
1265         get_physical (type, JackPortIsInput, outs);
1266 }
1267
1268 void
1269 AudioEngine::transport_stop ()
1270 {
1271         GET_PRIVATE_JACK_POINTER (_jack);
1272         jack_transport_stop (_priv_jack);
1273 }
1274
1275 void
1276 AudioEngine::transport_start ()
1277 {
1278         GET_PRIVATE_JACK_POINTER (_jack);
1279         jack_transport_start (_priv_jack);
1280 }
1281
1282 void
1283 AudioEngine::transport_locate (framepos_t where)
1284 {
1285         GET_PRIVATE_JACK_POINTER (_jack);
1286         jack_transport_locate (_priv_jack, where);
1287 }
1288
1289 AudioEngine::TransportState
1290 AudioEngine::transport_state ()
1291 {
1292         GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
1293         jack_position_t pos;
1294         return (TransportState) jack_transport_query (_priv_jack, &pos);
1295 }
1296
1297 int
1298 AudioEngine::reset_timebase ()
1299 {
1300         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1301         if (_session) {
1302                 if (_session->config.get_jack_time_master()) {
1303                         return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
1304                 } else {
1305                         return jack_release_timebase (_jack);
1306                 }
1307         }
1308         return 0;
1309 }
1310
1311 int
1312 AudioEngine::freewheel (bool onoff)
1313 {
1314         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1315
1316         if (onoff != _freewheeling) {
1317                 return jack_set_freewheel (_priv_jack, onoff);
1318
1319         } else {
1320                 /* already doing what has been asked for */
1321                 return 0;
1322         }
1323 }
1324
1325 void
1326 AudioEngine::remove_all_ports ()
1327 {
1328         /* make sure that JACK callbacks that will be invoked as we cleanup
1329          * ports know that they have nothing to do.
1330          */
1331
1332         port_remove_in_progress = true;
1333
1334         /* process lock MUST be held by caller
1335         */
1336
1337         {
1338                 RCUWriter<Ports> writer (ports);
1339                 boost::shared_ptr<Ports> ps = writer.get_copy ();
1340                 ps->clear ();
1341         }
1342
1343         /* clear dead wood list in RCU */
1344
1345         ports.flush ();
1346
1347         port_remove_in_progress = false;
1348 }
1349
1350 int
1351 AudioEngine::connect_to_jack (string client_name, string session_uuid)
1352 {
1353         EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
1354         boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
1355         jack_status_t status;
1356
1357         /* revert all environment settings back to whatever they were when ardour started
1358          */
1359
1360         if (global_epa) {
1361                 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
1362                 global_epa->restore ();
1363         }
1364
1365         jack_client_name = client_name; /* might be reset below */
1366 #ifdef HAVE_JACK_SESSION
1367         if (! session_uuid.empty())
1368             _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
1369         else
1370 #endif
1371         _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
1372
1373         if (_jack == NULL) {
1374                 // error message is not useful here
1375                 return -1;
1376         }
1377
1378         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1379
1380         if (status & JackNameNotUnique) {
1381                 jack_client_name = jack_get_client_name (_priv_jack);
1382         }
1383
1384         return 0;
1385 }
1386
1387 int
1388 AudioEngine::disconnect_from_jack ()
1389 {
1390         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1391
1392         if (_running) {
1393                 stop_metering_thread ();
1394         }
1395
1396         {
1397                 Glib::Threads::Mutex::Lock lm (_process_lock);
1398                 jack_client_close (_priv_jack);
1399                 _jack = 0;
1400         }
1401
1402         _buffer_size = 0;
1403         _frame_rate = 0;
1404         _raw_buffer_sizes.clear();
1405
1406         if (_running) {
1407                 _running = false;
1408                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
1409                 Stopped(); /* EMIT SIGNAL */
1410         }
1411
1412         return 0;
1413 }
1414
1415 int
1416 AudioEngine::reconnect_to_jack ()
1417 {
1418         if (_running) {
1419                 disconnect_from_jack ();
1420                 /* XXX give jackd a chance */
1421                 Glib::usleep (250000);
1422         }
1423
1424         if (connect_to_jack (jack_client_name, "")) {
1425                 error << _("failed to connect to JACK") << endmsg;
1426                 return -1;
1427         }
1428
1429         Ports::iterator i;
1430
1431         boost::shared_ptr<Ports> p = ports.reader ();
1432
1433         for (i = p->begin(); i != p->end(); ++i) {
1434                 if (i->second->reestablish ()) {
1435                         break;
1436                 }
1437         }
1438
1439         if (i != p->end()) {
1440                 /* failed */
1441                 remove_all_ports ();
1442                 return -1;
1443         }
1444
1445         GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
1446
1447         MIDI::Manager::instance()->reestablish (_priv_jack);
1448
1449         if (_session) {
1450                 _session->reset_jack_connection (_priv_jack);
1451                 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
1452                 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
1453         }
1454
1455         last_monitor_check = 0;
1456
1457         set_jack_callbacks ();
1458
1459         if (jack_activate (_priv_jack) == 0) {
1460                 _running = true;
1461                 _has_run = true;
1462         } else {
1463                 return -1;
1464         }
1465
1466         /* re-establish connections */
1467
1468         for (i = p->begin(); i != p->end(); ++i) {
1469                 i->second->reconnect ();
1470         }
1471
1472         MIDI::Manager::instance()->reconnect ();
1473
1474         Running (); /* EMIT SIGNAL*/
1475
1476         start_metering_thread ();
1477
1478         return 0;
1479 }
1480
1481 int
1482 AudioEngine::request_buffer_size (pframes_t nframes)
1483 {
1484         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
1485
1486         if (nframes == jack_get_buffer_size (_priv_jack)) {
1487                 return 0;
1488         }
1489
1490         return jack_set_buffer_size (_priv_jack, nframes);
1491 }
1492
1493 string
1494 AudioEngine::make_port_name_relative (string portname) const
1495 {
1496         string::size_type len;
1497         string::size_type n;
1498
1499         len = portname.length();
1500
1501         for (n = 0; n < len; ++n) {
1502                 if (portname[n] == ':') {
1503                         break;
1504                 }
1505         }
1506
1507         if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1508                 return portname.substr (n+1);
1509         }
1510
1511         return portname;
1512 }
1513
1514 string
1515 AudioEngine::make_port_name_non_relative (string portname) const
1516 {
1517         string str;
1518
1519         if (portname.find_first_of (':') != string::npos) {
1520                 return portname;
1521         }
1522
1523         str  = jack_client_name;
1524         str += ':';
1525         str += portname;
1526
1527         return str;
1528 }
1529
1530 bool
1531 AudioEngine::port_is_mine (const string& portname) const
1532 {
1533         if (portname.find_first_of (':') != string::npos) {
1534                 if (portname.substr (0, jack_client_name.length ()) != jack_client_name) {
1535                         return false;
1536                 }
1537         }
1538         return true;
1539 }
1540
1541 bool
1542 AudioEngine::is_realtime () const
1543 {
1544         GET_PRIVATE_JACK_POINTER_RET (_jack,false);
1545         return jack_is_realtime (_priv_jack);
1546 }
1547
1548 int
1549 AudioEngine::create_process_thread (boost::function<void()> f, jack_native_thread_t* thread, size_t stacksize)
1550 {
1551         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
1552         ThreadData* td = new ThreadData (this, f, stacksize);
1553
1554         if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
1555                                        jack_is_realtime (_priv_jack), _start_process_thread, td)) {
1556                 return -1;
1557         }
1558
1559         return 0;
1560 }
1561
1562 bool
1563 AudioEngine::stop_process_thread (jack_native_thread_t thread)
1564 {
1565         /**
1566          * can't use GET_PRIVATE_JACK_POINTER_RET (_jack, 0) here
1567          * because _jack is 0 when this is called. At least for
1568          * Jack 2 _jack arg is not used so it should be OK
1569          */
1570
1571 #if defined(USING_JACK2_EXPANSION_OF_JACK_API) || defined(PLATFORM_WINDOWS)
1572         if (jack_client_stop_thread (_jack, thread) != 0) {
1573                 error << "AudioEngine: cannot stop process thread" << endmsg;
1574                 return false;
1575         }
1576 #else
1577         void* status;
1578         pthread_join (thread, &status);
1579 #endif
1580
1581         return true;
1582 }
1583
1584 void*
1585 AudioEngine::_start_process_thread (void* arg)
1586 {
1587         ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1588         boost::function<void()> f = td->f;
1589         delete td;
1590
1591         f ();
1592
1593         return 0;
1594 }
1595
1596 bool
1597 AudioEngine::port_is_physical (const std::string& portname) const
1598 {
1599         GET_PRIVATE_JACK_POINTER_RET(_jack, false);
1600
1601         jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1602
1603         if (!port) {
1604                 return false;
1605         }
1606
1607         return jack_port_flags (port) & JackPortIsPhysical;
1608 }
1609
1610 void
1611 AudioEngine::request_jack_monitors_input (const std::string& portname, bool yn) const
1612 {
1613         GET_PRIVATE_JACK_POINTER(_jack);
1614
1615         jack_port_t *port = jack_port_by_name (_priv_jack, portname.c_str());
1616
1617         if (!port) {
1618                 return;
1619         }
1620
1621         jack_port_request_monitor (port, yn);
1622 }
1623
1624 void
1625 AudioEngine::update_latencies ()
1626 {
1627         GET_PRIVATE_JACK_POINTER (_jack);
1628         jack_recompute_total_latencies (_priv_jack);
1629 }
1630
1631 void
1632 AudioEngine::destroy ()
1633 {
1634         delete _instance;
1635         _instance = 0;
1636 }
1637