1 /*
2 * Copyright (C) 1999-2019 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2006-2007 Jesse Chappell <jesse@essej.net>
4 * Copyright (C) 2006-2014 David Robillard <d@drobilla.net>
5 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
6 * Copyright (C) 2008-2009 Hans Baier <hansfbaier@googlemail.com>
7 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24 #include <cmath>
25 #include <cerrno>
26 #include <algorithm>
27 #include <unistd.h>
28
29 #include <boost/algorithm/string/erase.hpp>
30
31 #include "pbd/i18n.h"
32 #include "pbd/error.h"
33 #include "pbd/enumwriter.h"
34 #include "pbd/pthread_utils.h"
35
36 #include <glibmm/threads.h>
37
38 #include "ardour/audioengine.h"
39 #include "ardour/auditioner.h"
40 #include "ardour/butler.h"
41 #include "ardour/cycle_timer.h"
42 #include "ardour/debug.h"
43 #include "ardour/disk_reader.h"
44 #include "ardour/graph.h"
45 #include "ardour/port.h"
46 #include "ardour/process_thread.h"
47 #include "ardour/scene_changer.h"
48 #include "ardour/session.h"
49 #include "ardour/transport_fsm.h"
50 #include "ardour/transport_master.h"
51 #include "ardour/transport_master_manager.h"
52 #include "ardour/ticker.h"
53 #include "ardour/types.h"
54 #include "ardour/vca.h"
55 #include "ardour/vca_manager.h"
56
57 #include "midi++/mmc.h"
58
59 using namespace ARDOUR;
60 using namespace PBD;
61 using namespace std;
62
63 #define TFSM_EVENT(evtype) { _transport_fsm->enqueue (new TransportFSM::Event (evtype)); }
64 #define TFSM_ROLL() { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::StartTransport)); }
65 #define TFSM_STOP(abort,clear) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::StopTransport,abort,clear)); }
66 #define TFSM_SPEED(speed,as_default) { _transport_fsm->enqueue (new TransportFSM::Event (speed,as_default)); }
67 #define TFSM_LOCATE(target,ltd,loop,force) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::Locate,target,ltd,loop,force)); }
68
69
70 /** Called by the audio engine when there is work to be done with JACK.
71 * @param nframes Number of samples to process.
72 */
73
74 void
process(pframes_t nframes)75 Session::process (pframes_t nframes)
76 {
77 TimerRAII tr (dsp_stats[OverallProcess]);
78
79 samplepos_t transport_at_start = _transport_sample;
80
81 _silent = false;
82
83 if (processing_blocked()) {
84 _silent = true;
85 return;
86 }
87
88 if (non_realtime_work_pending()) {
89 DEBUG_TRACE (DEBUG::Butler, string_compose ("non-realtime work pending: %1 (%2%3%4)\n", enum_2_string (post_transport_work()), std::hex, post_transport_work(), std::dec));
90 if (!_butler->transport_work_requested ()) {
91 DEBUG_TRACE (DEBUG::Butler, string_compose ("done, waiting? %1\n", _transport_fsm->waiting_for_butler()));
92 butler_completed_transport_work ();
93 } else {
94 DEBUG_TRACE (DEBUG::Butler, "doesn't seem to have finished yet (from view of RT thread)\n");
95 }
96 }
97
98 _engine.main_thread()->get_buffers ();
99
100 (this->*process_function) (nframes);
101
102 /* realtime-safe meter-position and processor-order changes
103 *
104 * ideally this would be done in
105 * Route::process_output_buffers() but various functions
106 * callig it hold a _processor_lock reader-lock
107 */
108 bool one_or_more_routes_declicking = false;
109 {
110 ProcessorChangeBlocker pcb (this);
111 boost::shared_ptr<RouteList> r = routes.reader ();
112 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
113 if ((*i)->apply_processor_changes_rt()) {
114 _rt_emit_pending = true;
115 }
116 if ((*i)->declick_in_progress()) {
117 one_or_more_routes_declicking = true;
118 }
119 }
120 }
121
122 if (_rt_emit_pending) {
123 if (!_rt_thread_active) {
124 emit_route_signals ();
125 }
126 if (pthread_mutex_trylock (&_rt_emit_mutex) == 0) {
127 pthread_cond_signal (&_rt_emit_cond);
128 pthread_mutex_unlock (&_rt_emit_mutex);
129 _rt_emit_pending = false;
130 }
131 }
132
133 /* We are checking two things here:
134 *
135 * 1) whether or not all tracks have finished a declick out.
136 * 2) is the transport FSM waiting to be told this
137 */
138
139 if (!one_or_more_routes_declicking && declick_in_progress()) {
140 /* end of the declick has been reached by all routes */
141 TFSM_EVENT (TransportFSM::DeclickDone);
142 }
143
144 _engine.main_thread()->drop_buffers ();
145
146 /* deliver MIDI clock. Note that we need to use the transport sample
147 * position at the start of process(), not the value at the end of
148 * it. We may already have ticked() because of a transport state
149 * change, for example.
150 */
151
152 try {
153 _scene_changer->run (transport_at_start, transport_at_start + nframes);
154 } catch (...) {
155 /* don't bother with a message */
156 }
157
158 SendFeedback (); /* EMIT SIGNAL */
159 }
160
161 int
fail_roll(pframes_t nframes)162 Session::fail_roll (pframes_t nframes)
163 {
164 return no_roll (nframes);
165 }
166
167 int
no_roll(pframes_t nframes)168 Session::no_roll (pframes_t nframes)
169 {
170 PT_TIMING_CHECK (4);
171 TimerRAII tr (dsp_stats[NoRoll]);
172
173 samplepos_t end_sample = _transport_sample + floor (nframes * _transport_fsm->transport_speed());
174 int ret = 0;
175 boost::shared_ptr<RouteList> r = routes.reader ();
176
177 if (_click_io) {
178 _click_io->silence (nframes);
179 }
180
181 VCAList v = _vca_manager->vcas ();
182 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
183 (*i)->automation_run (_transport_sample, nframes);
184 }
185
186 _global_locate_pending = locate_pending ();
187
188 if (_process_graph) {
189 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
190 _process_graph->routes_no_roll( nframes, _transport_sample, end_sample, non_realtime_work_pending());
191 } else {
192 PT_TIMING_CHECK (10);
193 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
194
195 if ((*i)->is_auditioner()) {
196 continue;
197 }
198
199 if ((*i)->no_roll (nframes, _transport_sample, end_sample, non_realtime_work_pending())) {
200 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
201 ret = -1;
202 break;
203 }
204 }
205 PT_TIMING_CHECK (11);
206 }
207
208 PT_TIMING_CHECK (5);
209 return ret;
210 }
211
212 /** @param need_butler to be set to true by this method if it needs the butler,
213 * otherwise it must be left alone.
214 */
215 int
process_routes(pframes_t nframes,bool & need_butler)216 Session::process_routes (pframes_t nframes, bool& need_butler)
217 {
218 TimerRAII tr (dsp_stats[Roll]);
219 boost::shared_ptr<RouteList> r = routes.reader ();
220
221 const samplepos_t start_sample = _transport_sample;
222 const samplepos_t end_sample = _transport_sample + floor (nframes * _transport_fsm->transport_speed());
223
224 if (actively_recording ()) {
225 _capture_duration += nframes;
226 }
227
228 VCAList v = _vca_manager->vcas ();
229 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
230 (*i)->automation_run (start_sample, nframes);
231 }
232
233 _global_locate_pending = locate_pending();
234
235 if (_process_graph) {
236 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
237 if (_process_graph->process_routes (nframes, start_sample, end_sample, need_butler) < 0) {
238 stop_transport ();
239 return -1;
240 }
241 } else {
242
243 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
244
245 int ret;
246
247 if ((*i)->is_auditioner()) {
248 continue;
249 }
250
251 bool b = false;
252
253 if ((ret = (*i)->roll (nframes, start_sample, end_sample, b)) < 0) {
254 TFSM_STOP (false, false);
255 return -1;
256 }
257
258 if (b) {
259 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 rolled and needs butler\n", (*i)->name()));
260 need_butler = true;
261 }
262 }
263 }
264
265 return 0;
266 }
267
268 void
get_track_statistics()269 Session::get_track_statistics ()
270 {
271 float pworst = 1.0f;
272 float cworst = 1.0f;
273
274 boost::shared_ptr<RouteList> rl = routes.reader();
275 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
276
277 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
278
279 if (!tr || tr->is_private_route()) {
280 continue;
281 }
282
283 pworst = min (pworst, tr->playback_buffer_load());
284 cworst = min (cworst, tr->capture_buffer_load());
285 }
286
287 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
288 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
289
290 if (actively_recording()) {
291 set_dirty();
292 }
293 }
294
295 bool
compute_audible_delta(samplepos_t & pos_and_delta) const296 Session::compute_audible_delta (samplepos_t& pos_and_delta) const
297 {
298 if (_transport_fsm->transport_speed() == 0.0 || _count_in_samples > 0 || _remaining_latency_preroll > 0) {
299 /* cannot compute audible delta, because the session is
300 generating silence that does not correspond to the timeline,
301 but is instead filling playback buffers to manage latency
302 alignment.
303 */
304 DEBUG_TRACE (DEBUG::Slave, string_compose ("still adjusting for latency (%1) and/or count-in (%2) or stopped %1\n", _remaining_latency_preroll, _count_in_samples, _transport_fsm->transport_speed()));
305 return false;
306 }
307
308 pos_and_delta -= _transport_sample;
309 return true;
310 }
311
312 samplecnt_t
calc_preroll_subcycle(samplecnt_t ns) const313 Session::calc_preroll_subcycle (samplecnt_t ns) const
314 {
315 boost::shared_ptr<RouteList> r = routes.reader ();
316 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
317 samplecnt_t route_offset = (*i)->playback_latency ();
318 if (_remaining_latency_preroll > route_offset + ns) {
319 /* route will no-roll for complete pre-roll cycle */
320 continue;
321 }
322 if (_remaining_latency_preroll > route_offset) {
323 /* route may need partial no-roll and partial roll from
324 * (_transport_sample - _remaining_latency_preroll) .. +ns.
325 * shorten and split the cycle.
326 */
327 ns = std::min (ns, (_remaining_latency_preroll - route_offset));
328 }
329 }
330 return ns;
331 }
332
333 /** Process callback used when the auditioner is not active */
334 void
process_with_events(pframes_t nframes)335 Session::process_with_events (pframes_t nframes)
336 {
337 PT_TIMING_CHECK (3);
338 TimerRAII tr (dsp_stats[ProcessFunction]);
339
340 SessionEvent* ev;
341 pframes_t this_nframes;
342 samplepos_t end_sample;
343 bool session_needs_butler = false;
344 samplecnt_t samples_moved;
345
346 /* make sure the auditioner is silent */
347
348 if (auditioner) {
349 auditioner->silence (nframes);
350 }
351
352 /* handle any pending events */
353
354 while (pending_events.read (&ev, 1) == 1) {
355 merge_event (ev);
356 }
357
358 /* if we are not in the middle of a state change,
359 and there are immediate events queued up,
360 process them.
361 */
362
363 while (!non_realtime_work_pending() && !immediate_events.empty()) {
364 SessionEvent *ev = immediate_events.front ();
365 immediate_events.pop_front ();
366 process_event (ev);
367 }
368 /* only count-in when going to roll at speed 1.0 */
369 if (_transport_fsm->transport_speed() != 1.0 && _count_in_samples > 0) {
370 _count_in_samples = 0;
371 }
372 if (_transport_fsm->transport_speed() == 0.0) {
373 _remaining_latency_preroll = 0;
374 }
375
376 assert (_count_in_samples == 0 || _remaining_latency_preroll == 0 || _count_in_samples == _remaining_latency_preroll);
377
378 // DEBUG_TRACE (DEBUG::Transport, string_compose ("Running count in/latency preroll of %1 & %2\n", _count_in_samples, _remaining_latency_preroll));
379
380 while (_count_in_samples > 0 || _remaining_latency_preroll > 0) {
381 samplecnt_t ns;
382
383 if (_remaining_latency_preroll > 0) {
384 ns = std::min ((samplecnt_t)nframes, _remaining_latency_preroll);
385 } else {
386 ns = std::min ((samplecnt_t)nframes, _count_in_samples);
387 }
388
389 /* process until next route in-point */
390 ns = calc_preroll_subcycle (ns);
391
392 if (_count_in_samples > 0) {
393 run_click (_transport_sample - _count_in_samples, ns);
394 assert (_count_in_samples >= ns);
395 _count_in_samples -= ns;
396 }
397
398 if (_remaining_latency_preroll > 0) {
399 if (_count_in_samples == 0) {
400 click (_transport_sample - _remaining_latency_preroll, ns);
401 }
402 if (process_routes (ns, session_needs_butler)) {
403 fail_roll (ns);
404 }
405 } else {
406 no_roll (ns);
407 }
408
409 if (_remaining_latency_preroll > 0) {
410 assert (_remaining_latency_preroll >= ns);
411 _remaining_latency_preroll -= ns;
412 }
413
414 nframes -= ns;
415
416 /* process events.. */
417 if (!events.empty() && next_event != events.end()) {
418 SessionEvent* this_event = *next_event;
419 Events::iterator the_next_one = next_event;
420 ++the_next_one;
421
422 while (this_event && this_event->action_sample == _transport_sample) {
423 process_event (this_event);
424 if (the_next_one == events.end()) {
425 this_event = 0;
426 } else {
427 this_event = *the_next_one;
428 ++the_next_one;
429 }
430 }
431 set_next_event ();
432 }
433
434 if (nframes == 0) {
435 return;
436 } else {
437 _engine.split_cycle (ns);
438 }
439 }
440
441 /* Decide on what to do with quarter-frame MTC during this cycle */
442
443 bool const was_sending_qf_mtc = _send_qf_mtc;
444 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
445
446 if (_transport_fsm->transport_speed() != 0) {
447 _send_qf_mtc = (
448 Config->get_send_mtc () &&
449 _transport_fsm->transport_speed() >= (1 - tolerance) &&
450 _transport_fsm->transport_speed() <= (1 + tolerance)
451 );
452
453 if (_send_qf_mtc && !was_sending_qf_mtc) {
454 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
455 _send_timecode_update = true;
456 }
457
458 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (sample_rate () / 4)) {
459 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
460 a quarter of a second since we sent anything at all, so send a full MTC update
461 this cycle.
462 */
463 _send_timecode_update = true;
464 }
465
466 _pframes_since_last_mtc += nframes;
467 }
468
469 /* Events caused a transport change (or we re-started sending
470 * MTC), so send an MTC Full Frame (Timecode) message. This
471 * is sent whether rolling or not, to give slaves an idea of
472 * ardour time on locates (and allow slow slaves to position
473 * and prepare for rolling)
474 */
475 if (_send_timecode_update) {
476 send_full_time_code (_transport_sample, nframes);
477 }
478
479 if (!process_can_proceed()) {
480 _silent = true;
481 return;
482 }
483
484 if (events.empty() || next_event == events.end()) {
485 try_run_lua (nframes); // also during export ?? ->move to process_without_events()
486 /* lua scripts may inject events */
487 while (_n_lua_scripts > 0 && pending_events.read (&ev, 1) == 1) {
488 merge_event (ev);
489 }
490 if (events.empty() || next_event == events.end()) {
491 process_without_events (nframes);
492 return;
493 }
494 }
495
496 assert (_transport_fsm->transport_speed() == 0 || _transport_fsm->transport_speed() == 1.0 || _transport_fsm->transport_speed() == -1.0);
497
498 samples_moved = (samplecnt_t) nframes * _transport_fsm->transport_speed();
499 // DEBUG_TRACE (DEBUG::Transport, string_compose ("plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_fsm->transport_speed()));
500
501 end_sample = _transport_sample + samples_moved;
502
503 {
504 SessionEvent* this_event;
505 Events::iterator the_next_one;
506
507 if (!process_can_proceed()) {
508 _silent = true;
509 return;
510 }
511
512 if (!_exporting && config.get_external_sync()) {
513 if (!implement_master_strategy ()) {
514 no_roll (nframes);
515 return;
516 }
517 }
518
519 if (_transport_fsm->transport_speed() == 0) {
520 no_roll (nframes);
521 return;
522 }
523
524
525 samplepos_t stop_limit = compute_stop_limit ();
526
527 if (maybe_stop (stop_limit)) {
528 if (!_exporting && !timecode_transmission_suspended()) {
529 send_midi_time_code_for_cycle (_transport_sample, end_sample, nframes);
530 }
531
532 no_roll (nframes);
533 return;
534 }
535
536 this_event = *next_event;
537 the_next_one = next_event;
538 ++the_next_one;
539
540 /* yes folks, here it is, the actual loop where we really truly
541 process some audio
542 */
543
544 while (nframes) {
545
546 this_nframes = nframes; /* real (jack) time relative */
547 samples_moved = (samplecnt_t) floor (_transport_fsm->transport_speed() * nframes); /* transport relative */
548 // DEBUG_TRACE (DEBUG::Transport, string_compose ("sub-loop plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_fsm->transport_speed()));
549
550 /* running an event, position transport precisely to its time */
551 if (this_event && this_event->action_sample <= end_sample && this_event->action_sample >= _transport_sample) {
552 /* this isn't quite right for reverse play */
553 samples_moved = (samplecnt_t) (this_event->action_sample - _transport_sample);
554 // DEBUG_TRACE (DEBUG::Transport, string_compose ("sub-loop2 (for %4)plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_fsm->transport_speed(), enum_2_string (this_event->type)));
555 this_nframes = abs (floor(samples_moved / _transport_fsm->transport_speed()));
556 }
557
558 try_run_lua (this_nframes);
559
560 if (this_nframes) {
561
562 if (!_exporting && !timecode_transmission_suspended()) {
563 send_midi_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, this_nframes);
564 }
565
566 click (_transport_sample, this_nframes);
567
568 if (process_routes (this_nframes, session_needs_butler)) {
569 fail_roll (nframes);
570 return;
571 }
572
573 get_track_statistics ();
574
575 nframes -= this_nframes;
576
577 if (samples_moved < 0) {
578 decrement_transport_position (-samples_moved);
579 } else if (samples_moved) {
580 increment_transport_position (samples_moved);
581 } else {
582 DEBUG_TRACE (DEBUG::Transport, "no transport motion\n");
583 }
584
585 maybe_stop (stop_limit);
586 }
587
588 if (nframes > 0) {
589 _engine.split_cycle (this_nframes);
590 }
591
592 /* now handle this event and all others scheduled for the same time */
593
594 while (this_event && this_event->action_sample == _transport_sample) {
595 process_event (this_event);
596
597 if (the_next_one == events.end()) {
598 this_event = 0;
599 } else {
600 this_event = *the_next_one;
601 ++the_next_one;
602 }
603 }
604
605 /* if an event left our state changing, do the right thing */
606
607 if (nframes && non_realtime_work_pending()) {
608 no_roll (nframes);
609 break;
610 }
611
612 /* this is necessary to handle the case of seamless looping */
613 end_sample = _transport_sample + floor (nframes * _transport_fsm->transport_speed());
614 }
615
616 set_next_event ();
617
618 } /* implicit release of route lock */
619
620 if (session_needs_butler) {
621 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
622 _butler->summon ();
623 }
624 }
625
626 bool
transport_locked() const627 Session::transport_locked () const
628 {
629 if (!locate_pending() && (!config.get_external_sync() || (transport_master()->ok() && transport_master()->locked()))) {
630 return true;
631 }
632
633 return false;
634 }
635
636 void
process_without_events(pframes_t nframes)637 Session::process_without_events (pframes_t nframes)
638 {
639 TimerRAII tr (dsp_stats[ProcessFunction]);
640 bool session_needs_butler = false;
641 samplecnt_t samples_moved;
642
643 if (!process_can_proceed()) {
644 _silent = true;
645 return;
646 }
647
648 if (!_exporting && config.get_external_sync()) {
649 if (!implement_master_strategy ()) {
650 no_roll (nframes);
651 return;
652 }
653 }
654
655 assert (_transport_fsm->transport_speed() == 0 || _transport_fsm->transport_speed() == 1.0 || _transport_fsm->transport_speed() == -1.0);
656
657 if (_transport_fsm->transport_speed() == 0) {
658 // DEBUG_TRACE (DEBUG::Transport, string_compose ("transport not moving @ %1\n", _transport_sample));
659 no_roll (nframes);
660 return;
661 } else {
662 samples_moved = (samplecnt_t) nframes * _transport_fsm->transport_speed();
663 // DEBUG_TRACE (DEBUG::Transport, string_compose ("plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_fsm->transport_speed()));
664 }
665
666 if (!_exporting && !timecode_transmission_suspended()) {
667 send_midi_time_code_for_cycle (_transport_sample, _transport_sample + samples_moved, nframes);
668 }
669
670 samplepos_t const stop_limit = compute_stop_limit ();
671
672 if (maybe_stop (stop_limit)) {
673 no_roll (nframes);
674 return;
675 }
676
677 if (maybe_sync_start (nframes)) {
678 return;
679 }
680
681 click (_transport_sample, nframes);
682
683 if (process_routes (nframes, session_needs_butler)) {
684 fail_roll (nframes);
685 return;
686 }
687
688 get_track_statistics ();
689
690 if (samples_moved < 0) {
691 decrement_transport_position (-samples_moved);
692 // DEBUG_TRACE (DEBUG::Transport, string_compose ("DEcrement transport by %1 to %2\n", samples_moved, _transport_sample));
693 } else if (samples_moved) {
694 increment_transport_position (samples_moved);
695 // DEBUG_TRACE (DEBUG::Transport, string_compose ("INcrement transport by %1 to %2\n", samples_moved, _transport_sample));
696 } else {
697 DEBUG_TRACE (DEBUG::Transport, "no transport motion\n");
698 }
699
700 maybe_stop (stop_limit);
701
702 if (session_needs_butler) {
703 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
704 _butler->summon ();
705 }
706 }
707
708 /** Process callback used when the auditioner is active.
709 * @param nframes number of samples to process.
710 */
711 void
process_audition(pframes_t nframes)712 Session::process_audition (pframes_t nframes)
713 {
714 SessionEvent* ev;
715 boost::shared_ptr<RouteList> r = routes.reader ();
716
717 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
718 if (!(*i)->is_auditioner()) {
719 (*i)->silence (nframes);
720 }
721 }
722
723 /* run the auditioner, and if it says we need butler service, ask for it */
724
725 if (auditioner->play_audition (nframes) > 0) {
726 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
727 _butler->summon ();
728 }
729
730 /* if using a monitor section, run it because otherwise we don't hear anything */
731
732 if (_monitor_out && auditioner->needs_monitor()) {
733 _monitor_out->monitor_run (_transport_sample, _transport_sample + nframes, nframes);
734 }
735
736 /* handle pending events */
737
738 while (pending_events.read (&ev, 1) == 1) {
739 merge_event (ev);
740 }
741
742 /* if we are not in the middle of a state change,
743 and there are immediate events queued up,
744 process them.
745 */
746
747 while (!non_realtime_work_pending() && !immediate_events.empty()) {
748 SessionEvent *ev = immediate_events.front ();
749 immediate_events.pop_front ();
750 process_event (ev);
751 }
752
753 if (!auditioner->auditioning()) {
754 /* auditioner no longer active, so go back to the normal process callback */
755 process_function = &Session::process_with_events;
756 }
757 }
758
759 bool
maybe_sync_start(pframes_t & nframes)760 Session::maybe_sync_start (pframes_t & nframes)
761 {
762 pframes_t sync_offset;
763
764 if (!waiting_for_sync_offset) {
765 return false;
766 }
767
768 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
769
770 /* generate silence up to the sync point, then
771 adjust nframes + offset to reflect whatever
772 is left to do.
773 */
774
775 no_roll (sync_offset);
776 nframes -= sync_offset;
777 Port::increment_global_port_buffer_offset (sync_offset);
778 waiting_for_sync_offset = false;
779
780 if (nframes == 0) {
781 return true; // done, nothing left to process
782 }
783
784 } else {
785
786 /* sync offset point is not within this process()
787 cycle, so just generate silence. and don't bother
788 with any fancy stuff here, just the minimal silence.
789 */
790
791 _silent = true;
792
793 if (Config->get_locate_while_waiting_for_sync()) {
794 DEBUG_TRACE (DEBUG::Transport, "micro-locate while waiting for sync\n");
795 if (micro_locate (nframes)) {
796 /* XXX ERROR !!! XXX */
797 }
798 }
799
800 return true; // done, nothing left to process
801 }
802
803 return false;
804 }
805
806 void
queue_event(SessionEvent * ev)807 Session::queue_event (SessionEvent* ev)
808 {
809 if (deletion_in_progress ()) {
810 return;
811 } else if (loading ()) {
812 merge_event (ev);
813 } else {
814 Glib::Threads::Mutex::Lock lm (rb_write_lock);
815 pending_events.write (&ev, 1);
816 }
817 }
818
819 void
set_next_event()820 Session::set_next_event ()
821 {
822 if (events.empty()) {
823 next_event = events.end();
824 return;
825 }
826
827 if (next_event == events.end()) {
828 next_event = events.begin();
829 }
830
831 if ((*next_event)->action_sample > _transport_sample) {
832 next_event = events.begin();
833 }
834
835 for (; next_event != events.end(); ++next_event) {
836 if ((*next_event)->action_sample >= _transport_sample) {
837 break;
838 }
839 }
840 }
841
842 void
process_event(SessionEvent * ev)843 Session::process_event (SessionEvent* ev)
844 {
845 bool remove = true;
846 bool del = true;
847
848 /* if we're in the middle of a state change (i.e. waiting
849 for the butler thread to complete the non-realtime
850 part of the change), we'll just have to queue this
851 event for a time when the change is complete.
852 */
853
854 if (non_realtime_work_pending()) {
855
856 /* except locates, which we have the capability to handle */
857
858 if (ev->type != SessionEvent::Locate) {
859 immediate_events.insert (immediate_events.end(), ev);
860 _remove_event (ev);
861 return;
862 }
863 }
864
865 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_sample));
866
867 switch (ev->type) {
868 case SessionEvent::SetLoop:
869 /* this is the event sent by a UI to define whether or not we
870 use loop range playback or not.
871 */
872 set_play_loop (ev->yes_or_no, true);
873 break;
874
875 case SessionEvent::AutoLoop:
876 /* this is the event created by the Session that marks
877 the end of the loop range and if we're loop playing,
878 triggers a special kind of locate back to the start of the
879 loop range.
880 */
881 if (play_loop) {
882 /* roll after locate, set "for loop end" true
883 */
884 TFSM_LOCATE (ev->target_sample, MustRoll, true, false);
885 }
886 remove = false;
887 del = false;
888 break;
889
890 case SessionEvent::Locate:
891 /* args: do not roll after locate, clear state, not for loop, force */
892 DEBUG_TRACE (DEBUG::Transport, string_compose ("sending locate to %1 to tfsm\n", ev->target_sample));
893 TFSM_LOCATE (ev->target_sample, ev->locate_transport_disposition, false, ev->yes_or_no);
894 _send_timecode_update = true;
895 break;
896
897 case SessionEvent::LocateRoll:
898 /* args: roll after locate, clear state if not looping, not for loop, force */
899 TFSM_LOCATE (ev->target_sample, MustRoll, false, ev->yes_or_no);
900 _send_timecode_update = true;
901 break;
902
903 case SessionEvent::Skip:
904 if (Config->get_skip_playback()) {
905 TFSM_LOCATE (ev->target_sample, MustRoll, false, false);
906 _send_timecode_update = true;
907 }
908 remove = false;
909 del = false;
910 break;
911
912 case SessionEvent::LocateRollLocate:
913 // locate is handled by ::request_roll_at_and_return()
914 _requested_return_sample = ev->target_sample;
915 TFSM_LOCATE (ev->target2_sample, MustRoll, false, false);
916 _send_timecode_update = true;
917 break;
918
919
920 case SessionEvent::SetTransportSpeed:
921 TFSM_SPEED (ev->speed, ev->yes_or_no);
922 break;
923
924 case SessionEvent::StartRoll:
925 TFSM_ROLL ();
926 break;
927
928 case SessionEvent::EndRoll:
929 TFSM_STOP (ev->yes_or_no, ev->second_yes_or_no);
930 break;
931
932 case SessionEvent::SetTransportMaster:
933 /* do not allow changing the transport master if we're already
934 using one.
935 */
936 if (!config.get_external_sync()) {
937 TransportMasterManager::instance().set_current (ev->transport_master);
938 }
939 break;
940
941 case SessionEvent::PunchIn:
942 // cerr << "PunchIN at " << transport_sample() << endl;
943 if (config.get_punch_in() && record_status() == Enabled) {
944 enable_record ();
945 }
946 remove = false;
947 del = false;
948 break;
949
950 case SessionEvent::PunchOut:
951 // cerr << "PunchOUT at " << transport_sample() << endl;
952 if (config.get_punch_out()) {
953 step_back_from_record ();
954 }
955 remove = false;
956 del = false;
957 break;
958
959 case SessionEvent::RangeStop:
960 TFSM_STOP (ev->yes_or_no, false);
961 remove = false;
962 del = false;
963 break;
964
965 case SessionEvent::RangeLocate:
966 /* args: roll after locate, not with loop */
967 TFSM_LOCATE (ev->target_sample, MustRoll, false, false);
968 remove = false;
969 del = false;
970 break;
971
972 case SessionEvent::Overwrite:
973 if (boost::shared_ptr<Track> track = ev->track.lock()) {
974 overwrite_some_buffers (track, ev->overwrite);
975 }
976 break;
977
978 case SessionEvent::OverwriteAll:
979 overwrite_some_buffers (boost::shared_ptr<Track>(), ev->overwrite);
980 break;
981
982 case SessionEvent::Audition:
983 set_audition (ev->region);
984 // drop reference to region
985 ev->region.reset ();
986 break;
987
988 case SessionEvent::SetPlayAudioRange:
989 set_play_range (ev->audio_range, (ev->speed == 1.0f));
990 break;
991
992 case SessionEvent::CancelPlayAudioRange:
993 unset_play_range();
994 break;
995
996 case SessionEvent::RealTimeOperation:
997 process_rtop (ev);
998 del = false; // other side of RT request needs to clean up
999 break;
1000
1001 case SessionEvent::AdjustPlaybackBuffering:
1002 schedule_playback_buffering_adjustment ();
1003 break;
1004
1005 case SessionEvent::AdjustCaptureBuffering:
1006 schedule_capture_buffering_adjustment ();
1007 break;
1008
1009 case SessionEvent::SetTimecodeTransmission:
1010 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1011 break;
1012
1013 default:
1014 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1015 abort(); /*NOTREACHED*/
1016 break;
1017 };
1018
1019 if (remove) {
1020 del = del && !_remove_event (ev);
1021 }
1022
1023 if (del) {
1024 delete ev;
1025 }
1026 }
1027
1028 samplepos_t
compute_stop_limit() const1029 Session::compute_stop_limit () const
1030 {
1031 if (!Config->get_stop_at_session_end ()) {
1032 return max_samplepos;
1033 }
1034
1035 if (config.get_external_sync()) {
1036 return max_samplepos;
1037 }
1038
1039 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1040 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1041
1042 if (actively_recording ()) {
1043 /* permanently recording */
1044 return max_samplepos;
1045 } else if (punching_in && !punching_out) {
1046 /* punching in but never out */
1047 return max_samplepos;
1048 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_sample()) {
1049 /* punching in and punching out after session end */
1050 return max_samplepos;
1051 }
1052
1053 return current_end_sample ();
1054 }
1055
1056
1057
1058 /* dedicated thread for signal emission.
1059 *
1060 * while sending cross-thread signals from the process thread
1061 * is fine in general, PBD::Signal's use of boost::function and
1062 * boost:bind can produce a vast overhead which is not
1063 * acceptable for low latency.
1064 *
1065 * This works around the issue by moving the boost overhead
1066 * out of the RT thread. The overall load is probably higher but
1067 * the realtime thread remains unaffected.
1068 */
1069
1070 void
emit_route_signals()1071 Session::emit_route_signals ()
1072 {
1073 // TODO use RAII to allow using these signals in other places
1074 BatchUpdateStart(); /* EMIT SIGNAL */
1075 ProcessorChangeBlocker pcb (this);
1076 boost::shared_ptr<RouteList> r = routes.reader ();
1077 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1078 (*ci)->emit_pending_signals ();
1079 }
1080 BatchUpdateEnd(); /* EMIT SIGNAL */
1081 }
1082
1083 void
emit_thread_start()1084 Session::emit_thread_start ()
1085 {
1086 if (_rt_thread_active) {
1087 return;
1088 }
1089 _rt_thread_active = true;
1090
1091 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1092 _rt_thread_active = false;
1093 }
1094 }
1095
1096 void
emit_thread_terminate()1097 Session::emit_thread_terminate ()
1098 {
1099 if (!_rt_thread_active) {
1100 return;
1101 }
1102 _rt_thread_active = false;
1103
1104 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1105 pthread_cond_signal (&_rt_emit_cond);
1106 pthread_mutex_unlock (&_rt_emit_mutex);
1107 }
1108
1109 void *status;
1110 pthread_join (_rt_emit_thread, &status);
1111 }
1112
1113 void *
emit_thread(void * arg)1114 Session::emit_thread (void *arg)
1115 {
1116 Session *s = static_cast<Session *>(arg);
1117 pthread_set_name ("SessionSignals");
1118 s->emit_thread_run ();
1119 pthread_exit (0);
1120 return 0;
1121 }
1122
1123 void
emit_thread_run()1124 Session::emit_thread_run ()
1125 {
1126 pthread_mutex_lock (&_rt_emit_mutex);
1127 while (_rt_thread_active) {
1128 emit_route_signals();
1129 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1130 }
1131 pthread_mutex_unlock (&_rt_emit_mutex);
1132 }
1133
1134 double
plan_master_strategy_engine(pframes_t nframes,double master_speed,samplepos_t master_transport_sample,double)1135 Session::plan_master_strategy_engine (pframes_t nframes, double master_speed, samplepos_t master_transport_sample, double /* catch_speed */)
1136 {
1137 /* JACK Transport. */
1138
1139 TransportMasterManager& tmm (TransportMasterManager::instance());
1140 sampleoffset_t delta = _transport_sample - master_transport_sample;
1141 const bool interesting_transport_state_change_underway = (locate_pending() || declick_in_progress());
1142
1143 DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK Transport: delta = %1 transport change underway %2 master speed %3\n", delta, interesting_transport_state_change_underway, master_speed));
1144
1145 if (master_speed == 0) {
1146
1147 DEBUG_TRACE (DEBUG::Slave, "JACK transport: not moving\n");
1148
1149 const samplecnt_t wlp = worst_latency_preroll_buffer_size_ceil ();
1150
1151 if (delta != wlp) {
1152
1153 DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK transport: need to locate to reduce delta %1 vs %2\n", delta, wlp));
1154
1155 /* if we're not aligned with the current JACK * time, then jump to it */
1156
1157 if (!interesting_transport_state_change_underway) {
1158
1159 const samplepos_t locate_target = master_transport_sample + wlp;
1160 DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK transport: jump to master position %1 by locating to %2\n", master_transport_sample, locate_target));
1161 /* for JACK transport always stop after the locate (2nd argument == false) */
1162
1163 transport_master_strategy.action = TransportMasterLocate;
1164 transport_master_strategy.target = locate_target;
1165 transport_master_strategy.roll_disposition = MustStop;
1166
1167 return 1.0;
1168
1169 } else {
1170 DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK Transport: locate already in process, master @ %1, locating %2 declick %3\n",
1171 master_transport_sample, locate_pending(), declick_in_progress()));
1172 transport_master_strategy.action = TransportMasterRelax;
1173 return 1.0;
1174 }
1175 }
1176
1177 } else {
1178
1179 DEBUG_TRACE (DEBUG::Slave, string_compose ("JACK transport: MOVING at %1\n", master_speed));
1180
1181 if (_transport_fsm->rolling()) {
1182 /* master is rolling, and we're rolling ... with JACK we should always be perfectly in sync, so ... WTF? */
1183 if (delta) {
1184 if (remaining_latency_preroll() && worst_latency_preroll()) {
1185 /* our transport position is not moving because we're doing latency alignment. Nothing in particular to do */
1186 DEBUG_TRACE (DEBUG::Slave, "JACK transport: waiting for latency alignment\n");
1187 transport_master_strategy.action = TransportMasterRelax;
1188 return 1.0;
1189 } else {
1190 cerr << "\n\n\n IMPOSSIBLE! OUT OF SYNC (delta = " << delta << ") WITH JACK TRANSPORT (rlp = " << remaining_latency_preroll() << " wlp " << worst_latency_preroll() << ")\n\n\n";
1191 }
1192 }
1193 }
1194 }
1195
1196 if (!interesting_transport_state_change_underway) {
1197
1198 if (master_speed != 0.0) {
1199
1200 /* master rolling, we should be too */
1201
1202 if (_transport_fsm->transport_speed() == 0.0f) {
1203 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave starts transport: %1 sample %2 tf %3\n", master_speed, master_transport_sample, _transport_sample));
1204 transport_master_strategy.action = TransportMasterStart;
1205 return 1.0;
1206 }
1207
1208 } else if (!tmm.current()->starting()) { /* master stopped, not in "starting" state */
1209
1210 if (_transport_fsm->transport_speed() != 0.0f) {
1211 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 sample %2 tf %3\n", master_speed, master_transport_sample, _transport_sample));
1212 transport_master_strategy.action = TransportMasterStop;
1213 return 1.0;
1214 }
1215 }
1216 }
1217
1218 /* No varispeed with JACK */
1219 transport_master_strategy.action = TransportMasterRelax;
1220 return 1.0;
1221 }
1222
1223 double
plan_master_strategy(pframes_t nframes,double master_speed,samplepos_t master_transport_sample,double catch_speed)1224 Session::plan_master_strategy (pframes_t nframes, double master_speed, samplepos_t master_transport_sample, double catch_speed)
1225 {
1226 /* This is called from inside AudioEngine::process_callback(),
1227 * immediately after the TransportMasterManager has run its
1228 * ::pre_process_transport_masters() method to allow all transport
1229 * masters to update their information on the speed and position
1230 * indicated by their data sources.
1231 *
1232 * Our task here is to determine what the Session should do during its
1233 * process() call in order to respond to the transport master (or to
1234 * not respond at all, if we're not using external sync). We want to
1235 * set transport_master_strategy.action, which will be used from within
1236 * the Session process() callback (via ::implement_master_strategy())
1237 * to determine what, if anything to do there.
1238 *
1239 * The return value is the speed (aka "ratio") to be used by the port
1240 * resampler. If we're not chasing the master, the correct answer will
1241 * be 1.0. This can occur in a number of scenarios. If we are synced
1242 * and locked to the master, we want to use the "catch speed" given to
1243 * us as a parameter. This was determined by the
1244 * TransportMasterManager as the correct speed to use in order to
1245 * reduce the delta between the master's position and the session
1246 * transport position.
1247 *
1248 * In situations where we are not synced+locked, either temporarily or
1249 * longer term, we return 1.0, which leads to no resampling, and the
1250 * session will run at normal speed.
1251 */
1252
1253 if (!config.get_external_sync()) {
1254 return actual_speed ();
1255 }
1256
1257 /* When calling TransportMasterStart, sould aim for
1258 * delta >= _remaining_latency_preroll
1259 * This way there can be silent pre-roll of exactly the delta time.
1260 *
1261 * In order to meet this condition, TransportMasterStart needs be set
1262 * if the *end* of the current cycle can reach _remaining_latency_preroll.
1263 * So current_block_size needs to be added here.
1264 */
1265 const samplecnt_t wlp = worst_latency_preroll_buffer_size_ceil () + current_block_size;
1266
1267 TransportMasterManager& tmm (TransportMasterManager::instance());
1268 const samplecnt_t locate_threshold = 5 * current_block_size;
1269
1270 if (tmm.master_invalid_this_cycle()) {
1271 DEBUG_TRACE (DEBUG::Slave, "session told not to use the transport master this cycle\n");
1272 if (_transport_fsm->rolling() && Config->get_transport_masters_just_roll_when_sync_lost()) {
1273 transport_master_strategy.action = TransportMasterRelax;
1274 } else {
1275 transport_master_strategy.action = TransportMasterNoRoll;
1276 }
1277 return 1.0;
1278 }
1279
1280 if (tmm.current()->type() == Engine) {
1281 /* JACK is fundamentally different */
1282 return plan_master_strategy_engine (nframes, master_speed, master_transport_sample, catch_speed);
1283 }
1284
1285 const sampleoffset_t delta = _transport_sample - master_transport_sample;
1286
1287 DEBUG_TRACE (DEBUG::Slave, string_compose ("\n\n\n\nsession at %1, master at %2, delta: %3 res: %4 TFSM state %5 action %6\n", _transport_sample, master_transport_sample, delta, tmm.current()->resolution(), _transport_fsm->current_state(), transport_master_strategy.action));
1288
1289 const bool interesting_transport_state_change_underway = (locate_pending() || declick_in_progress());
1290
1291 if ((transport_master_strategy.action == TransportMasterWait) || (transport_master_strategy.action == TransportMasterNoRoll)) {
1292
1293 /* We've either been:
1294 *
1295 * 1) waiting for the master to catch up with a position that
1296 * we located to (Wait)
1297 * 2) waiting to be able to use the master's speed & position
1298 *
1299 * The two cases are very similar, but differ in the conditions
1300 * under which we need to initiate a (possibly successive)
1301 * locate in response to the master's position
1302 *
1303 * This code is very similar to the non-wait case (the "else"
1304 * that ends this scope). The big difference is that here we
1305 * know that we've just finished a locate specifically in order
1306 * to catch the master. This changes the logic a little bit.
1307 */
1308
1309 DEBUG_TRACE (DEBUG::Slave, "had been waiting for locate-to-catch-master to finish\n");
1310
1311 if (interesting_transport_state_change_underway) {
1312 /* still waiting for the declick and/or locate to
1313 finish ... nothing to do for now.
1314 */
1315 DEBUG_TRACE (DEBUG::Slave, "still waiting for the locate to finish\n");
1316 return 1.0;
1317 }
1318
1319 bool should_locate;
1320
1321 if (transport_master_strategy.action == TransportMasterNoRoll) {
1322
1323 /* We've been waiting to be able to use the master's
1324 * position (i.e to get a lock on the incoming data
1325 * stream). We need to locate if we're either ahead or
1326 * behind the master by <threshold>.
1327 */
1328
1329 should_locate = abs (delta) > locate_threshold;
1330 } else {
1331
1332 /* we located to be ahead of the master's position (see
1333 * the locate call in the next "else" scope where we
1334 * jump ahead by a significant distance).
1335 *
1336 * So, we should be ahead (or behind) the master's
1337 * position, and waiting for it to get close to us.
1338 *
1339 * We only need to locate again if we are actually
1340 * behind (or ahead, for reverse motion) of the master
1341 * by more than <threshold>.
1342 */
1343
1344 should_locate = delta < 0 && (abs (delta) > locate_threshold);
1345 }
1346
1347 if (should_locate) {
1348
1349 /* we're too far from the master to catch it via
1350 * varispeed ... need to locate ahead of it, wait for
1351 * it to get cose to us, then varispeed to sync.
1352 *
1353 * We assume that the transport state after the locate
1354 * is always Stopped - we don't restart the transport
1355 * until the master catches us, or at least gets close
1356 * to our new position.
1357 *
1358 * Any time we locate, we need to reset the DLL used by
1359 * the TransportMasterManager. Do that here, since the
1360 * TMM will not need that again until after we start
1361 * the locate (and hence the apparent transport
1362 * position of the Session will reflect the target we
1363 * set here). That is because the locate will be
1364 * initiated in the Session::process() callback that is
1365 * about to happen right after we return.
1366 */
1367
1368 tmm.reinit (master_speed, master_transport_sample);
1369
1370 samplepos_t locate_target = master_transport_sample;
1371
1372 /* locate to a position "worst_latency_preroll" head of
1373 * the master, but also add in a generous estimate to
1374 * cover the time it will take to locate to that
1375 * position, based on our worst-case estimate for this
1376 * session (so far).
1377 */
1378
1379 locate_target += wlp + lrintf (ntracks() * sample_rate() * (1.5 * (g_atomic_int_get (&_current_usecs_per_track) / 1000000.0)));
1380
1381 DEBUG_TRACE (DEBUG::Slave, string_compose ("After locate-to-catch-master, still too far off (%1). Locate again to %2\n", delta, locate_target));
1382
1383 transport_master_strategy.action = TransportMasterLocate;
1384 transport_master_strategy.target = locate_target;
1385 transport_master_strategy.roll_disposition = MustStop;
1386 transport_master_strategy.catch_speed = catch_speed;
1387
1388 return 1.0;
1389 }
1390
1391 if (delta > wlp) {
1392
1393 /* We're close, but haven't reached the point where we
1394 * need to start rolling for preroll latency yet.
1395 */
1396
1397 DEBUG_TRACE (DEBUG::Slave, string_compose ("master @ %1 is not yet within %2 of our position %3 (delta is %4)\n", master_transport_sample, wlp, _transport_sample, delta));
1398 return 1.0;
1399 }
1400
1401 /* case #3: we should start rolling */
1402
1403 DEBUG_TRACE (DEBUG::Slave, string_compose ("master @ %1 is WITHIN %2 of our position %3 (delta is %4), so start\n", master_transport_sample, wlp, _transport_sample, delta));
1404
1405 if (delta > _remaining_latency_preroll) {
1406 /* increase pre-roll to match delta. this allows
1407 * to directly catch the transport w/o vari-speed */
1408 _remaining_latency_preroll = delta;
1409 }
1410
1411 transport_master_strategy.action = TransportMasterStart;
1412 transport_master_strategy.catch_speed = catch_speed;
1413 return catch_speed;
1414
1415 }
1416
1417 /* currently we're not waiting to sync with the master. So
1418 * check if we're way out of alignment (case #1) or just a bit
1419 * out of alignment (case #2)
1420 */
1421
1422 if (abs (delta) > locate_threshold) {
1423
1424 /* CASE ONE
1425 *
1426 * This is a heuristic rather than a strictly provable rule. The idea
1427 * is that if we're "far away" from the master, we should locate to its
1428 * current position, and then varispeed to sync with it.
1429 *
1430 * On the other hand, if we're close to it, just varispeed.
1431 */
1432
1433 tmm.reinit (master_speed, master_transport_sample);
1434
1435 samplepos_t locate_target = master_transport_sample;
1436
1437 locate_target += wlp + lrintf (ntracks() * sample_rate() * (1.5 * (g_atomic_int_get (&_current_usecs_per_track) / 1000000.0)));
1438
1439 DEBUG_TRACE (DEBUG::Slave, string_compose ("request locate to master position %1\n", locate_target));
1440
1441 transport_master_strategy.action = TransportMasterLocate;
1442 transport_master_strategy.target = locate_target;
1443 transport_master_strategy.roll_disposition = (master_speed != 0) ? MustRoll : MustStop;
1444 transport_master_strategy.catch_speed = catch_speed;
1445
1446 /* Session::process_with(out)_events() will take this
1447 * up when called.
1448 */
1449
1450 return 1.0;
1451
1452 } else if (abs (delta) > tmm.current()->resolution()) {
1453
1454 /* CASE TWO
1455 *
1456 * If we're close, but not within the resolution of the
1457 * master, just varispeed to chase the master, and be
1458 * silent till we're synced
1459 */
1460
1461 tmm.block_disk_output ();
1462
1463 } else {
1464
1465 /* speed is set, we're locked and synced and good to go */
1466
1467 if (!locate_pending() && !declick_in_progress()) {
1468 DEBUG_TRACE (DEBUG::Slave, "master/slave synced & locked\n");
1469 tmm.unblock_disk_output ();
1470 }
1471 }
1472
1473 if (master_speed != 0.0) {
1474
1475 /* master rolling, we should be too */
1476
1477 if (_transport_fsm->transport_speed() == 0.0f) {
1478 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave starts transport: %1 sample %2 tf %3\n", master_speed, master_transport_sample, _transport_sample));
1479 transport_master_strategy.action = TransportMasterStart;
1480 transport_master_strategy.catch_speed = catch_speed;
1481 return catch_speed;
1482 }
1483
1484 } else if (!tmm.current()->starting()) { /* master stopped, not in "starting" state */
1485
1486 if (_transport_fsm->transport_speed() != 0.0f) {
1487 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 sample %2 tf %3\n", master_speed, master_transport_sample, _transport_sample));
1488 transport_master_strategy.action = TransportMasterStop;
1489 return catch_speed;
1490 }
1491 }
1492
1493 /* we were not waiting for the master, we're close enough to
1494 * it, and our transport state already matched the master
1495 * (stopped or rolling). We should just continue
1496 * resampling/varispeeding at "catch_speed" in order to remain
1497 * synced with the master.
1498 */
1499
1500 transport_master_strategy.action = TransportMasterRelax;
1501 return catch_speed;
1502 }
1503
1504 bool
implement_master_strategy()1505 Session::implement_master_strategy ()
1506 {
1507 /* This is called from within Session::process(), only if we are using
1508 * external sync. The task here is simply to implement whatever actions
1509 * where decided by ::plan_master_strategy (), from within the
1510 * ::process() callback (the planning step is executed before
1511 * Session::process() begins.
1512 */
1513
1514 DEBUG_TRACE (DEBUG::Slave, string_compose ("Implementing master strategy: %1\n", transport_master_strategy.action));
1515
1516 switch (transport_master_strategy.action) {
1517 case TransportMasterNoRoll:
1518 /* This is the one case where we do not want the session to
1519 call ::roll() under any circumstances. Returning false here
1520 will do that.
1521 */
1522 return false;
1523 case TransportMasterRelax:
1524 break;
1525 case TransportMasterWait:
1526 break;
1527 case TransportMasterLocate:
1528 transport_master_strategy.action = TransportMasterWait;
1529 TFSM_LOCATE(transport_master_strategy.target, transport_master_strategy.roll_disposition, false, false);
1530 break;
1531 case TransportMasterStart:
1532 TFSM_EVENT (TransportFSM::StartTransport);
1533 break;
1534 case TransportMasterStop:
1535 TFSM_STOP (false, false);
1536 break;
1537 }
1538
1539 return true;
1540 }
1541