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