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