63a51b76c488159fd1715953f41d9d0bf8a00a2e
[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
26 #include <glibmm/timer.h>
27 #include <pbd/pthread_utils.h>
28 #include <pbd/stacktrace.h>
29 #include <pbd/unknown_type.h>
30
31 #include <ardour/audioengine.h>
32 #include <ardour/buffer.h>
33 #include <ardour/port.h>
34 #include <ardour/jack_audio_port.h>
35 #include <ardour/jack_midi_port.h>
36 #include <ardour/session.h>
37 #include <ardour/cycle_timer.h>
38 #include <ardour/utils.h>
39 #ifdef VST_SUPPORT
40 #include <fst.h>
41 #endif
42
43 #include <ardour/timestamps.h>
44
45 #include "i18n.h"
46
47 using namespace std;
48 using namespace ARDOUR;
49 using namespace PBD;
50
51 gint AudioEngine::m_meter_exit;
52
53 static void 
54 ardour_jack_error (const char* msg) 
55 {
56         error << "JACK: " << msg << endmsg;
57 }
58
59 AudioEngine::AudioEngine (string client_name) 
60         : ports (new Ports)
61 {
62         session = 0;
63         session_remove_pending = false;
64         _running = false;
65         _has_run = false;
66         last_monitor_check = 0;
67         monitor_check_interval = max_frames;
68         _processed_frames = 0;
69         _freewheeling = false;
70         _usecs_per_cycle = 0;
71         _jack = 0;
72         _frame_rate = 0;
73         _buffer_size = 0;
74         _freewheeling = false;
75         _freewheel_thread_registered = false;
76
77         m_meter_thread = 0;
78         g_atomic_int_set (&m_meter_exit, 0);
79
80         if (connect_to_jack (client_name)) {
81                 throw NoBackendAvailable ();
82         }
83
84         start_metering_thread();
85
86         JackPort::set_engine (this);
87 }
88
89 AudioEngine::~AudioEngine ()
90 {
91         {
92                 Glib::Mutex::Lock tm (_process_lock);
93                 session_removed.signal ();
94                 
95                 if (_running) {
96                         jack_client_close (_jack);
97                 }
98                 
99                 stop_metering_thread ();
100         }
101 }
102
103 jack_client_t*
104 AudioEngine::jack() const
105 {
106         return _jack;
107 }
108
109 void
110 _thread_init_callback (void *arg)
111 {
112         /* make sure that anybody who needs to know about this thread
113            knows about it.
114         */
115
116         PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("Audioengine"), 4096);
117 }
118
119 int
120 AudioEngine::start ()
121 {
122         if (!_running) {
123
124                 if (session) {
125                         nframes_t blocksize = jack_get_buffer_size (_jack);
126
127                         session->set_block_size (blocksize);
128                         session->set_frame_rate (jack_get_sample_rate (_jack));
129
130                         /* page in as much of the session process code as we
131                            can before we really start running.
132                         */
133
134                         session->process (blocksize);
135                         session->process (blocksize);
136                         session->process (blocksize);
137                         session->process (blocksize);
138                         session->process (blocksize);
139                         session->process (blocksize);
140                         session->process (blocksize);
141                         session->process (blocksize);
142                 }
143
144                 _processed_frames = 0;
145                 last_monitor_check = 0;
146
147                 jack_on_shutdown (_jack, halted, this);
148                 jack_set_graph_order_callback (_jack, _graph_order_callback, this);
149                 jack_set_thread_init_callback (_jack, _thread_init_callback, this);
150                 jack_set_process_callback (_jack, _process_callback, this);
151                 jack_set_sample_rate_callback (_jack, _sample_rate_callback, this);
152                 jack_set_buffer_size_callback (_jack, _bufsize_callback, this);
153                 jack_set_xrun_callback (_jack, _xrun_callback, this);
154                 jack_set_sync_callback (_jack, _jack_sync_callback, this);
155                 jack_set_freewheel_callback (_jack, _freewheel_callback, this);
156
157                 if (Config->get_jack_time_master()) {
158                         jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this);
159                 }
160
161                 if (jack_activate (_jack) == 0) {
162                         _running = true;
163                         _has_run = true;
164                         Running(); /* EMIT SIGNAL */
165                 } else {
166                         // error << _("cannot activate JACK client") << endmsg;
167                 }
168         }
169
170         return _running ? 0 : -1;
171 }
172
173 int
174 AudioEngine::stop (bool forever)
175 {
176         if (_running) {
177                 _running = false;
178                 if (forever) {
179                         jack_client_t* foo = _jack;
180                         _jack = 0;
181                         jack_client_close (foo);
182                         stop_metering_thread ();
183                 } else {
184                         jack_deactivate (_jack);
185                 }
186                 Stopped(); /* EMIT SIGNAL */
187         }
188
189         return _running ? -1 : 0;
190 }
191
192
193 bool
194 AudioEngine::get_sync_offset (nframes_t& offset) const
195 {
196
197 #ifdef HAVE_JACK_VIDEO_SUPPORT
198
199         jack_position_t pos;
200         
201         (void) jack_transport_query (_jack, &pos);
202
203         if (pos.valid & JackVideoFrameOffset) {
204                 offset = pos.video_offset;
205                 return true;
206         }
207
208 #endif
209
210         return false;
211 }
212
213 void
214 AudioEngine::_jack_timebase_callback (jack_transport_state_t state, nframes_t nframes,
215                                       jack_position_t* pos, int new_position, void *arg)
216 {
217         static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
218 }
219
220 void
221 AudioEngine::jack_timebase_callback (jack_transport_state_t state, nframes_t nframes,
222                                      jack_position_t* pos, int new_position)
223 {
224         if (_jack && session && session->synced_to_jack()) {
225                 session->jack_timebase_callback (state, nframes, pos, new_position);
226         }
227 }
228
229 int
230 AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
231 {
232         return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
233 }
234
235 int
236 AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
237 {
238         if (_jack && session) {
239                 return session->jack_sync_callback (state, pos);
240         }
241
242         return true;
243 }
244
245 int
246 AudioEngine::_xrun_callback (void *arg)
247 {
248         AudioEngine* ae = static_cast<AudioEngine*> (arg);
249         if (ae->jack()) {
250                 ae->Xrun (); /* EMIT SIGNAL */
251         }
252         return 0;
253 }
254
255 int
256 AudioEngine::_graph_order_callback (void *arg)
257 {
258         AudioEngine* ae = static_cast<AudioEngine*> (arg);
259         if (ae->jack()) {
260                 ae->GraphReordered (); /* EMIT SIGNAL */
261         }
262         return 0;
263 }
264
265 /** Wrapped which is called by JACK as its process callback.  It is just
266  * here to get us back into C++ land by calling AudioEngine::process_callback()
267  * @param nframes Number of frames passed by JACK.
268  * @param arg User argument passed by JACK, which will be the AudioEngine*.
269  */
270 int
271 AudioEngine::_process_callback (nframes_t nframes, void *arg)
272 {
273         return static_cast<AudioEngine *> (arg)->process_callback (nframes);
274 }
275
276 void
277 AudioEngine::_freewheel_callback (int onoff, void *arg)
278 {
279         static_cast<AudioEngine*>(arg)->_freewheeling = onoff;
280 }
281
282 /** Method called by JACK (via _process_callback) which says that there
283  * is work to be done.
284  * @param nframes Number of frames to process.
285  */
286 int
287 AudioEngine::process_callback (nframes_t nframes)
288 {
289         // CycleTimer ct ("AudioEngine::process");
290         Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
291
292         /// The number of frames that will have been processed when we've finished
293         nframes_t next_processed_frames;
294         
295         /* handle wrap around of total frames counter */
296
297         if (max_frames - _processed_frames < nframes) {
298                 next_processed_frames = nframes - (max_frames - _processed_frames);
299         } else {
300                 next_processed_frames = _processed_frames + nframes;
301         }
302
303         if (!tm.locked() || session == 0) {
304                 /* return having done nothing */
305                 _processed_frames = next_processed_frames;
306                 return 0;
307         }
308
309         if (session_remove_pending) {
310                 /* perform the actual session removal */
311                 session = 0;
312                 session_remove_pending = false;
313                 session_removed.signal();
314                 _processed_frames = next_processed_frames;
315                 return 0;
316         }
317
318         if (_freewheeling) {
319                 /* emit the Freewheel signal and stop freewheeling in the event of trouble */
320                 if (Freewheel (nframes)) {
321                         cerr << "Freewheeling returned non-zero!\n";
322                         _freewheeling = false;
323                         jack_set_freewheel (_jack, false);
324                 }
325                 return 0;
326         }
327
328         boost::shared_ptr<Ports> p = ports.reader();
329
330         // Prepare ports (ie read data if necessary)
331         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
332                 (*i)->cycle_start (nframes);
333         }
334         
335         if (session) {
336                 session->process (nframes);
337         }
338
339         if (!_running) {
340                 _processed_frames = next_processed_frames;
341                 return 0;
342         }
343         
344         // Finalize ports (ie write data if necessary)
345         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
346                 (*i)->cycle_end ();
347         }
348
349         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
350
351                 boost::shared_ptr<Ports> p = ports.reader();
352
353                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
354                         
355                         Port *port = (*i);
356                         bool x;
357                         
358                         if (port->_last_monitor != (x = port->monitoring_input ())) {
359                                 port->_last_monitor = x;
360                                 /* XXX I think this is dangerous, due to 
361                                    a likely mutex in the signal handlers ...
362                                 */
363                                  port->MonitorInputChanged (x); /* EMIT SIGNAL */
364                         }
365                 }
366                 last_monitor_check = next_processed_frames;
367         }
368
369         _processed_frames = next_processed_frames;
370         return 0;
371 }
372
373 int
374 AudioEngine::_sample_rate_callback (nframes_t nframes, void *arg)
375 {
376         return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
377 }
378
379 int
380 AudioEngine::jack_sample_rate_callback (nframes_t nframes)
381 {
382         _frame_rate = nframes;
383         _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
384         
385         /* check for monitor input change every 1/10th of second */
386
387         monitor_check_interval = nframes / 10;
388         last_monitor_check = 0;
389         
390         if (session) {
391                 session->set_frame_rate (nframes);
392         }
393
394         SampleRateChanged (nframes); /* EMIT SIGNAL */
395
396         return 0;
397 }
398
399 int
400 AudioEngine::_bufsize_callback (nframes_t nframes, void *arg)
401 {
402         return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
403 }
404
405 int
406 AudioEngine::jack_bufsize_callback (nframes_t nframes)
407 {
408         _buffer_size = nframes;
409         _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
410         last_monitor_check = 0;
411
412         boost::shared_ptr<Ports> p = ports.reader();
413
414         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
415                 (*i)->reset();
416         }
417
418         if (session) {
419                 session->set_block_size (_buffer_size);
420         }
421
422         return 0;
423 }
424
425 void
426 AudioEngine::stop_metering_thread ()
427 {
428         if (m_meter_thread) {
429                 g_atomic_int_set (&m_meter_exit, 1);
430                 m_meter_thread->join ();
431                 m_meter_thread = 0;
432         }
433 }
434
435 void
436 AudioEngine::start_metering_thread ()
437 {
438         if (m_meter_thread == 0) {
439                 m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread),
440                                 500000, true, true, Glib::THREAD_PRIORITY_NORMAL);
441         }
442 }
443
444 void
445 AudioEngine::meter_thread ()
446 {
447         while (true) {
448                 Glib::usleep (10000); /* 1/100th sec interval */
449                 if (g_atomic_int_get(&m_meter_exit)) {
450                         break;
451                 }
452                 IO::update_meters ();
453         }
454 }
455
456 void 
457 AudioEngine::set_session (Session *s)
458 {
459         Glib::Mutex::Lock pl (_process_lock);
460
461         if (!session) {
462
463                 session = s;
464
465                 nframes_t blocksize = jack_get_buffer_size (_jack);
466                 
467                 /* page in as much of the session process code as we
468                    can before we really start running.
469                 */
470                 
471                 boost::shared_ptr<Ports> p = ports.reader();
472
473                 for (Ports::iterator i = p->begin(); i != p->end(); ++i)
474                         (*i)->cycle_start (blocksize);
475
476                 s->process (blocksize);
477                 s->process (blocksize);
478                 s->process (blocksize);
479                 s->process (blocksize);
480                 s->process (blocksize);
481                 s->process (blocksize);
482                 s->process (blocksize);
483                 s->process (blocksize);
484
485                 for (Ports::iterator i = p->begin(); i != p->end(); ++i)
486                         (*i)->cycle_end ();
487
488         }
489 }
490
491 void 
492 AudioEngine::remove_session ()
493 {
494         Glib::Mutex::Lock lm (_process_lock);
495
496         if (_running) {
497
498                 if (session) {
499                         session_remove_pending = true;
500                         session_removed.wait(_process_lock);
501                 }
502
503         } else {
504                 session = 0;
505         }
506         
507         remove_all_ports ();
508 }
509
510 Port *
511 AudioEngine::register_port (DataType type, const string& portname, bool input)
512 {
513         Port* newport = 0;
514
515         try {
516                 if (type == DataType::AUDIO)
517                         newport = new JackAudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
518                 else if (type == DataType::MIDI)
519                         newport = new JackMidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
520                 else
521                         throw unknown_type();
522         
523                 if (newport != 0) {
524                         RCUWriter<Ports> writer (ports);
525                         boost::shared_ptr<Ports> ps = writer.get_copy ();
526                         ps->insert (ps->begin(), newport);
527                         /* writer goes out of scope, forces update */
528                 }
529         
530                 return newport;
531         }
532
533         catch (...) {
534                 throw PortRegistrationFailure();
535         }
536 }
537
538 Port *
539 AudioEngine::register_input_port (DataType type, const string& portname)
540 {
541         return register_port (type, portname, true);
542 }
543
544 Port *
545 AudioEngine::register_output_port (DataType type, const string& portname)
546 {
547         return register_port (type, portname, false);
548 }
549
550 int          
551 AudioEngine::unregister_port (Port& port)
552 {
553         if (!_running) { 
554                 /* probably happening when the engine has been halted by JACK,
555                    in which case, there is nothing we can do here.
556                    */
557                 return 0;
558         }
559
560         {
561                 
562                 RCUWriter<Ports> writer (ports);
563                 boost::shared_ptr<Ports> ps = writer.get_copy ();
564                 
565                 for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) {
566                         if ((*i) == &port) {
567                                 remove_connections_for (port);
568                                 cerr << "eraseing " << (*i)->name() << endl;
569                                 delete *i;
570                                 ps->erase (i);
571                                 break;
572                         }
573                 }
574                 
575                 /* writer goes out of scope, forces update */
576         }
577
578         return 0;
579 }
580
581 int 
582 AudioEngine::connect (const string& source, const string& destination)
583 {
584         if (!_running) {
585                 if (!_has_run) {
586                         fatal << _("connect called before engine was started") << endmsg;
587                         /*NOTREACHED*/
588                 } else {
589                         return -1;
590                 }
591         }
592         
593         string s = make_port_name_non_relative (source);
594         string d = make_port_name_non_relative (destination);
595
596         int ret = jack_connect (_jack, s.c_str(), d.c_str());
597
598         if (ret == 0) {
599                 pair<string,string> c (s, d);
600                 port_connections.push_back (c);
601         } else if (ret == EEXIST) {
602                 error << string_compose(_("AudioEngine: connection already exists: %1 (%2) to %3 (%4)"), 
603                                  source, s, destination, d) 
604                       << endmsg;
605         } else {
606                 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"), 
607                                  source, s, destination, d) 
608                       << endmsg;
609         }
610
611         return ret;
612 }
613
614 int 
615 AudioEngine::disconnect (const string& source, const string& destination)
616 {
617         if (!_running) {
618                 if (!_has_run) {
619                         fatal << _("disconnect called before engine was started") << endmsg;
620                         /*NOTREACHED*/
621                 } else {
622                         return -1;
623                 }
624         }
625         
626         string s = make_port_name_non_relative (source);
627         string d = make_port_name_non_relative (destination);
628
629         int ret = jack_disconnect (_jack, s.c_str(), d.c_str());
630
631         if (ret == 0) {
632                 pair<string,string> c (s, d);
633                 PortConnections::iterator i;
634                 
635                 if ((i = find (port_connections.begin(), port_connections.end(), c)) != port_connections.end()) {
636                         port_connections.erase (i);
637                 }
638         }
639          
640         return ret;
641 }
642
643 int
644 AudioEngine::disconnect (Port& port)
645 {
646         if (!_running) {
647                 if (!_has_run) {
648                         fatal << _("disconnect called before engine was started") << endmsg;
649                         /*NOTREACHED*/
650                 } else {
651                         return -1;
652                 }
653         }
654
655         int ret = port.disconnect ();
656
657         if (ret == 0) {
658                 remove_connections_for (port);
659         }
660
661         return ret;
662
663 }
664
665 ARDOUR::nframes_t
666 AudioEngine::frame_rate ()
667 {
668         if (_jack) {
669                 if (_frame_rate == 0) {
670                         return (_frame_rate = jack_get_sample_rate (_jack));
671                 } else {
672                         return _frame_rate;
673                 }
674         } else {
675                 fatal << X_("programming error: AudioEngine::frame_rate() called while disconnected from JACK")
676                       << endmsg;
677                 /*NOTREACHED*/
678                 return 0;
679         }
680 }
681
682 ARDOUR::nframes_t
683 AudioEngine::frames_per_cycle ()
684 {
685         if (_jack) {
686                 if (_buffer_size == 0) {
687                         return (_buffer_size = jack_get_buffer_size (_jack));
688                 } else {
689                         return _buffer_size;
690                 }
691         } else {
692                 fatal << X_("programming error: AudioEngine::frame_rate() called while disconnected from JACK")
693                       << endmsg;
694                 /*NOTREACHED*/
695                 return 0;
696         }
697 }
698
699 /** Get a port by name.
700  * Note this can return NULL, it will NOT create a port if it is not found (any more).
701  */
702 Port *
703 AudioEngine::get_port_by_name (const string& portname, bool keep)
704 {
705         Glib::Mutex::Lock lm (_process_lock);
706
707         if (!_running) {
708                 if (!_has_run) {
709                         fatal << _("get_port_by_name() called before engine was started") << endmsg;
710                         /*NOTREACHED*/
711                 } else {
712                         return 0;
713                 }
714         }
715         
716         boost::shared_ptr<Ports> pr = ports.reader();
717         
718         for (Ports::iterator i = pr->begin(); i != pr->end(); ++i) {
719                 if (portname == (*i)->name()) {
720                         return (*i);
721                 }
722         }
723
724         return 0;
725 }
726
727 const char **
728 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
729 {
730         if (!_running) {
731                 if (!_has_run) {
732                         fatal << _("get_ports called before engine was started") << endmsg;
733                         /*NOTREACHED*/
734                 } else {
735                         return 0;
736                 }
737         }
738         return jack_get_ports (_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
739 }
740
741 void
742 AudioEngine::halted (void *arg)
743 {
744         AudioEngine* ae = static_cast<AudioEngine *> (arg);
745
746         ae->_running = false;
747         ae->_buffer_size = 0;
748         ae->_frame_rate = 0;
749         ae->_jack = 0;
750
751         ae->Halted(); /* EMIT SIGNAL */
752 }
753
754 uint32_t
755 AudioEngine::n_physical_outputs () const
756 {
757         const char ** ports;
758         uint32_t i = 0;
759
760         if (!_jack) {
761                 return 0;
762         }
763
764         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
765                 return 0;
766         }
767
768         if (ports) {
769                 for (i = 0; ports[i]; ++i);
770                 free (ports);
771         }
772         return i;
773 }
774
775 uint32_t
776 AudioEngine::n_physical_inputs () const
777 {
778         const char ** ports;
779         uint32_t i = 0;
780         
781         if (!_jack) {
782                 return 0;
783         }
784         
785         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
786                 return 0;
787         }
788
789         if (ports) {
790                 for (i = 0; ports[i]; ++i);
791                 free (ports);
792         }
793         return i;
794 }
795
796 void
797 AudioEngine::get_physical_inputs (vector<string>& ins)
798 {
799         const char ** ports;
800         uint32_t i = 0;
801         
802         if (!_jack) {
803                 return;
804         }
805         
806         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
807                 return;
808         }
809
810         if (ports) {
811                 for (i = 0; ports[i]; ++i) {
812                         ins.push_back (ports[i]);
813                 }
814                 free (ports);
815         }
816 }
817
818 void
819 AudioEngine::get_physical_outputs (vector<string>& outs)
820 {
821         const char ** ports;
822         uint32_t i = 0;
823         
824         if (!_jack) {
825                 return;
826         }
827         
828         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
829                 return;
830         }
831
832         if (ports) {
833                 for (i = 0; ports[i]; ++i) {
834                         outs.push_back (ports[i]);
835                 }
836                 free (ports);
837         }
838 }
839
840 string
841 AudioEngine::get_nth_physical (DataType type, uint32_t n, int flag)
842 {
843         const char ** ports;
844         uint32_t i;
845         string ret;
846
847         assert(type != DataType::NIL);
848
849         if (!_running || !_jack) {
850                 if (!_has_run) {
851                         fatal << _("get_nth_physical called before engine was started") << endmsg;
852                         /*NOTREACHED*/
853                 } else {
854                         return "";
855                 }
856         }
857
858         ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|flag);
859         
860         if (ports == 0) {
861                 return "";
862         }
863
864         for (i = 0; i < n && ports[i]; ++i);
865
866         if (ports[i]) {
867                 ret = ports[i];
868         }
869
870         free ((char *) ports);
871
872         return ret;
873 }
874
875 ARDOUR::nframes_t
876 AudioEngine::get_port_total_latency (const Port& port)
877 {
878         return port.total_latency ();
879 }
880
881 void
882 AudioEngine::update_total_latency (const Port& port)
883 {
884         if (!_jack) {
885                 fatal << _("update_total_latency() called with no JACK client connection") << endmsg;
886                 /*NOTREACHED*/
887         }
888
889         if (!_running) {
890                 if (!_has_run) {
891                         fatal << _("update_total_latency() called before engine was started") << endmsg;
892                         /*NOTREACHED*/
893                 } 
894         }
895
896         port.recompute_total_latency ();
897 }
898
899 void
900 AudioEngine::transport_stop ()
901 {
902         // cerr << "tell JACK to stop\n";
903         if (_jack) {
904                 jack_transport_stop (_jack);
905         }
906 }
907
908 void
909 AudioEngine::transport_start ()
910 {
911         // cerr << "tell JACK to start\n";
912         if (_jack) {
913                 jack_transport_start (_jack);
914         }
915 }
916
917 void
918 AudioEngine::transport_locate (nframes_t where)
919 {
920         // cerr << "tell JACK to locate to " << where << endl;
921         if (_jack) {
922                 jack_transport_locate (_jack, where);
923         }
924 }
925
926 AudioEngine::TransportState
927 AudioEngine::transport_state ()
928 {
929         if (_jack) {
930                 jack_position_t pos;
931                 return (TransportState) jack_transport_query (_jack, &pos);
932         } else {
933                 return (TransportState) JackTransportStopped;
934         }
935 }
936
937 int
938 AudioEngine::reset_timebase ()
939 {
940         if (_jack) {
941                 if (Config->get_jack_time_master()) {
942                         return jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this);
943                 } else {
944                         return jack_release_timebase (_jack);
945                 }
946         } else {
947                 return -1;
948         }
949 }
950
951 int
952 AudioEngine::freewheel (bool onoff)
953 {
954         if (_jack) {
955
956                 if (onoff) {
957                         _freewheel_thread_registered = false;
958                 }
959
960                 return jack_set_freewheel (_jack, onoff);
961
962         } else {
963                 return -1;
964         }
965 }
966
967 void
968 AudioEngine::remove_all_ports ()
969 {
970         /* process lock MUST be held */
971
972         {
973                 RCUWriter<Ports> writer (ports);
974                 boost::shared_ptr<Ports> ps = writer.get_copy ();
975                 ps->clear ();
976         }
977
978         port_connections.clear ();
979 }
980
981 void
982 AudioEngine::remove_connections_for (Port& port)
983 {
984         for (PortConnections::iterator i = port_connections.begin(); i != port_connections.end(); ) {
985                 PortConnections::iterator tmp;
986                 
987                 tmp = i;
988                 ++tmp;
989                 
990                 if ((*i).first == port.name()) {
991                         port_connections.erase (i);
992                 }
993
994                 i = tmp;
995         }
996 }
997
998 #ifdef HAVE_JACK_CLIENT_OPEN
999
1000 int
1001 AudioEngine::connect_to_jack (string client_name)
1002 {
1003         jack_options_t options = JackNullOption;
1004         jack_status_t status;
1005         const char *server_name = NULL;
1006
1007         jack_client_name = client_name; /* might be reset below */
1008
1009         _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name);
1010         
1011         if (_jack == NULL) {
1012
1013                 if (status & JackServerFailed) {
1014                         error << _("Unable to connect to JACK server") << endmsg;
1015                 }
1016                 
1017                 // error message is not useful here
1018                 return -1;
1019         }
1020
1021         if (status & JackServerStarted) {
1022                 info << _("JACK server started") << endmsg;
1023         }
1024
1025         if (status & JackNameNotUnique) {
1026                 jack_client_name = jack_get_client_name (_jack);
1027         }
1028
1029         jack_set_error_function (ardour_jack_error);
1030         
1031         return 0;
1032 }
1033
1034 #else
1035
1036 int
1037 AudioEngine::connect_to_jack (string client_name)
1038 {
1039         jack_client_name = client_name;
1040
1041         if ((_jack = jack_client_new (client_name.c_str())) == NULL) {
1042                 return -1;
1043         }
1044
1045         return 0;
1046 }
1047
1048 #endif /* HAVE_JACK_CLIENT_OPEN */
1049
1050 int 
1051 AudioEngine::disconnect_from_jack ()
1052 {
1053         if (_jack == 0) {
1054                 return 0;
1055         }
1056
1057         jack_client_close (_jack);
1058
1059         _buffer_size = 0;
1060         _frame_rate = 0;
1061
1062         if (_running) {
1063                 _running = false;
1064                 Stopped(); /* EMIT SIGNAL */
1065         }
1066
1067         _jack = 0;
1068         return 0;
1069 }
1070
1071 int
1072 AudioEngine::reconnect_to_jack ()
1073 {
1074         if (_jack) {
1075                 disconnect_from_jack ();
1076                 /* XXX give jackd a chance */
1077                 Glib::usleep (250000);
1078         }
1079
1080         if (connect_to_jack (jack_client_name)) {
1081                 error << _("failed to connect to JACK") << endmsg;
1082                 return -1;
1083         }
1084
1085         Ports::iterator i;
1086
1087         boost::shared_ptr<Ports> p = ports.reader ();
1088
1089         for (i = p->begin(); i != p->end(); ++i) {
1090
1091                 if ((*i)->reestablish ()) {
1092                         break;
1093                 } 
1094         }
1095
1096         if (i != p->end()) {
1097                 /* failed */
1098                 remove_all_ports ();
1099                 return -1;
1100         } 
1101
1102
1103         if (session) {
1104                 session->reset_jack_connection (_jack);
1105                 nframes_t blocksize = jack_get_buffer_size (_jack);
1106                 session->set_block_size (blocksize);
1107                 session->set_frame_rate (jack_get_sample_rate (_jack));
1108         }
1109
1110         last_monitor_check = 0;
1111         
1112         jack_on_shutdown (_jack, halted, this);
1113         jack_set_graph_order_callback (_jack, _graph_order_callback, this);
1114         jack_set_thread_init_callback (_jack, _thread_init_callback, this);
1115         jack_set_process_callback (_jack, _process_callback, this);
1116         jack_set_sample_rate_callback (_jack, _sample_rate_callback, this);
1117         jack_set_buffer_size_callback (_jack, _bufsize_callback, this);
1118         jack_set_xrun_callback (_jack, _xrun_callback, this);
1119         jack_set_sync_callback (_jack, _jack_sync_callback, this);
1120         jack_set_freewheel_callback (_jack, _freewheel_callback, this);
1121         
1122         if (Config->get_jack_time_master()) {
1123                 jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this);
1124         }
1125         
1126         if (jack_activate (_jack) == 0) {
1127                 _running = true;
1128                 _has_run = true;
1129         } else {
1130                 return -1;
1131         }
1132
1133         /* re-establish connections */
1134         
1135         for (PortConnections::iterator i = port_connections.begin(); i != port_connections.end(); ++i) {
1136                 
1137                 int err;
1138                 
1139                 if ((err = jack_connect (_jack, (*i).first.c_str(), (*i).second.c_str())) != 0) {
1140                         if (err != EEXIST) {
1141                                 error << string_compose (_("could not reconnect %1 and %2 (err = %3)"),
1142                                                   (*i).first, (*i).second, err)
1143                                       << endmsg;
1144                         }
1145                 }
1146         }
1147
1148         Running (); /* EMIT SIGNAL*/
1149
1150         return 0;
1151 }
1152
1153 int
1154 AudioEngine::request_buffer_size (nframes_t nframes)
1155 {
1156         if (_jack) {
1157
1158                 if (nframes == jack_get_buffer_size (_jack)) {
1159                         return 0;
1160                 }
1161
1162                 return jack_set_buffer_size (_jack, nframes);
1163
1164         } else {
1165                 return -1;
1166         }
1167 }
1168
1169 void
1170 AudioEngine::update_total_latencies ()
1171 {
1172 #ifdef HAVE_JACK_RECOMPUTE_LATENCIES
1173         jack_recompute_total_latencies (_jack);
1174 #endif
1175 }
1176                 
1177 string
1178 AudioEngine::make_port_name_relative (string portname)
1179 {
1180         string::size_type len;
1181         string::size_type n;
1182         
1183         len = portname.length();
1184
1185         for (n = 0; n < len; ++n) {
1186                 if (portname[n] == ':') {
1187                         break;
1188                 }
1189         }
1190         
1191         if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1192                 return portname.substr (n+1);
1193         }
1194
1195         return portname;
1196 }
1197
1198 string
1199 AudioEngine::make_port_name_non_relative (string portname)
1200 {
1201         string str;
1202
1203         if (portname.find_first_of (':') != string::npos) {
1204                 return portname;
1205         }
1206
1207         str  = jack_client_name;
1208         str += ':';
1209         str += portname;
1210         
1211         return str;
1212 }
1213
1214 bool
1215 AudioEngine::is_realtime () const
1216 {
1217         if (_jack) {
1218                 return jack_is_realtime (_jack);
1219         } else {
1220                 return false;
1221         }
1222 }