most of libardour now actually compiles
[ardour.git] / libs / ardour / jack_audiobackend.cc
1 /*
2     Copyright (C) 2013 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 */
19
20 #include <jack/jack.h>
21
22 #include "ardour/audioengine.h"
23 #include "ardour/types.h"
24 #include "ardour/jack_audiobackend.h"
25
26 using namespace ARDOUR;
27 using std::string;
28
29 #define GET_PRIVATE_JACK_POINTER(j)  jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return; }
30 #define GET_PRIVATE_JACK_POINTER_RET(j,r) jack_client_t* _priv_jack = (jack_client_t*) (j); if (!_priv_jack) { return r; }
31
32 JACKAudioBackend::JACKAudioBackend (AudioEngine& e)
33         : AudioBackend (e)
34         , _jack (0)
35         , _target_sample_rate (48000)
36         , _target_buffer_size (1024)
37         , _target_sample_format (FloatingPoint)
38         , _target_interleaved (false)
39         , _target_input_channels (-1)
40         , _target_output_channels (-1)
41         , _target_systemic_input_latency (0)
42         , _target_systemic_output_latency (0)
43 {
44 }
45
46 int
47 JACKAudioBackend::set_device_name (const string& dev)
48 {
49         _target_device = dev;
50         return 0;
51 }
52
53 int
54 JACKAudioBackend::start ()
55 {
56         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
57
58         if (!_running) {
59
60                 if (!jack_port_type_get_buffer_size) {
61                         warning << _("This version of JACK is old - you should upgrade to a newer version that supports jack_port_type_get_buffer_size()") << endmsg;
62                 }
63
64                 if (_session) {
65                         BootMessage (_("Connect session to engine"));
66                         _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
67                 }
68
69                 /* a proxy for whether jack_activate() will definitely call the buffer size
70                  * callback. with older versions of JACK, this function symbol will be null.
71                  * this is reliable, but not clean.
72                  */
73
74                 if (!jack_port_type_get_buffer_size) {
75                         jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
76                 }
77                 
78                 _processed_frames = 0;
79                 last_monitor_check = 0;
80
81                 set_jack_callbacks ();
82
83                 if (jack_activate (_priv_jack) == 0) {
84                         _running = true;
85                         _has_run = true;
86                         Running(); /* EMIT SIGNAL */
87                 } else {
88                         // error << _("cannot activate JACK client") << endmsg;
89                 }
90         }
91                 
92         return _running ? 0 : -1;
93 }
94
95 int
96 JACKAudioBackend::stop ()
97 {
98         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
99
100         {
101                 Glib::Threads::Mutex::Lock lm (_process_lock);
102                 jack_client_close (_priv_jack);
103                 _jack = 0;
104         }
105
106         _buffer_size = 0;
107         _frame_rate = 0;
108         _raw_buffer_sizes.clear();
109
110         return 0;
111 }
112
113 int
114 JACKAudioBackend::pause ()
115 {
116         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
117
118         if (_priv_jack) {
119                 jack_deactivate (_priv_jack);
120         }
121
122         return 0;
123 }
124
125 int
126 JACKAudioBackend::freewheel (bool onoff)
127 {
128         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
129
130         if (onoff == _freewheeling) {
131                 /* already doing what has been asked for */
132                 
133                 return 0;
134         }
135
136         return jack_set_freewheel (_priv_jack, onoff);
137 }
138
139 int
140 JACKAudioBackend::set_parameters (const Parameters& params)
141 {
142         return 0;
143 }
144
145 int 
146 JACKAudioBackend::get_parameters (Parameters& params) const
147 {
148         return 0;
149 }
150
151 /* parameters */
152
153 ARDOUR::pframes_t
154 AudioEngine::frames_per_cycle () const
155 {
156         GET_PRIVATE_JACK_POINTER_RET (_jack,0);
157         if (_buffer_size == 0) {
158                 return jack_get_buffer_size (_jack);
159         } else {
160                 return _buffer_size;
161         }
162 }
163
164 ARDOUR::framecnt_t
165 AudioEngine::frame_rate () const
166 {
167         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
168         if (_frame_rate == 0) {
169                 return (_frame_rate = jack_get_sample_rate (_priv_jack));
170         } else {
171                 return _frame_rate;
172         }
173 }
174
175 size_t
176 AudioEngine::raw_buffer_size (DataType t)
177 {
178         std::map<DataType,size_t>::const_iterator s = _raw_buffer_sizes.find(t);
179         return (s != _raw_buffer_sizes.end()) ? s->second : 0;
180 }
181
182
183
184 /*--- private support methods ---*/
185
186 int
187 JACKAudioBackend::connect_to_jack (string client_name, string session_uuid)
188 {
189         EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
190         boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
191         jack_status_t status;
192
193         /* revert all environment settings back to whatever they were when ardour started
194          */
195
196         if (global_epa) {
197                 current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
198                 global_epa->restore ();
199         }
200
201         jack_client_name = client_name; /* might be reset below */
202 #ifdef HAVE_JACK_SESSION
203         if (!session_uuid.empty())
204             _jack = jack_client_open (jack_client_name.c_str(), JackSessionID, &status, session_uuid.c_str());
205         else
206 #endif
207         _jack = jack_client_open (jack_client_name.c_str(), JackNullOption, &status, 0);
208
209         if (_jack == NULL) {
210                 // error message is not useful here
211                 return -1;
212         }
213
214         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
215
216         if (status & JackNameNotUnique) {
217                 jack_client_name = jack_get_client_name (_priv_jack);
218         }
219
220         return 0;
221 }
222
223 int
224 JACKAudioBackend::disconnect_from_jack ()
225 {
226
227 int
228 JACKAudioBackend::reconnect_to_jack ()
229 {
230         if (_running) {
231                 disconnect_from_jack ();
232                 /* XXX give jackd a chance */
233                 Glib::usleep (250000);
234         }
235
236         if (connect_to_jack (jack_client_name, "")) {
237                 error << _("failed to connect to JACK") << endmsg;
238                 return -1;
239         }
240
241         Ports::iterator i;
242
243         boost::shared_ptr<Ports> p = ports.reader ();
244
245         for (i = p->begin(); i != p->end(); ++i) {
246                 if (i->second->reestablish ()) {
247                         break;
248                 }
249         }
250
251         if (i != p->end()) {
252                 /* failed */
253                 remove_all_ports ();
254                 return -1;
255         }
256
257         GET_PRIVATE_JACK_POINTER_RET (_jack,-1);
258
259         MIDI::Manager::instance()->reestablish (_priv_jack);
260
261         if (_session) {
262                 _session->reset_jack_connection (_priv_jack);
263                 jack_bufsize_callback (jack_get_buffer_size (_priv_jack));
264                 _session->set_frame_rate (jack_get_sample_rate (_priv_jack));
265         }
266
267         last_monitor_check = 0;
268
269         set_jack_callbacks ();
270
271         if (jack_activate (_priv_jack) == 0) {
272                 _running = true;
273                 _has_run = true;
274         } else {
275                 return -1;
276         }
277
278         /* re-establish connections */
279
280         for (i = p->begin(); i != p->end(); ++i) {
281                 i->second->reconnect ();
282         }
283
284         MIDI::Manager::instance()->reconnect ();
285
286         Running (); /* EMIT SIGNAL*/
287
288         start_metering_thread ();
289
290         return 0;
291 }
292
293 int
294 JACKAudioBackend::request_buffer_size (pframes_t nframes)
295 {
296         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
297
298         if (nframes == jack_get_buffer_size (_priv_jack)) {
299                 return 0;
300         }
301
302         return jack_set_buffer_size (_priv_jack, nframes);
303 }
304
305 /* --- TRANSPORT STATE MANAGEMENT --- */
306
307 void
308 JACKAudioBackend::transport_stop ()
309 {
310         GET_PRIVATE_JACK_POINTER (_jack);
311         jack_transport_stop (_priv_jack);
312 }
313
314 void
315 JACKAudioBackend::transport_start ()
316 {
317         GET_PRIVATE_JACK_POINTER (_jack);
318         jack_transport_start (_priv_jack);
319 }
320
321 void
322 JACKAudioBackend::transport_locate (framepos_t where)
323 {
324         GET_PRIVATE_JACK_POINTER (_jack);
325         jack_transport_locate (_priv_jack, where);
326 }
327
328 framepos_t 
329 JACKAudioBackend::transport_frame () const 
330 {
331         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
332         return jack_get_current_transport_frame (_priv_jack);
333 }
334
335 JACKAudioBackend::TransportState
336 JACKAudioBackend::transport_state ()
337 {
338         GET_PRIVATE_JACK_POINTER_RET (_jack, ((TransportState) JackTransportStopped));
339         jack_position_t pos;
340         return (TransportState) jack_transport_query (_priv_jack, &pos);
341 }
342
343 int
344 JACKAudioBackend::set_time_master (bool yn)
345 {
346         GET_PRIVATE_JACK_POINTER_RET (_jack, -1);
347         if (yn) {
348                 return jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
349         } else {
350                 return jack_release_timebase (_jack);
351         }
352 }
353
354 /* process-time */
355
356 framecnt_t frame_rate () const;
357 pframes_t frames_per_cycle () const;
358
359 size_t raw_buffer_size(DataType t);
360
361 int usecs_per_cycle () const { return _usecs_per_cycle; }
362
363 bool
364 JACKAudioBackend::get_sync_offset (pframes_t& offset) const
365 {
366
367 #ifdef HAVE_JACK_VIDEO_SUPPORT
368
369         GET_PRIVATE_JACK_POINTER_RET (_jack, false);
370
371         jack_position_t pos;
372
373         if (_priv_jack) {
374                 (void) jack_transport_query (_priv_jack, &pos);
375
376                 if (pos.valid & JackVideoFrameOffset) {
377                         offset = pos.video_offset;
378                         return true;
379                 }
380         }
381 #else
382         /* keep gcc happy */
383         offset = 0;
384 #endif
385
386         return false;
387 }
388
389 pframes_t
390 JACKAudioBackend::frames_since_cycle_start ()
391 {
392         jack_client_t* _priv_jack = _jack;
393         if (!_running || !_priv_jack) {
394                 return 0;
395         }
396         return jack_frames_since_cycle_start (_priv_jack);
397 }
398
399 pframes_t
400 JACKAudioBackend::frame_time ()
401 {
402         jack_client_t* _priv_jack = _jack;
403         if (!_running || !_priv_jack) {
404                 return 0;
405         }
406         return jack_frame_time (_priv_jack);
407 }
408
409 pframes_t
410 JACKAudioBackend::frame_time_at_cycle_start ()
411 {
412         jack_client_t* _priv_jack = _jack;
413         if (!_running || !_priv_jack) {
414                 return 0;
415         }
416         return jack_last_frame_time (_priv_jack);
417 }
418
419 /* JACK Callbacks */
420
421 static void
422 ardour_jack_error (const char* msg)
423 {
424         error << "JACK: " << msg << endmsg;
425 }
426
427 void
428 JACKAudioBackend::set_jack_callbacks ()
429 {
430         GET_PRIVATE_JACK_POINTER (_jack);
431
432         if (jack_on_info_shutdown) {
433                 jack_on_info_shutdown (_priv_jack, halted_info, this);
434         } else {
435                 jack_on_shutdown (_priv_jack, halted, this);
436         }
437
438         jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
439         jack_set_process_thread (_priv_jack, _process_thread, this);
440         jack_set_sample_rate_callback (_priv_jack, _sample_rate_callback, this);
441         jack_set_buffer_size_callback (_priv_jack, _bufsize_callback, this);
442         jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
443         jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
444         jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
445         jack_set_xrun_callback (_priv_jack, _xrun_callback, this);
446         jack_set_sync_callback (_priv_jack, _jack_sync_callback, this);
447         jack_set_freewheel_callback (_priv_jack, _freewheel_callback, this);
448
449         if (_session && _session->config.get_jack_time_master()) {
450                 jack_set_timebase_callback (_priv_jack, 0, _jack_timebase_callback, this);
451         }
452
453 #ifdef HAVE_JACK_SESSION
454         if( jack_set_session_callback)
455                 jack_set_session_callback (_priv_jack, _session_callback, this);
456 #endif
457
458         if (jack_set_latency_callback) {
459                 jack_set_latency_callback (_priv_jack, _latency_callback, this);
460         }
461
462         jack_set_error_function (ardour_jack_error);
463 }
464
465 void
466 JACKAudioBackend::_jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
467                                       jack_position_t* pos, int new_position, void *arg)
468 {
469         static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position);
470 }
471
472 void
473 JACKAudioBackend::jack_timebase_callback (jack_transport_state_t state, pframes_t nframes,
474                                      jack_position_t* pos, int new_position)
475 {
476         if (_jack && _session && _session->synced_to_jack()) {
477                 _session->jack_timebase_callback (state, nframes, pos, new_position);
478         }
479 }
480
481 int
482 JACKAudioBackend::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg)
483 {
484         return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos);
485 }
486
487 int
488 JACKAudioBackend::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
489 {
490         if (_jack && _session) {
491                 return _session->jack_sync_callback (state, pos);
492         }
493
494         return true;
495 }
496
497 int
498 JACKAudioBackend::_xrun_callback (void *arg)
499 {
500         AudioEngine* ae = static_cast<AudioEngine*> (arg);
501         if (ae->connected()) {
502                 ae->Xrun (); /* EMIT SIGNAL */
503         }
504         return 0;
505 }
506
507 #ifdef HAVE_JACK_SESSION
508 void
509 JACKAudioBackend::_session_callback (jack_session_event_t *event, void *arg)
510 {
511         AudioEngine* ae = static_cast<AudioEngine*> (arg);
512         if (ae->connected()) {
513                 ae->JackSessionEvent ( event ); /* EMIT SIGNAL */
514         }
515 }
516 #endif
517
518 int
519 JACKAudioBackend::_graph_order_callback (void *arg)
520 {
521         AudioEngine* ae = static_cast<AudioEngine*> (arg);
522
523         if (ae->connected() && !ae->port_remove_in_progress) {
524                 ae->GraphReordered (); /* EMIT SIGNAL */
525         }
526         
527         return 0;
528 }
529
530 void
531 JACKAudioBackend::_freewheel_callback (int onoff, void *arg)
532 {
533         static_cast<AudioEngine*>(arg)->freewheel_callback (onoff);
534 }
535
536 void
537 JACKAudioBackend::freewheel_callback (int onoff)
538 {
539         _freewheeling = onoff;
540
541         if (onoff) {
542                 _pre_freewheel_mmc_enabled = MIDI::Manager::instance()->mmc()->send_enabled ();
543                 MIDI::Manager::instance()->mmc()->enable_send (false);
544         } else {
545                 MIDI::Manager::instance()->mmc()->enable_send (_pre_freewheel_mmc_enabled);
546         }
547 }
548
549 void
550 JACKAudioBackend::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
551 {
552         AudioEngine* ae = static_cast<AudioEngine*> (arg);
553
554         if (!ae->port_remove_in_progress) {
555                 ae->PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
556         }
557 }
558
559 void
560 JACKAudioBackend::_latency_callback (jack_latency_callback_mode_t mode, void* arg)
561 {
562         return static_cast<AudioEngine *> (arg)->jack_latency_callback (mode);
563 }
564
565 void
566 JACKAudioBackend::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn, void* arg)
567 {
568         AudioEngine* ae = static_cast<AudioEngine*> (arg);
569         ae->connect_callback (id_a, id_b, conn);
570 }
571
572 void
573 JACKAudioBackend::connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn)
574 {
575         if (port_remove_in_progress) {
576                 return;
577         }
578
579         GET_PRIVATE_JACK_POINTER (_jack);
580
581         jack_port_t* jack_port_a = jack_port_by_id (_priv_jack, id_a);
582         jack_port_t* jack_port_b = jack_port_by_id (_priv_jack, id_b);
583
584         boost::shared_ptr<Port> port_a;
585         boost::shared_ptr<Port> port_b;
586         Ports::iterator x;
587         boost::shared_ptr<Ports> pr = ports.reader ();
588
589
590         x = pr->find (make_port_name_relative (jack_port_name (jack_port_a)));
591         if (x != pr->end()) {
592                 port_a = x->second;
593         }
594
595         x = pr->find (make_port_name_relative (jack_port_name (jack_port_b)));
596         if (x != pr->end()) {
597                 port_b = x->second;
598         }
599
600         PortConnectedOrDisconnected (
601                 port_a, jack_port_name (jack_port_a),
602                 port_b, jack_port_name (jack_port_b),
603                 conn == 0 ? false : true
604                 ); /* EMIT SIGNAL */
605 }
606
607 int
608 JACKAudioBackend::create_process_thread (boost::function<void()> f, pthread_t* thread, size_t stacksize)
609 {
610         GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
611         ThreadData* td = new ThreadData (this, f, stacksize);
612
613         if (jack_client_create_thread (_priv_jack, thread, jack_client_real_time_priority (_priv_jack),
614                                        jack_is_realtime (_priv_jack), _start_process_thread, td)) {
615                 return -1;
616         }
617
618         return 0;
619 }
620
621 void*
622 JACKAudioBackend::_start_process_thread (void* arg)
623 {
624         ThreadData* td = reinterpret_cast<ThreadData*> (arg);
625         boost::function<void()> f = td->f;
626         delete td;
627
628         f ();
629
630         return 0;
631 }
632
633 void*
634 JACKAudioBackend::_process_thread (void *arg)
635 {
636         return static_cast<AudioEngine *> (arg)->process_thread ();
637 }
638
639 void*
640 JACKAudioBackend::process_thread ()
641 {
642         /* JACK doesn't do this for us when we use the wait API
643          */
644
645         _thread_init_callback (0);
646
647         _main_thread = new ProcessThread;
648
649         while (1) {
650                 GET_PRIVATE_JACK_POINTER_RET(_jack,0);
651
652                 pframes_t nframes = jack_cycle_wait (_priv_jack);
653                 
654                 if (engine.process_callback (nframes)) {
655                         return 0;
656                 }
657
658                 jack_cycle_signal (_priv_jack, 0);
659         }
660
661         return 0;
662 }
663
664 int
665 JACKAudioBackend::_sample_rate_callback (pframes_t nframes, void *arg)
666 {
667         return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes);
668 }
669
670 int
671 JACKAudioBackend::jack_sample_rate_callback (pframes_t nframes)
672 {
673         _frame_rate = nframes;
674         _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0);
675
676         /* check for monitor input change every 1/10th of second */
677
678         monitor_check_interval = nframes / 10;
679         last_monitor_check = 0;
680
681         if (_session) {
682                 _session->set_frame_rate (nframes);
683         }
684
685         SampleRateChanged (nframes); /* EMIT SIGNAL */
686
687         return 0;
688 }
689
690 void
691 JACKAudioBackend::jack_latency_callback (jack_latency_callback_mode_t mode)
692 {
693         if (_session) {
694                 _session->update_latency (mode == JackPlaybackLatency);
695         }
696 }
697
698 int
699 JACKAudioBackend::_bufsize_callback (pframes_t nframes, void *arg)
700 {
701         return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes);
702 }
703
704 int
705 JACKAudioBackend::jack_bufsize_callback (pframes_t nframes)
706 {
707         /* if the size has not changed, this should be a no-op */
708
709         if (nframes == _buffer_size) {
710                 return 0;
711         }
712
713         GET_PRIVATE_JACK_POINTER_RET (_jack, 1);
714
715         _buffer_size = nframes;
716         _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
717         last_monitor_check = 0;
718
719         if (jack_port_type_get_buffer_size) {
720                 _raw_buffer_sizes[DataType::AUDIO] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_AUDIO_TYPE);
721                 _raw_buffer_sizes[DataType::MIDI] = jack_port_type_get_buffer_size (_priv_jack, JACK_DEFAULT_MIDI_TYPE);
722         } else {
723
724                 /* Old version of JACK.
725
726                    These crude guesses, see below where we try to get the right answers.
727
728                    Note that our guess for MIDI deliberatey tries to overestimate
729                    by a little. It would be nicer if we could get the actual
730                    size from a port, but we have to use this estimate in the
731                    event that there are no MIDI ports currently. If there are
732                    the value will be adjusted below.
733                 */
734
735                 _raw_buffer_sizes[DataType::AUDIO] = nframes * sizeof (Sample);
736                 _raw_buffer_sizes[DataType::MIDI] = nframes * 4 - (nframes/2);
737         }
738
739         {
740                 Glib::Threads::Mutex::Lock lm (_process_lock);
741
742                 boost::shared_ptr<Ports> p = ports.reader();
743
744                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
745                         i->second->reset();
746                 }
747         }
748
749         if (_session) {
750                 _session->set_block_size (_buffer_size);
751         }
752
753         return 0;
754 }
755
756 void
757 JACKAudioBackend::halted_info (jack_status_t code, const char* reason, void *arg)
758 {
759         /* called from jack shutdown handler  */
760
761         AudioEngine* ae = static_cast<AudioEngine *> (arg);
762         bool was_running = ae->_running;
763
764         ae->stop_metering_thread ();
765
766         ae->_running = false;
767         ae->_buffer_size = 0;
768         ae->_frame_rate = 0;
769         ae->_jack = 0;
770
771         if (was_running) {
772                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
773 #ifdef HAVE_JACK_ON_INFO_SHUTDOWN
774                 switch (code) {
775                 case JackBackendError:
776                         ae->Halted(reason); /* EMIT SIGNAL */
777                         break;
778                 default:
779                         ae->Halted(""); /* EMIT SIGNAL */
780                 }
781 #else
782                 ae->Halted(""); /* EMIT SIGNAL */
783 #endif
784         }
785 }
786
787 void
788 JACKAudioBackend::halted (void *arg)
789 {
790         cerr << "HALTED by JACK\n";
791
792         /* called from jack shutdown handler  */
793
794         AudioEngine* ae = static_cast<AudioEngine *> (arg);
795         bool was_running = ae->_running;
796
797         ae->stop_metering_thread ();
798
799         ae->_running = false;
800         ae->_buffer_size = 0;
801         ae->_frame_rate = 0;
802         ae->_jack = 0;
803
804         if (was_running) {
805                 MIDI::JackMIDIPort::JackHalted (); /* EMIT SIGNAL */
806                 ae->Halted(""); /* EMIT SIGNAL */
807         }
808 }
809