Merged with trunk R879
[ardour.git] / libs / ardour / audioengine.cc
1 /*
2     Copyright (C) 2002 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <unistd.h>
22 #include <cerrno>
23 #include <vector>
24
25 #include <glibmm/timer.h>
26 #include <pbd/pthread_utils.h>
27 #include <pbd/unknown_type.h>
28
29 #include <ardour/audioengine.h>
30 #include <ardour/buffer.h>
31 #include <ardour/port.h>
32 #include <ardour/audio_port.h>
33 #include <ardour/midi_port.h>
34 #include <ardour/session.h>
35 #include <ardour/cycle_timer.h>
36 #include <ardour/utils.h>
37 #ifdef VST_SUPPORT
38 #include <fst.h>
39 #endif
40
41 #include <ardour/timestamps.h>
42
43 #include "i18n.h"
44
45 using namespace std;
46 using namespace ARDOUR;
47 using namespace PBD;
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         
167 bool
168 AudioEngine::get_sync_offset (jack_nframes_t& offset) const
169 {
170         jack_position_t pos;
171         
172         (void) jack_transport_query (_jack, &pos);
173
174         if (pos.valid & JackVideoFrameOffset) {
175                 offset = pos.video_offset;
176                 return true;
177         }
178
179         return false;
180 }
181
182 void
183 AudioEngine::_jack_timebase_callback (jack_transport_state_t state, jack_nframes_t nframes,
184                                       jack_position_t* pos, int new_position, void *arg)
185 {
186         static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
187 }
188
189 void
190 AudioEngine::jack_timebase_callback (jack_transport_state_t state, jack_nframes_t nframes,
191                                      jack_position_t* pos, int new_position)
192 {
193         if (session && session->synced_to_jack()) {
194                 session->jack_timebase_callback (state, nframes, pos, new_position);
195         }
196 }
197
198 int
199 AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
200 {
201         return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
202 }
203
204 int
205 AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
206 {
207         if (session) {
208                 return session->jack_sync_callback (state, pos);
209         } else {
210                 return true;
211         }
212 }
213
214 int
215 AudioEngine::_xrun_callback (void *arg)
216 {
217          static_cast<AudioEngine *>(arg)->Xrun (); /* EMIT SIGNAL */
218         return 0;
219 }
220
221 int
222 AudioEngine::_graph_order_callback (void *arg)
223 {
224         static_cast<AudioEngine *>(arg)->GraphReordered (); /* EMIT SIGNAL */
225         return 0;
226 }
227
228 int
229 AudioEngine::_process_callback (jack_nframes_t nframes, void *arg)
230 {
231         return static_cast<AudioEngine *> (arg)->process_callback (nframes);
232 }
233
234 void
235 AudioEngine::_freewheel_callback (int onoff, void *arg)
236 {
237         static_cast<AudioEngine*>(arg)->_freewheeling = onoff;
238 }
239
240 int
241 AudioEngine::process_callback (jack_nframes_t nframes)
242 {
243         // CycleTimer ct ("AudioEngine::process");
244         Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
245         jack_nframes_t next_processed_frames;
246         
247         /* handle wrap around of total frames counter */
248
249         if (max_frames - _processed_frames < nframes) {
250                 next_processed_frames = nframes - (max_frames - _processed_frames);
251         } else {
252                 next_processed_frames = _processed_frames + nframes;
253         }
254         
255         if (!tm.locked() || session == 0) {
256                 _processed_frames = next_processed_frames;
257                 return 0;
258         }
259
260         if (session_remove_pending) {
261                 session = 0;
262                 session_remove_pending = false;
263                 session_removed.signal();
264                 _processed_frames = next_processed_frames;
265                 return 0;
266         }
267
268         if (_freewheeling) {
269                 if (Freewheel (nframes)) {
270                         _freewheeling = false;
271                         jack_set_freewheel (_jack, false);
272                 }
273                 return 0;
274         }
275
276         boost::shared_ptr<Ports> p = ports.reader();
277
278         // Prepare ports (ie read data if necessary)
279         for (Ports::iterator i = p->begin(); i != p->end(); ++i)
280                 (*i)->cycle_start(nframes);
281         
282         session->process (nframes);
283
284         if (!_running) {
285                 /* we were zombified, maybe because a ladspa plugin took
286                    too long, or jackd exited, or something like that.
287                 */
288                 
289                 _processed_frames = next_processed_frames;
290                 return 0;
291         }
292         
293         // Finalize ports (ie write data if necessary)
294         for (Ports::iterator i = p->begin(); i != p->end(); ++i)
295                 (*i)->cycle_end();
296
297         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
298
299                 boost::shared_ptr<Ports> p = ports.reader();
300
301                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
302                         
303                         Port *port = (*i);
304                         bool x;
305                         
306                         if (port->_last_monitor != (x = port->monitoring_input ())) {
307                                 port->_last_monitor = x;
308                                 /* XXX I think this is dangerous, due to 
309                                    a likely mutex in the signal handlers ...
310                                 */
311                                  port->MonitorInputChanged (x); /* EMIT SIGNAL */
312                         }
313                 }
314                 last_monitor_check = next_processed_frames;
315         }
316
317         _processed_frames = next_processed_frames;
318         return 0;
319 }
320
321 int
322 AudioEngine::_sample_rate_callback (jack_nframes_t nframes, void *arg)
323 {
324         return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
325 }
326
327 int
328 AudioEngine::jack_sample_rate_callback (jack_nframes_t nframes)
329 {
330         _frame_rate = nframes;
331         _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
332         
333         /* check for monitor input change every 1/10th of second */
334
335         monitor_check_interval = nframes / 10;
336         last_monitor_check = 0;
337         
338         if (session) {
339                 session->set_frame_rate (nframes);
340         }
341
342         SampleRateChanged (nframes); /* EMIT SIGNAL */
343
344         return 0;
345 }
346
347 int
348 AudioEngine::_bufsize_callback (jack_nframes_t nframes, void *arg)
349 {
350         return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
351 }
352
353 int
354 AudioEngine::jack_bufsize_callback (jack_nframes_t nframes)
355 {
356         _buffer_size = nframes;
357         _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
358         last_monitor_check = 0;
359
360         boost::shared_ptr<Ports> p = ports.reader();
361
362         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
363                 (*i)->reset();
364         }
365
366         if (session) {
367                 session->set_block_size (_buffer_size);
368         }
369
370         return 0;
371 }
372
373 void
374 AudioEngine::start_metering_thread ()
375 {
376         if(m_meter_thread == 0) {
377                 m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread), false);
378         }
379 }
380
381 void
382 AudioEngine::meter_thread ()
383 {
384         while (g_atomic_int_get(&m_meter_exit) != true) {
385         Glib::usleep (10000); /* 1/100th sec interval */
386         IO::update_meters ();
387         }
388         return;
389 }
390
391 void 
392 AudioEngine::set_session (Session *s)
393 {
394         if (!session) {
395                 session = s;
396         }
397 }
398
399 void 
400 AudioEngine::remove_session ()
401 {
402         Glib::Mutex::Lock lm (_process_lock);
403
404         if (_running) {
405
406                 if (session) {
407                         session_remove_pending = true;
408                         session_removed.wait(_process_lock);
409                 } 
410
411         } else {
412
413                 session = 0;
414
415         }
416         
417         remove_all_ports ();
418
419 }
420
421 Port *
422 AudioEngine::register_input_port (DataType type, const string& portname)
423 {
424         if (!_running) {
425                 if (!_has_run) {
426                         fatal << _("register input port called before engine was started") << endmsg;
427                         /*NOTREACHED*/
428                 } else {
429                         return 0;
430                 }
431         }
432
433         jack_port_t *p = jack_port_register (_jack, portname.c_str(), type.to_jack_type(), JackPortIsInput, 0);
434
435         if (p) {
436
437                 Port* newport = 0;
438                 
439                 if (type == DataType::AUDIO)
440                         newport = new AudioPort (p);
441                 else if (type == DataType::MIDI)
442                         newport = new MidiPort (p);
443                 else
444                         throw unknown_type();
445
446                 if (newport != 0) {
447                         RCUWriter<Ports> writer (ports);
448                         boost::shared_ptr<Ports> ps = writer.get_copy ();
449                         ps->insert (ps->begin(), newport);
450                         /* writer goes out of scope, forces update */
451                 }
452
453                 return newport;
454
455         } else {
456
457                 _process_lock.unlock();
458                 throw PortRegistrationFailure();
459         }
460
461         return 0;
462 }
463
464 Port *
465 AudioEngine::register_output_port (DataType type, const string& portname)
466 {
467         if (!_running) {
468                 if (!_has_run) {
469                         fatal << _("register output port called before engine was started") << endmsg;
470                         /*NOTREACHED*/
471                 } else {
472                         return 0;
473                 }
474         }
475
476         jack_port_t* p = 0;
477         
478         if ((p = jack_port_register (_jack, portname.c_str(),
479                         type.to_jack_type(), JackPortIsOutput, 0)) != 0) {
480                 
481                 Port* newport = 0;
482                 
483                 if (type == DataType::AUDIO)
484                         newport = new AudioPort (p);
485                 else if (type == DataType::MIDI)
486                         newport = new MidiPort (p);
487                 else
488                         throw unknown_type ();
489
490                 if (newport != 0) {
491                         RCUWriter<Ports> writer (ports);
492                         boost::shared_ptr<Ports> ps = writer.get_copy ();
493                         ps->insert (ps->begin(), newport);
494                         /* writer goes out of scope, forces update */
495                 }
496                 
497                 return newport;
498                 
499         } else {
500
501                 _process_lock.unlock();
502                 throw PortRegistrationFailure ();
503         }
504
505         return 0;
506 }
507
508
509 int          
510 AudioEngine::unregister_port (Port& port)
511 {
512         if (!_running) { 
513                 /* probably happening when the engine has been halted by JACK,
514                    in which case, there is nothing we can do here.
515                    */
516                 return 0;
517         }
518
519         int ret = jack_port_unregister (_jack, port._port);
520
521         if (ret == 0) {
522
523                 {
524
525                         RCUWriter<Ports> writer (ports);
526                         boost::shared_ptr<Ports> ps = writer.get_copy ();
527
528                         for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) {
529                                 if ((*i) == &port) {
530                                         ps->erase (i);
531                                         break;
532                                 }
533                         }
534
535                         /* writer goes out of scope, forces update */
536                 }
537
538                 remove_connections_for (port);
539         }
540
541         return ret;
542 }
543
544 int 
545 AudioEngine::connect (const string& source, const string& destination)
546 {
547         if (!_running) {
548                 if (!_has_run) {
549                         fatal << _("connect 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_connect (_jack, s.c_str(), d.c_str());
560
561         if (ret == 0) {
562                 pair<string,string> c (s, d);
563                 port_connections.push_back (c);
564         } else {
565                 error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"), 
566                                  source, s, destination, d) 
567                       << endmsg;
568         }
569
570         return ret;
571 }
572
573 int 
574 AudioEngine::disconnect (const string& source, const string& destination)
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         string s = make_port_name_non_relative (source);
586         string d = make_port_name_non_relative (destination);
587
588         int ret = jack_disconnect (_jack, s.c_str(), d.c_str());
589
590         if (ret == 0) {
591                 pair<string,string> c (s, d);
592                 PortConnections::iterator i;
593                 
594                 if ((i = find (port_connections.begin(), port_connections.end(), c)) != port_connections.end()) {
595                         port_connections.erase (i);
596                 }
597         }
598          
599         return ret;
600 }
601
602 int
603 AudioEngine::disconnect (Port& port)
604 {
605         if (!_running) {
606                 if (!_has_run) {
607                         fatal << _("disconnect called before engine was started") << endmsg;
608                         /*NOTREACHED*/
609                 } else {
610                         return -1;
611                 }
612         }
613
614         int ret = jack_port_disconnect (_jack, port._port);
615
616         if (ret == 0) {
617                 remove_connections_for (port);
618         }
619
620         return ret;
621
622 }
623
624 jack_nframes_t
625 AudioEngine::frame_rate ()
626 {
627         if (_jack) {
628                 if (_frame_rate == 0) {
629                         return (_frame_rate = jack_get_sample_rate (_jack));
630                 } else {
631                         return _frame_rate;
632                 }
633         } else {
634                 fatal << X_("programming error: AudioEngine::frame_rate() called while disconnected from JACK")
635                       << endmsg;
636                 /*NOTREACHED*/
637                 return 0;
638         }
639 }
640
641 jack_nframes_t
642 AudioEngine::frames_per_cycle ()
643 {
644         if (_jack) {
645                 if (_buffer_size == 0) {
646                         return (_buffer_size = jack_get_buffer_size (_jack));
647                 } else {
648                         return _buffer_size;
649                 }
650         } else {
651                 fatal << X_("programming error: AudioEngine::frame_rate() called while disconnected from JACK")
652                       << endmsg;
653                 /*NOTREACHED*/
654                 return 0;
655         }
656 }
657
658 /** Get a port by name.
659  * Note this can return NULL, it will NOT create a port if it is not found (any more).
660  */
661 Port *
662 AudioEngine::get_port_by_name (const string& portname, bool keep)
663 {
664         Glib::Mutex::Lock lm (_process_lock);
665
666         if (!_running) {
667                 if (!_has_run) {
668                         fatal << _("get_port_by_name() called before engine was started") << endmsg;
669                         /*NOTREACHED*/
670                 } else {
671                         return 0;
672                 }
673         }
674         
675         boost::shared_ptr<Ports> pr = ports.reader();
676         
677         for (Ports::iterator i = pr->begin(); i != pr->end(); ++i) {
678                 if (portname == (*i)->name()) {
679                         return (*i);
680                 }
681         }
682
683         return 0;
684 }
685
686 const char **
687 AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags)
688 {
689         if (!_running) {
690                 if (!_has_run) {
691                         fatal << _("get_ports called before engine was started") << endmsg;
692                         /*NOTREACHED*/
693                 } else {
694                         return 0;
695                 }
696         }
697         return jack_get_ports (_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags);
698 }
699
700 void
701 AudioEngine::halted (void *arg)
702 {
703         AudioEngine *ae = reinterpret_cast<AudioEngine *> (arg);
704
705         ae->_running = false;
706         ae->_jack = 0;
707
708         ae->_buffer_size = 0;
709         ae->_frame_rate = 0;
710
711         ae->Halted(); /* EMIT SIGNAL */
712 }
713
714 uint32_t
715 AudioEngine::n_physical_outputs () const
716 {
717         const char ** ports;
718         uint32_t i = 0;
719
720         if (!_jack) {
721                 return 0;
722         }
723
724         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
725                 return 0;
726         }
727
728         if (ports) {
729                 for (i = 0; ports[i]; ++i);
730                 free (ports);
731         }
732         return i;
733 }
734
735 uint32_t
736 AudioEngine::n_physical_inputs () const
737 {
738         const char ** ports;
739         uint32_t i = 0;
740         
741         if (!_jack) {
742                 return 0;
743         }
744         
745         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
746                 return 0;
747         }
748
749         if (ports) {
750                 for (i = 0; ports[i]; ++i);
751                 free (ports);
752         }
753         return i;
754 }
755
756 void
757 AudioEngine::get_physical_inputs (vector<string>& ins)
758 {
759         const char ** ports;
760         uint32_t i = 0;
761         
762         if (!_jack) {
763                 return;
764         }
765         
766         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) {
767                 return;
768         }
769
770         if (ports) {
771                 for (i = 0; ports[i]; ++i) {
772                         ins.push_back (ports[i]);
773                 }
774                 free (ports);
775         }
776 }
777
778 void
779 AudioEngine::get_physical_outputs (vector<string>& outs)
780 {
781         const char ** ports;
782         uint32_t i = 0;
783         
784         if (!_jack) {
785                 return;
786         }
787         
788         if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) {
789                 return;
790         }
791
792         if (ports) {
793                 for (i = 0; ports[i]; ++i) {
794                         outs.push_back (ports[i]);
795                 }
796                 free (ports);
797         }
798 }
799
800 string
801 AudioEngine::get_nth_physical (DataType type, uint32_t n, int flag)
802 {
803         const char ** ports;
804         uint32_t i;
805         string ret;
806
807         assert(type != DataType::NIL);
808
809         if (!_running || !_jack) {
810                 if (!_has_run) {
811                         fatal << _("get_nth_physical called before engine was started") << endmsg;
812                         /*NOTREACHED*/
813                 } else {
814                         return "";
815                 }
816         }
817
818         ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|flag);
819         
820         if (ports == 0) {
821                 return "";
822         }
823
824         for (i = 0; i < n && ports[i]; ++i);
825
826         if (ports[i]) {
827                 ret = ports[i];
828         }
829
830         free ((char *) ports);
831
832         return ret;
833 }
834
835 jack_nframes_t
836 AudioEngine::get_port_total_latency (const Port& port)
837 {
838         if (!_jack) {
839                 fatal << _("get_port_total_latency() called with no JACK client connection") << endmsg;
840                 /*NOTREACHED*/
841         }
842
843         if (!_running) {
844                 if (!_has_run) {
845                         fatal << _("get_port_total_latency() called before engine was started") << endmsg;
846                         /*NOTREACHED*/
847                 } 
848         }
849
850         return jack_port_get_total_latency (_jack, port._port);
851 }
852
853 void
854 AudioEngine::transport_stop ()
855 {
856         // cerr << "tell JACK to stop\n";
857         if (_jack) {
858                 jack_transport_stop (_jack);
859         }
860 }
861
862 void
863 AudioEngine::transport_start ()
864 {
865         // cerr << "tell JACK to start\n";
866         if (_jack) {
867                 jack_transport_start (_jack);
868         }
869 }
870
871 void
872 AudioEngine::transport_locate (jack_nframes_t where)
873 {
874         // cerr << "tell JACK to locate to " << where << endl;
875         if (_jack) {
876                 jack_transport_locate (_jack, where);
877         }
878 }
879
880 AudioEngine::TransportState
881 AudioEngine::transport_state ()
882 {
883         if (_jack) {
884                 jack_position_t pos;
885                 return (TransportState) jack_transport_query (_jack, &pos);
886         } else {
887                 return (TransportState) JackTransportStopped;
888         }
889 }
890
891 int
892 AudioEngine::reset_timebase ()
893 {
894         if (_jack) {
895                 if (Config->get_jack_time_master()) {
896                         return jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this);
897                 } else {
898                         return jack_release_timebase (_jack);
899                 }
900         } else {
901                 return -1;
902         }
903 }
904
905 int
906 AudioEngine::freewheel (bool onoff)
907 {
908         if (_jack) {
909
910                 if (onoff) {
911                         _freewheel_thread_registered = false;
912                 }
913
914                 return jack_set_freewheel (_jack, onoff);
915
916         } else {
917                 return -1;
918         }
919 }
920
921 void
922 AudioEngine::remove_all_ports ()
923 {
924         /* process lock MUST be held */
925
926         if (_jack) {
927                 boost::shared_ptr<Ports> p = ports.reader();
928
929                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
930                         jack_port_unregister (_jack, (*i)->_port);
931                 }
932         }
933
934         {
935                 RCUWriter<Ports> writer (ports);
936                 boost::shared_ptr<Ports> ps = writer.get_copy ();
937                 ps->clear ();
938         }
939
940         port_connections.clear ();
941 }
942
943 void
944 AudioEngine::remove_connections_for (Port& port)
945 {
946         for (PortConnections::iterator i = port_connections.begin(); i != port_connections.end(); ) {
947                 PortConnections::iterator tmp;
948                 
949                 tmp = i;
950                 ++tmp;
951                 
952                 if ((*i).first == port.name()) {
953                         port_connections.erase (i);
954                 }
955
956                 i = tmp;
957         }
958 }
959
960 #ifdef HAVE_JACK_CLIENT_OPEN
961
962 int
963 AudioEngine::connect_to_jack (string client_name)
964 {
965         jack_options_t options = JackNullOption;
966         jack_status_t status;
967         const char *server_name = NULL;
968
969         jack_client_name = client_name; /* might be reset below */
970
971         _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name);
972         
973         if (_jack == NULL) {
974
975                 if (status & JackServerFailed) {
976                         error << _("Unable to connect to JACK server") << endmsg;
977                 }
978                 
979                 error << string_compose (_("Could not connect to JACK server as  \"%1\""), jack_client_name) <<  endmsg;
980                 return -1;
981         }
982
983         if (status & JackServerStarted) {
984                 info << _("JACK server started") << endmsg;
985         }
986
987         if (status & JackNameNotUnique) {
988                 jack_client_name = jack_get_client_name (_jack);
989         }
990         
991         return 0;
992 }
993
994 #else
995
996 int
997 AudioEngine::connect_to_jack (string client_name)
998 {
999         jack_client_name = client_name;
1000
1001         if ((_jack = jack_client_new (client_name.c_str())) == NULL) {
1002                 return -1;
1003         }
1004
1005         return 0;
1006 }
1007
1008 #endif /* HAVE_JACK_CLIENT_OPEN */
1009
1010 int 
1011 AudioEngine::disconnect_from_jack ()
1012 {
1013         if (_jack == 0) {
1014                 return 0;
1015         }
1016
1017         if (jack_client_close (_jack)) {
1018                 error << _("cannot shutdown connection to JACK") << endmsg;
1019         }
1020
1021         _buffer_size = 0;
1022         _frame_rate = 0;
1023
1024         if (_running) {
1025                 _running = false;
1026                 Stopped(); /* EMIT SIGNAL */
1027         }
1028
1029         _jack = 0;
1030         return 0;
1031 }
1032
1033 int
1034 AudioEngine::reconnect_to_jack ()
1035 {
1036         if (_jack) {
1037                 disconnect_from_jack ();
1038                 /* XXX give jackd a chance */
1039                 Glib::usleep (250000);
1040         }
1041
1042         if (connect_to_jack (jack_client_name)) {
1043                 error << _("failed to connect to JACK") << endmsg;
1044                 return -1;
1045         }
1046
1047         Ports::iterator i;
1048
1049         boost::shared_ptr<Ports> p = ports.reader ();
1050
1051         for (i = p->begin(); i != p->end(); ++i) {
1052
1053                 /* XXX hack hack hack */
1054
1055                 string long_name = (*i)->name();
1056                 string short_name;
1057                 
1058                 short_name = long_name.substr (long_name.find_last_of (':') + 1);
1059
1060                 if (((*i)->_port = jack_port_register (_jack, short_name.c_str(), (*i)->type().to_jack_type(), (*i)->flags(), 0)) == 0) {
1061                         error << string_compose (_("could not reregister %1"), (*i)->name()) << endmsg;
1062                         break;
1063                 } else {
1064                 }
1065
1066                 (*i)->reset ();
1067
1068                 if ((*i)->flags() & JackPortIsOutput) {
1069                         (*i)->silence (jack_get_buffer_size (_jack), 0);
1070                 }
1071         }
1072
1073         if (i != p->end()) {
1074                 /* failed */
1075                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
1076                         jack_port_unregister (_jack, (*i)->_port);
1077                 }
1078                 return -1;
1079         } 
1080
1081
1082         if (session) {
1083                 jack_nframes_t blocksize = jack_get_buffer_size (_jack);
1084                 session->set_block_size (blocksize);
1085                 session->set_frame_rate (jack_get_sample_rate (_jack));
1086         }
1087
1088         last_monitor_check = 0;
1089         
1090         jack_on_shutdown (_jack, halted, this);
1091         jack_set_graph_order_callback (_jack, _graph_order_callback, this);
1092         jack_set_thread_init_callback (_jack, _thread_init_callback, this);
1093         jack_set_process_callback (_jack, _process_callback, this);
1094         jack_set_sample_rate_callback (_jack, _sample_rate_callback, this);
1095         jack_set_buffer_size_callback (_jack, _bufsize_callback, this);
1096         jack_set_xrun_callback (_jack, _xrun_callback, this);
1097         jack_set_sync_callback (_jack, _jack_sync_callback, this);
1098         jack_set_freewheel_callback (_jack, _freewheel_callback, this);
1099         
1100         if (Config->get_jack_time_master()) {
1101                 jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this);
1102         }
1103         
1104         if (jack_activate (_jack) == 0) {
1105                 _running = true;
1106                 _has_run = true;
1107         } else {
1108                 return -1;
1109         }
1110
1111         /* re-establish connections */
1112         
1113         for (PortConnections::iterator i = port_connections.begin(); i != port_connections.end(); ++i) {
1114                 
1115                 int err;
1116                 
1117                 if ((err = jack_connect (_jack, (*i).first.c_str(), (*i).second.c_str())) != 0) {
1118                         if (err != EEXIST) {
1119                                 error << string_compose (_("could not reconnect %1 and %2 (err = %3)"),
1120                                                   (*i).first, (*i).second, err)
1121                                       << endmsg;
1122                         }
1123                 }
1124         }
1125
1126         Running (); /* EMIT SIGNAL*/
1127
1128         return 0;
1129 }
1130
1131 int
1132 AudioEngine::request_buffer_size (jack_nframes_t nframes)
1133 {
1134         if (_jack) {
1135                 int ret = jack_set_buffer_size (_jack, nframes);
1136                 return ret;
1137         } else {
1138                 return -1;
1139         }
1140 }
1141
1142 void
1143 AudioEngine::update_total_latencies ()
1144 {
1145 #ifdef HAVE_JACK_RECOMPUTE_LATENCIES
1146         jack_recompute_total_latencies (_jack);
1147 #endif
1148 }
1149                 
1150 string
1151 AudioEngine::make_port_name_relative (string portname)
1152 {
1153         string::size_type len;
1154         string::size_type n;
1155         
1156         len = portname.length();
1157
1158         for (n = 0; n < len; ++n) {
1159                 if (portname[n] == ':') {
1160                         break;
1161                 }
1162         }
1163         
1164         if ((n != len) && (portname.substr (0, n) == jack_client_name)) {
1165                 return portname.substr (n+1);
1166         }
1167
1168         return portname;
1169 }
1170
1171 string
1172 AudioEngine::make_port_name_non_relative (string portname)
1173 {
1174         string str;
1175
1176         if (portname.find_first_of (':') != string::npos) {
1177                 return portname;
1178         }
1179
1180         str  = jack_client_name;
1181         str += ':';
1182         str += portname;
1183         
1184         return str;
1185 }
1186