start work on the changes to EngineControl (dialog) to integrate with new backend...
[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 */
19
20 #include <unistd.h>
21 #include <cerrno>
22 #include <vector>
23 #include <exception>
24 #include <stdexcept>
25 #include <sstream>
26
27 #include <glibmm/timer.h>
28 #include <glibmm/pattern.h>
29 #include <glibmm/module.h>
30
31 #include "pbd/epa.h"
32 #include "pbd/file_utils.h"
33 #include "pbd/pthread_utils.h"
34 #include "pbd/stacktrace.h"
35 #include "pbd/unknown_type.h"
36
37 #include <jack/weakjack.h>
38
39 #include "midi++/port.h"
40 #include "midi++/jack_midi_port.h"
41 #include "midi++/mmc.h"
42 #include "midi++/manager.h"
43
44 #include "ardour/audio_port.h"
45 #include "ardour/audio_backend.h"
46 #include "ardour/audioengine.h"
47 #include "ardour/backend_search_path.h"
48 #include "ardour/buffer.h"
49 #include "ardour/cycle_timer.h"
50 #include "ardour/internal_send.h"
51 #include "ardour/meter.h"
52 #include "ardour/midi_port.h"
53 #include "ardour/port.h"
54 #include "ardour/process_thread.h"
55 #include "ardour/session.h"
56
57 #include "i18n.h"
58
59 using namespace std;
60 using namespace ARDOUR;
61 using namespace PBD;
62
63 gint AudioEngine::m_meter_exit;
64 AudioEngine* AudioEngine::_instance = 0;
65
66 AudioEngine::AudioEngine ()
67         : session_remove_pending (false)
68         , session_removal_countdown (-1)
69         , monitor_check_interval (INT32_MAX)
70         , last_monitor_check (0)
71         , _processed_frames (0)
72         , _freewheeling (false)
73         , _pre_freewheel_mmc_enabled (false)
74         , m_meter_thread (0)
75         , _main_thread (0)
76 {
77         g_atomic_int_set (&m_meter_exit, 0);
78         discover_backends ();
79 }
80
81 AudioEngine::~AudioEngine ()
82 {
83         drop_backend ();
84
85         config_connection.disconnect ();
86
87         {
88                 Glib::Threads::Mutex::Lock tm (_process_lock);
89                 session_removed.signal ();
90                 stop_metering_thread ();
91         }
92 }
93
94 AudioEngine*
95 AudioEngine::create ()
96 {
97         if (_instance) {
98                 return _instance;
99         }
100
101         _instance = new AudioEngine ();
102         
103         return _instance;
104 }
105
106 void
107 _thread_init_callback (void * /*arg*/)
108 {
109         /* make sure that anybody who needs to know about this thread
110            knows about it.
111         */
112
113         pthread_set_name (X_("audioengine"));
114
115         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("Audioengine"), 4096);
116         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("Audioengine"), 128);
117
118         SessionEvent::create_per_thread_pool (X_("Audioengine"), 512);
119
120         MIDI::JackMIDIPort::set_process_thread (pthread_self());
121 }
122
123 void
124 AudioEngine::split_cycle (pframes_t offset)
125 {
126         /* caller must hold process lock */
127
128         Port::increment_global_port_buffer_offset (offset);
129
130         /* tell all Ports that we're going to start a new (split) cycle */
131
132         boost::shared_ptr<Ports> p = ports.reader();
133
134         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
135                 i->second->cycle_split ();
136         }
137 }
138
139 int
140 AudioEngine::sample_rate_change (pframes_t nframes)
141 {
142         /* check for monitor input change every 1/10th of second */
143
144         monitor_check_interval = nframes / 10;
145         last_monitor_check = 0;
146
147         if (_session) {
148                 _session->set_frame_rate (nframes);
149         }
150
151         SampleRateChanged (nframes); /* EMIT SIGNAL */
152
153         return 0;
154 }
155
156 int 
157 AudioEngine::buffer_size_change (pframes_t bufsiz)
158 {
159         if (_session) {
160                 _session->set_block_size (bufsiz);
161                 last_monitor_check = 0;
162         }
163
164         return 0;
165 }
166
167 /** Method called by our ::process_thread when there is work to be done.
168  *  @param nframes Number of frames to process.
169  */
170 int
171 AudioEngine::process_callback (pframes_t nframes)
172 {
173         Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
174
175         PT_TIMING_REF;
176         PT_TIMING_CHECK (1);
177
178         /// The number of frames that will have been processed when we've finished
179         pframes_t next_processed_frames;
180
181         /* handle wrap around of total frames counter */
182
183         if (max_framepos - _processed_frames < nframes) {
184                 next_processed_frames = nframes - (max_framepos - _processed_frames);
185         } else {
186                 next_processed_frames = _processed_frames + nframes;
187         }
188
189         if (!tm.locked()) {
190                 /* return having done nothing */
191                 _processed_frames = next_processed_frames;
192                 return 0;
193         }
194
195         if (session_remove_pending) {
196
197                 /* perform the actual session removal */
198
199                 if (session_removal_countdown < 0) {
200
201                         /* fade out over 1 second */
202                         session_removal_countdown = sample_rate()/2;
203                         session_removal_gain = 1.0;
204                         session_removal_gain_step = 1.0/session_removal_countdown;
205
206                 } else if (session_removal_countdown > 0) {
207
208                         /* we'll be fading audio out.
209                            
210                            if this is the last time we do this as part 
211                            of session removal, do a MIDI panic now
212                            to get MIDI stopped. This relies on the fact
213                            that "immediate data" (aka "out of band data") from
214                            MIDI tracks is *appended* after any other data, 
215                            so that it emerges after any outbound note ons, etc.
216                         */
217
218                         if (session_removal_countdown <= nframes) {
219                                 _session->midi_panic ();
220                         }
221
222                 } else {
223                         /* fade out done */
224                         _session = 0;
225                         session_removal_countdown = -1; // reset to "not in progress"
226                         session_remove_pending = false;
227                         session_removed.signal(); // wakes up thread that initiated session removal
228                 }
229         }
230
231         if (_session == 0) {
232
233                 if (!_freewheeling) {
234                         MIDI::Manager::instance()->cycle_start(nframes);
235                         MIDI::Manager::instance()->cycle_end();
236                 }
237
238                 _processed_frames = next_processed_frames;
239
240                 return 0;
241         }
242
243         /* tell all relevant objects that we're starting a new cycle */
244
245         InternalSend::CycleStart (nframes);
246         Port::set_global_port_buffer_offset (0);
247         Port::set_cycle_framecnt (nframes);
248
249         /* tell all Ports that we're starting a new cycle */
250
251         boost::shared_ptr<Ports> p = ports.reader();
252
253         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
254                 i->second->cycle_start (nframes);
255         }
256
257         /* test if we are freewheeling and there are freewheel signals connected.
258            ardour should act normally even when freewheeling unless /it/ is
259            exporting 
260         */
261
262         if (_freewheeling && !Freewheel.empty()) {
263
264                 Freewheel (nframes);
265
266         } else {
267                 MIDI::Manager::instance()->cycle_start(nframes);
268
269                 if (_session) {
270                         _session->process (nframes);
271                 }
272
273                 MIDI::Manager::instance()->cycle_end();
274         }
275
276         if (_freewheeling) {
277                 return 0;
278         }
279
280         if (!_running) {
281                 _processed_frames = next_processed_frames;
282                 return 0;
283         }
284
285         if (last_monitor_check + monitor_check_interval < next_processed_frames) {
286
287                 boost::shared_ptr<Ports> p = ports.reader();
288
289                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
290
291                         bool x;
292
293                         if (i->second->last_monitor() != (x = i->second->monitoring_input ())) {
294                                 i->second->set_last_monitor (x);
295                                 /* XXX I think this is dangerous, due to
296                                    a likely mutex in the signal handlers ...
297                                 */
298                                 i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
299                         }
300                 }
301                 last_monitor_check = next_processed_frames;
302         }
303
304         if (_session->silent()) {
305
306                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
307
308                         if (i->second->sends_output()) {
309                                 i->second->get_buffer(nframes).silence(nframes);
310                         }
311                 }
312         }
313
314         if (session_remove_pending && session_removal_countdown) {
315
316                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
317
318                         if (i->second->sends_output()) {
319
320                                 boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
321                                 if (ap) {
322                                         Sample* s = ap->engine_get_whole_audio_buffer ();
323                                         gain_t g = session_removal_gain;
324                                         
325                                         for (pframes_t n = 0; n < nframes; ++n) {
326                                                 *s++ *= g;
327                                                 g -= session_removal_gain_step;
328                                         }
329                                 }
330                         }
331                 }
332                 
333                 if (session_removal_countdown > nframes) {
334                         session_removal_countdown -= nframes;
335                 } else {
336                         session_removal_countdown = 0;
337                 }
338
339                 session_removal_gain -= (nframes * session_removal_gain_step);
340         }
341
342         // Finalize ports
343
344         for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
345                 i->second->cycle_end (nframes);
346         }
347
348         _processed_frames = next_processed_frames;
349
350         PT_TIMING_CHECK (2);
351         
352         return 0;
353 }
354
355
356 void
357 AudioEngine::stop_metering_thread ()
358 {
359         if (m_meter_thread) {
360                 g_atomic_int_set (&m_meter_exit, 1);
361                 m_meter_thread->join ();
362                 m_meter_thread = 0;
363         }
364 }
365
366 void
367 AudioEngine::start_metering_thread ()
368 {
369         if (m_meter_thread == 0) {
370                 g_atomic_int_set (&m_meter_exit, 0);
371                 m_meter_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::meter_thread, this));
372         }
373 }
374
375 void
376 AudioEngine::meter_thread ()
377 {
378         pthread_set_name (X_("meter"));
379
380         while (true) {
381                 Glib::usleep (10000); /* 1/100th sec interval */
382                 if (g_atomic_int_get(&m_meter_exit)) {
383                         break;
384                 }
385                 Metering::Meter ();
386         }
387 }
388
389 void
390 AudioEngine::set_session (Session *s)
391 {
392         Glib::Threads::Mutex::Lock pl (_process_lock);
393
394         SessionHandlePtr::set_session (s);
395
396         if (_session) {
397
398                 start_metering_thread ();
399
400                 pframes_t blocksize = _backend->buffer_size ();
401
402                 /* page in as much of the session process code as we
403                    can before we really start running.
404                 */
405
406                 boost::shared_ptr<Ports> p = ports.reader();
407
408                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
409                         i->second->cycle_start (blocksize);
410                 }
411
412                 _session->process (blocksize);
413                 _session->process (blocksize);
414                 _session->process (blocksize);
415                 _session->process (blocksize);
416                 _session->process (blocksize);
417                 _session->process (blocksize);
418                 _session->process (blocksize);
419                 _session->process (blocksize);
420
421                 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
422                         i->second->cycle_end (blocksize);
423                 }
424         }
425 }
426
427 void
428 AudioEngine::remove_session ()
429 {
430         Glib::Threads::Mutex::Lock lm (_process_lock);
431
432         if (_running) {
433
434                 stop_metering_thread ();
435
436                 if (_session) {
437                         session_remove_pending = true;
438                         session_removal_countdown = 0;
439                         session_removed.wait(_process_lock);
440                 }
441
442         } else {
443                 SessionHandlePtr::set_session (0);
444         }
445
446         remove_all_ports ();
447 }
448
449
450 void
451 AudioEngine::died ()
452 {
453         /* called from a signal handler for SIGPIPE */
454
455         stop_metering_thread ();
456
457         _running = false;
458 }
459
460 int
461 AudioEngine::reset_timebase ()
462 {
463         if (_session) {
464                 if (_session->config.get_jack_time_master()) {
465                         _backend->set_time_master (true);
466                 } else {
467                         _backend->set_time_master (false);
468                 }
469         }
470         return 0;
471 }
472
473
474 void
475 AudioEngine::destroy ()
476 {
477         delete _instance;
478         _instance = 0;
479 }
480
481 int
482 AudioEngine::discover_backends ()
483 {
484         vector<std::string> backend_modules;
485
486         _backends.clear ();
487
488         Glib::PatternSpec so_extension_pattern("*backend.so");
489         Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
490
491         find_matching_files_in_search_path (backend_search_path (),
492                                             so_extension_pattern, backend_modules);
493
494         find_matching_files_in_search_path (backend_search_path (),
495                                             dylib_extension_pattern, backend_modules);
496
497         DEBUG_TRACE (DEBUG::Panning, string_compose (_("looking for backends in %1\n"), backend_search_path().to_string()));
498
499         for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
500
501                 AudioBackendInfo* info;
502
503                 if ((info = backend_discover (*i)) != 0) {
504                         _backends.insert (make_pair (info->name, info));
505                 }
506         }
507
508         return _backends.size();
509 }
510
511 AudioBackendInfo*
512 AudioEngine::backend_discover (const string& path)
513 {
514         Glib::Module module (path);
515         AudioBackendInfo* info;
516         void* sym = 0;
517
518         if (!module) {
519                 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
520                                         Glib::Module::get_last_error()) << endmsg;
521                 return 0;
522         }
523         
524         if (!module.get_symbol ("descriptor", sym)) {
525                 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor."), path) << endmsg;
526                 error << Glib::Module::get_last_error() << endmsg;
527                 return 0;
528         }
529
530         module.make_resident ();
531         
532         info = (AudioBackendInfo*) sym;
533         
534         return info;
535 }
536
537 vector<const AudioBackendInfo*>
538 AudioEngine::available_backends() const
539 {
540         vector<const AudioBackendInfo*> r;
541         
542         for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
543                 r.push_back (i->second);
544         }
545
546         return r;
547 }
548
549 string
550 AudioEngine::current_backend_name() const
551 {
552         if (_backend) {
553                 return _backend->name();
554         } 
555         return string();
556 }
557
558 void
559 AudioEngine::drop_backend ()
560 {
561         if (_backend) {
562                 _backend->stop ();
563                 _backend.reset ();
564         }
565 }
566
567 boost::shared_ptr<AudioBackend>
568 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
569 {
570         BackendMap::iterator b = _backends.find (name);
571
572         if (b == _backends.end()) {
573                 return boost::shared_ptr<AudioBackend>();
574         }
575
576         drop_backend ();
577
578         try {
579                 cerr << "Instantiate " << b->second->name << " with " << arg1 << " + " << arg2 << endl;
580
581                 if (b->second->instantiate (arg1, arg2)) {
582                         cerr << "i failed\n";
583                         throw failed_constructor ();
584                 }
585
586                 _backend = b->second->backend_factory (*this);
587                 _impl = b->second->portengine_factory (*this);
588
589         } catch (exception& e) {
590                 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
591                 return boost::shared_ptr<AudioBackend>();
592         }
593
594         return _backend;
595 }
596
597 /* BACKEND PROXY WRAPPERS */
598
599 int
600 AudioEngine::start ()
601 {
602         if (!_backend) {
603                 return -1;
604         }
605
606         if (!_running) {
607
608                 if (_session) {
609                         BootMessage (_("Connect session to engine"));
610                         _session->set_frame_rate (_backend->sample_rate());
611                 }
612
613                 _processed_frames = 0;
614                 last_monitor_check = 0;
615
616                 if (_backend->start() == 0) {
617                         _running = true;
618                         last_monitor_check = 0;
619
620                         if (_session && _session->config.get_jack_time_master()) {
621                                 _backend->set_time_master (true);
622                         }
623
624                         Running(); /* EMIT SIGNAL */
625                 } else {
626                         /* should report error? */
627                 }
628         }
629                 
630         return _running ? 0 : -1;
631 }
632
633 int
634 AudioEngine::stop ()
635 {
636         if (!_backend) {
637                 return 0;
638         }
639
640         Glib::Threads::Mutex::Lock lm (_process_lock);
641
642         if (_backend->stop () == 0) {
643                 _running = false;
644                 stop_metering_thread ();
645
646                 Stopped (); /* EMIT SIGNAL */
647
648                 return 0;
649         }
650
651         return -1;
652 }
653
654 int
655 AudioEngine::pause ()
656 {
657         if (!_backend) {
658                 return 0;
659         }
660         
661         if (_backend->pause () == 0) {
662                 _running = false;
663                 Stopped(); /* EMIT SIGNAL */
664                 return 0;
665         }
666
667         return -1;
668 }
669
670 int
671 AudioEngine::freewheel (bool start_stop)
672 {
673         if (!_backend) {
674                 return -1;
675         }
676
677         /* _freewheeling will be set when first Freewheel signal occurs */
678
679         return _backend->freewheel (start_stop);
680 }
681
682 float
683 AudioEngine::get_cpu_load() const 
684 {
685         if (!_backend) {
686                 return 0.0;
687         }
688         return _backend->cpu_load ();
689 }
690
691 bool
692 AudioEngine::is_realtime() const 
693 {
694         if (!_backend) {
695                 return false;
696         }
697
698         return _backend->is_realtime();
699 }
700
701 bool
702 AudioEngine::connected() const 
703 {
704         if (!_backend) {
705                 return false;
706         }
707
708         return _backend->connected();
709 }
710
711 void
712 AudioEngine::transport_start ()
713 {
714         if (!_backend) {
715                 return;
716         }
717         return _backend->transport_start ();
718 }
719
720 void
721 AudioEngine::transport_stop ()
722 {
723         if (!_backend) {
724                 return;
725         }
726         return _backend->transport_stop ();
727 }
728
729 TransportState
730 AudioEngine::transport_state ()
731 {
732         if (!_backend) {
733                 return TransportStopped;
734         }
735         return _backend->transport_state ();
736 }
737
738 void
739 AudioEngine::transport_locate (framepos_t pos)
740 {
741         if (!_backend) {
742                 return;
743         }
744         return _backend->transport_locate (pos);
745 }
746
747 framepos_t
748 AudioEngine::transport_frame()
749 {
750         if (!_backend) {
751                 return 0;
752         }
753         return _backend->transport_frame ();
754 }
755
756 framecnt_t
757 AudioEngine::sample_rate () const
758 {
759         if (!_backend) {
760                 return 0;
761         }
762         return _backend->sample_rate ();
763 }
764
765 pframes_t
766 AudioEngine::samples_per_cycle () const
767 {
768         if (!_backend) {
769                 return 0;
770         }
771         return _backend->buffer_size ();
772 }
773
774 int
775 AudioEngine::usecs_per_cycle () const
776 {
777         if (!_backend) {
778                 return -1;
779         }
780         return _backend->usecs_per_cycle ();
781 }
782
783 size_t
784 AudioEngine::raw_buffer_size (DataType t)
785 {
786         if (!_backend) {
787                 return -1;
788         }
789         return _backend->raw_buffer_size (t);
790 }
791
792 pframes_t
793 AudioEngine::sample_time ()
794 {
795         if (!_backend) {
796                 return 0;
797         }
798         return _backend->sample_time ();
799 }
800
801 pframes_t
802 AudioEngine::sample_time_at_cycle_start ()
803 {
804         if (!_backend) {
805                 return 0;
806         }
807         return _backend->sample_time_at_cycle_start ();
808 }
809
810 pframes_t
811 AudioEngine::samples_since_cycle_start ()
812 {
813         if (!_backend) {
814                 return 0;
815         }
816         return _backend->samples_since_cycle_start ();
817 }
818
819 bool
820 AudioEngine::get_sync_offset (pframes_t& offset) const
821 {
822         if (!_backend) {
823                 return false;
824         }
825         return _backend->get_sync_offset (offset);
826 }
827
828 int
829 AudioEngine::create_process_thread (boost::function<void()> func, pthread_t* thr, size_t stacksize)
830 {
831         if (!_backend) {
832                 return -1;
833         }
834         return _backend->create_process_thread (func, thr, stacksize);
835 }
836
837
838 int
839 AudioEngine::set_device_name (const std::string& name)
840 {
841         if (!_backend) {
842                 return -1;
843         }
844         return _backend->set_device_name  (name);
845 }
846
847 int
848 AudioEngine::set_sample_rate (float sr)
849 {
850         if (!_backend) {
851                 return -1;
852         }
853         return _backend->set_sample_rate  (sr);
854 }
855
856 int
857 AudioEngine::set_buffer_size (uint32_t bufsiz)
858 {
859         if (!_backend) {
860                 return -1;
861         }
862         return _backend->set_buffer_size  (bufsiz);
863 }
864
865 int
866 AudioEngine::set_sample_format (SampleFormat sf)
867 {
868         if (!_backend) {
869                 return -1;
870         }
871         return _backend->set_sample_format  (sf);
872 }
873
874 int
875 AudioEngine::set_interleaved (bool yn)
876 {
877         if (!_backend) {
878                 return -1;
879         }
880         return _backend->set_interleaved  (yn);
881 }
882
883 int
884 AudioEngine::set_input_channels (uint32_t ic)
885 {
886         if (!_backend) {
887                 return -1;
888         }
889         return _backend->set_input_channels  (ic);
890 }
891
892 int
893 AudioEngine::set_output_channels (uint32_t oc)
894 {
895         if (!_backend) {
896                 return -1;
897         }
898         return _backend->set_output_channels (oc);
899 }
900
901 int
902 AudioEngine::set_systemic_input_latency (uint32_t il)
903 {
904         if (!_backend) {
905                 return -1;
906         }
907         return _backend->set_systemic_input_latency  (il);
908 }
909
910 int
911 AudioEngine::set_systemic_output_latency (uint32_t ol)
912 {
913         if (!_backend) {
914                 return -1;
915         }
916         return _backend->set_systemic_output_latency  (ol);
917 }
918
919 /* END OF BACKEND PROXY API */
920
921 void
922 AudioEngine::thread_init_callback (void* arg)
923 {
924         /* make sure that anybody who needs to know about this thread
925            knows about it.
926         */
927
928         pthread_set_name (X_("audioengine"));
929
930         PBD::notify_gui_about_thread_creation ("gui", pthread_self(), X_("AudioEngine"), 4096);
931         PBD::notify_gui_about_thread_creation ("midiui", pthread_self(), X_("AudioEngine"), 128);
932
933         SessionEvent::create_per_thread_pool (X_("AudioEngine"), 512);
934
935         MIDI::JackMIDIPort::set_process_thread (pthread_self());
936
937         if (arg) {
938                 AudioEngine* ae = static_cast<AudioEngine*> (arg);
939                 /* the special thread created/managed by the backend */
940                 ae->_main_thread = new ProcessThread;
941         }
942 }
943
944 /* XXXX
945 void
946 AudioEngine::timebase_callback (TransportState state, pframes_t nframes, jack_position_t pos, int new_position)
947 {
948         if (_session && _session->synced_to_jack()) {
949                 // _session->timebase_callback (state, nframes, pos, new_position);
950         }
951 }
952 */
953
954 int
955 AudioEngine::sync_callback (TransportState state, framepos_t position)
956 {
957         if (_session) {
958                 return _session->jack_sync_callback (state, position);
959         }
960         return 0;
961 }
962
963 void
964 AudioEngine::freewheel_callback (bool onoff)
965 {
966         if (onoff) {
967                 _pre_freewheel_mmc_enabled = MIDI::Manager::instance()->mmc()->send_enabled ();
968                 MIDI::Manager::instance()->mmc()->enable_send (false);
969         } else {
970                 MIDI::Manager::instance()->mmc()->enable_send (_pre_freewheel_mmc_enabled);
971         }
972 }
973
974 void
975 AudioEngine::latency_callback (bool for_playback)
976 {
977         if (_session) {
978                 _session->update_latency (for_playback);
979         }
980 }
981
982 void
983 AudioEngine::update_latencies ()
984 {
985         if (_backend) {
986                 _backend->update_latencies ();
987         }
988 }
989
990 void
991 AudioEngine::halted_callback (const char* why)
992 {
993         stop_metering_thread ();
994         
995         MIDI::JackMIDIPort::EngineHalted (); /* EMIT SIGNAL */
996         Halted (why); /* EMIT SIGNAL */
997 }
998
999 bool
1000 AudioEngine::setup_required () const
1001 {
1002         if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1003                 return false;
1004         }
1005
1006         return true;
1007 }