1 /*
2 * Copyright (C) 2005-2019 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2006-2016 David Robillard <d@drobilla.net>
4 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
5 * Copyright (C) 2008-2010 Sakari Bergen <sakari.bergen@beatwaves.net>
6 * Copyright (C) 2008 Hans Baier <hansfbaier@googlemail.com>
7 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
8 * Copyright (C) 2013-2014 John Emmas <john@creativepost.co.uk>
9 * Copyright (C) 2013-2015 Tim Mayberry <mojofunk@gmail.com>
10 * Copyright (C) 2015 GZharun <grygoriiz@wavesglobal.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 */
26
27 #include <unistd.h>
28 #include <cerrno>
29 #include <vector>
30 #include <exception>
31 #include <stdexcept>
32 #include <sstream>
33 #include <cmath>
34
35 #include <glibmm/timer.h>
36 #include <glibmm/pattern.h>
37 #include <glibmm/module.h>
38
39 #include "pbd/epa.h"
40 #include "pbd/file_utils.h"
41 #include "pbd/pthread_utils.h"
42 #include "pbd/unknown_type.h"
43
44 #include "midi++/port.h"
45 #include "midi++/mmc.h"
46
47 #include "ardour/async_midi_port.h"
48 #include "ardour/ardour.h"
49 #include "ardour/audio_port.h"
50 #include "ardour/audio_backend.h"
51 #include "ardour/audioengine.h"
52 #include "ardour/search_paths.h"
53 #include "ardour/buffer.h"
54 #include "ardour/cycle_timer.h"
55 #include "ardour/internal_send.h"
56 #include "ardour/meter.h"
57 #include "ardour/midi_port.h"
58 #include "ardour/midiport_manager.h"
59 #include "ardour/mididm.h"
60 #include "ardour/mtdm.h"
61 #include "ardour/port.h"
62 #include "ardour/process_thread.h"
63 #include "ardour/rc_configuration.h"
64 #include "ardour/session.h"
65 #include "ardour/transport_master_manager.h"
66
67 #include "pbd/i18n.h"
68
69 using namespace std;
70 using namespace ARDOUR;
71 using namespace PBD;
72
73 AudioEngine* AudioEngine::_instance = 0;
74
75 static GATOMIC_QUAL gint audioengine_thread_cnt = 1;
76
77 #ifdef SILENCE_AFTER
78 #define SILENCE_AFTER_SECONDS 600
79 #endif
80
AudioEngine()81 AudioEngine::AudioEngine ()
82 : session_remove_pending (false)
83 , session_removal_countdown (-1)
84 , _running (false)
85 , _freewheeling (false)
86 , monitor_check_interval (INT32_MAX)
87 , last_monitor_check (0)
88 , _processed_samples (-1)
89 , m_meter_thread (0)
90 , _main_thread (0)
91 , _mtdm (0)
92 , _mididm (0)
93 , _measuring_latency (MeasureNone)
94 , _latency_flush_samples (0)
95 , _latency_signal_latency (0)
96 , _stopped_for_latency (false)
97 , _started_for_latency (false)
98 , _in_destructor (false)
99 , _last_backend_error_string(AudioBackend::get_error_string(AudioBackend::NoError))
100 , _hw_reset_event_thread(0)
101 , _hw_devicelist_update_thread(0)
102 , _start_cnt (0)
103 , _init_countdown (0)
104 #ifdef SILENCE_AFTER_SECONDS
105 , _silence_countdown (0)
106 , _silence_hit_cnt (0)
107 #endif
108 {
109 reset_silence_countdown ();
110 start_hw_event_processing();
111 discover_backends ();
112
113 g_atomic_int_set (&_hw_reset_request_count, 0);
114 g_atomic_int_set (&_pending_playback_latency_callback, 0);
115 g_atomic_int_set (&_pending_capture_latency_callback, 0);
116 g_atomic_int_set (&_hw_devicelist_update_count, 0);
117 g_atomic_int_set (&_stop_hw_reset_processing, 0);
118 g_atomic_int_set (&_stop_hw_devicelist_processing, 0);
119 }
120
~AudioEngine()121 AudioEngine::~AudioEngine ()
122 {
123 _in_destructor = true;
124 stop_hw_event_processing();
125 drop_backend ();
126 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
127 i->second->deinstantiate();
128 }
129 delete _main_thread;
130 }
131
132 AudioEngine*
create()133 AudioEngine::create ()
134 {
135 if (_instance) {
136 return _instance;
137 }
138
139 _instance = new AudioEngine ();
140
141 return _instance;
142 }
143
144 void
split_cycle(pframes_t nframes)145 AudioEngine::split_cycle (pframes_t nframes)
146 {
147 /* caller must hold process lock */
148
149 boost::shared_ptr<Ports> p = _ports.reader();
150
151 /* This is mainly for the benefit of rt-control ports (MTC, MClk)
152 *
153 * Normally ports are flushed by the route:
154 * ARDOUR::MidiPort::flush_buffers(unsigned int)
155 * ARDOUR::Delivery::flush_buffers(long)
156 * ARDOUR::Route::flush_processor_buffers_locked(long)
157 * ARDOUR::Route::run_route(long, long, unsigned int, bool, bool)
158 * ...
159 *
160 * This is required so that route -> route connections work during
161 * normal processing.
162 *
163 * However some non-route ports may contain MIDI events
164 * from current Port::port_offset() .. Port::port_offset() + nframes.
165 * If those events are not pushed to ports before the cycle split,
166 * MidiPort::flush_buffers will drop them (event time is out of bounds).
167 *
168 * TODO: for optimized builds MidiPort::flush_buffers() could
169 * be relaxed, ignore ev->time() checks, and simply send
170 * all events as-is.
171 */
172 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
173 i->second->flush_buffers (nframes);
174 }
175
176 Port::increment_global_port_buffer_offset (nframes);
177
178 /* tell all Ports that we're going to start a new (split) cycle */
179
180
181 for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
182 i->second->cycle_split ();
183 }
184 }
185
186 int
sample_rate_change(pframes_t nframes)187 AudioEngine::sample_rate_change (pframes_t nframes)
188 {
189 /* check for monitor input change every 1/10th of second */
190
191 monitor_check_interval = nframes / 10;
192 last_monitor_check = 0;
193
194 if (_session) {
195 _session->set_sample_rate (nframes);
196 }
197
198 SampleRateChanged (nframes); /* EMIT SIGNAL */
199
200 #ifdef SILENCE_AFTER_SECONDS
201 _silence_countdown = nframes * SILENCE_AFTER_SECONDS;
202 #endif
203
204 return 0;
205 }
206
207 int
buffer_size_change(pframes_t bufsiz)208 AudioEngine::buffer_size_change (pframes_t bufsiz)
209 {
210 set_port_buffer_sizes (bufsiz);
211
212 if (_session) {
213 _session->set_block_size (bufsiz);
214 last_monitor_check = 0;
215 }
216
217 BufferSizeChanged (bufsiz); /* EMIT SIGNAL */
218
219 return 0;
220 }
221
222 /** Method called by our ::process_thread when there is work to be done.
223 * @param nframes Number of samples to process.
224 */
225 #ifdef __clang__
226 __attribute__((annotate("realtime")))
227 #endif
228 int
process_callback(pframes_t nframes)229 AudioEngine::process_callback (pframes_t nframes)
230 {
231 TimerRAII tr (dsp_stats[ProcessCallback]);
232 Glib::Threads::Mutex::Lock tm (_process_lock, Glib::Threads::TRY_LOCK);
233 Port::set_speed_ratio (1.0);
234
235 PT_TIMING_REF;
236 PT_TIMING_CHECK (1);
237
238 /// The number of samples that will have been processed when we've finished
239 pframes_t next_processed_samples;
240
241 if (_processed_samples < 0) {
242 _processed_samples = sample_time();
243 cerr << "IIIIINIT PS to " << _processed_samples << endl;
244 }
245
246 /* handle wrap around of total samples counter */
247
248 if (max_samplepos - _processed_samples < nframes) {
249 next_processed_samples = nframes - (max_samplepos - _processed_samples);
250 } else {
251 next_processed_samples = _processed_samples + nframes;
252 }
253
254 if (!tm.locked()) {
255 /* return having done nothing */
256 if (_session) {
257 Xrun();
258 }
259 /* really only JACK requires this
260 * (other backends clear the output buffers
261 * before the process_callback. it may even be
262 * jack/alsa only). but better safe than sorry.
263 */
264 PortManager::silence_outputs (nframes);
265 return 0;
266 }
267
268 /* The coreaudio-backend calls thread_init_callback() if
269 * the hardware changes or pthread_self() changes.
270 *
271 * However there are cases when neither holds true, yet
272 * the thread-pool changes: e.g. connect a headphone to
273 * a shared mic/headphone jack.
274 * It's probably related to, or caused by clocksource changes.
275 *
276 * For reasons yet unknown Glib::Threads::Private() can
277 * use a different thread-private in the same pthread
278 * (coreaudio render callback).
279 *
280 * Coreaudio must set something which influences
281 * pthread_key_t uniqness or reset the key using
282 * pthread_getspecific().
283 */
284 if (! SessionEvent::has_per_thread_pool ()) {
285 thread_init_callback (NULL);
286 }
287
288 /* This is for JACK, where the latency callback arrives in sync with
289 * port registration (usually while ardour holds the process-lock
290 * or with _adding_routes_in_progress or _route_deletion_in_progress set,
291 * potentially while processing in parallel.
292 *
293 * Note: this must be done without holding the _process_lock
294 */
295 if (_session) {
296 bool lp = false;
297 bool lc = false;
298 if (g_atomic_int_compare_and_exchange (&_pending_playback_latency_callback, 1, 0)) {
299 lp = true;
300 }
301 if (g_atomic_int_compare_and_exchange (&_pending_capture_latency_callback, 1, 0)) {
302 lc = true;
303 }
304 if (lp || lc) {
305 tm.release ();
306 if (lp) {
307 _session->update_latency (true);
308 }
309 if (lc) {
310 _session->update_latency (false);
311 }
312 tm.acquire ();
313 }
314 }
315
316 if (_session && _init_countdown > 0) {
317 --_init_countdown;
318 /* Warm up caches */
319 PortManager::cycle_start (nframes, _session);
320 _session->process (nframes);
321 PortManager::silence (nframes);
322 PortManager::cycle_end (nframes);
323 if (_init_countdown == 0) {
324 _session->reset_xrun_count();
325 ARDOUR::reset_performance_meters (_session);
326 }
327
328 return 0;
329 }
330
331 bool return_after_remove_check = false;
332
333 if (_measuring_latency == MeasureAudio && _mtdm) {
334 /* run a normal cycle from the perspective of the PortManager
335 so that we get silence on all registered ports.
336
337 we overwrite the silence on the two ports used for latency
338 measurement.
339 */
340
341 PortManager::cycle_start (nframes);
342 PortManager::silence (nframes);
343
344 if (_latency_input_port && _latency_output_port) {
345 PortEngine& pe (port_engine());
346
347 Sample* in = (Sample*) pe.get_buffer (_latency_input_port, nframes);
348 Sample* out = (Sample*) pe.get_buffer (_latency_output_port, nframes);
349
350 _mtdm->process (nframes, in, out);
351 }
352
353 PortManager::cycle_end (nframes);
354 return_after_remove_check = true;
355
356 } else if (_measuring_latency == MeasureMIDI && _mididm) {
357 /* run a normal cycle from the perspective of the PortManager
358 so that we get silence on all registered ports.
359
360 we overwrite the silence on the two ports used for latency
361 measurement.
362 */
363
364 PortManager::cycle_start (nframes);
365 PortManager::silence (nframes);
366
367 if (_latency_input_port && _latency_output_port) {
368 PortEngine& pe (port_engine());
369
370 _mididm->process (nframes, pe,
371 pe.get_buffer (_latency_input_port, nframes),
372 pe.get_buffer (_latency_output_port, nframes));
373 }
374
375 PortManager::cycle_end (nframes);
376 return_after_remove_check = true;
377
378 } else if (_latency_flush_samples) {
379
380 /* wait for the appropriate duration for the MTDM signal to
381 * drain from the ports before we revert to normal behaviour.
382 */
383
384 PortManager::cycle_start (nframes);
385 PortManager::silence (nframes);
386 PortManager::cycle_end (nframes);
387
388 if (_latency_flush_samples > nframes) {
389 _latency_flush_samples -= nframes;
390 } else {
391 _latency_flush_samples = 0;
392 }
393
394 return_after_remove_check = true;
395 }
396
397 if (session_remove_pending) {
398
399 /* perform the actual session removal */
400
401 if (session_removal_countdown < 0) {
402
403 /* fade out over 1 second */
404 session_removal_countdown = sample_rate()/2;
405 session_removal_gain = GAIN_COEFF_UNITY;
406 session_removal_gain_step = 1.0/session_removal_countdown;
407
408 } else if (session_removal_countdown > 0) {
409
410 /* we'll be fading audio out.
411
412 if this is the last time we do this as part
413 of session removal, do a MIDI panic now
414 to get MIDI stopped. This relies on the fact
415 that "immediate data" (aka "out of band data") from
416 MIDI tracks is *appended* after any other data,
417 so that it emerges after any outbound note ons, etc.
418 */
419
420 if (session_removal_countdown <= nframes) {
421 assert (_session);
422 _session->midi_panic ();
423 }
424
425 } else {
426 /* fade out done */
427 _session = 0;
428 session_removal_countdown = -1; // reset to "not in progress"
429 session_remove_pending = false;
430 session_removed.signal(); // wakes up thread that initiated session removal
431 }
432 }
433
434 if (return_after_remove_check) {
435 return 0;
436 }
437
438 TransportMasterManager& tmm (TransportMasterManager::instance());
439
440 /* make sure the TMM is up to date about the current session */
441
442 if (_session != tmm.session()) {
443 tmm.set_session (_session);
444 }
445
446 if (_session == 0) {
447
448 if (!_freewheeling) {
449 PortManager::silence_outputs (nframes);
450 }
451
452 _processed_samples = next_processed_samples;
453
454 return 0;
455 }
456
457 if (!_freewheeling || Freewheel.empty()) {
458 /* catch_speed is the speed that we estimate we need to run at
459 to catch (or remain locked to) a transport master.
460 */
461 double catch_speed = tmm.pre_process_transport_masters (nframes, sample_time_at_cycle_start());
462 catch_speed = _session->plan_master_strategy (nframes, tmm.get_current_speed_in_process_context(), tmm.get_current_position_in_process_context(), catch_speed);
463 Port::set_speed_ratio (catch_speed);
464 DEBUG_TRACE (DEBUG::Slave, string_compose ("transport master (current=%1) gives speed %2 (ports using %3)\n", tmm.current() ? tmm.current()->name() : string("[]"), catch_speed, Port::speed_ratio()));
465
466 #if 0 // USE FOR DEBUG ONLY
467 /* use with Dummy backend, engine pulse and
468 * scripts/_find_nonzero_sample.lua
469 * to correlate with recorded region alignment.
470 */
471 static bool was_rolling = false;
472 bool is_rolling = _session->transport_rolling();
473 if (!was_rolling && is_rolling) {
474 samplepos_t stacs = sample_time_at_cycle_start ();
475 samplecnt_t sr = sample_rate ();
476 samplepos_t tp = _session->transport_sample ();
477 /* Note: this does not take Port latency into account:
478 * - always add 12 samples (Port::_resampler_quality)
479 * - ExistingMaterial: subtract playback latency from engine-pulse
480 * We assume the player listens and plays along. Recorded region is moved
481 * back by playback_latency
482 */
483 printf (" ******** Starting play at %ld, next pulse: %ld\n", stacs, ((sr - (stacs % sr)) %sr) + tp);
484 }
485 was_rolling = is_rolling;
486 #endif
487 }
488
489 /* tell all relevant objects that we're starting a new cycle */
490
491 InternalSend::CycleStart (nframes);
492
493 /* tell all Ports that we're starting a new cycle */
494
495 PortManager::cycle_start (nframes, _session);
496
497 /* test if we are freewheeling and there are freewheel signals connected.
498 * ardour should act normally even when freewheeling unless /it/ is
499 * exporting (which is what Freewheel.empty() tests for).
500 */
501
502 if (_freewheeling && !Freewheel.empty()) {
503 Freewheel (nframes);
504 } else {
505 samplepos_t start_sample = _session->transport_sample ();
506 samplecnt_t pre_roll = _session->remaining_latency_preroll ();
507
508 if (Port::cycle_nframes () <= nframes) {
509 _session->process (Port::cycle_nframes ());
510 } else {
511 pframes_t remain = Port::cycle_nframes ();
512 while (remain > 0) {
513 /* keep track of split_cycle() calls by Session::process */
514 samplecnt_t poff = Port::port_offset ();
515 pframes_t nf = std::min (remain, nframes);
516 _session->process (nf);
517 remain -= nf;
518 if (remain > 0) {
519 /* calculate split-cycle offset */
520 samplecnt_t delta = Port::port_offset () - poff;
521 assert (delta >= 0 && delta <= nf);
522 if (nf > delta) {
523 split_cycle (nf - delta);
524 }
525 }
526 }
527 }
528
529 /* send timecode for current cycle */
530 samplepos_t end_sample = _session->transport_sample ();
531 _session->send_ltc_for_cycle (start_sample, end_sample, nframes);
532 /* and MIDI Clock */
533 _session->send_mclk_for_cycle (start_sample, end_sample, nframes, pre_roll);
534 }
535
536 if (_freewheeling) {
537 PortManager::cycle_end (nframes, _session);
538 return 0;
539 }
540
541 if (!_running) {
542 _processed_samples = next_processed_samples;
543 return 0;
544 }
545
546 if (last_monitor_check + monitor_check_interval < next_processed_samples) {
547
548 PortManager::check_monitoring ();
549 last_monitor_check = next_processed_samples;
550 }
551
552 #ifdef SILENCE_AFTER_SECONDS
553
554 bool was_silent = (_silence_countdown == 0);
555
556 if (_silence_countdown >= nframes) {
557 _silence_countdown -= nframes;
558 } else {
559 _silence_countdown = 0;
560 }
561
562 if (!was_silent && _silence_countdown == 0) {
563 _silence_hit_cnt++;
564 BecameSilent (); /* EMIT SIGNAL */
565 }
566
567 if (_silence_countdown == 0 || _session->silent()) {
568 PortManager::silence (nframes);
569 }
570
571 #else
572 if (_session->silent()) {
573 PortManager::silence (nframes, _session);
574 }
575 #endif
576
577 if (session_remove_pending && session_removal_countdown) {
578
579 PortManager::cycle_end_fade_out (session_removal_gain, session_removal_gain_step, nframes, _session);
580
581 if (session_removal_countdown > nframes) {
582 session_removal_countdown -= nframes;
583 } else {
584 session_removal_countdown = 0;
585 }
586
587 session_removal_gain -= (nframes * session_removal_gain_step);
588 } else {
589 PortManager::cycle_end (nframes, _session);
590 }
591
592 _processed_samples = next_processed_samples;
593
594 PT_TIMING_CHECK (2);
595
596 return 0;
597 }
598
599 void
reset_silence_countdown()600 AudioEngine::reset_silence_countdown ()
601 {
602 #ifdef SILENCE_AFTER_SECONDS
603 double sr = 48000; /* default in case there is no backend */
604
605 sr = sample_rate();
606
607 _silence_countdown = max (60 * sr, /* 60 seconds */
608 sr * (SILENCE_AFTER_SECONDS / ::pow (2.0, (double) _silence_hit_cnt)));
609
610 #endif
611 }
612
613 void
launch_device_control_app()614 AudioEngine::launch_device_control_app()
615 {
616 if (_state_lock.trylock () ) {
617 _backend->launch_control_app ();
618 _state_lock.unlock ();
619 }
620 }
621
622
623 void
request_backend_reset()624 AudioEngine::request_backend_reset()
625 {
626 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
627 g_atomic_int_inc (&_hw_reset_request_count);
628 _hw_reset_condition.signal ();
629 }
630
631 int
backend_reset_requested()632 AudioEngine::backend_reset_requested()
633 {
634 return g_atomic_int_get (&_hw_reset_request_count);
635 }
636
637 void
do_reset_backend()638 AudioEngine::do_reset_backend()
639 {
640 SessionEvent::create_per_thread_pool (X_("Backend reset processing thread"), 1024);
641 pthread_set_name ("EngineWatchdog");
642
643 Glib::Threads::Mutex::Lock guard (_reset_request_lock);
644
645 while (!g_atomic_int_get (&_stop_hw_reset_processing)) {
646
647 if (g_atomic_int_get (&_hw_reset_request_count) != 0 && _backend) {
648
649 _reset_request_lock.unlock();
650
651 Glib::Threads::RecMutex::Lock pl (_state_lock);
652 g_atomic_int_dec_and_test (&_hw_reset_request_count);
653
654 std::cout << "AudioEngine::RESET::Reset request processing. Requests left: " << _hw_reset_request_count << std::endl;
655 DeviceResetStarted(); // notify about device reset to be started
656
657 // backup the device name
658 std::string name = _backend->device_name ();
659
660 std::cout << "AudioEngine::RESET::Reseting device..." << std::endl;
661 if ( ( 0 == stop () ) &&
662 ( 0 == _backend->reset_device () ) &&
663 ( 0 == start () ) ) {
664
665 std::cout << "AudioEngine::RESET::Engine started..." << std::endl;
666
667 // inform about possible changes
668 BufferSizeChanged (_backend->buffer_size() );
669 DeviceResetFinished(); // notify about device reset finish
670
671 } else {
672
673 DeviceResetFinished(); // notify about device reset finish
674 // we've got an error
675 DeviceError();
676 }
677
678 std::cout << "AudioEngine::RESET::Done." << std::endl;
679
680 _reset_request_lock.lock();
681
682 } else {
683
684 _hw_reset_condition.wait (_reset_request_lock);
685
686 }
687 }
688 }
689
690 void
request_device_list_update()691 AudioEngine::request_device_list_update()
692 {
693 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
694 g_atomic_int_inc (&_hw_devicelist_update_count);
695 _hw_devicelist_update_condition.signal ();
696 }
697
698 void
do_devicelist_update()699 AudioEngine::do_devicelist_update()
700 {
701 SessionEvent::create_per_thread_pool (X_("Device list update processing thread"), 512);
702 pthread_set_name ("DeviceList");
703
704 Glib::Threads::Mutex::Lock guard (_devicelist_update_lock);
705
706 while (!_stop_hw_devicelist_processing) {
707
708 if (g_atomic_int_get (&_hw_devicelist_update_count)) {
709
710 _devicelist_update_lock.unlock();
711
712 Glib::Threads::RecMutex::Lock pl (_state_lock);
713
714 g_atomic_int_dec_and_test (&_hw_devicelist_update_count);
715 DeviceListChanged (); /* EMIT SIGNAL */
716
717 _devicelist_update_lock.lock();
718
719 } else {
720 _hw_devicelist_update_condition.wait (_devicelist_update_lock);
721 }
722 }
723 }
724
725
726 void
start_hw_event_processing()727 AudioEngine::start_hw_event_processing()
728 {
729 if (_hw_reset_event_thread == 0) {
730 g_atomic_int_set (&_hw_reset_request_count, 0);
731 g_atomic_int_set (&_stop_hw_reset_processing, 0);
732 _hw_reset_event_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_reset_backend, this));
733 }
734
735 if (_hw_devicelist_update_thread == 0) {
736 g_atomic_int_set (&_hw_devicelist_update_count, 0);
737 g_atomic_int_set (&_stop_hw_devicelist_processing, 0);
738 _hw_devicelist_update_thread = Glib::Threads::Thread::create (boost::bind (&AudioEngine::do_devicelist_update, this));
739 }
740 }
741
742
743 void
stop_hw_event_processing()744 AudioEngine::stop_hw_event_processing()
745 {
746 if (_hw_reset_event_thread) {
747 g_atomic_int_set (&_stop_hw_reset_processing, 1);
748 g_atomic_int_set (&_hw_reset_request_count, 0);
749 _hw_reset_condition.signal ();
750 _hw_reset_event_thread->join ();
751 _hw_reset_event_thread = 0;
752 }
753
754 if (_hw_devicelist_update_thread) {
755 g_atomic_int_set (&_stop_hw_devicelist_processing, 1);
756 g_atomic_int_set (&_hw_devicelist_update_count, 0);
757 _hw_devicelist_update_condition.signal ();
758 _hw_devicelist_update_thread->join ();
759 _hw_devicelist_update_thread = 0;
760 }
761 }
762
763 void
set_session(Session * s)764 AudioEngine::set_session (Session *s)
765 {
766 Glib::Threads::Mutex::Lock pl (_process_lock);
767
768 SessionHandlePtr::set_session (s);
769
770 if (_session) {
771 _init_countdown = std::max (4, (int)(_backend->sample_rate () / _backend->buffer_size ()) / 8);
772 g_atomic_int_set (&_pending_playback_latency_callback, 0);
773 g_atomic_int_set (&_pending_capture_latency_callback, 0);
774 }
775 }
776
777 void
remove_session()778 AudioEngine::remove_session ()
779 {
780 Glib::Threads::Mutex::Lock lm (_process_lock);
781
782 if (_running) {
783
784 if (_session) {
785 session_remove_pending = true;
786 /* signal the start of the fade out countdown */
787 session_removal_countdown = -1;
788 session_removed.wait(_process_lock);
789 }
790
791 } else {
792 SessionHandlePtr::set_session (0);
793 }
794
795 remove_all_ports ();
796 }
797
798 void
died()799 AudioEngine::died ()
800 {
801 /* called from a signal handler for SIGPIPE */
802 _running = false;
803 }
804
805 int
reset_timebase()806 AudioEngine::reset_timebase ()
807 {
808 if (_session) {
809 if (_session->config.get_jack_time_master()) {
810 _backend->set_time_master (true);
811 } else {
812 _backend->set_time_master (false);
813 }
814 }
815 return 0;
816 }
817
818
819 void
destroy()820 AudioEngine::destroy ()
821 {
822 delete _instance;
823 _instance = 0;
824 }
825
826 int
discover_backends()827 AudioEngine::discover_backends ()
828 {
829 vector<std::string> backend_modules;
830
831 _backends.clear ();
832
833 Glib::PatternSpec so_extension_pattern("*backend.so");
834 Glib::PatternSpec dylib_extension_pattern("*backend.dylib");
835
836 #if defined(PLATFORM_WINDOWS) && defined(DEBUGGABLE_BACKENDS)
837 #if defined(DEBUG) || defined(_DEBUG)
838 Glib::PatternSpec dll_extension_pattern("*backendD.dll");
839 #else
840 Glib::PatternSpec dll_extension_pattern("*backendRDC.dll");
841 #endif
842 #else
843 Glib::PatternSpec dll_extension_pattern("*backend.dll");
844 #endif
845
846 find_files_matching_pattern (backend_modules, backend_search_path (),
847 so_extension_pattern);
848
849 find_files_matching_pattern (backend_modules, backend_search_path (),
850 dylib_extension_pattern);
851
852 find_files_matching_pattern (backend_modules, backend_search_path (),
853 dll_extension_pattern);
854
855 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("looking for backends in %1\n", backend_search_path().to_string()));
856
857 for (vector<std::string>::iterator i = backend_modules.begin(); i != backend_modules.end(); ++i) {
858
859 AudioBackendInfo* info;
860
861 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Checking possible backend in %1\n", *i));
862
863 if ((info = backend_discover (*i)) != 0) {
864 _backends.insert (make_pair (info->name, info));
865 }
866 }
867
868 DEBUG_TRACE (DEBUG::AudioEngine, string_compose ("Found %1 backends\n", _backends.size()));
869
870 return _backends.size();
871 }
872
873 AudioBackendInfo*
backend_discover(const string & path)874 AudioEngine::backend_discover (const string& path)
875 {
876 #ifdef PLATFORM_WINDOWS
877 // do not show popup dialog (e.g. missing libjack.dll)
878 // win7+ should use SetThreadErrorMode()
879 SetErrorMode(SEM_FAILCRITICALERRORS);
880 #endif
881 Glib::Module module (path);
882 #ifdef PLATFORM_WINDOWS
883 SetErrorMode(0); // reset to system default
884 #endif
885 AudioBackendInfo* info;
886 AudioBackendInfo* (*dfunc)(void);
887 void* func = 0;
888
889 if (!module) {
890 error << string_compose(_("AudioEngine: cannot load module \"%1\" (%2)"), path,
891 Glib::Module::get_last_error()) << endmsg;
892 return 0;
893 }
894
895 if (!module.get_symbol ("descriptor", func)) {
896 error << string_compose(_("AudioEngine: backend at \"%1\" has no descriptor function."), path) << endmsg;
897 error << Glib::Module::get_last_error() << endmsg;
898 return 0;
899 }
900
901 dfunc = (AudioBackendInfo* (*)(void))func;
902 info = dfunc();
903 if (!info->available()) {
904 return 0;
905 }
906
907 module.make_resident ();
908
909 return info;
910 }
911
912 #ifdef NDEBUG
running_from_source_tree()913 static bool running_from_source_tree ()
914 {
915 // dup ARDOUR_UI_UTILS::running_from_source_tree ()
916 gchar const *x = g_getenv ("ARDOUR_THEMES_PATH");
917 return x && (string (x).find ("gtk2_ardour") != string::npos);
918 }
919 #endif
920
921 vector<const AudioBackendInfo*>
available_backends() const922 AudioEngine::available_backends() const
923 {
924 vector<const AudioBackendInfo*> r;
925
926 for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
927 #ifdef NDEBUG
928 if (i->first == "None (Dummy)" && !running_from_source_tree () && Config->get_hide_dummy_backend ()) {
929 continue;
930 }
931 #endif
932 r.push_back (i->second);
933 }
934
935 return r;
936 }
937
938 string
current_backend_name() const939 AudioEngine::current_backend_name() const
940 {
941 if (_backend) {
942 return _backend->name();
943 }
944 return string();
945 }
946
947 void
drop_backend()948 AudioEngine::drop_backend ()
949 {
950 if (_backend) {
951 /* see also ::stop() */
952 _backend->stop ();
953 _running = false;
954 if (_session && !_session->loading() && !_session->deletion_in_progress()) {
955 // it's not a halt, but should be handled the same way:
956 // disable record, stop transport and I/O processign but save the data.
957 _session->engine_halted ();
958 }
959 Port::PortDrop (); /* EMIT SIGNAL */
960 TransportMasterManager& tmm (TransportMasterManager::instance());
961 tmm.engine_stopped ();
962 tmm.set_session (0); // unregister TMM ports
963
964 /* Stopped is needed for Graph to explicitly terminate threads */
965 Stopped (); /* EMIT SIGNAL */
966 _backend->drop_device ();
967 _backend.reset ();
968 }
969 }
970
971 boost::shared_ptr<AudioBackend>
set_backend(const std::string & name,const std::string & arg1,const std::string & arg2)972 AudioEngine::set_backend (const std::string& name, const std::string& arg1, const std::string& arg2)
973 {
974 BackendMap::iterator b = _backends.find (name);
975
976 if (b == _backends.end()) {
977 return boost::shared_ptr<AudioBackend>();
978 }
979
980 drop_backend ();
981
982 try {
983 if (b->second->instantiate (arg1, arg2)) {
984 throw failed_constructor ();
985 }
986
987 _backend = b->second->factory (*this);
988
989 } catch (exception& e) {
990 error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
991 return boost::shared_ptr<AudioBackend>();
992 }
993
994 return _backend;
995 }
996
997 /* BACKEND PROXY WRAPPERS */
998
999 int
start(bool for_latency)1000 AudioEngine::start (bool for_latency)
1001 {
1002 if (!_backend) {
1003 return -1;
1004 }
1005
1006 if (_running && _backend->can_change_systemic_latency_when_running()) {
1007 _started_for_latency = for_latency;
1008 }
1009
1010 if (_running) {
1011 return 0;
1012 }
1013
1014 _processed_samples = 0;
1015 last_monitor_check = 0;
1016
1017 int error_code = _backend->start (for_latency);
1018
1019 if (error_code != 0) {
1020 _last_backend_error_string = AudioBackend::get_error_string((AudioBackend::ErrorCode) error_code);
1021 return -1;
1022 }
1023
1024 _running = true;
1025
1026 if (_session) {
1027 _session->set_sample_rate (_backend->sample_rate());
1028
1029 if (_session->config.get_jack_time_master()) {
1030 _backend->set_time_master (true);
1031 }
1032
1033 }
1034
1035 if (!for_latency) {
1036 /* Call the library-wide ::init_post_engine() before emitting
1037 * running to ensure that its tasks are complete before any
1038 * signal handlers execute. PBD::Signal does not ensure
1039 * ordering of signal handlers so even if ::init_post_engine()
1040 * is connected first, it may not run first.
1041 */
1042
1043 ARDOUR::init_post_engine (_start_cnt);
1044
1045 Running (_start_cnt); /* EMIT SIGNAL */
1046
1047 /* latency start/stop cycles do not count as "starts" */
1048
1049 _start_cnt++;
1050 }
1051
1052
1053 return 0;
1054 }
1055
1056 int
stop(bool for_latency)1057 AudioEngine::stop (bool for_latency)
1058 {
1059 bool stop_engine = true;
1060
1061 if (!_backend) {
1062 return 0;
1063 }
1064
1065 Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
1066
1067 if (running()) {
1068 pl.acquire ();
1069 }
1070
1071 if (for_latency && _backend->can_change_systemic_latency_when_running()) {
1072 stop_engine = false;
1073 if (_running && _started_for_latency) {
1074 _backend->start (false); // keep running, reload latencies
1075 }
1076 } else {
1077 if (_backend->stop ()) {
1078 if (pl.locked ()) {
1079 pl.release ();
1080 }
1081 return -1;
1082 }
1083 }
1084
1085 if (pl.locked ()) {
1086 pl.release ();
1087 }
1088
1089 const bool was_running_will_stop = (_running && stop_engine);
1090
1091 if (was_running_will_stop) {
1092 _running = false;
1093 }
1094
1095 if (_session && was_running_will_stop && !_session->loading() && !_session->deletion_in_progress()) {
1096 // it's not a halt, but should be handled the same way:
1097 // disable record, stop transport and I/O processign but save the data.
1098 _session->engine_halted ();
1099 }
1100
1101 if (was_running_will_stop) {
1102 if (!for_latency) {
1103 _started_for_latency = false;
1104 } else if (!_started_for_latency) {
1105 _stopped_for_latency = true;
1106 }
1107 }
1108 _processed_samples = 0;
1109 _measuring_latency = MeasureNone;
1110 _latency_output_port.reset ();
1111 _latency_input_port.reset ();
1112
1113 if (stop_engine) {
1114 Port::PortDrop ();
1115 }
1116
1117 if (stop_engine) {
1118 TransportMasterManager& tmm (TransportMasterManager::instance());
1119 tmm.engine_stopped ();
1120 Stopped (); /* EMIT SIGNAL */
1121 }
1122
1123 return 0;
1124 }
1125
1126 int
freewheel(bool start_stop)1127 AudioEngine::freewheel (bool start_stop)
1128 {
1129 if (!_backend) {
1130 return -1;
1131 }
1132
1133 /* _freewheeling will be set when first Freewheel signal occurs */
1134
1135 return _backend->freewheel (start_stop);
1136 }
1137
1138 float
get_dsp_load() const1139 AudioEngine::get_dsp_load() const
1140 {
1141 if (!_backend || !_running) {
1142 return 0.0;
1143 }
1144 return _backend->dsp_load ();
1145 }
1146
1147 bool
is_realtime() const1148 AudioEngine::is_realtime() const
1149 {
1150 if (!_backend) {
1151 return false;
1152 }
1153
1154 return _backend->is_realtime();
1155 }
1156
1157 int
client_real_time_priority()1158 AudioEngine::client_real_time_priority ()
1159 {
1160 if (!_backend) {
1161 assert (0);
1162 return PBD_RT_PRI_PROC;
1163 }
1164 if (!_backend->is_realtime ()) {
1165 /* this is only an issue with the Dummy backend.
1166 * - with JACK, we require rt permissions.
1167 * - with ALSA/Pulseaudio this can only happen if rt permissions
1168 * are n/a. Other atempts to get rt will fail likewise.
1169 *
1170 * perhaps:
1171 * TODO: use is_realtime () ? PBD_SCHED_FIFO : PBD_SCHED_OTHER
1172 */
1173 return PBD_RT_PRI_PROC; // XXX
1174 }
1175
1176 return _backend->client_real_time_priority();
1177 }
1178
1179 void
transport_start()1180 AudioEngine::transport_start ()
1181 {
1182 if (!_backend) {
1183 return;
1184 }
1185 return _backend->transport_start ();
1186 }
1187
1188 void
transport_stop()1189 AudioEngine::transport_stop ()
1190 {
1191 if (!_backend) {
1192 return;
1193 }
1194 return _backend->transport_stop ();
1195 }
1196
1197 TransportState
transport_state()1198 AudioEngine::transport_state ()
1199 {
1200 if (!_backend) {
1201 return TransportStopped;
1202 }
1203 return _backend->transport_state ();
1204 }
1205
1206 void
transport_locate(samplepos_t pos)1207 AudioEngine::transport_locate (samplepos_t pos)
1208 {
1209 if (!_backend) {
1210 return;
1211 }
1212 return _backend->transport_locate (pos);
1213 }
1214
1215 samplepos_t
transport_sample()1216 AudioEngine::transport_sample()
1217 {
1218 if (!_backend) {
1219 return 0;
1220 }
1221 return _backend->transport_sample ();
1222 }
1223
1224 samplecnt_t
sample_rate() const1225 AudioEngine::sample_rate () const
1226 {
1227 if (!_backend) {
1228 return 0;
1229 }
1230 return _backend->sample_rate ();
1231 }
1232
1233 pframes_t
samples_per_cycle() const1234 AudioEngine::samples_per_cycle () const
1235 {
1236 if (!_backend) {
1237 return 0;
1238 }
1239 return _backend->buffer_size ();
1240 }
1241
1242 int
usecs_per_cycle() const1243 AudioEngine::usecs_per_cycle () const
1244 {
1245 if (!_backend) {
1246 return -1;
1247 }
1248 return _backend->usecs_per_cycle ();
1249 }
1250
1251 size_t
raw_buffer_size(DataType t)1252 AudioEngine::raw_buffer_size (DataType t)
1253 {
1254 if (!_backend) {
1255 return -1;
1256 }
1257 return _backend->raw_buffer_size (t);
1258 }
1259
1260 samplepos_t
sample_time()1261 AudioEngine::sample_time ()
1262 {
1263 if (!_backend) {
1264 return 0;
1265 }
1266 return _backend->sample_time ();
1267 }
1268
1269 samplepos_t
sample_time_at_cycle_start()1270 AudioEngine::sample_time_at_cycle_start ()
1271 {
1272 if (!_backend) {
1273 return 0;
1274 }
1275 return _backend->sample_time_at_cycle_start ();
1276 }
1277
1278 pframes_t
samples_since_cycle_start()1279 AudioEngine::samples_since_cycle_start ()
1280 {
1281 if (!_backend) {
1282 return 0;
1283 }
1284 return _backend->samples_since_cycle_start ();
1285 }
1286
1287 bool
get_sync_offset(pframes_t & offset) const1288 AudioEngine::get_sync_offset (pframes_t& offset) const
1289 {
1290 if (!_backend) {
1291 return false;
1292 }
1293 return _backend->get_sync_offset (offset);
1294 }
1295
1296 int
create_process_thread(boost::function<void ()> func)1297 AudioEngine::create_process_thread (boost::function<void()> func)
1298 {
1299 if (!_backend) {
1300 return -1;
1301 }
1302 return _backend->create_process_thread (func);
1303 }
1304
1305 int
join_process_threads()1306 AudioEngine::join_process_threads ()
1307 {
1308 if (!_backend) {
1309 return -1;
1310 }
1311 return _backend->join_process_threads ();
1312 }
1313
1314 bool
in_process_thread()1315 AudioEngine::in_process_thread ()
1316 {
1317 if (!_backend) {
1318 return false;
1319 }
1320 return _backend->in_process_thread ();
1321 }
1322
1323 uint32_t
process_thread_count()1324 AudioEngine::process_thread_count ()
1325 {
1326 if (!_backend) {
1327 return 0;
1328 }
1329 return _backend->process_thread_count ();
1330 }
1331
1332 int
set_device_name(const std::string & name)1333 AudioEngine::set_device_name (const std::string& name)
1334 {
1335 if (!_backend) {
1336 return -1;
1337 }
1338 return _backend->set_device_name (name);
1339 }
1340
1341 int
set_sample_rate(float sr)1342 AudioEngine::set_sample_rate (float sr)
1343 {
1344 if (!_backend) {
1345 return -1;
1346 }
1347
1348 return _backend->set_sample_rate (sr);
1349 }
1350
1351 int
set_buffer_size(uint32_t bufsiz)1352 AudioEngine::set_buffer_size (uint32_t bufsiz)
1353 {
1354 if (!_backend) {
1355 return -1;
1356 }
1357 return _backend->set_buffer_size (bufsiz);
1358 }
1359
1360 int
set_interleaved(bool yn)1361 AudioEngine::set_interleaved (bool yn)
1362 {
1363 if (!_backend) {
1364 return -1;
1365 }
1366 return _backend->set_interleaved (yn);
1367 }
1368
1369 int
set_input_channels(uint32_t ic)1370 AudioEngine::set_input_channels (uint32_t ic)
1371 {
1372 if (!_backend) {
1373 return -1;
1374 }
1375 return _backend->set_input_channels (ic);
1376 }
1377
1378 int
set_output_channels(uint32_t oc)1379 AudioEngine::set_output_channels (uint32_t oc)
1380 {
1381 if (!_backend) {
1382 return -1;
1383 }
1384 return _backend->set_output_channels (oc);
1385 }
1386
1387 int
set_systemic_input_latency(uint32_t il)1388 AudioEngine::set_systemic_input_latency (uint32_t il)
1389 {
1390 if (!_backend) {
1391 return -1;
1392 }
1393 return _backend->set_systemic_input_latency (il);
1394 }
1395
1396 int
set_systemic_output_latency(uint32_t ol)1397 AudioEngine::set_systemic_output_latency (uint32_t ol)
1398 {
1399 if (!_backend) {
1400 return -1;
1401 }
1402 return _backend->set_systemic_output_latency (ol);
1403 }
1404
1405 bool
thread_initialised_for_audio_processing()1406 AudioEngine::thread_initialised_for_audio_processing ()
1407 {
1408 return SessionEvent::has_per_thread_pool () && AsyncMIDIPort::is_process_thread();
1409 }
1410
1411 /* END OF BACKEND PROXY API */
1412
1413 void
thread_init_callback(void * arg)1414 AudioEngine::thread_init_callback (void* arg)
1415 {
1416 /* make sure that anybody who needs to know about this thread
1417 knows about it.
1418 */
1419
1420 pthread_set_name (X_("audioengine"));
1421
1422 const int thread_num = g_atomic_int_add (&audioengine_thread_cnt, 1);
1423 const string thread_name = string_compose (X_("AudioEngine %1"), thread_num);
1424
1425 SessionEvent::create_per_thread_pool (thread_name, 512);
1426 PBD::notify_event_loops_about_thread_creation (pthread_self(), thread_name, 4096);
1427 AsyncMIDIPort::set_process_thread (pthread_self());
1428
1429 if (arg) {
1430 delete AudioEngine::instance()->_main_thread;
1431 /* the special thread created/managed by the backend */
1432 AudioEngine::instance()->_main_thread = new ProcessThread;
1433 }
1434 }
1435
1436 int
sync_callback(TransportState state,samplepos_t position)1437 AudioEngine::sync_callback (TransportState state, samplepos_t position)
1438 {
1439 DEBUG_TRACE (DEBUG::BackendCallbacks, string_compose (X_("sync callback %1, %2\n"), state, position));
1440 if (_session) {
1441 return _session->backend_sync_callback (state, position);
1442 }
1443 return 0;
1444 }
1445
1446 void
freewheel_callback(bool onoff)1447 AudioEngine::freewheel_callback (bool onoff)
1448 {
1449 DEBUG_TRACE (DEBUG::BackendCallbacks, string_compose (X_("freewheel callback onoff %1\n"), onoff));
1450 _freewheeling = onoff;
1451 }
1452
1453 void
latency_callback(bool for_playback)1454 AudioEngine::latency_callback (bool for_playback)
1455 {
1456 DEBUG_TRACE (DEBUG::BackendCallbacks, string_compose (X_("latency callback playback ? %1\n"), for_playback));
1457 if (!_session) {
1458 return;
1459 }
1460
1461 if (in_process_thread ()) {
1462 /* internal backends emit the latency callback in the rt-callback,
1463 * async to connect/disconnect or port creation/deletion.
1464 * All is fine.
1465 */
1466 _session->update_latency (for_playback);
1467 } else {
1468 /* However jack 1/2 emit the callback in sync with creating the port
1469 * (or while handling the connection change).
1470 * e.g. JACK2 jack_port_register() blocks and the jack_latency_callback
1471 * from a different thread: https://pastebin.com/mitGBwpq
1472 * but at this point in time Ardour still holds the process callback
1473 * because JACK2 can process in parallel to latency callbacks.
1474 *
1475 * see also Session::update_latency() and git-ref 1983f56592dfea5f7498
1476 */
1477 queue_latency_update (for_playback);
1478 }
1479 }
1480
1481 void
queue_latency_update(bool for_playback)1482 AudioEngine::queue_latency_update (bool for_playback)
1483 {
1484 if (for_playback) {
1485 g_atomic_int_set (&_pending_playback_latency_callback, 1);
1486 } else {
1487 g_atomic_int_set (&_pending_capture_latency_callback, 1);
1488 }
1489 }
1490
1491 void
update_latencies()1492 AudioEngine::update_latencies ()
1493 {
1494 if (_backend) {
1495 _backend->update_latencies ();
1496 }
1497 }
1498
1499 void
halted_callback(const char * why)1500 AudioEngine::halted_callback (const char* why)
1501 {
1502 DEBUG_TRACE (DEBUG::BackendCallbacks, string_compose (X_("halted callback why: [%1]\n"), why));
1503 if (_in_destructor) {
1504 /* everything is under control */
1505 return;
1506 }
1507
1508 _running = false;
1509
1510 Port::PortDrop (); /* EMIT SIGNAL */
1511
1512 if (!_started_for_latency) {
1513 Halted (why); /* EMIT SIGNAL */
1514 }
1515 }
1516
1517 bool
setup_required() const1518 AudioEngine::setup_required () const
1519 {
1520 if (_backend) {
1521 if (_backend->info().already_configured())
1522 return false;
1523 } else {
1524 if (_backends.size() == 1 && _backends.begin()->second->already_configured()) {
1525 return false;
1526 }
1527 }
1528
1529 return true;
1530 }
1531
1532 int
prepare_for_latency_measurement()1533 AudioEngine::prepare_for_latency_measurement ()
1534 {
1535 if (!_backend) {
1536 return -1;
1537 }
1538
1539 if (running() && _started_for_latency) {
1540 return 0;
1541 }
1542
1543 if (_backend->can_change_systemic_latency_when_running()) {
1544 if (_running) {
1545 _backend->start (true); // zero latency reporting of running backend
1546 } else if (start (true)) {
1547 return -1;
1548 }
1549 _started_for_latency = true;
1550 return 0;
1551 }
1552
1553 if (running()) {
1554 stop (true);
1555 }
1556
1557 if (start (true)) {
1558 return -1;
1559 }
1560 _started_for_latency = true;
1561 return 0;
1562 }
1563
1564 int
start_latency_detection(bool for_midi)1565 AudioEngine::start_latency_detection (bool for_midi)
1566 {
1567 if (prepare_for_latency_measurement ()) {
1568 return -1;
1569 }
1570
1571 PortEngine& pe (port_engine());
1572
1573 delete _mtdm;
1574 _mtdm = 0;
1575
1576 delete _mididm;
1577 _mididm = 0;
1578
1579 /* find the ports we will connect to */
1580
1581 PortEngine::PortHandle out = pe.get_port_by_name (_latency_output_name);
1582 PortEngine::PortHandle in = pe.get_port_by_name (_latency_input_name);
1583
1584 if (!out || !in) {
1585 stop (true);
1586 return -1;
1587 }
1588
1589 /* create the ports we will use to read/write data */
1590 if (for_midi) {
1591 if ((_latency_output_port = pe.register_port ("latency_out", DataType::MIDI, IsOutput)) == 0) {
1592 stop (true);
1593 return -1;
1594 }
1595 if (pe.connect (_latency_output_port, _latency_output_name)) {
1596 pe.unregister_port (_latency_output_port);
1597 stop (true);
1598 return -1;
1599 }
1600
1601 const string portname ("latency_in");
1602 if ((_latency_input_port = pe.register_port (portname, DataType::MIDI, IsInput)) == 0) {
1603 pe.unregister_port (_latency_input_port);
1604 pe.unregister_port (_latency_output_port);
1605 stop (true);
1606 return -1;
1607 }
1608 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1609 pe.unregister_port (_latency_input_port);
1610 pe.unregister_port (_latency_output_port);
1611 stop (true);
1612 return -1;
1613 }
1614
1615 _mididm = new MIDIDM (sample_rate());
1616
1617 } else {
1618
1619 if ((_latency_output_port = pe.register_port ("latency_out", DataType::AUDIO, IsOutput)) == 0) {
1620 stop (true);
1621 return -1;
1622 }
1623 if (pe.connect (_latency_output_port, _latency_output_name)) {
1624 pe.unregister_port (_latency_output_port);
1625 stop (true);
1626 return -1;
1627 }
1628
1629 const string portname ("latency_in");
1630 if ((_latency_input_port = pe.register_port (portname, DataType::AUDIO, IsInput)) == 0) {
1631 pe.unregister_port (_latency_input_port);
1632 pe.unregister_port (_latency_output_port);
1633 stop (true);
1634 return -1;
1635 }
1636 if (pe.connect (_latency_input_name, make_port_name_non_relative (portname))) {
1637 pe.unregister_port (_latency_input_port);
1638 pe.unregister_port (_latency_output_port);
1639 stop (true);
1640 return -1;
1641 }
1642
1643 _mtdm = new MTDM (sample_rate());
1644
1645 }
1646
1647 LatencyRange lr;
1648 _latency_signal_latency = 0;
1649 lr = pe.get_latency_range (in, false);
1650 _latency_signal_latency = lr.max;
1651 lr = pe.get_latency_range (out, true);
1652 _latency_signal_latency += lr.max;
1653
1654 /* all created and connected, lets go */
1655 _latency_flush_samples = samples_per_cycle();
1656 _measuring_latency = for_midi ? MeasureMIDI : MeasureAudio;
1657
1658 return 0;
1659 }
1660
1661 void
stop_latency_detection()1662 AudioEngine::stop_latency_detection ()
1663 {
1664 _measuring_latency = MeasureNone;
1665
1666 if (_latency_output_port) {
1667 port_engine().unregister_port (_latency_output_port);
1668 _latency_output_port.reset();
1669 }
1670 if (_latency_input_port) {
1671 port_engine().unregister_port (_latency_input_port);
1672 _latency_input_port.reset();
1673 }
1674
1675 if (_running && _backend->can_change_systemic_latency_when_running()) {
1676 if (_started_for_latency) {
1677 _running = false; // force reload: reset latencies and emit Running()
1678 start ();
1679 }
1680 }
1681
1682 if (_running && !_started_for_latency) {
1683 assert (!_stopped_for_latency);
1684 return;
1685 }
1686
1687 if (!_backend->can_change_systemic_latency_when_running()) {
1688 stop (true);
1689 }
1690
1691 if (_stopped_for_latency) {
1692 start ();
1693 }
1694
1695 _stopped_for_latency = false;
1696 _started_for_latency = false;
1697 }
1698
1699 void
set_latency_output_port(const string & name)1700 AudioEngine::set_latency_output_port (const string& name)
1701 {
1702 _latency_output_name = name;
1703 }
1704
1705 void
set_latency_input_port(const string & name)1706 AudioEngine::set_latency_input_port (const string& name)
1707 {
1708 _latency_input_name = name;
1709 }
1710
1711 void
add_pending_port_deletion(Port * p)1712 AudioEngine::add_pending_port_deletion (Port* p)
1713 {
1714 if (_session) {
1715 DEBUG_TRACE (DEBUG::Ports, string_compose ("adding %1 to pending port deletion list\n", p->name()));
1716 if (_port_deletions_pending.write (&p, 1) != 1) {
1717 error << string_compose (_("programming error: port %1 could not be placed on the pending deletion queue\n"), p->name()) << endmsg;
1718 }
1719 _session->auto_connect_thread_wakeup ();
1720 } else {
1721 DEBUG_TRACE (DEBUG::Ports, string_compose ("Directly delete port %1\n", p->name()));
1722 delete p;
1723 }
1724 }
1725