add Session::transport_stopped_or_stopping()
[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_buffer_size_ceil ();
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_buffer_size_ceil ();
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         bool start_after_butler_done_msg = false;
720
721         if ((ptw & (PostTransportReverse|PostTransportRoll))) {
722                 start_after_butler_done_msg = true;
723         }
724
725         ptw = PostTransportWork (ptw & ~(PostTransportAdjustPlaybackBuffering|PostTransportAdjustCaptureBuffering|PostTransportOverWrite|PostTransportReverse|PostTransportRoll));
726         set_post_transport_work (ptw);
727
728         set_next_event ();
729
730         if (_transport_fsm->waiting_for_butler()) {
731                 TFSM_EVENT (TransportFSM::ButlerDone);
732         }
733
734         DiskReader::dec_no_disk_output ();
735
736         if (start_after_butler_done_msg) {
737                 if (_transport_speed) {
738                         /* reversal is done ... tell TFSM that it is time to start*/
739                         TFSM_EVENT (TransportFSM::StartTransport);
740                 }
741         }
742 }
743
744 void
745 Session::schedule_butler_for_transport_work ()
746 {
747         assert (_transport_fsm->waiting_for_butler ());
748         DEBUG_TRACE (DEBUG::Butler, "summon butler for transport work\n");
749         _butler->schedule_transport_work ();
750 }
751
752 bool
753 Session::maybe_stop (samplepos_t limit)
754 {
755         ENSURE_PROCESS_THREAD;
756         if ((_transport_speed > 0.0f && _transport_sample >= limit) || (_transport_speed < 0.0f && _transport_sample == 0)) {
757                 if (synced_to_engine ()) {
758                         _engine.transport_stop ();
759                 } else {
760                         TFSM_EVENT (TransportFSM::StopTransport);
761                 }
762                 return true;
763         }
764         return false;
765 }
766
767 int
768 Session::micro_locate (samplecnt_t distance)
769 {
770         ENSURE_PROCESS_THREAD;
771
772         boost::shared_ptr<RouteList> rl = routes.reader();
773         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
774                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
775                 if (tr && !tr->can_internal_playback_seek (distance)) {
776                         return -1;
777                 }
778         }
779
780         DEBUG_TRACE (DEBUG::Transport, string_compose ("micro-locate by %1\n", distance));
781
782         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
783                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
784                 if (tr) {
785                         tr->internal_playback_seek (distance);
786                 }
787         }
788
789         _transport_sample += distance;
790         return 0;
791 }
792
793 void
794 Session::flush_all_inserts ()
795 {
796         ENSURE_PROCESS_THREAD;
797         boost::shared_ptr<RouteList> r = routes.reader ();
798
799         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
800                 (*i)->flush_processors ();
801         }
802 }
803
804 /* *****************************************************************************
805  * END REALTIME ACTIONS
806  * ****************************************************************************/
807
808 void
809 Session::add_post_transport_work (PostTransportWork ptw)
810 {
811         PostTransportWork oldval;
812         PostTransportWork newval;
813         int tries = 0;
814
815         while (tries < 8) {
816                 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
817                 newval = PostTransportWork (oldval | ptw);
818                 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
819                         /* success */
820                         return;
821                 }
822         }
823
824         error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
825 }
826
827 bool
828 Session::should_ignore_transport_request (TransportRequestSource src, TransportRequestType type) const
829 {
830         if (config.get_external_sync()) {
831                 if (TransportMasterManager::instance().current()->allow_request (src, type)) {
832                         return false;
833                 } else {
834                         return true;
835                 }
836         }
837         return false;
838 }
839
840 bool
841 Session::synced_to_engine() const
842 {
843         return config.get_external_sync() && TransportMasterManager::instance().current()->type() == Engine;
844 }
845
846 void
847 Session::request_sync_source (boost::shared_ptr<TransportMaster> tm)
848 {
849         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportMaster, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
850         ev->transport_master = tm;
851         DEBUG_TRACE (DEBUG::Slave, "sent request for new transport master\n");
852         queue_event (ev);
853 }
854
855 void
856 Session::request_transport_speed (double speed, bool as_default, TransportRequestSource origin)
857 {
858         if (synced_to_engine()) {
859                 if (speed != 0) {
860                         _engine.transport_start ();
861                 } else {
862                         _engine.transport_stop ();
863                 }
864                 return;
865         }
866
867         if (should_ignore_transport_request (origin, TR_Speed)) {
868                 return;
869         }
870
871         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
872         ev->third_yes_or_no = as_default; // as_default
873         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1 as default = %2\n", speed, as_default));
874         queue_event (ev);
875 }
876
877 /** Request a new transport speed, but if the speed parameter is exactly zero then use
878  *  a very small +ve value to prevent the transport actually stopping.  This method should
879  *  be used by callers who are varying transport speed but don't ever want to stop it.
880  */
881 void
882 Session::request_transport_speed_nonzero (double speed, bool as_default, TransportRequestSource origin)
883 {
884         if (should_ignore_transport_request (origin, TransportRequestType (TR_Speed|TR_Start))) {
885                 return;
886         }
887
888         if (speed == 0) {
889                 speed = DBL_EPSILON;
890         }
891
892         request_transport_speed (speed, as_default);
893 }
894
895 void
896 Session::request_stop (bool abort, bool clear_state, TransportRequestSource origin)
897 {
898         if (synced_to_engine()) {
899                 _engine.transport_stop ();
900                 return;
901         }
902
903         if (should_ignore_transport_request (origin, TR_Stop)) {
904                 return;
905         }
906
907         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, audible_sample(), 0.0, abort, clear_state);
908         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));
909         queue_event (ev);
910 }
911
912 void
913 Session::request_locate (samplepos_t target_sample, bool with_roll, TransportRequestSource origin)
914 {
915         if (synced_to_engine()) {
916                 _engine.transport_locate (target_sample);
917                 return;
918         }
919
920         if (should_ignore_transport_request (origin, TR_Locate)) {
921                 return;
922         }
923
924         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, false);
925         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_sample));
926         queue_event (ev);
927 }
928
929 void
930 Session::force_locate (samplepos_t target_sample, bool with_roll)
931 {
932         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_sample, 0, true);
933         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_sample));
934         queue_event (ev);
935 }
936
937 void
938 Session::unset_preroll_record_trim ()
939 {
940         _preroll_record_trim_len = 0;
941 }
942
943 void
944 Session::request_preroll_record_trim (samplepos_t rec_in, samplecnt_t preroll)
945 {
946         if (actively_recording ()) {
947                 return;
948         }
949         unset_preroll_record_trim ();
950
951         config.set_punch_in (false);
952         config.set_punch_out (false);
953
954         samplepos_t pos = std::max ((samplepos_t)0, rec_in - preroll);
955         _preroll_record_trim_len = preroll;
956         maybe_enable_record ();
957         request_locate (pos, true);
958         set_requested_return_sample (rec_in);
959 }
960
961 void
962 Session::request_count_in_record ()
963 {
964         if (actively_recording ()) {
965                 return;
966         }
967         if (transport_rolling()) {
968                 return;
969         }
970         maybe_enable_record ();
971         _count_in_once = true;
972         request_transport_speed (1.0, true);
973 }
974
975 void
976 Session::request_play_loop (bool yn, bool change_transport_roll)
977 {
978         if (transport_master_is_external() && yn) {
979                 // don't attempt to loop when not using Internal Transport
980                 // see also gtk2_ardour/ardour_ui_options.cc parameter_changed()
981                 return;
982         }
983
984         SessionEvent* ev;
985         Location *location = _locations->auto_loop_location();
986         double target_speed;
987
988         if (location == 0 && yn) {
989                 error << _("Cannot loop - no loop range defined")
990                       << endmsg;
991                 return;
992         }
993
994         if (change_transport_roll) {
995                 if (transport_rolling()) {
996                         /* start looping at current speed */
997                         target_speed = transport_speed ();
998                 } else {
999                         /* currently stopped */
1000                         if (yn) {
1001                                 /* start looping at normal speed */
1002                                 target_speed = 1.0;
1003                         } else {
1004                                 target_speed = 0.0;
1005                         }
1006                 }
1007         } else {
1008                 /* leave the speed alone */
1009                 target_speed = transport_speed ();
1010         }
1011
1012         ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, target_speed, yn, change_transport_roll);
1013         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, change roll state ? %2\n", yn, change_transport_roll));
1014         queue_event (ev);
1015 }
1016
1017 void
1018 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
1019 {
1020         SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
1021         if (range) {
1022                 ev->audio_range = *range;
1023         } else {
1024                 ev->audio_range.clear ();
1025         }
1026         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
1027         queue_event (ev);
1028 }
1029
1030 void
1031 Session::request_cancel_play_range ()
1032 {
1033         SessionEvent* ev = new SessionEvent (SessionEvent::CancelPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, 0);
1034         queue_event (ev);
1035 }
1036
1037
1038 bool
1039 Session::solo_selection_active ()
1040 {
1041         if (_soloSelection.empty()) {
1042                 return false;
1043         }
1044         return true;
1045 }
1046
1047 void
1048 Session::solo_selection (StripableList &list, bool new_state)
1049 {
1050         boost::shared_ptr<ControlList> solo_list (new ControlList);
1051         boost::shared_ptr<ControlList> unsolo_list (new ControlList);
1052
1053         if (new_state)
1054                 _soloSelection = list;
1055         else
1056                 _soloSelection.clear();
1057
1058         boost::shared_ptr<RouteList> rl = get_routes();
1059
1060         for (ARDOUR::RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1061
1062                 if ( !(*i)->is_track() ) {
1063                         continue;
1064                 }
1065
1066                 boost::shared_ptr<Stripable> s (*i);
1067
1068                 bool found = (std::find(list.begin(), list.end(), s) != list.end());
1069                 if ( new_state && found ) {
1070
1071                         solo_list->push_back (s->solo_control());
1072
1073                         //must invalidate playlists on selected tracks, so only selected regions get heard
1074                         boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (*i);
1075                         if (track) {
1076                                 boost::shared_ptr<Playlist> playlist = track->playlist();
1077                                 if (playlist) {
1078                                         playlist->ContentsChanged();
1079                                 }
1080                         }
1081                 } else {
1082                         unsolo_list->push_back (s->solo_control());
1083                 }
1084         }
1085
1086         set_controls (solo_list, 1.0, Controllable::NoGroup);
1087         set_controls (unsolo_list, 0.0, Controllable::NoGroup);
1088 }
1089
1090
1091 void
1092 Session::butler_transport_work ()
1093 {
1094         /* Note: this function executes in the butler thread context */
1095
1096   restart:
1097         boost::shared_ptr<RouteList> r = routes.reader ();
1098         int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
1099         bool finished = true;
1100         PostTransportWork ptw = post_transport_work();
1101         uint64_t before;
1102
1103         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));
1104
1105         if (ptw & PostTransportLocate) {
1106
1107                 if (get_play_loop()) {
1108
1109                         DEBUG_TRACE (DEBUG::Butler, "flush loop recording fragment to disk\n");
1110
1111                         /* this locate might be happening while we are
1112                          * loop recording.
1113                          *
1114                          * Non-seamless looping will require a locate (below) that
1115                          * will reset capture buffers and throw away data.
1116                          *
1117                          * Rather than first find all tracks and see if they
1118                          * have outstanding data, just do a flush anyway. It
1119                          * may be cheaper this way anyway, and is certainly
1120                          * more accurate.
1121                          */
1122
1123                         bool more_disk_io_to_do = false;
1124                         uint32_t errors = 0;
1125
1126                         do {
1127                                 more_disk_io_to_do = _butler->flush_tracks_to_disk_after_locate (r, errors);
1128
1129                                 if (errors) {
1130                                         break;
1131                                 }
1132
1133                                 if (more_disk_io_to_do) {
1134                                         continue;
1135                                 }
1136
1137                         } while (false);
1138
1139                 }
1140         }
1141
1142         if (ptw & PostTransportAdjustPlaybackBuffering) {
1143                 /* need to prevent concurrency with ARDOUR::Reader::run(),
1144                  * DiskWriter::adjust_buffering() re-allocates the ringbuffer */
1145                 Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
1146                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1147                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1148                         if (tr) {
1149                                 tr->adjust_playback_buffering ();
1150                                 /* and refill those buffers ... */
1151                         }
1152                         (*i)->non_realtime_locate (_transport_sample);
1153                 }
1154                 VCAList v = _vca_manager->vcas ();
1155                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1156                         (*i)->non_realtime_locate (_transport_sample);
1157                 }
1158         }
1159
1160         if (ptw & PostTransportAdjustCaptureBuffering) {
1161                 /* need to prevent concurrency with ARDOUR::DiskWriter::run(),
1162                  * DiskWriter::adjust_buffering() re-allocates the ringbuffer */
1163                 Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ());
1164                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1165                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1166                         if (tr) {
1167                                 tr->adjust_capture_buffering ();
1168                         }
1169                 }
1170         }
1171
1172         if (ptw & PostTransportReverse) {
1173
1174                 clear_clicks();
1175
1176                 /* don't seek if locate will take care of that in non_realtime_stop() */
1177
1178                 if (!(ptw & PostTransportLocate)) {
1179                         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1180                                 (*i)->non_realtime_locate (_transport_sample);
1181
1182                                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
1183                                         /* new request, stop seeking, and start again */
1184                                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
1185                                         goto restart;
1186                                 }
1187                         }
1188                         VCAList v = _vca_manager->vcas ();
1189                         for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1190                                 (*i)->non_realtime_locate (_transport_sample);
1191                         }
1192                 }
1193         }
1194
1195         if (ptw & PostTransportLocate) {
1196                 DEBUG_TRACE (DEBUG::Transport, "nonrealtime locate invoked from BTW\n");
1197                 non_realtime_locate ();
1198         }
1199
1200         if (ptw & PostTransportStop) {
1201                 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
1202                 if (!finished) {
1203                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
1204                         goto restart;
1205                 }
1206         }
1207
1208         if (ptw & PostTransportOverWrite) {
1209                 non_realtime_overwrite (on_entry, finished);
1210                 if (!finished) {
1211                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
1212                         goto restart;
1213                 }
1214         }
1215
1216         if (ptw & PostTransportAudition) {
1217                 non_realtime_set_audition ();
1218         }
1219
1220         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
1221
1222         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()));
1223 }
1224
1225 void
1226 Session::non_realtime_overwrite (int on_entry, bool& finished)
1227 {
1228         boost::shared_ptr<RouteList> rl = routes.reader();
1229         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1230                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1231                 if (tr && tr->pending_overwrite ()) {
1232                         tr->overwrite_existing_buffers ();
1233                 }
1234                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
1235                         finished = false;
1236                         return;
1237                 }
1238         }
1239 }
1240
1241 void
1242 Session::non_realtime_locate ()
1243 {
1244         DEBUG_TRACE (DEBUG::Transport, string_compose ("locate tracks to %1\n", _transport_sample));
1245
1246         if (Config->get_loop_is_mode() && get_play_loop()) {
1247
1248                 Location *loc  = _locations->auto_loop_location();
1249
1250                 if (!loc || (_transport_sample < loc->start() || _transport_sample >= loc->end())) {
1251                         /* jumped out of loop range: stop tracks from looping,
1252                            but leave loop (mode) enabled.
1253                          */
1254                         set_track_loop (false);
1255
1256                 } else if (loc && ((loc->start() <= _transport_sample) || (loc->end() > _transport_sample))) {
1257
1258                         /* jumping to start of loop. This  might have been done before but it is
1259                          * idempotent and cheap. Doing it here ensures that when we start playback
1260                          * outside the loop we still flip tracks into the magic seamless mode
1261                          * when needed.
1262                          */
1263                         set_track_loop (true);
1264
1265                 } else if (loc) {
1266                         set_track_loop (false);
1267                 }
1268
1269         } else {
1270
1271                 /* no more looping .. should have been noticed elsewhere */
1272         }
1273
1274
1275         samplepos_t tf;
1276
1277         {
1278                 boost::shared_ptr<RouteList> rl = routes.reader();
1279
1280           restart:
1281                 gint sc = g_atomic_int_get (&_seek_counter);
1282                 tf = _transport_sample;
1283
1284                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1285                         (*i)->non_realtime_locate (tf);
1286                         if (sc != g_atomic_int_get (&_seek_counter)) {
1287                                 std::cerr << "\n\nLOCATE INTERRUPTED BY LOCATE!!!\n\n";
1288                                 goto restart;
1289                         }
1290                 }
1291         }
1292
1293         {
1294                 /* VCAs are quick to locate because they have no data (except
1295                    automation) associated with them. Don't bother with a
1296                    restart mechanism here, but do use the same transport sample
1297                    that the Routes used.
1298                 */
1299                 VCAList v = _vca_manager->vcas ();
1300                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1301                         (*i)->non_realtime_locate (tf);
1302                 }
1303         }
1304
1305         _scene_changer->locate (_transport_sample);
1306
1307         /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
1308            rather than clearing them so that the RT thread has to spend time constructing
1309            them (in Session::click).
1310          */
1311         clear_clicks ();
1312 }
1313
1314 bool
1315 Session::select_playhead_priority_target (samplepos_t& jump_to)
1316 {
1317         if (!transport_master_no_external_or_using_engine() || !config.get_auto_return()) {
1318                 return false;
1319         }
1320
1321         jump_to = _last_roll_location;
1322         return jump_to >= 0;
1323 }
1324
1325 void
1326 Session::follow_playhead_priority ()
1327 {
1328         samplepos_t target;
1329
1330         if (select_playhead_priority_target (target)) {
1331                 request_locate (target);
1332         }
1333 }
1334
1335 void
1336 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
1337 {
1338         struct tm* now;
1339         time_t     xnow;
1340         bool       did_record;
1341         bool       saved;
1342         PostTransportWork ptw = post_transport_work();
1343
1344         did_record = false;
1345         saved = false;
1346
1347         boost::shared_ptr<RouteList> rl = routes.reader();
1348         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1349                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1350                 if (tr && tr->get_captured_samples () != 0) {
1351                         did_record = true;
1352                         break;
1353                 }
1354         }
1355
1356         /* stop and locate are merged here because they share a lot of common stuff */
1357
1358         time (&xnow);
1359         now = localtime (&xnow);
1360
1361         if (auditioner) {
1362                 auditioner->cancel_audition ();
1363         }
1364
1365         if (did_record) {
1366                 begin_reversible_command (Operations::capture);
1367                 _have_captured = true;
1368         }
1369
1370         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
1371
1372         if (abort && did_record) {
1373                 /* no reason to save the session file when we remove sources
1374                  */
1375                 _state_of_the_state = StateOfTheState (_state_of_the_state | InCleanup);
1376         }
1377
1378         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1379                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1380                 if (tr) {
1381                         tr->transport_stopped_wallclock (*now, xnow, abort);
1382                 }
1383         }
1384
1385         if (abort && did_record) {
1386                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
1387         }
1388
1389         boost::shared_ptr<RouteList> r = routes.reader ();
1390
1391         if (did_record) {
1392                 commit_reversible_command ();
1393                 /* increase take name */
1394                 if (config.get_track_name_take () && !config.get_take_name ().empty()) {
1395                         string newname = config.get_take_name();
1396                         config.set_take_name(bump_name_number (newname));
1397                 }
1398         }
1399
1400         if (_engine.running()) {
1401                 PostTransportWork ptw = post_transport_work ();
1402
1403                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1404                         (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate));
1405                 }
1406                 VCAList v = _vca_manager->vcas ();
1407                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1408                         (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate));
1409                 }
1410         }
1411
1412         /* If we are not synced to a "true" external master, and we're not
1413          * handling an explicit locate, we should consider whether or not to
1414          * "auto-return". This could mean going to a specifically requested
1415          * location, or just back to the start of the last roll.
1416          */
1417
1418         if (transport_master_no_external_or_using_engine() && !(ptw & PostTransportLocate)) {
1419
1420                 bool do_locate = false;
1421
1422                 if (_requested_return_sample >= 0) {
1423
1424                         /* explicit return request pre-queued in event list. overrides everything else */
1425
1426                         _transport_sample = _requested_return_sample;
1427
1428                         /* cancel this request */
1429                         _requested_return_sample = -1;
1430                         do_locate = true;
1431
1432                 } else if (Config->get_auto_return_target_list()) {
1433
1434                         samplepos_t jump_to;
1435
1436                         if (select_playhead_priority_target (jump_to)) {
1437
1438                                 /* there's a valid target (we don't care how it
1439                                  * was derived here)
1440                                  */
1441
1442                                 _transport_sample = jump_to;
1443                                 do_locate = true;
1444
1445                         } else if (abort) {
1446
1447                                 /* roll aborted (typically capture) with
1448                                  * auto-return enabled
1449                                  */
1450
1451                                 _transport_sample = _last_roll_location;
1452                                 do_locate = true;
1453
1454                         }
1455                 }
1456
1457
1458                 if (do_locate && synced_to_engine()) {
1459
1460                         /* We will unconditionally locate to _transport_sample
1461                          * below, which will refill playback buffers based on
1462                          * _transport_sample, and maximises the buffering they
1463                          * represent.
1464                          *
1465                          * But if we are synced to engine (JACK), we should
1466                          * locate the engine (JACK) as well. We would follow
1467                          * the engine (JACK) on the next process cycle, but
1468                          * since we're going to do a locate below anyway,
1469                          * it seems pointless to not use just do it ourselves
1470                          * right now, rather than wait for the engine (JACK) to
1471                          * provide the new position on the next cycle.
1472                          *
1473                          * Despite the generic name of the called method
1474                          * (::transport_locate()) this method only does
1475                          * anything if the audio/MIDI backend is JACK.
1476                          */
1477
1478                         _engine.transport_locate (_transport_sample);
1479
1480                 }
1481         }
1482
1483         clear_clicks();
1484         unset_preroll_record_trim ();
1485
1486         /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
1487         */
1488
1489         if (ptw & (PostTransportClearSubstate|PostTransportStop)) {
1490                 unset_play_range ();
1491                 if (!loop_changing && !Config->get_loop_is_mode()) {
1492                         unset_play_loop ();
1493                 }
1494         }
1495
1496         /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
1497
1498         {
1499                 DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
1500                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1501                         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
1502                         (*i)->non_realtime_locate (_transport_sample);
1503
1504                         if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
1505                                 finished = false;
1506                                 /* we will be back */
1507                                 return;
1508                         }
1509                 }
1510         }
1511
1512         {
1513                 VCAList v = _vca_manager->vcas ();
1514                 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
1515                         (*i)->non_realtime_locate (_transport_sample);
1516                 }
1517         }
1518
1519         have_looped = false;
1520
1521         /* don't bother with this stuff if we're disconnected from the engine,
1522            because there will be no process callbacks to deliver stuff from
1523         */
1524
1525         if (_engine.running() && !_engine.freewheeling()) {
1526                 // need to queue this in the next RT cycle
1527                 _send_timecode_update = true;
1528
1529                 if (transport_master()->type() == MTC) {
1530                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
1531
1532                         /* This (::non_realtime_stop()) gets called by main
1533                            process thread, which will lead to confusion
1534                            when calling AsyncMIDIPort::write().
1535
1536                            Something must be done. XXX
1537                         */
1538                         send_mmc_locate (_transport_sample);
1539                 }
1540         }
1541
1542         if ((ptw & PostTransportLocate) && get_record_enabled()) {
1543                 /* This is scheduled by realtime_stop(), which is also done
1544                  * when a slave requests /locate/ for an initial sync.
1545                  * We can't hold up the slave for long with a save() here,
1546                  * without breaking its initial sync cycle.
1547                  *
1548                  * save state only if there's no slave or if it's not yet locked.
1549                  */
1550                 if (!transport_master_is_external() || !transport_master()->locked()) {
1551                         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: requests save\n"));
1552                         SaveSessionRequested (_current_snapshot_name);
1553                         saved = true;
1554                 }
1555         }
1556
1557         /* save the current state of things if appropriate */
1558
1559         if (did_record && !saved) {
1560                 SaveSessionRequested (_current_snapshot_name);
1561         }
1562
1563         PositionChanged (_transport_sample); /* EMIT SIGNAL */
1564         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC with speed = %1\n", _transport_speed));
1565         TransportStateChange (); /* EMIT SIGNAL */
1566         AutomationWatch::instance().transport_stop_automation_watches (_transport_sample);
1567
1568         ptw = PostTransportWork (ptw & ~(PostTransportAbort|PostTransportStop|PostTransportClearSubstate));
1569         set_post_transport_work (ptw);
1570 }
1571
1572 void
1573 Session::set_play_loop (bool yn, bool change_transport_state)
1574 {
1575         ENSURE_PROCESS_THREAD;
1576         /* Called from event-handling context */
1577
1578         DEBUG_TRACE (DEBUG::Transport, string_compose ("set_play_loop (%1)\n", yn));
1579
1580         Location *loc;
1581
1582         if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
1583                 /* nothing to do, or can't change loop status while recording */
1584                 return;
1585         }
1586
1587         if (yn && synced_to_engine()) {
1588                 warning << string_compose (
1589                         _("Looping cannot be supported while %1 is using JACK transport.\n"
1590                           "Recommend changing the configured options"), PROGRAM_NAME)
1591                         << endmsg;
1592                 return;
1593         }
1594
1595         if (yn) {
1596
1597                 play_loop = true;
1598                 have_looped = false;
1599
1600                 if (loc) {
1601
1602                         unset_play_range ();
1603                         /* set all tracks to use internal looping */
1604                         set_track_loop (true);
1605
1606                         merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
1607
1608                         if (!Config->get_loop_is_mode()) {
1609                                 /* args: positition, roll=true, flush=true, for_loop_end=false, force buffer, refill  looping */
1610                                 /* set this so that when/if we stop for locate,
1611                                    we do not call unset_play_loop(). This is a
1612                                    crude mechanism. Got a better idea?
1613                                 */
1614                                 loop_changing = true;
1615                                 TFSM_LOCATE (loc->start(), true, true, false, true);
1616                         } else if (!transport_rolling()) {
1617                                 /* loop-is-mode: not rolling, just locate to loop start */
1618                                 TFSM_LOCATE (loc->start(), false, true, false, true);
1619                         }
1620                 }
1621
1622         } else {
1623
1624                 unset_play_loop ();
1625         }
1626
1627         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC2 with speed = %1\n", _transport_speed));
1628         TransportStateChange ();
1629 }
1630
1631 void
1632 Session::unset_play_loop (bool change_transport_state)
1633 {
1634         if (play_loop) {
1635
1636                 play_loop = false;
1637                 clear_events (SessionEvent::AutoLoop);
1638                 set_track_loop (false);
1639
1640                 /* likely need to flush track buffers: this will locate us to wherever we are */
1641
1642                 if (change_transport_state && transport_rolling ()) {
1643                         TFSM_EVENT (TransportFSM::StopTransport);
1644                 }
1645
1646                 overwrite_some_buffers (boost::shared_ptr<Route>(), LoopDisabled);
1647
1648                 TransportStateChange (); /* EMIT SIGNAL */
1649         }
1650 }
1651
1652 void
1653 Session::set_track_loop (bool yn)
1654 {
1655         Location* loc = _locations->auto_loop_location ();
1656
1657         if (!loc) {
1658                 yn = false;
1659         }
1660
1661         boost::shared_ptr<RouteList> rl = routes.reader ();
1662
1663         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1664                 if (*i && !(*i)->is_private_route()) {
1665                         (*i)->set_loop (yn ? loc : 0);
1666                 }
1667         }
1668
1669         DiskReader::reset_loop_declick (loc, nominal_sample_rate());
1670 }
1671
1672 samplecnt_t
1673 Session::worst_latency_preroll () const
1674 {
1675         return _worst_output_latency + _worst_input_latency;
1676 }
1677
1678 samplecnt_t
1679 Session::worst_latency_preroll_buffer_size_ceil () const
1680 {
1681         return lrintf (ceil ((_worst_output_latency + _worst_input_latency) / (float) current_block_size) * current_block_size);
1682 }
1683
1684 void
1685 Session::unset_play_range ()
1686 {
1687         _play_range = false;
1688         _clear_event_type (SessionEvent::RangeStop);
1689         _clear_event_type (SessionEvent::RangeLocate);
1690 }
1691
1692 void
1693 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1694 {
1695         SessionEvent* ev;
1696
1697         /* Called from event-processing context */
1698
1699         unset_play_range ();
1700
1701         if (range.empty()) {
1702                 /* _play_range set to false in unset_play_range()
1703                  */
1704                 if (!leave_rolling) {
1705                         /* stop transport */
1706                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1707                         merge_event (ev);
1708                 }
1709                 return;
1710         }
1711
1712         _play_range = true;
1713
1714         /* cancel loop play */
1715         unset_play_loop ();
1716
1717         list<AudioRange>::size_type sz = range.size();
1718
1719         if (sz > 1) {
1720
1721                 list<AudioRange>::iterator i = range.begin();
1722                 list<AudioRange>::iterator next;
1723
1724                 while (i != range.end()) {
1725
1726                         next = i;
1727                         ++next;
1728
1729                         /* locating/stopping is subject to delays for declicking.
1730                          */
1731
1732                         samplepos_t requested_sample = i->end;
1733
1734                         if (requested_sample > current_block_size) {
1735                                 requested_sample -= current_block_size;
1736                         } else {
1737                                 requested_sample = 0;
1738                         }
1739
1740                         if (next == range.end()) {
1741                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_sample, 0, 0.0f);
1742                         } else {
1743                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_sample, (*next).start, 0.0f);
1744                         }
1745
1746                         merge_event (ev);
1747
1748                         i = next;
1749                 }
1750
1751         } else if (sz == 1) {
1752
1753                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1754                 merge_event (ev);
1755
1756         }
1757
1758         /* save range so we can do auto-return etc. */
1759
1760         current_audio_range = range;
1761
1762         /* now start rolling at the right place */
1763
1764         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1765         merge_event (ev);
1766
1767         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1768         TransportStateChange ();
1769 }
1770
1771 void
1772 Session::request_bounded_roll (samplepos_t start, samplepos_t end)
1773 {
1774         AudioRange ar (start, end, 0);
1775         list<AudioRange> lar;
1776
1777         lar.push_back (ar);
1778         request_play_range (&lar, true);
1779 }
1780
1781 void
1782 Session::set_requested_return_sample (samplepos_t return_to)
1783 {
1784         _requested_return_sample = return_to;
1785 }
1786
1787 void
1788 Session::request_roll_at_and_return (samplepos_t start, samplepos_t return_to)
1789 {
1790         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1791         ev->target2_sample = start;
1792         queue_event (ev);
1793 }
1794
1795 void
1796 Session::engine_halted ()
1797 {
1798         /* there will be no more calls to process(), so
1799            we'd better clean up for ourselves, right now.
1800
1801            We can't queue SessionEvents because they only get
1802            handled from within a process callback.
1803         */
1804
1805         /* this just stops the FSM engine ... it doesn't change the state of
1806          * the FSM directly or anything else ... but the FSM will be
1807          * reinitialized when we call its ::start() method from
1808          * ::engine_running() (if we ever get there)
1809          */
1810
1811         _transport_fsm->stop ();
1812
1813         /* Synchronously do the realtime part of a transport stop.
1814          *
1815          * Calling this will cause the butler to asynchronously run
1816          * ::non_realtime_stop() where the rest of the "stop" work will be
1817          * done.
1818          */
1819
1820         realtime_stop (false, true);
1821 }
1822
1823 void
1824 Session::engine_running ()
1825 {
1826         _transport_fsm->start ();
1827 }
1828
1829 void
1830 Session::xrun_recovery ()
1831 {
1832         ++_xrun_count;
1833
1834         Xrun (_transport_sample); /* EMIT SIGNAL */
1835
1836         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1837
1838                 /* it didn't actually halt, but we need
1839                    to handle things in the same way.
1840                 */
1841
1842                 engine_halted();
1843         }
1844 }
1845
1846 void
1847 Session::route_processors_changed (RouteProcessorChange c)
1848 {
1849         if (g_atomic_int_get (&_ignore_route_processor_changes) > 0) {
1850                 return;
1851         }
1852
1853         if (c.type == RouteProcessorChange::MeterPointChange) {
1854                 set_dirty ();
1855                 return;
1856         }
1857
1858         if (c.type == RouteProcessorChange::RealTimeChange) {
1859                 set_dirty ();
1860                 return;
1861         }
1862
1863         resort_routes ();
1864         update_latency_compensation (false, false);
1865
1866         set_dirty ();
1867 }
1868
1869 void
1870 Session::allow_auto_play (bool yn)
1871 {
1872         auto_play_legal = yn;
1873 }
1874
1875
1876 void
1877 Session::send_mmc_locate (samplepos_t t)
1878 {
1879         if (t < 0) {
1880                 return;
1881         }
1882
1883         if (!_engine.freewheeling()) {
1884                 Timecode::Time time;
1885                 timecode_time_subframes (t, time);
1886                 send_immediate_mmc (MIDI::MachineControlCommand (time));
1887         }
1888 }
1889
1890 /** Ask the transport to not send timecode until further notice.  The suspension
1891  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1892  *  should be checked by the caller to find out when.
1893  */
1894 void
1895 Session::request_suspend_timecode_transmission ()
1896 {
1897         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1898         queue_event (ev);
1899 }
1900
1901 void
1902 Session::request_resume_timecode_transmission ()
1903 {
1904         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1905         queue_event (ev);
1906 }
1907
1908 bool
1909 Session::timecode_transmission_suspended () const
1910 {
1911         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1912 }
1913
1914 boost::shared_ptr<TransportMaster>
1915 Session::transport_master() const
1916 {
1917         return TransportMasterManager::instance().current();
1918 }
1919
1920 bool
1921 Session::transport_master_is_external () const
1922 {
1923         return TransportMasterManager::instance().current() && config.get_external_sync();
1924 }
1925
1926 bool
1927 Session::transport_master_no_external_or_using_engine () const
1928 {
1929         return !TransportMasterManager::instance().current() || !config.get_external_sync() || (TransportMasterManager::instance().current()->type() == Engine);
1930 }
1931
1932 void
1933 Session::sync_source_changed (SyncSource type, samplepos_t pos, pframes_t cycle_nframes)
1934 {
1935         /* Runs in process() context */
1936
1937         boost::shared_ptr<TransportMaster> master = TransportMasterManager::instance().current();
1938
1939         if (master->can_loop()) {
1940                 request_play_loop (false);
1941         } else if (master->has_loop()) {
1942                 request_play_loop (true);
1943         }
1944
1945         /* slave change, reset any DiskIO block on disk output because it is no
1946            longer valid with a new slave.
1947         */
1948
1949         DiskReader::dec_no_disk_output ();
1950
1951 #if 0
1952         we should not be treating specific transport masters as special cases because there maybe > 1 of a particular type
1953
1954         boost::shared_ptr<MTC_TransportMaster> mtc_master = boost::dynamic_pointer_cast<MTC_TransportMaster> (master);
1955
1956         if (mtc_master) {
1957                 mtc_master->ActiveChanged.connect_same_thread (mtc_status_connection, boost::bind (&Session::mtc_status_changed, this, _1));
1958                 MTCSyncStateChanged(mtc_master->locked() );
1959         } else {
1960                 if (g_atomic_int_compare_and_exchange (&_mtc_active, 1, 0)) {
1961                         MTCSyncStateChanged( false );
1962                 }
1963                 mtc_status_connection.disconnect ();
1964         }
1965
1966         boost::shared_ptr<LTC_TransportMaster> ltc_master = boost::dynamic_pointer_cast<LTC_TransportMaster> (master);
1967
1968         if (ltc_master) {
1969                 ltc_master->ActiveChanged.connect_same_thread (ltc_status_connection, boost::bind (&Session::ltc_status_changed, this, _1));
1970                 LTCSyncStateChanged (ltc_master->locked() );
1971         } else {
1972                 if (g_atomic_int_compare_and_exchange (&_ltc_active, 1, 0)) {
1973                         LTCSyncStateChanged( false );
1974                 }
1975                 ltc_status_connection.disconnect ();
1976         }
1977 #endif
1978
1979         DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", master));
1980
1981         // need to queue this for next process() cycle
1982         _send_timecode_update = true;
1983
1984         boost::shared_ptr<RouteList> rl = routes.reader();
1985         const bool externally_slaved = transport_master_is_external();
1986
1987         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1988                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1989                 if (tr && !tr->is_private_route()) {
1990                         tr->set_slaved (externally_slaved);
1991                 }
1992         }
1993
1994         set_dirty();
1995 }
1996
1997 bool
1998 Session::transport_stopped() const
1999 {
2000         return _transport_fsm->stopped();
2001 }
2002
2003 bool
2004 Session::transport_stopped_or_stopping() const
2005 {
2006         return _transport_fsm->stopped() || _transport_fsm->stopping();
2007 }
2008
2009 bool
2010 Session::transport_rolling() const
2011 {
2012         return _transport_speed != 0.0 && _count_in_samples == 0 && _remaining_latency_preroll == 0;
2013 }
2014
2015 bool
2016 Session::locate_pending () const
2017 {
2018         return _transport_fsm->locating();
2019 }
2020
2021 bool
2022 Session::declick_in_progress () const
2023 {
2024         return _transport_fsm->declick_in_progress();
2025 }