2c93e10d47ae676238a480b0d5776981e3bc756f
[ardour.git] / libs / ardour / session_transport.cc
1 /*
2  * Copyright (C) 1999-2019 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2005-2009 Taybin Rutkin <taybin@taybin.com>
4  * Copyright (C) 2006-2007 Jesse Chappell <jesse@essej.net>
5  * Copyright (C) 2006-2012 David Robillard <d@drobilla.net>
6  * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
7  * Copyright (C) 2008-2009 Hans Baier <hansfbaier@googlemail.com>
8  * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
9  * Copyright (C) 2014-2018 Ben Loftis <ben@harrisonconsoles.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 #ifdef WAF_BUILD
28 #include "libardour-config.h"
29 #endif
30
31 #include <cmath>
32 #include <cerrno>
33 #include <unistd.h>
34
35 #include <boost/algorithm/string/erase.hpp>
36
37 #include "pbd/error.h"
38 #include "pbd/enumwriter.h"
39 #include "pbd/i18n.h"
40 #include "pbd/memento_command.h"
41 #include "pbd/pthread_utils.h"
42 #include "pbd/stacktrace.h"
43 #include "pbd/undo.h"
44
45 #include "midi++/mmc.h"
46 #include "midi++/port.h"
47
48 #include "ardour/audio_backend.h"
49 #include "ardour/audioengine.h"
50 #include "ardour/auditioner.h"
51 #include "ardour/automation_watch.h"
52 #include "ardour/butler.h"
53 #include "ardour/click.h"
54 #include "ardour/debug.h"
55 #include "ardour/disk_reader.h"
56 #include "ardour/location.h"
57 #include "ardour/playlist.h"
58 #include "ardour/profile.h"
59 #include "ardour/scene_changer.h"
60 #include "ardour/session.h"
61 #include "ardour/transport_fsm.h"
62 #include "ardour/transport_master.h"
63 #include "ardour/transport_master_manager.h"
64 #include "ardour/tempo.h"
65 #include "ardour/operations.h"
66 #include "ardour/vca.h"
67 #include "ardour/vca_manager.h"
68
69 using namespace std;
70 using namespace ARDOUR;
71 using namespace PBD;
72
73
74 #ifdef NDEBUG
75 # define ENSURE_PROCESS_THREAD do {} while (0)
76 #else
77 # define ENSURE_PROCESS_THREAD                           \
78   do {                                                   \
79     if (!AudioEngine::instance()->in_process_thread()) { \
80       PBD::stacktrace (std::cerr, 30);                   \
81     }                                                    \
82   } while (0)
83 #endif
84
85
86 #define TFSM_EVENT(evtype) { _transport_fsm->enqueue (new TransportFSM::Event (evtype)); }
87 #define TFSM_STOP(abort,clear) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::StopTransport,abort,clear)); }
88 #define TFSM_LOCATE(target,roll,flush,loop,force) { _transport_fsm->enqueue (new TransportFSM::Event (TransportFSM::Locate,target,roll,flush,loop,force)); }
89
90 /* *****************************************************************************
91  * REALTIME ACTIONS (to be called on state transitions)
92  * ****************************************************************************/
93
94 void
95 Session::realtime_stop (bool abort, bool clear_state)
96 {
97         ENSURE_PROCESS_THREAD;
98
99         DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1 speed = %2\n", _transport_sample, _transport_speed));
100         PostTransportWork todo = PostTransportWork (0);
101
102         if (_last_transport_speed < 0.0f) {
103                 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
104                 _default_transport_speed = 1.0;
105                 DiskReader::inc_no_disk_output (); // for the buffer reversal
106         } else {
107                 todo = PostTransportWork (todo | PostTransportStop);
108         }
109
110         /* call routes */
111
112         boost::shared_ptr<RouteList> r = routes.reader ();
113
114         for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
115                 (*i)->realtime_handle_transport_stopped ();
116         }
117
118         DEBUG_TRACE (DEBUG::Transport, string_compose ("stop complete, auto-return scheduled for return to %1\n", _requested_return_sample));
119
120         if (abort) {
121                 todo = PostTransportWork (todo | PostTransportAbort);
122         }
123
124         if (clear_state) {
125                 todo = PostTransportWork (todo | PostTransportClearSubstate);
126         }
127
128         if (todo) {
129                 add_post_transport_work (todo);
130         }
131
132         _clear_event_type (SessionEvent::RangeStop);
133         _clear_event_type (SessionEvent::RangeLocate);
134
135         //clear our solo-selection, if there is one
136         if ( solo_selection_active() ) {
137                 solo_selection ( _soloSelection, false );
138         }
139
140         /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
141         disable_record (true, (!Config->get_latched_record_enable() && clear_state));
142
143         if (clear_state && !Config->get_loop_is_mode()) {
144                 unset_play_loop ();
145         }
146
147         reset_slave_state ();
148
149         _transport_speed = 0;
150         _target_transport_speed = 0;
151         _engine_speed = 1.0;
152
153         g_atomic_int_set (&_playback_load, 100);
154         g_atomic_int_set (&_capture_load, 100);
155
156         if (config.get_use_video_sync()) {
157                 waiting_for_sync_offset = true;
158         }
159
160         if (todo) {
161                 TFSM_EVENT (TransportFSM::ButlerRequired);
162         }
163 }
164
165 /** @param with_mmc true to send a MMC locate command when the locate is done */
166 void
167 Session::locate (samplepos_t target_sample, bool with_roll, bool with_flush, bool for_loop_end, bool force, bool with_mmc)
168 {
169         ENSURE_PROCESS_THREAD;
170
171         if (target_sample < 0) {
172                 error << _("Locate called for negative sample position - ignored") << endmsg;
173                 return;
174         }
175
176         bool need_butler = false;
177
178         /* Locates for seamless looping are fairly different from other
179          * locates. They assume that the diskstream buffers for each track
180          * already have the correct data in them, and thus there is no need to
181          * actually tell the tracks to locate. What does need to be done,
182          * though, is all the housekeeping that is associated with non-linear
183          * changes in the value of _transport_sample.
184          */
185
186         DEBUG_TRACE (DEBUG::Transport, string_compose ("rt-locate to %1, roll %2 flush %3 for loop end %4 force %5 mmc %6\n",
187                                                        target_sample, with_roll, with_flush, for_loop_end, force, with_mmc));
188
189         if (!force && _transport_sample == target_sample && !loop_changing && !for_loop_end) {
190
191                 /* already at the desired position. Not forced to locate,
192                    the loop isn't changing, so unless we're told to
193                    start rolling also, there's nothing to do but
194                    tell the world where we are (again).
195                 */
196
197                 if (with_roll) {
198                         set_transport_speed (1.0, 0, false);
199                 }
200                 loop_changing = false;
201                 TFSM_EVENT (TransportFSM::LocateDone);
202                 Located (); /* EMIT SIGNAL */
203                 return;
204         }
205
206         // Update Timecode time
207         _transport_sample = target_sample;
208         _nominal_jack_transport_sample = boost::none;
209         // Bump seek counter so that any in-process locate in the butler
210         // thread(s?) can restart.
211         g_atomic_int_inc (&_seek_counter);
212         _last_roll_or_reversal_location = target_sample;
213         if (!for_loop_end) {
214                 _remaining_latency_preroll = worst_latency_preroll ();
215         }
216         timecode_time(_transport_sample, transmitting_timecode_time); // XXX here?
217
218         /* do "stopped" stuff if:
219          *
220          * we are rolling AND
221          * no autoplay in effect AND
222          * we're not going to keep rolling after the locate AND
223          * !(playing a loop with JACK sync) AND
224          * we're not synced to an external transport master
225          *
226          */
227
228
229         /* it is important here that we use the internal state of the transport
230            FSM, not the public facing result of ::transport_rolling()
231         */
232         bool transport_was_stopped = _transport_fsm->stopped();
233
234         if (!transport_was_stopped &&
235             (!auto_play_legal || !config.get_auto_play()) &&
236             !with_roll &&
237             !(synced_to_engine() && play_loop) &&
238             !(config.get_external_sync() && !synced_to_engine())) {
239
240                 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
241                 transport_was_stopped = true;
242
243         } else {
244
245                 /* Tell all routes to do the RT part of locate */
246
247                 boost::shared_ptr<RouteList> r = routes.reader ();
248                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
249                         (*i)->realtime_locate (for_loop_end);
250                 }
251         }
252
253         if (force || !for_loop_end || loop_changing) {
254
255                 PostTransportWork todo = PostTransportLocate;
256
257                 if (with_roll && transport_was_stopped) {
258                         todo = PostTransportWork (todo | PostTransportRoll);
259                 }
260
261                 add_post_transport_work (todo);
262                 need_butler = true;
263
264         } else {
265
266                 /* this is functionally what clear_clicks() does but with a tentative lock */
267
268                 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
269
270                 if (clickm.locked()) {
271
272                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
273                                 delete *i;
274                         }
275
276                         clicks.clear ();
277                 }
278         }
279
280         if (with_roll) {
281                 /* switch from input if we're going to roll */
282                 if (Config->get_monitoring_model() == HardwareMonitoring) {
283                         set_track_monitor_input_status (!config.get_auto_input());
284                 }
285         } else {
286                 /* otherwise we're going to stop, so do the opposite */
287                 if (Config->get_monitoring_model() == HardwareMonitoring) {
288                         set_track_monitor_input_status (true);
289                 }
290         }
291
292         /* cancel looped playback if transport pos outside of loop range */
293         if (play_loop) {
294
295                 Location* al = _locations->auto_loop_location();
296
297                 if (al) {
298                         if (_transport_sample < al->start() || _transport_sample >= al->end()) {
299
300                                 // located outside the loop: cancel looping directly, this is called from event handling context
301
302                                 have_looped = false;
303
304                                 if (!Config->get_loop_is_mode()) {
305                                         set_play_loop (false, false);
306                                 } else {
307                                         /* this will make the non_realtime_locate() in the butler
308                                            which then causes seek() in tracks actually do the right
309                                            thing.
310                                         */
311                                         set_track_loop (false);
312                                 }
313
314                         } else if (_transport_sample == al->start()) {
315
316                                 // located to start of loop - this is looping, basically
317
318                                 if (!have_looped) {
319                                         /* first time */
320                                         if (_last_roll_location != al->start()) {
321                                                 /* didn't start at loop start - playback must have
322                                                  * started before loop since we've now hit the loop
323                                                  * end.
324                                                  */
325                                                 add_post_transport_work (PostTransportLocate);
326                                                 need_butler = true;
327                                         }
328
329                                 }
330
331                                 boost::shared_ptr<RouteList> rl = routes.reader();
332
333                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
334                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
335
336                                         if (tr && tr->rec_enable_control()->get_value()) {
337                                                 // tell it we've looped, so it can deal with the record state
338                                                 tr->transport_looped (_transport_sample);
339                                         }
340                                 }
341
342                                 have_looped = true;
343                                 TransportLooped(); // EMIT SIGNAL
344                         }
345                 }
346         }
347
348         if (need_butler) {
349                 TFSM_EVENT (TransportFSM::ButlerRequired);
350         } else {
351                 TFSM_EVENT (TransportFSM::LocateDone);
352                 loop_changing = false;
353         }
354
355         _send_timecode_update = true;
356
357         if (with_mmc) {
358                 send_mmc_locate (_transport_sample);
359         }
360
361         _last_roll_location = _last_roll_or_reversal_location =  _transport_sample;
362         if (!synced_to_engine () || _transport_sample == _engine.transport_sample ()) {
363                 Located (); /* EMIT SIGNAL */
364         }
365 }
366
367 void
368 Session::post_locate ()
369 {
370         if (transport_master_is_external() && !synced_to_engine()) {
371                 const samplepos_t current_master_position = TransportMasterManager::instance().get_current_position_in_process_context();
372                 if (abs (current_master_position - _transport_sample) > TransportMasterManager::instance().current()->resolution()) {
373                         _last_roll_location = _last_roll_or_reversal_location =  _transport_sample;
374                 }
375         }
376 }
377
378 /** Set the transport speed.
379  *  Called from the process thread.
380  *  @param speed New speed
381  */
382 void
383 Session::set_transport_speed (double speed, samplepos_t destination_sample, bool abort, bool clear_state, bool as_default)
384 {
385         ENSURE_PROCESS_THREAD;
386         DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n",
387                                                        speed, abort, clear_state, _transport_speed, _transport_sample, as_default));
388
389         /* max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
390            and user needs. We really need CD-style "skip" playback for ffwd and rewind.
391         */
392
393         if (speed > 0) {
394                 speed = min ((double) Config->get_max_transport_speed(), speed);
395         } else if (speed < 0) {
396                 speed = max ((double) -Config->get_max_transport_speed(), speed);
397         }
398
399         double new_engine_speed = 1.0;
400         if (speed != 0) {
401                 new_engine_speed = fabs (speed);
402                 if (speed < 0) speed = -1;
403                 if (speed > 0) speed = 1;
404         }
405
406         if (_transport_speed == speed && new_engine_speed == _engine_speed) {
407                 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
408                         _default_transport_speed = 1.0;
409                 }
410                 return;
411         }
412
413 #if 0 // TODO pref: allow vari-speed recording
414         if (actively_recording() && speed != 1.0 && speed != 0.0) {
415                 /* no varispeed during recording */
416                 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, sample %2\n",
417                                                        _transport_speed, _transport_sample));
418                 return;
419         }
420 #endif
421
422         _target_transport_speed = fabs(speed);
423         _engine_speed = new_engine_speed;
424
425         if (transport_rolling() && speed == 0.0) {
426
427                 /* we are rolling and we want to stop */
428
429                 if (Config->get_monitoring_model() == HardwareMonitoring) {
430                         set_track_monitor_input_status (true);
431                 }
432
433                 if (synced_to_engine ()) {
434                         if (clear_state) {
435                                 /* do this here because our response to the slave won't
436                                    take care of it.
437                                 */
438                                 _play_range = false;
439                                 _count_in_once = false;
440                                 unset_play_loop ();
441                         }
442                 } else {
443                         bool const auto_return_enabled = (!config.get_external_sync() && (Config->get_auto_return_target_list() || abort));
444
445                         if (!auto_return_enabled) {
446                                 _requested_return_sample = destination_sample;
447                         }
448
449                 }
450
451                 TFSM_STOP (abort, false);
452
453         } else if (transport_stopped() && speed == 1.0) {
454
455                 if (as_default) {
456                         _default_transport_speed = speed;
457                 }
458
459                 /* we are stopped and we want to start rolling at speed 1 */
460
461                 if (Config->get_loop_is_mode() && play_loop) {
462
463                         Location *location = _locations->auto_loop_location();
464
465                         if (location != 0) {
466                                 if (_transport_sample != location->start()) {
467
468                                         /* force tracks to do their thing */
469                                         set_track_loop (true);
470
471                                         /* jump to start and then roll from there */
472
473                                         request_locate (location->start(), true);
474                                         return;
475                                 }
476                         }
477                 }
478
479                 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
480                         set_track_monitor_input_status (false);
481                 }
482
483                 TFSM_EVENT (TransportFSM::StartTransport);
484
485         } else {
486
487                 /* not zero, not 1.0 ... varispeed */
488
489                 // TODO handled transport start..  _remaining_latency_preroll
490                 // and reversal of playback direction.
491
492                 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
493                         warning << string_compose (
494                                 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
495                                 PROGRAM_NAME)
496                                 << endmsg;
497                         return;
498                 }
499
500 #if 0
501                 if (actively_recording()) {
502                         return;
503                 }
504 #endif
505
506                 if (speed > 0.0 && _transport_sample == current_end_sample()) {
507                         return;
508                 }
509
510                 if (speed < 0.0 && _transport_sample == 0) {
511                         return;
512                 }
513
514                 clear_clicks ();
515
516                 /* if we are reversing relative to the current speed, or relative to the speed
517                    before the last stop, then we have to do extra work.
518                 */
519
520                 PostTransportWork todo = PostTransportWork (0);
521
522                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0 && speed < 0.0)) {
523                         todo = PostTransportWork (todo | PostTransportReverse);
524                         DiskReader::inc_no_disk_output (); // for the buffer reversal
525                         _last_roll_or_reversal_location = _transport_sample;
526                 }
527
528                 _last_transport_speed = _transport_speed;
529                 _transport_speed = speed;
530
531                 if (as_default) {
532                         _default_transport_speed = speed;
533                 }
534
535                 if (todo) {
536                         add_post_transport_work (todo);
537                         TFSM_EVENT (TransportFSM::ButlerRequired);
538                 }
539
540                 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
541
542                 /* throttle signal emissions.
543                  * when slaved [_last]_transport_speed
544                  * usually changes every cycle (tiny amounts due to DLL).
545                  * Emitting a signal every cycle is overkill and unwarranted.
546                  *
547                  * Using _last_transport_speed is not acceptable,
548                  * since it allows for large changes over a long period
549                  * of time. Hence we introduce a dedicated variable to keep track
550                  *
551                  * The 0.2% dead-zone is somewhat arbitrary. Main use-case
552                  * for TransportStateChange() here is the ShuttleControl display.
553                  */
554                 if (fabs (_signalled_varispeed - actual_speed ()) > .002
555                     // still, signal hard changes to 1.0 and 0.0:
556                     || (actual_speed () == 1.0 && _signalled_varispeed != 1.0)
557                     || (actual_speed () == 0.0 && _signalled_varispeed != 0.0)
558                    )
559                 {
560                         TransportStateChange (); /* EMIT SIGNAL */
561                         _signalled_varispeed = actual_speed ();
562                 }
563         }
564 }
565
566 /** Stop the transport.  */
567 void
568 Session::stop_transport (bool abort, bool clear_state)
569 {
570         ENSURE_PROCESS_THREAD;
571
572         _count_in_once = false;
573
574         DEBUG_TRACE (DEBUG::Transport, string_compose ("time to actually stop with TS @ %1\n", _transport_sample));
575
576         realtime_stop (abort, clear_state);
577 }
578
579 /** Called from the process thread */
580 void
581 Session::start_transport ()
582 {
583         ENSURE_PROCESS_THREAD;
584         DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
585
586         _last_roll_location = _transport_sample;
587         _last_roll_or_reversal_location = _transport_sample;
588         _remaining_latency_preroll = worst_latency_preroll ();
589
590         have_looped = false;
591
592         /* if record status is Enabled, move it to Recording. if its
593            already Recording, move it to Disabled.
594         */
595
596         switch (record_status()) {
597         case Enabled:
598                 if (!config.get_punch_in()) {
599                         /* This is only for UIs (keep blinking rec-en before
600                          * punch-in, don't show rec-region etc). The UI still
601                          * depends on SessionEvent::PunchIn and ensuing signals.
602                          *
603                          * The disk-writers handle punch in/out internally
604                          * in their local delay-compensated timeframe.
605                          */
606                         enable_record ();
607                 }
608                 break;
609
610         case Recording:
611                 if (!play_loop) {
612                         disable_record (false);
613                 }
614                 break;
615
616         default:
617                 break;
618         }
619
620         _transport_speed = _default_transport_speed;
621         _target_transport_speed = _transport_speed;
622
623         if (!_engine.freewheeling()) {
624                 Timecode::Time time;
625                 timecode_time_subframes (_transport_sample, time);
626                 if (transport_master()->type() == MTC) {
627                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
628                 }
629
630                 if ((actively_recording () || (config.get_punch_in () && get_record_enabled ()))
631                     && click_data && (config.get_count_in () || _count_in_once)) {
632                         _count_in_once = false;
633                         /* calculate count-in duration (in audio samples)
634                          * - use [fixed] tempo/meter at _transport_sample
635                          * - calc duration of 1 bar + time-to-beat before or at transport_sample
636                          */
637                         const Tempo& tempo = _tempo_map->tempo_at_sample (_transport_sample);
638                         const Meter& meter = _tempo_map->meter_at_sample (_transport_sample);
639
640                         const double num = meter.divisions_per_bar ();
641                         const double den = meter.note_divisor ();
642                         const double barbeat = _tempo_map->exact_qn_at_sample (_transport_sample, 0) * den / (4. * num);
643                         const double bar_fract = fmod (barbeat, 1.0); // fraction of bar elapsed.
644
645                         _count_in_samples = meter.samples_per_bar (tempo, _current_sample_rate);
646
647                         double dt = _count_in_samples / num;
648                         if (bar_fract == 0) {
649                                 /* at bar boundary, count-in 2 bars before start. */
650                                 _count_in_samples *= 2;
651                         } else {
652                                 /* beats left after full bar until roll position */
653                                 _count_in_samples *= 1. + bar_fract;
654                         }
655
656                         if (_count_in_samples > _remaining_latency_preroll) {
657                                 _remaining_latency_preroll = _count_in_samples;
658                         }
659
660                         int clickbeat = 0;
661                         samplepos_t cf = _transport_sample - _count_in_samples;
662                         samplecnt_t offset = _click_io->connected_latency (true);
663                         while (cf < _transport_sample + offset) {
664                                 add_click (cf, clickbeat == 0);
665                                 cf += dt;
666                                 clickbeat = fmod (clickbeat + 1, num);
667                         }
668
669                         if (_count_in_samples < _remaining_latency_preroll) {
670                                 _count_in_samples = _remaining_latency_preroll;
671                         }
672                 }
673         }
674
675         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
676         TransportStateChange (); /* EMIT SIGNAL */
677 }
678
679 bool
680 Session::should_roll_after_locate () const
681 {
682         /* a locate must previously have been requested and completed before
683          * this answer can be considered correct
684          */
685
686         return ((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (post_transport_work() & PostTransportRoll);
687
688 }
689
690 /** Do any transport work in the audio thread that needs to be done after the
691  * butler thread is finished.  Audio thread, realtime safe.
692  */
693 void
694 Session::butler_completed_transport_work ()
695 {
696         ENSURE_PROCESS_THREAD;
697         PostTransportWork ptw = post_transport_work ();
698
699         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler done, RT cleanup for %1\n", enum_2_string (ptw)));
700
701         if (ptw & PostTransportAudition) {
702                 if (auditioner && auditioner->auditioning()) {
703                         process_function = &Session::process_audition;
704                 } else {
705                         process_function = &Session::process_with_events;
706                 }
707                 ptw = PostTransportWork (ptw & ~PostTransportAudition);
708                 set_post_transport_work (ptw);
709         }
710
711         if (ptw & PostTransportLocate) {
712                 post_locate ();
713                 ptw = PostTransportWork (ptw & ~PostTransportLocate);
714                 set_post_transport_work (ptw);
715                 loop_changing = false;
716                 TFSM_EVENT (TransportFSM::LocateDone);
717         }
718
719         if (ptw & PostTransportAdjustPlaybackBuffering) {
720                 /* we blocked output while this happened */
721                 DiskReader::dec_no_disk_output ();
722                 ptw = PostTransportWork (ptw & ~PostTransportAdjustPlaybackBuffering);
723                 set_post_transport_work (ptw);
724         }
725
726         bool start_after_butler_done_msg = false;
727
728         if ((ptw & (PostTransportReverse|PostTransportRoll))) {
729                 start_after_butler_done_msg = true;
730         }
731
732         ptw = PostTransportWork (ptw & ~(PostTransportAdjustCaptureBuffering|PostTransportOverWrite|PostTransportReverse|PostTransportRoll));
733         set_post_transport_work (ptw);
734
735         set_next_event ();
736
737         if (_transport_fsm->waiting_for_butler()) {
738                 TFSM_EVENT (TransportFSM::ButlerDone);
739         }
740
741         DiskReader::dec_no_disk_output ();
742
743         if (start_after_butler_done_msg) {
744                 if (_transport_speed) {
745                         /* reversal is done ... tell TFSM that it is time to start*/
746                         TFSM_EVENT (TransportFSM::StartTransport);
747                 }
748         }
749 }
750
751 void
752 Session::schedule_butler_for_transport_work ()
753 {
754         assert (_transport_fsm->waiting_for_butler ());
755         DEBUG_TRACE (DEBUG::Butler, "summon butler for transport work\n");
756         _butler->schedule_transport_work ();
757 }
758
759 bool
760 Session::maybe_stop (samplepos_t limit)
761 {
762         ENSURE_PROCESS_THREAD;
763         if ((_transport_speed > 0.0f && _transport_sample >= limit) || (_transport_speed < 0.0f && _transport_sample == 0)) {
764                 if (synced_to_engine ()) {
765                         _engine.transport_stop ();
766                 } else {
767                         TFSM_EVENT (TransportFSM::StopTransport);
768                 }
769                 return true;
770         }
771         return false;
772 }
773
774 int
775 Session::micro_locate (samplecnt_t distance)
776 {
777         ENSURE_PROCESS_THREAD;
778
779         boost::shared_ptr<RouteList> rl = routes.reader();
780         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
781                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
782                 if (tr && !tr->can_internal_playback_seek (distance)) {
783                         return -1;
784                 }
785         }
786
787         DEBUG_TRACE (DEBUG::Transport, string_compose ("micro-locate by %1\n", distance));
788
789         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
790                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
791                 if (tr) {
792                         tr->internal_playback_seek (distance);
793                 }
794         }
795
796         _transport_sample += distance;
797         return 0;
798 }
799
800 void
801 Session::flush_all_inserts ()
802 {
803         ENSURE_PROCESS_THREAD;
804         boost::shared_ptr<RouteList> r = routes.reader ();
805
806         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
807                 (*i)->flush_processors ();
808         }
809 }
810
811 /* *****************************************************************************
812  * END REALTIME ACTIONS
813  * ****************************************************************************/
814
815 void
816 Session::add_post_transport_work (PostTransportWork ptw)
817 {
818         PostTransportWork oldval;
819         PostTransportWork newval;
820         int tries = 0;
821
822         while (tries < 8) {
823                 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
824                 newval = PostTransportWork (oldval | ptw);
825                 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
826                         /* success */
827                         return;
828                 }
829         }
830
831         error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
832 }
833
834 bool
835 Session::should_ignore_transport_request (TransportRequestSource src, TransportRequestType type) const
836 {
837         if (config.get_external_sync()) {
838                 if (TransportMasterManager::instance().current()->allow_request (src, type)) {
839                         return false;
840                 } else {
841                         return true;
842                 }
843         }
844         return false;
845 }
846
847 bool
848 Session::synced_to_engine() const
849 {
850         return config.get_external_sync() && TransportMasterManager::instance().current()->type() == Engine;
851 }
852
853 void
854 Session::request_sync_source (boost::shared_ptr<TransportMaster> tm)
855 {
856         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportMaster, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
857         ev->transport_master = tm;
858         DEBUG_TRACE (DEBUG::Slave, "sent request for new transport master\n");
859         queue_event (ev);
860 }
861
862 void
863 Session::request_transport_speed (double speed, bool as_default, TransportRequestSource origin)
864 {
865         if (synced_to_engine()) {
866                 if (speed != 0) {
867                         _engine.transport_start ();
868                 } else {
869                         _engine.transport_stop ();
870                 }
871                 return;
872         }
873
874         if (should_ignore_transport_request (origin, TR_Speed)) {
875                 return;
876         }
877
878         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
879         ev->third_yes_or_no = as_default; // as_default
880         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
881         queue_event (ev);
882 }
883
884 /** Request a new transport speed, but if the speed parameter is exactly zero then use
885  *  a very small +ve value to prevent the transport actually stopping.  This method should
886  *  be used by callers who are varying transport speed but don't ever want to stop it.
887  */
888 void
889 Session::request_transport_speed_nonzero (double speed, bool as_default, TransportRequestSource origin)
890 {
891         if (should_ignore_transport_request (origin, TransportRequestType (TR_Speed|TR_Start))) {
892                 return;
893         }
894
895         if (speed == 0) {
896                 speed = DBL_EPSILON;
897         }
898
899         request_transport_speed (speed, as_default);
900 }
901
902 void
903 Session::request_stop (bool abort, bool clear_state, TransportRequestSource origin)
904 {
905         if (synced_to_engine()) {
906                 _engine.transport_stop ();
907                 return;
908         }
909
910         if (should_ignore_transport_request (origin, TR_Stop)) {
911                 return;
912         }
913
914         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, audible_sample(), 0.0, abort, clear_state);
915         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, audible %3 transport %4 abort = %1, clear state = %2\n", abort, clear_state, audible_sample(), _transport_sample));
916         queue_event (ev);
917 }
918
919 void
920 Session::request_locate (samplepos_t target_sample, bool with_roll, TransportRequestSource origin)
921 {
922         if (synced_to_engine()) {
923                 _engine.transport_locate (target_sample);
924                 return;
925         }
926
927         if (should_ignore_transport_request (origin, TR_Locate)) {
928                 return;
929         }
930
931         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, false);
932         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_sample));
933         queue_event (ev);
934 }
935
936 void
937 Session::force_locate (samplepos_t target_sample, bool with_roll)
938 {
939         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, true);
940         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_sample));
941         queue_event (ev);
942 }
943
944 void
945 Session::unset_preroll_record_trim ()
946 {
947         _preroll_record_trim_len = 0;
948 }
949
950 void
951 Session::request_preroll_record_trim (samplepos_t rec_in, samplecnt_t preroll)
952 {
953         if (actively_recording ()) {
954                 return;
955         }
956         unset_preroll_record_trim ();
957
958         config.set_punch_in (false);
959         config.set_punch_out (false);
960
961         samplepos_t pos = std::max ((samplepos_t)0, rec_in - preroll);
962         _preroll_record_trim_len = preroll;
963         maybe_enable_record ();
964         request_locate (pos, true);
965         set_requested_return_sample (rec_in);
966 }
967
968 void
969 Session::request_count_in_record ()
970 {
971         if (actively_recording ()) {
972                 return;
973         }
974         if (transport_rolling()) {
975                 return;
976         }
977         maybe_enable_record ();
978         _count_in_once = true;
979         request_transport_speed (1.0, true);
980 }
981
982 void
983 Session::request_play_loop (bool yn, bool change_transport_roll)
984 {
985         if (transport_master_is_external() && yn) {
986                 // don't attempt to loop when not using Internal Transport
987                 // see also gtk2_ardour/ardour_ui_options.cc parameter_changed()
988                 return;
989         }
990
991         SessionEvent* ev;
992         Location *location = _locations->auto_loop_location();
993         double target_speed;
994
995         if (location == 0 && yn) {
996                 error << _("Cannot loop - no loop range defined")
997                       << endmsg;
998                 return;
999         }
1000
1001         if (change_transport_roll) {
1002                 if (transport_rolling()) {
1003                         /* start looping at current speed */
1004                         target_speed = transport_speed ();
1005                 } else {
1006                         /* currently stopped */
1007                         if (yn) {
1008                                 /* start looping at normal speed */
1009                                 target_speed = 1.0;
1010                         } else {
1011                                 target_speed = 0.0;
1012                         }
1013                 }
1014         } else {
1015                 /* leave the speed alone */
1016                 target_speed = transport_speed ();
1017         }
1018
1019         ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn, change_transport_roll);
1020         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
1021         queue_event (ev);
1022 }
1023
1024 void
1025 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
1026 {
1027         SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
1028         if (range) {
1029                 ev->audio_range = *range;
1030         } else {
1031                 ev->audio_range.clear ();
1032         }
1033         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
1034         queue_event (ev);
1035 }
1036
1037 void
1038 Session::request_cancel_play_range ()
1039 {
1040         SessionEvent* ev = new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
1041         queue_event (ev);
1042 }
1043
1044
1045 bool
1046 Session::solo_selection_active ()
1047 {
1048         if (_soloSelection.empty()) {
1049                 return false;
1050         }
1051         return true;
1052 }
1053
1054 void
1055 Session::solo_selection (StripableList &list, bool new_state)
1056 {
1057         boost::shared_ptr<ControlList> solo_list (new ControlList);
1058         boost::shared_ptr<ControlList> unsolo_list (new ControlList);
1059
1060         if (new_state)
1061                 _soloSelection = list;
1062         else
1063                 _soloSelection.clear();
1064
1065         boost::shared_ptr<RouteList> rl = get_routes();
1066
1067         for (ARDOUR::RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1068
1069                 if ( !(*i)->is_track() ) {
1070                         continue;
1071                 }
1072
1073                 boost::shared_ptr<Stripable> s (*i);
1074
1075                 bool found = (std::find(list.begin(), list.end(), s) != list.end());
1076                 if ( new_state && found ) {
1077
1078                         solo_list->push_back (s->solo_control());
1079
1080                         //must invalidate playlists on selected tracks, so only selected regions get heard
1081                         boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (*i);
1082                         if (track) {
1083                                 boost::shared_ptr<Playlist> playlist = track->playlist();
1084                                 if (playlist) {
1085                                         playlist->ContentsChanged();
1086                                 }
1087                         }
1088                 } else {
1089                         unsolo_list->push_back (s->solo_control());
1090                 }
1091         }
1092
1093         set_controls (solo_list, 1.0, Controllable::NoGroup);
1094         set_controls (unsolo_list, 0.0, Controllable::NoGroup);
1095 }
1096
1097
1098 void
1099 Session::butler_transport_work ()
1100 {
1101         /* Note: this function executes in the butler thread context */
1102
1103   restart:
1104         boost::shared_ptr<RouteList> r = routes.reader ();
1105         int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
1106         bool finished = true;
1107         PostTransportWork ptw = post_transport_work();
1108         uint64_t before;
1109
1110         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = [%1] (0x%3%4%5) at %2\n", enum_2_string (ptw), (before = g_get_monotonic_time()), std::hex, ptw, std::dec));
1111
1112         if (ptw & PostTransportLocate) {
1113
1114                 if (get_play_loop()) {
1115
1116                         DEBUG_TRACE (DEBUG::Butler, "flush loop recording fragment to disk\n");
1117
1118                         /* this locate might be happening while we are
1119                          * loop recording.
1120                          *
1121                          * Non-seamless looping will require a locate (below) that
1122                          * will reset capture buffers and throw away data.
1123                          *
1124                          * Rather than first find all tracks and see if they
1125                          * have outstanding data, just do a flush anyway. It
1126                          * may be cheaper this way anyway, and is certainly
1127                          * more accurate.
1128                          */
1129
1130                         bool more_disk_io_to_do = false;
1131                         uint32_t errors = 0;
1132
1133                         do {
1134                                 more_disk_io_to_do = _butler->flush_tracks_to_disk_after_locate (r, errors);
1135
1136                                 if (errors) {
1137                                         break;
1138                                 }
1139
1140                                 if (more_disk_io_to_do) {
1141                                         continue;
1142                                 }
1143
1144                         } while (false);
1145
1146                 }
1147         }
1148
1149         if (ptw & PostTransportAdjustPlaybackBuffering) {
1150                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1151                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1152                         if (tr) {
1153                                 tr->adjust_playback_buffering ();
1154                                 /* and refill those buffers ... */
1155                         }
1156                         (*i)->non_realtime_locate (_transport_sample);
1157                 }
1158                 VCAList v = _vca_manager->vcas ();
1159                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1160                         (*i)->non_realtime_locate (_transport_sample);
1161                 }
1162         }
1163
1164         if (ptw & PostTransportAdjustCaptureBuffering) {
1165                 /* need to prevent concurrency with ARDOUR::DiskWriter::run(),
1166                  * DiskWriter::adjust_buffering() re-allocates the ringbuffer */
1167                 Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
1168                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1169                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1170                         if (tr) {
1171                                 tr->adjust_capture_buffering ();
1172                         }
1173                 }
1174         }
1175
1176         if (ptw & PostTransportReverse) {
1177
1178                 clear_clicks();
1179
1180                 /* don't seek if locate will take care of that in non_realtime_stop() */
1181
1182                 if (!(ptw & PostTransportLocate)) {
1183                         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1184                                 (*i)->non_realtime_locate (_transport_sample);
1185
1186                                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
1187                                         /* new request, stop seeking, and start again */
1188                                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
1189                                         goto restart;
1190                                 }
1191                         }
1192                         VCAList v = _vca_manager->vcas ();
1193                         for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1194                                 (*i)->non_realtime_locate (_transport_sample);
1195                         }
1196                 }
1197         }
1198
1199         if (ptw & PostTransportLocate) {
1200                 DEBUG_TRACE (DEBUG::Transport, "nonrealtime locate invoked from BTW\n");
1201                 non_realtime_locate ();
1202         }
1203
1204         if (ptw & PostTransportStop) {
1205                 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
1206                 if (!finished) {
1207                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
1208                         goto restart;
1209                 }
1210         }
1211
1212         if (ptw & PostTransportOverWrite) {
1213                 non_realtime_overwrite (on_entry, finished);
1214                 if (!finished) {
1215                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
1216                         goto restart;
1217                 }
1218         }
1219
1220         if (ptw & PostTransportAudition) {
1221                 non_realtime_set_audition ();
1222         }
1223
1224         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
1225
1226         DEBUG_TRACE (DEBUG::Transport, string_compose (X_("Butler transport work all done after %1 usecs @ %2 trw = %3\n"), g_get_monotonic_time() - before, _transport_sample, _butler->transport_work_requested()));
1227 }
1228
1229 void
1230 Session::non_realtime_overwrite (int on_entry, bool& finished)
1231 {
1232         boost::shared_ptr<RouteList> rl = routes.reader();
1233         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1234                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1235                 if (tr && tr->pending_overwrite ()) {
1236                         tr->overwrite_existing_buffers ();
1237                 }
1238                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
1239                         finished = false;
1240                         return;
1241                 }
1242         }
1243 }
1244
1245 void
1246 Session::non_realtime_locate ()
1247 {
1248         DEBUG_TRACE (DEBUG::Transport, string_compose ("locate tracks to %1\n", _transport_sample));
1249
1250         if (Config->get_loop_is_mode() && get_play_loop()) {
1251
1252                 Location *loc  = _locations->auto_loop_location();
1253
1254                 if (!loc || (_transport_sample < loc->start() || _transport_sample >= loc->end())) {
1255                         /* jumped out of loop range: stop tracks from looping,
1256                            but leave loop (mode) enabled.
1257                          */
1258                         set_track_loop (false);
1259
1260                 } else if (loc && ((loc->start() <= _transport_sample) || (loc->end() > _transport_sample))) {
1261
1262                         /* jumping to start of loop. This  might have been done before but it is
1263                          * idempotent and cheap. Doing it here ensures that when we start playback
1264                          * outside the loop we still flip tracks into the magic seamless mode
1265                          * when needed.
1266                          */
1267                         set_track_loop (true);
1268
1269                 } else if (loc) {
1270                         set_track_loop (false);
1271                 }
1272
1273         } else {
1274
1275                 /* no more looping .. should have been noticed elsewhere */
1276         }
1277
1278
1279         samplepos_t tf;
1280
1281         {
1282                 boost::shared_ptr<RouteList> rl = routes.reader();
1283
1284           restart:
1285                 gint sc = g_atomic_int_get (&_seek_counter);
1286                 tf = _transport_sample;
1287
1288                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1289                         (*i)->non_realtime_locate (tf);
1290                         if (sc != g_atomic_int_get (&_seek_counter)) {
1291                                 std::cerr << "\n\nLOCATE INTERRUPTED BY LOCATE!!!\n\n";
1292                                 goto restart;
1293                         }
1294                 }
1295         }
1296
1297         {
1298                 /* VCAs are quick to locate because they have no data (except
1299                    automation) associated with them. Don't bother with a
1300                    restart mechanism here, but do use the same transport sample
1301                    that the Routes used.
1302                 */
1303                 VCAList v = _vca_manager->vcas ();
1304                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1305                         (*i)->non_realtime_locate (tf);
1306                 }
1307         }
1308
1309         _scene_changer->locate (_transport_sample);
1310
1311         /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
1312            rather than clearing them so that the RT thread has to spend time constructing
1313            them (in Session::click).
1314          */
1315         clear_clicks ();
1316 }
1317
1318 bool
1319 Session::select_playhead_priority_target (samplepos_t& jump_to)
1320 {
1321         if (!transport_master_no_external_or_using_engine() || !config.get_auto_return()) {
1322                 return false;
1323         }
1324
1325         jump_to = _last_roll_location;
1326         return jump_to >= 0;
1327 }
1328
1329 void
1330 Session::follow_playhead_priority ()
1331 {
1332         samplepos_t target;
1333
1334         if (select_playhead_priority_target (target)) {
1335                 request_locate (target);
1336         }
1337 }
1338
1339 void
1340 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
1341 {
1342         struct tm* now;
1343         time_t     xnow;
1344         bool       did_record;
1345         bool       saved;
1346         PostTransportWork ptw = post_transport_work();
1347
1348         did_record = false;
1349         saved = false;
1350
1351         boost::shared_ptr<RouteList> rl = routes.reader();
1352         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1353                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1354                 if (tr && tr->get_captured_samples () != 0) {
1355                         did_record = true;
1356                         break;
1357                 }
1358         }
1359
1360         /* stop and locate are merged here because they share a lot of common stuff */
1361
1362         time (&xnow);
1363         now = localtime (&xnow);
1364
1365         if (auditioner) {
1366                 auditioner->cancel_audition ();
1367         }
1368
1369         if (did_record) {
1370                 begin_reversible_command (Operations::capture);
1371                 _have_captured = true;
1372         }
1373
1374         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
1375
1376         if (abort && did_record) {
1377                 /* no reason to save the session file when we remove sources
1378                  */
1379                 _state_of_the_state = StateOfTheState (_state_of_the_state | InCleanup);
1380         }
1381
1382         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1383                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1384                 if (tr) {
1385                         tr->transport_stopped_wallclock (*now, xnow, abort);
1386                 }
1387         }
1388
1389         if (abort && did_record) {
1390                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
1391         }
1392
1393         boost::shared_ptr<RouteList> r = routes.reader ();
1394
1395         if (did_record) {
1396                 commit_reversible_command ();
1397                 /* increase take name */
1398                 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
1399                         string newname = config.get_take_name();
1400                         config.set_take_name(bump_name_number (newname));
1401                 }
1402         }
1403
1404         if (_engine.running()) {
1405                 PostTransportWork ptw = post_transport_work ();
1406
1407                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1408                         (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate));
1409                 }
1410                 VCAList v = _vca_manager->vcas ();
1411                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1412                         (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate));
1413                 }
1414         }
1415
1416         /* If we are not synced to a "true" external master, and we're not
1417          * handling an explicit locate, we should consider whether or not to
1418          * "auto-return". This could mean going to a specifically requested
1419          * location, or just back to the start of the last roll.
1420          */
1421
1422         if (transport_master_no_external_or_using_engine() && !(ptw & PostTransportLocate)) {
1423
1424                 bool do_locate = false;
1425
1426                 if (_requested_return_sample >= 0) {
1427
1428                         /* explicit return request pre-queued in event list. overrides everything else */
1429
1430                         _transport_sample = _requested_return_sample;
1431
1432                         /* cancel this request */
1433                         _requested_return_sample = -1;
1434                         do_locate = true;
1435
1436                 } else if (Config->get_auto_return_target_list()) {
1437
1438                         samplepos_t jump_to;
1439
1440                         if (select_playhead_priority_target (jump_to)) {
1441
1442                                 /* there's a valid target (we don't care how it
1443                                  * was derived here)
1444                                  */
1445
1446                                 _transport_sample = jump_to;
1447                                 do_locate = true;
1448
1449                         } else if (abort) {
1450
1451                                 /* roll aborted (typically capture) with
1452                                  * auto-return enabled
1453                                  */
1454
1455                                 _transport_sample = _last_roll_location;
1456                                 do_locate = true;
1457
1458                         }
1459                 }
1460
1461
1462                 if (do_locate && synced_to_engine()) {
1463
1464                         /* We will unconditionally locate to _transport_sample
1465                          * below, which will refill playback buffers based on
1466                          * _transport_sample, and maximises the buffering they
1467                          * represent.
1468                          *
1469                          * But if we are synced to engine (JACK), we should
1470                          * locate the engine (JACK) as well. We would follow
1471                          * the engine (JACK) on the next process cycle, but
1472                          * since we're going to do a locate below anyway,
1473                          * it seems pointless to not use just do it ourselves
1474                          * right now, rather than wait for the engine (JACK) to
1475                          * provide the new position on the next cycle.
1476                          *
1477                          * Despite the generic name of the called method
1478                          * (::transport_locate()) this method only does
1479                          * anything if the audio/MIDI backend is JACK.
1480                          */
1481
1482                         _engine.transport_locate (_transport_sample);
1483
1484                 }
1485         }
1486
1487         clear_clicks();
1488         unset_preroll_record_trim ();
1489
1490         /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
1491         */
1492
1493         if (ptw & (PostTransportClearSubstate|PostTransportStop)) {
1494                 unset_play_range ();
1495                 if (!loop_changing && !Config->get_loop_is_mode()) {
1496                         unset_play_loop ();
1497                 }
1498         }
1499
1500         /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
1501
1502         {
1503                 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
1504                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1505                         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
1506                         (*i)->non_realtime_locate (_transport_sample);
1507
1508                         if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
1509                                 finished = false;
1510                                 /* we will be back */
1511                                 return;
1512                         }
1513                 }
1514         }
1515
1516         {
1517                 VCAList v = _vca_manager->vcas ();
1518                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1519                         (*i)->non_realtime_locate (_transport_sample);
1520                 }
1521         }
1522
1523         have_looped = false;
1524
1525         /* don't bother with this stuff if we're disconnected from the engine,
1526            because there will be no process callbacks to deliver stuff from
1527         */
1528
1529         if (_engine.running() && !_engine.freewheeling()) {
1530                 // need to queue this in the next RT cycle
1531                 _send_timecode_update = true;
1532
1533                 if (transport_master()->type() == MTC) {
1534                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
1535
1536                         /* This (::non_realtime_stop()) gets called by main
1537                            process thread, which will lead to confusion
1538                            when calling AsyncMIDIPort::write().
1539
1540                            Something must be done. XXX
1541                         */
1542                         send_mmc_locate (_transport_sample);
1543                 }
1544         }
1545
1546         if ((ptw & PostTransportLocate) && get_record_enabled()) {
1547                 /* This is scheduled by realtime_stop(), which is also done
1548                  * when a slave requests /locate/ for an initial sync.
1549                  * We can't hold up the slave for long with a save() here,
1550                  * without breaking its initial sync cycle.
1551                  *
1552                  * save state only if there's no slave or if it's not yet locked.
1553                  */
1554                 if (!transport_master_is_external() || !transport_master()->locked()) {
1555                         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: requests save\n"));
1556                         SaveSessionRequested (_current_snapshot_name);
1557                         saved = true;
1558                 }
1559         }
1560
1561         /* save the current state of things if appropriate */
1562
1563         if (did_record && !saved) {
1564                 SaveSessionRequested (_current_snapshot_name);
1565         }
1566
1567         PositionChanged (_transport_sample); /* EMIT SIGNAL */
1568         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
1569         TransportStateChange (); /* EMIT SIGNAL */
1570         AutomationWatch::instance().transport_stop_automation_watches (_transport_sample);
1571
1572         ptw = PostTransportWork (ptw & ~(PostTransportAbort|PostTransportStop|PostTransportClearSubstate));
1573         set_post_transport_work (ptw);
1574 }
1575
1576 void
1577 Session::set_play_loop (bool yn, bool change_transport_state)
1578 {
1579         ENSURE_PROCESS_THREAD;
1580         /* Called from event-handling context */
1581
1582         DEBUG_TRACE (DEBUG::Transport, string_compose ("set_play_loop (%1)\n", yn));
1583
1584         Location *loc;
1585
1586         if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
1587                 /* nothing to do, or can't change loop status while recording */
1588                 return;
1589         }
1590
1591         if (yn && synced_to_engine()) {
1592                 warning << string_compose (
1593                         _("Looping cannot be supported while %1 is using JACK transport.\n"
1594                           "Recommend changing the configured options"), PROGRAM_NAME)
1595                         << endmsg;
1596                 return;
1597         }
1598
1599         if (yn) {
1600
1601                 play_loop = true;
1602                 have_looped = false;
1603
1604                 if (loc) {
1605
1606                         unset_play_range ();
1607                         /* set all tracks to use internal looping */
1608                         set_track_loop (true);
1609
1610                         merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
1611
1612                         if (!Config->get_loop_is_mode()) {
1613                                 /* args: positition, roll=true, flush=true, for_loop_end=false, force buffer, refill  looping */
1614                                 /* set this so that when/if we stop for locate,
1615                                    we do not call unset_play_loop(). This is a
1616                                    crude mechanism. Got a better idea?
1617                                 */
1618                                 loop_changing = true;
1619                                 TFSM_LOCATE (loc->start(), true, true, false, true);
1620                         } else if (!transport_rolling()) {
1621                                 /* loop-is-mode: not rolling, just locate to loop start */
1622                                 TFSM_LOCATE (loc->start(), false, true, false, true);
1623                         }
1624                 }
1625
1626         } else {
1627
1628                 unset_play_loop ();
1629         }
1630
1631         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
1632         TransportStateChange ();
1633 }
1634
1635 void
1636 Session::unset_play_loop (bool change_transport_state)
1637 {
1638         if (play_loop) {
1639
1640                 play_loop = false;
1641                 clear_events (SessionEvent::AutoLoop);
1642                 set_track_loop (false);
1643
1644                 /* likely need to flush track buffers: this will locate us to wherever we are */
1645
1646                 if (change_transport_state && transport_rolling ()) {
1647                         TFSM_EVENT (TransportFSM::StopTransport);
1648                 }
1649
1650                 overwrite_some_buffers (boost::shared_ptr<Route>(), LoopDisabled);
1651
1652                 TransportStateChange (); /* EMIT SIGNAL */
1653         }
1654 }
1655
1656 void
1657 Session::set_track_loop (bool yn)
1658 {
1659         Location* loc = _locations->auto_loop_location ();
1660
1661         if (!loc) {
1662                 yn = false;
1663         }
1664
1665         boost::shared_ptr<RouteList> rl = routes.reader ();
1666
1667         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1668                 if (*i && !(*i)->is_private_route()) {
1669                         (*i)->set_loop (yn ? loc : 0);
1670                 }
1671         }
1672
1673         DiskReader::reset_loop_declick (loc, nominal_sample_rate());
1674 }
1675
1676 samplecnt_t
1677 Session::worst_latency_preroll () const
1678 {
1679         return _worst_output_latency + _worst_input_latency;
1680 }
1681
1682 void
1683 Session::unset_play_range ()
1684 {
1685         _play_range = false;
1686         _clear_event_type (SessionEvent::RangeStop);
1687         _clear_event_type (SessionEvent::RangeLocate);
1688 }
1689
1690 void
1691 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1692 {
1693         SessionEvent* ev;
1694
1695         /* Called from event-processing context */
1696
1697         unset_play_range ();
1698
1699         if (range.empty()) {
1700                 /* _play_range set to false in unset_play_range()
1701                  */
1702                 if (!leave_rolling) {
1703                         /* stop transport */
1704                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1705                         merge_event (ev);
1706                 }
1707                 return;
1708         }
1709
1710         _play_range = true;
1711
1712         /* cancel loop play */
1713         unset_play_loop ();
1714
1715         list<AudioRange>::size_type sz = range.size();
1716
1717         if (sz > 1) {
1718
1719                 list<AudioRange>::iterator i = range.begin();
1720                 list<AudioRange>::iterator next;
1721
1722                 while (i != range.end()) {
1723
1724                         next = i;
1725                         ++next;
1726
1727                         /* locating/stopping is subject to delays for declicking.
1728                          */
1729
1730                         samplepos_t requested_sample = i->end;
1731
1732                         if (requested_sample > current_block_size) {
1733                                 requested_sample -= current_block_size;
1734                         } else {
1735                                 requested_sample = 0;
1736                         }
1737
1738                         if (next == range.end()) {
1739                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_sample, 0, 0.0f);
1740                         } else {
1741                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_sample, (*next).start, 0.0f);
1742                         }
1743
1744                         merge_event (ev);
1745
1746                         i = next;
1747                 }
1748
1749         } else if (sz == 1) {
1750
1751                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1752                 merge_event (ev);
1753
1754         }
1755
1756         /* save range so we can do auto-return etc. */
1757
1758         current_audio_range = range;
1759
1760         /* now start rolling at the right place */
1761
1762         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1763         merge_event (ev);
1764
1765         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1766         TransportStateChange ();
1767 }
1768
1769 void
1770 Session::request_bounded_roll (samplepos_t start, samplepos_t end)
1771 {
1772         AudioRange ar (start, end, 0);
1773         list<AudioRange> lar;
1774
1775         lar.push_back (ar);
1776         request_play_range (&lar, true);
1777 }
1778
1779 void
1780 Session::set_requested_return_sample (samplepos_t return_to)
1781 {
1782         _requested_return_sample = return_to;
1783 }
1784
1785 void
1786 Session::request_roll_at_and_return (samplepos_t start, samplepos_t return_to)
1787 {
1788         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1789         ev->target2_sample = start;
1790         queue_event (ev);
1791 }
1792
1793 void
1794 Session::engine_halted ()
1795 {
1796         /* there will be no more calls to process(), so
1797            we'd better clean up for ourselves, right now.
1798
1799            We can't queue SessionEvents because they only get
1800            handled from within a process callback.
1801         */
1802
1803         /* this just stops the FSM engine ... it doesn't change the state of
1804          * the FSM directly or anything else ... but the FSM will be
1805          * reinitialized when we call its ::start() method from
1806          * ::engine_running() (if we ever get there)
1807          */
1808
1809         _transport_fsm->stop ();
1810
1811         /* Synchronously do the realtime part of a transport stop.
1812          *
1813          * Calling this will cause the butler to asynchronously run
1814          * ::non_realtime_stop() where the rest of the "stop" work will be
1815          * done.
1816          */
1817
1818         realtime_stop (false, true);
1819 }
1820
1821 void
1822 Session::engine_running ()
1823 {
1824         _transport_fsm->start ();
1825 }
1826
1827 void
1828 Session::xrun_recovery ()
1829 {
1830         ++_xrun_count;
1831
1832         Xrun (_transport_sample); /* EMIT SIGNAL */
1833
1834         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1835
1836                 /* it didn't actually halt, but we need
1837                    to handle things in the same way.
1838                 */
1839
1840                 engine_halted();
1841         }
1842 }
1843
1844 void
1845 Session::route_processors_changed (RouteProcessorChange c)
1846 {
1847         if (g_atomic_int_get (&_ignore_route_processor_changes) > 0) {
1848                 return;
1849         }
1850
1851         if (c.type == RouteProcessorChange::MeterPointChange) {
1852                 set_dirty ();
1853                 return;
1854         }
1855
1856         if (c.type == RouteProcessorChange::RealTimeChange) {
1857                 set_dirty ();
1858                 return;
1859         }
1860
1861         resort_routes ();
1862         update_latency_compensation (false, false);
1863
1864         set_dirty ();
1865 }
1866
1867 void
1868 Session::allow_auto_play (bool yn)
1869 {
1870         auto_play_legal = yn;
1871 }
1872
1873
1874 void
1875 Session::send_mmc_locate (samplepos_t t)
1876 {
1877         if (t < 0) {
1878                 return;
1879         }
1880
1881         if (!_engine.freewheeling()) {
1882                 Timecode::Time time;
1883                 timecode_time_subframes (t, time);
1884                 send_immediate_mmc (MIDI::MachineControlCommand (time));
1885         }
1886 }
1887
1888 /** Ask the transport to not send timecode until further notice.  The suspension
1889  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1890  *  should be checked by the caller to find out when.
1891  */
1892 void
1893 Session::request_suspend_timecode_transmission ()
1894 {
1895         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1896         queue_event (ev);
1897 }
1898
1899 void
1900 Session::request_resume_timecode_transmission ()
1901 {
1902         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1903         queue_event (ev);
1904 }
1905
1906 bool
1907 Session::timecode_transmission_suspended () const
1908 {
1909         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1910 }
1911
1912 boost::shared_ptr<TransportMaster>
1913 Session::transport_master() const
1914 {
1915         return TransportMasterManager::instance().current();
1916 }
1917
1918 bool
1919 Session::transport_master_is_external () const
1920 {
1921         return TransportMasterManager::instance().current() && config.get_external_sync();
1922 }
1923
1924 bool
1925 Session::transport_master_no_external_or_using_engine () const
1926 {
1927         return !TransportMasterManager::instance().current() || !config.get_external_sync() || (TransportMasterManager::instance().current()->type() == Engine);
1928 }
1929
1930 void
1931 Session::sync_source_changed (SyncSource type, samplepos_t pos, pframes_t cycle_nframes)
1932 {
1933         /* Runs in process() context */
1934
1935         boost::shared_ptr<TransportMaster> master = TransportMasterManager::instance().current();
1936
1937         if (master->can_loop()) {
1938                 request_play_loop (false);
1939         } else if (master->has_loop()) {
1940                 request_play_loop (true);
1941         }
1942
1943         /* slave change, reset any DiskIO block on disk output because it is no
1944            longer valid with a new slave.
1945         */
1946
1947         DiskReader::dec_no_disk_output ();
1948
1949 #if 0
1950         we should not be treating specific transport masters as special cases because there maybe > 1 of a particular type
1951
1952         boost::shared_ptr<MTC_TransportMaster> mtc_master = boost::dynamic_pointer_cast<MTC_TransportMaster> (master);
1953
1954         if (mtc_master) {
1955                 mtc_master->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1));
1956                 MTCSyncStateChanged(mtc_master->locked() );
1957         } else {
1958                 if (g_atomic_int_compare_and_exchange (&_mtc_active, 1, 0)) {
1959                         MTCSyncStateChanged( false );
1960                 }
1961                 mtc_status_connection.disconnect ();
1962         }
1963
1964         boost::shared_ptr<LTC_TransportMaster> ltc_master = boost::dynamic_pointer_cast<LTC_TransportMaster> (master);
1965
1966         if (ltc_master) {
1967                 ltc_master->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1));
1968                 LTCSyncStateChanged (ltc_master->locked() );
1969         } else {
1970                 if (g_atomic_int_compare_and_exchange (&_ltc_active, 1, 0)) {
1971                         LTCSyncStateChanged( false );
1972                 }
1973                 ltc_status_connection.disconnect ();
1974         }
1975 #endif
1976
1977         DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", master));
1978
1979         // need to queue this for next process() cycle
1980         _send_timecode_update = true;
1981
1982         boost::shared_ptr<RouteList> rl = routes.reader();
1983         const bool externally_slaved = transport_master_is_external();
1984
1985         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1986                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1987                 if (tr && !tr->is_private_route()) {
1988                         tr->set_slaved (externally_slaved);
1989                 }
1990         }
1991
1992         set_dirty();
1993 }
1994
1995 bool
1996 Session::transport_stopped() const
1997 {
1998         return _transport_fsm->stopped();
1999 }
2000
2001 bool
2002 Session::transport_rolling() const
2003 {
2004         return _transport_speed != 0.0 && _count_in_samples == 0 && _remaining_latency_preroll == 0;
2005 }
2006
2007 bool
2008 Session::locate_pending () const
2009 {
2010         return _transport_fsm->locating();
2011 }
2012
2013 bool
2014 Session::declick_in_progress () const
2015 {
2016         return _transport_fsm->declick_in_progress();
2017 }