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