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