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