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