13feb3f3f38541a18fb6f283fc9543b7243f89fc
[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         if (connect_to_jack (client_name)) {
71                 throw NoBackendAvailable ();
72         }
73
74         start_metering_thread();
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 void
746 AudioEngine::get_physical_inputs (vector<string>& ins)
747 {
748         const char ** ports;
749         uint32_t i = 0;
750         
751         if (!_jack) {
752                 return;
753         }
754         
755         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
756                 return;
757         }
758
759         if (ports) {
760                 for (i = 0; ports[i]; ++i) {
761                         ins.push_back (ports[i]);
762                 }
763                 free (ports);
764         }
765 }
766
767 void
768 AudioEngine::get_physical_outputs (vector<string>& outs)
769 {
770         const char ** ports;
771         uint32_t i = 0;
772         
773         if (!_jack) {
774                 return;
775         }
776         
777         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
778                 return;
779         }
780
781         if (ports) {
782                 for (i = 0; ports[i]; ++i) {
783                         outs.push_back (ports[i]);
784                 }
785                 free (ports);
786         }
787 }
788
789 string
790 AudioEngine::get_nth_physical (uint32_t n, int flag)
791 {
792         const char ** ports;
793         uint32_t i;
794         string ret;
795
796         if (!_running || !_jack) {
797                 if (!_has_run) {
798                         fatal << _("get_nth_physical called before engine was started") << endmsg;
799                         /*NOTREACHED*/
800                 } else {
801                         return "";
802                 }
803         }
804
805         ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|flag);
806         
807         if (ports == 0) {
808                 return "";
809         }
810
811         for (i = 0; i < n && ports[i]; ++i);
812
813         if (ports[i]) {
814                 ret = ports[i];
815         }
816
817         free ((char *) ports);
818
819         return ret;
820 }
821
822 jack_nframes_t
823 AudioEngine::get_port_total_latency (const Port& port)
824 {
825         if (!_jack) {
826                 fatal << _("get_port_total_latency() called with no JACK client connection") << endmsg;
827                 /*NOTREACHED*/
828         }
829
830         if (!_running) {
831                 if (!_has_run) {
832                         fatal << _("get_port_total_latency() called before engine was started") << endmsg;
833                         /*NOTREACHED*/
834                 } 
835         }
836
837         return jack_port_get_total_latency (_jack, port._port);
838 }
839
840 void
841 AudioEngine::transport_stop ()
842 {
843         // cerr << "tell JACK to stop\n";
844         if (_jack) {
845                 jack_transport_stop (_jack);
846         }
847 }
848
849 void
850 AudioEngine::transport_start ()
851 {
852         // cerr << "tell JACK to start\n";
853         if (_jack) {
854                 jack_transport_start (_jack);
855         }
856 }
857
858 void
859 AudioEngine::transport_locate (jack_nframes_t where)
860 {
861         // cerr << "tell JACK to locate to " << where << endl;
862         if (_jack) {
863                 jack_transport_locate (_jack, where);
864         }
865 }
866
867 AudioEngine::TransportState
868 AudioEngine::transport_state ()
869 {
870         if (_jack) {
871                 jack_position_t pos;
872                 return (TransportState) jack_transport_query (_jack, &pos);
873         } else {
874                 return (TransportState) JackTransportStopped;
875         }
876 }
877
878 int
879 AudioEngine::reset_timebase ()
880 {
881         if (_jack) {
882                 if (Config->get_jack_time_master()) {
883                         return jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this);
884                 } else {
885                         return jack_release_timebase (_jack);
886                 }
887         } else {
888                 return -1;
889         }
890 }
891
892 int
893 AudioEngine::freewheel (bool onoff)
894 {
895         if (_jack) {
896
897                 if (onoff) {
898                         _freewheel_thread_registered = false;
899                 }
900
901                 return jack_set_freewheel (_jack, onoff);
902
903         } else {
904                 return -1;
905         }
906 }
907
908 void
909 AudioEngine::remove_all_ports ()
910 {
911         /* process lock MUST be held */
912
913         if (_jack) {
914                 boost::shared_ptr<Ports> p = ports.reader();
915
916                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
917                         jack_port_unregister (_jack, (*i)->_port);
918                 }
919         }
920
921         {
922                 RCUWriter<Ports> writer (ports);
923                 boost::shared_ptr<Ports> ps = writer.get_copy ();
924                 ps->clear ();
925         }
926
927         port_connections.clear ();
928 }
929
930 void
931 AudioEngine::remove_connections_for (Port* port)
932 {
933         for (PortConnections::iterator i = port_connections.begin(); i != port_connections.end(); ) {
934                 PortConnections::iterator tmp;
935                 
936                 tmp = i;
937                 ++tmp;
938                 
939                 if ((*i).first == port->name()) {
940                         port_connections.erase (i);
941                 }
942
943                 i = tmp;
944         }
945 }
946
947 #ifdef HAVE_JACK_CLIENT_OPEN
948
949 int
950 AudioEngine::connect_to_jack (string client_name)
951 {
952         jack_options_t options = JackNullOption;
953         jack_status_t status;
954         const char *server_name = NULL;
955
956         jack_client_name = client_name; /* might be reset below */
957
958         _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name);
959         
960         if (_jack == NULL) {
961
962                 if (status & JackServerFailed) {
963                         error << _("Unable to connect to JACK server") << endmsg;
964                 }
965                 
966                 error << string_compose (_("Could not connect to JACK server as  \"%1\""), jack_client_name) <<  endmsg;
967                 return -1;
968         }
969
970         if (status & JackServerStarted) {
971                 info << _("JACK server started") << endmsg;
972         }
973
974         if (status & JackNameNotUnique) {
975                 jack_client_name = jack_get_client_name (_jack);
976         }
977         
978         return 0;
979 }
980
981 #else
982
983 int
984 AudioEngine::connect_to_jack (string client_name)
985 {
986         jack_client_name = client_name;
987
988         if ((_jack = jack_client_new (client_name.c_str())) == NULL) {
989                 return -1;
990         }
991
992         return 0;
993 }
994
995 #endif /* HAVE_JACK_CLIENT_OPEN */
996
997 int 
998 AudioEngine::disconnect_from_jack ()
999 {
1000         if (_jack == 0) {
1001                 return 0;
1002         }
1003
1004         if (jack_client_close (_jack)) {
1005                 error << _("cannot shutdown connection to JACK") << endmsg;
1006         }
1007
1008         _buffer_size = 0;
1009         _frame_rate = 0;
1010
1011         if (_running) {
1012                 _running = false;
1013                 Stopped(); /* EMIT SIGNAL */
1014         }
1015
1016         _jack = 0;
1017         return 0;
1018 }
1019
1020 int
1021 AudioEngine::reconnect_to_jack ()
1022 {
1023         if (_jack) {
1024                 disconnect_from_jack ();
1025                 /* XXX give jackd a chance */
1026                 Glib::usleep (250000);
1027         }
1028
1029         if (connect_to_jack (jack_client_name)) {
1030                 error << _("failed to connect to JACK") << endmsg;
1031                 return -1;
1032         }
1033
1034         Ports::iterator i;
1035
1036         boost::shared_ptr<Ports> p = ports.reader ();
1037
1038         for (i = p->begin(); i != p->end(); ++i) {
1039
1040                 /* XXX hack hack hack */
1041
1042                 string long_name = (*i)->name();
1043                 string short_name;
1044                 
1045                 short_name = long_name.substr (long_name.find_last_of (':') + 1);
1046
1047                 if (((*i)->_port = jack_port_register (_jack, short_name.c_str(), (*i)->type(), (*i)->flags(), 0)) == 0) {
1048                         error << string_compose (_("could not reregister %1"), (*i)->name()) << endmsg;
1049                         break;
1050                 } else {
1051                 }
1052
1053                 (*i)->reset ();
1054
1055                 if ((*i)->flags() & JackPortIsOutput) {
1056                         (*i)->silence (jack_get_buffer_size (_jack), 0);
1057                 }
1058         }
1059
1060         if (i != p->end()) {
1061                 /* failed */
1062                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
1063                         jack_port_unregister (_jack, (*i)->_port);
1064                 }
1065                 return -1;
1066         } 
1067
1068
1069         if (session) {
1070                 jack_nframes_t blocksize = jack_get_buffer_size (_jack);
1071                 session->set_block_size (blocksize);
1072                 session->set_frame_rate (jack_get_sample_rate (_jack));
1073         }
1074
1075         last_monitor_check = 0;
1076         
1077         jack_on_shutdown (_jack, halted, this);
1078         jack_set_graph_order_callback (_jack, _graph_order_callback, this);
1079         jack_set_thread_init_callback (_jack, _thread_init_callback, this);
1080         jack_set_process_callback (_jack, _process_callback, this);
1081         jack_set_sample_rate_callback (_jack, _sample_rate_callback, this);
1082         jack_set_buffer_size_callback (_jack, _bufsize_callback, this);
1083         jack_set_xrun_callback (_jack, _xrun_callback, this);
1084         jack_set_sync_callback (_jack, _jack_sync_callback, this);
1085         jack_set_freewheel_callback (_jack, _freewheel_callback, this);
1086         
1087         if (Config->get_jack_time_master()) {
1088                 jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this);
1089         }
1090         
1091         if (jack_activate (_jack) == 0) {
1092                 _running = true;
1093                 _has_run = true;
1094         } else {
1095                 return -1;
1096         }
1097
1098         /* re-establish connections */
1099         
1100         for (PortConnections::iterator i = port_connections.begin(); i != port_connections.end(); ++i) {
1101                 
1102                 int err;
1103                 
1104                 if ((err = jack_connect (_jack, (*i).first.c_str(), (*i).second.c_str())) != 0) {
1105                         if (err != EEXIST) {
1106                                 error << string_compose (_("could not reconnect %1 and %2 (err = %3)"),
1107                                                   (*i).first, (*i).second, err)
1108                                       << endmsg;
1109                         }
1110                 }
1111         }
1112
1113         Running (); /* EMIT SIGNAL*/
1114
1115         return 0;
1116 }
1117
1118 int
1119 AudioEngine::request_buffer_size (jack_nframes_t nframes)
1120 {
1121         if (_jack) {
1122                 int ret = jack_set_buffer_size (_jack, nframes);
1123                 return ret;
1124         } else {
1125                 return -1;
1126         }
1127 }
1128
1129 void
1130 AudioEngine::update_total_latencies ()
1131 {
1132 #ifdef HAVE_JACK_RECOMPUTE_LATENCIES
1133         jack_recompute_total_latencies (_jack);
1134 #endif
1135 }
1136                 
1137 string
1138 AudioEngine::make_port_name_relative (string portname)
1139 {
1140         string::size_type len;
1141         string::size_type n;
1142         
1143         len = portname.length();
1144
1145         for (n = 0; n < len; ++n) {
1146                 if (portname[n] == ':') {
1147                         break;
1148                 }
1149         }
1150         
1151         if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1152                 return portname.substr (n+1);
1153         }
1154
1155         return portname;
1156 }
1157
1158 string
1159 AudioEngine::make_port_name_non_relative (string portname)
1160 {
1161         string str;
1162
1163         if (portname.find_first_of (':') != string::npos) {
1164                 return portname;
1165         }
1166
1167         str  = jack_client_name;
1168         str += ':';
1169         str += portname;
1170         
1171         return str;
1172 }
1173