Declick before the end of seamless loops, not after the end, so that loops are render...
[ardour.git] / libs / ardour / session_transport.cc
1 /*
2     Copyright (C) 1999-2003 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <cmath>
25 #include <cerrno>
26 #include <unistd.h>
27
28 #include "pbd/undo.h"
29 #include "pbd/error.h"
30 #include "pbd/enumwriter.h"
31 #include "pbd/pthread_utils.h"
32 #include "pbd/memento_command.h"
33
34 #include "midi++/mmc.h"
35 #include "midi++/port.h"
36 #include "midi++/manager.h"
37
38 #include "ardour/audioengine.h"
39 #include "ardour/auditioner.h"
40 #include "ardour/butler.h"
41 #include "ardour/click.h"
42 #include "ardour/debug.h"
43 #include "ardour/location.h"
44 #include "ardour/session.h"
45 #include "ardour/slave.h"
46 #include "ardour/operations.h"
47
48 #include "i18n.h"
49
50 using namespace std;
51 using namespace ARDOUR;
52 using namespace PBD;
53
54 void
55 Session::add_post_transport_work (PostTransportWork ptw)
56 {
57         PostTransportWork oldval;
58         PostTransportWork newval;
59         int tries = 0;
60
61         while (tries < 8) {
62                 oldval = (PostTransportWork) g_atomic_int_get (&_post_transport_work);
63                 newval = PostTransportWork (oldval | ptw);
64                 if (g_atomic_int_compare_and_exchange (&_post_transport_work, oldval, newval)) {
65                         /* success */
66                         return;
67                 }
68         }
69
70         error << "Could not set post transport work! Crazy thread madness, call the programmers" << endmsg;
71 }
72
73 void
74 Session::request_input_change_handling ()
75 {
76         if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
77                 SessionEvent* ev = new SessionEvent (SessionEvent::InputConfigurationChange, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
78                 queue_event (ev);
79         }
80 }
81
82 void
83 Session::request_sync_source (Slave* new_slave)
84 {
85         SessionEvent* ev = new SessionEvent (SessionEvent::SetSyncSource, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
86         bool seamless;
87
88         seamless = Config->get_seamless_loop ();
89
90         if (dynamic_cast<JACK_Slave*>(new_slave)) {
91                 /* JACK cannot support seamless looping at present */
92                 Config->set_seamless_loop (false);
93         } else {
94                 /* reset to whatever the value was before we last switched slaves */
95                 Config->set_seamless_loop (_was_seamless);
96         }
97
98         /* save value of seamless from before the switch */
99         _was_seamless = seamless;
100
101         ev->slave = new_slave;
102         queue_event (ev);
103 }
104
105 void
106 Session::request_transport_speed (double speed)
107 {
108         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
109         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport speed = %1\n", speed));
110         queue_event (ev);
111 }
112
113 /** Request a new transport speed, but if the speed parameter is exactly zero then use
114  *  a very small +ve value to prevent the transport actually stopping.  This method should
115  *  be used by callers who are varying transport speed but don't ever want to stop it.
116  */
117 void
118 Session::request_transport_speed_nonzero (double speed)
119 {
120         if (speed == 0) {
121                 speed = DBL_EPSILON;
122         }
123
124         request_transport_speed (speed);
125 }
126
127 void
128 Session::request_track_speed (Track* tr, double speed)
129 {
130         SessionEvent* ev = new SessionEvent (SessionEvent::SetTrackSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, speed);
131         ev->set_ptr (tr);
132         queue_event (ev);
133 }
134
135 void
136 Session::request_stop (bool abort, bool clear_state)
137 {
138         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0, abort, clear_state);
139         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request transport stop, abort = %1, clear state = %2\n", abort, clear_state));
140         queue_event (ev);
141 }
142
143 void
144 Session::request_locate (framepos_t target_frame, bool with_roll)
145 {
146         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, false);
147         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request locate to %1\n", target_frame));
148         queue_event (ev);
149 }
150
151 void
152 Session::force_locate (framepos_t target_frame, bool with_roll)
153 {
154         SessionEvent *ev = new SessionEvent (with_roll ? SessionEvent::LocateRoll : SessionEvent::Locate, SessionEvent::Add, SessionEvent::Immediate, target_frame, 0, true);
155         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request forced locate to %1\n", target_frame));
156         queue_event (ev);
157 }
158
159 void
160 Session::request_play_loop (bool yn, bool leave_rolling)
161 {
162         SessionEvent* ev;
163         Location *location = _locations->auto_loop_location();
164
165         if (location == 0 && yn) {
166                 error << _("Cannot loop - no loop range defined")
167                       << endmsg;
168                 return;
169         }
170
171         ev = new SessionEvent (SessionEvent::SetLoop, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
172         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request set loop = %1, leave rolling ? %2\n", yn, leave_rolling));
173         queue_event (ev);
174
175         if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
176                 // request an immediate locate to refresh the tracks
177                 // after disabling looping
178                 request_locate (_transport_frame-1, false);
179         }
180 }
181
182 void
183 Session::request_play_range (list<AudioRange>* range, bool leave_rolling)
184 {
185         SessionEvent* ev = new SessionEvent (SessionEvent::SetPlayAudioRange, SessionEvent::Add, SessionEvent::Immediate, 0, (leave_rolling ? 1.0 : 0.0));
186         if (range) {
187                 ev->audio_range = *range;
188         } else {
189                 ev->audio_range.clear ();
190         }
191         DEBUG_TRACE (DEBUG::Transport, string_compose ("Request play range, leave rolling ? %1\n", leave_rolling));
192         queue_event (ev);
193 }
194
195 void
196 Session::realtime_stop (bool abort, bool clear_state)
197 {
198         DEBUG_TRACE (DEBUG::Transport, string_compose ("realtime stop @ %1\n", _transport_frame));
199         PostTransportWork todo = PostTransportWork (0);
200
201         /* assume that when we start, we'll be moving forwards */
202
203         if (_transport_speed < 0.0f) {
204                 todo = (PostTransportWork (todo | PostTransportStop | PostTransportReverse));
205         } else {
206                 todo = PostTransportWork (todo | PostTransportStop);
207         }
208
209         /* call routes */
210
211         boost::shared_ptr<RouteList> r = routes.reader ();
212
213         for (RouteList::iterator i = r->begin (); i != r->end(); ++i) {
214                 (*i)->realtime_handle_transport_stopped ();
215         }
216
217         if (actively_recording()) {
218
219                 /* move the transport position back to where the
220                    request for a stop was noticed. we rolled
221                    past that point to pick up delayed input (and/or to delick)
222                 */
223
224                 if (worst_playback_latency() > current_block_size) {
225                         /* we rolled past the stop point to pick up data that had
226                            not yet arrived. move back to where the stop occured.
227                         */
228                         decrement_transport_position (current_block_size + (worst_input_latency() - current_block_size));
229                 } else {
230                         decrement_transport_position (current_block_size);
231                 }
232
233                 /* the duration change is not guaranteed to have happened, but is likely */
234
235                 todo = PostTransportWork (todo | PostTransportDuration);
236         }
237
238         if (abort) {
239                 todo = PostTransportWork (todo | PostTransportAbort);
240         }
241
242         if (clear_state) {
243                 todo = PostTransportWork (todo | PostTransportClearSubstate);
244         }
245
246         if (todo) {
247                 add_post_transport_work (todo);
248         }
249
250         _clear_event_type (SessionEvent::StopOnce);
251         _clear_event_type (SessionEvent::RangeStop);
252         _clear_event_type (SessionEvent::RangeLocate);
253
254         /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
255         disable_record (true, (!Config->get_latched_record_enable() && clear_state));
256
257         reset_slave_state ();
258
259         _transport_speed = 0;
260         _target_transport_speed = 0;
261
262         g_atomic_int_set (&_playback_load, 100);
263         g_atomic_int_set (&_capture_load, 100);
264
265         if (config.get_use_video_sync()) {
266                 waiting_for_sync_offset = true;
267         }
268
269         transport_sub_state = 0;
270 }
271
272 void
273 Session::realtime_locate ()
274 {
275         boost::shared_ptr<RouteList> r = routes.reader ();
276         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
277                 (*i)->realtime_locate ();
278         }
279 }
280
281 void
282 Session::butler_transport_work ()
283 {
284   restart:
285         bool finished;
286         PostTransportWork ptw;
287         boost::shared_ptr<RouteList> r = routes.reader ();
288
289         int on_entry = g_atomic_int_get (&_butler->should_do_transport_work);
290         finished = true;
291         ptw = post_transport_work();
292
293         DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler transport work, todo = %1\n", enum_2_string (ptw)));
294
295         if (ptw & PostTransportAdjustPlaybackBuffering) {
296                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
297                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
298                         if (tr) {
299                                 tr->adjust_playback_buffering ();
300                                 /* and refill those buffers ... */
301                                 tr->non_realtime_locate (_transport_frame);
302                         }
303                 }
304
305         }
306
307         if (ptw & PostTransportAdjustCaptureBuffering) {
308                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
309                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
310                         if (tr) {
311                                 tr->adjust_capture_buffering ();
312                         }
313                 }
314         }
315
316         if (ptw & PostTransportCurveRealloc) {
317                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
318                         (*i)->curve_reallocate();
319                 }
320         }
321
322         if (ptw & PostTransportInputChange) {
323                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
324                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
325                         if (tr) {
326                                 tr->non_realtime_input_change ();
327                         }
328                 }
329         }
330
331         if (ptw & PostTransportSpeed) {
332                 non_realtime_set_speed ();
333         }
334
335         if (ptw & PostTransportReverse) {
336
337                 clear_clicks();
338                 cumulative_rf_motion = 0;
339                 reset_rf_scale (0);
340
341                 /* don't seek if locate will take care of that in non_realtime_stop() */
342
343                 if (!(ptw & PostTransportLocate)) {
344
345                         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
346                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
347                                 if (tr && !tr->hidden()) {
348                                         tr->non_realtime_locate (_transport_frame);
349                                 }
350                                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
351                                         /* new request, stop seeking, and start again */
352                                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
353                                         goto restart;
354                                 }
355                         }
356                 }
357         }
358
359         if (ptw & PostTransportLocate) {
360                 non_realtime_locate ();
361         }
362
363         if (ptw & PostTransportStop) {
364                 non_realtime_stop (ptw & PostTransportAbort, on_entry, finished);
365                 if (!finished) {
366                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
367                         goto restart;
368                 }
369         }
370
371         if (ptw & PostTransportOverWrite) {
372                 non_realtime_overwrite (on_entry, finished);
373                 if (!finished) {
374                         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
375                         goto restart;
376                 }
377         }
378
379         if (ptw & PostTransportAudition) {
380                 non_realtime_set_audition ();
381         }
382
383         g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
384
385         DEBUG_TRACE (DEBUG::Transport, X_("Butler transport work all done\n"));
386 }
387
388 void
389 Session::non_realtime_set_speed ()
390 {
391         boost::shared_ptr<RouteList> rl = routes.reader();
392         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
393                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
394                 if (tr) {
395                         tr->non_realtime_set_speed ();
396                 }
397         }
398 }
399
400 void
401 Session::non_realtime_overwrite (int on_entry, bool& finished)
402 {
403         boost::shared_ptr<RouteList> rl = routes.reader();
404         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
405                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
406                 if (tr && tr->pending_overwrite ()) {
407                         tr->overwrite_existing_buffers ();
408                 }
409                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
410                         finished = false;
411                         return;
412                 }
413         }
414 }
415
416
417 void
418 Session::non_realtime_locate ()
419 {
420         boost::shared_ptr<RouteList> rl = routes.reader();
421         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
422                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
423                 if (tr) {
424                         tr->non_realtime_locate (_transport_frame);
425                 }
426         }
427
428         /* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
429            rather than clearing them so that the RT thread has to spend time constructing
430            them (in Session::click).
431          */
432         clear_clicks ();
433 }
434
435
436 void
437 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
438 {
439         struct tm* now;
440         time_t     xnow;
441         bool       did_record;
442         bool       saved;
443         PostTransportWork ptw = post_transport_work();
444
445         did_record = false;
446         saved = false;
447
448         boost::shared_ptr<RouteList> rl = routes.reader();
449         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
450                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
451                 if (tr && tr->get_captured_frames () != 0) {
452                         did_record = true;
453                         break;
454                 }
455         }
456
457         /* stop and locate are merged here because they share a lot of common stuff */
458
459         time (&xnow);
460         now = localtime (&xnow);
461
462         if (auditioner) {
463                 auditioner->cancel_audition ();
464         }
465
466         cumulative_rf_motion = 0;
467         reset_rf_scale (0);
468
469         if (did_record) {
470                 begin_reversible_command (Operations::capture);
471                 _have_captured = true;
472         }
473
474         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: DS stop\n"));
475
476         if (abort && did_record) {
477                 /* no reason to save the session file when we remove sources
478                  */
479                 _state_of_the_state = StateOfTheState (_state_of_the_state|InCleanup);
480         }
481
482         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
483                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
484                 if (tr) {
485                         tr->transport_stopped_wallclock (*now, xnow, abort);
486                 }
487         }
488
489         if (abort && did_record) {
490                 _state_of_the_state = StateOfTheState (_state_of_the_state & ~InCleanup);
491         }
492
493         boost::shared_ptr<RouteList> r = routes.reader ();
494
495         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
496                 if (!(*i)->is_hidden()) {
497                         (*i)->set_pending_declick (0);
498                 }
499         }
500
501         if (did_record) {
502                 commit_reversible_command ();
503         }
504
505         if (_engine.running()) {
506                 PostTransportWork ptw = post_transport_work ();
507                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
508                         (*i)->nonrealtime_handle_transport_stopped (abort, (ptw & PostTransportLocate), (!(ptw & PostTransportLocate) || pending_locate_flush));
509                 }
510                 update_latency_compensation ();
511         }
512
513         bool const auto_return_enabled =
514                 (!config.get_external_sync() && config.get_auto_return());
515
516         if (auto_return_enabled ||
517             (ptw & PostTransportLocate) ||
518             (_requested_return_frame >= 0) ||
519             synced_to_jack()) {
520
521                 if (pending_locate_flush) {
522                         flush_all_inserts ();
523                 }
524
525                 if ((auto_return_enabled || synced_to_jack() || _requested_return_frame >= 0) &&
526                     !(ptw & PostTransportLocate)) {
527
528                         /* no explicit locate queued */
529
530                         bool do_locate = false;
531
532                         if (_requested_return_frame >= 0) {
533
534                                 /* explicit return request pre-queued in event list. overrides everything else */
535
536                                 cerr << "explicit auto-return to " << _requested_return_frame << endl;
537
538                                 _transport_frame = _requested_return_frame;
539                                 do_locate = true;
540
541                         } else {
542                                 if (config.get_auto_return()) {
543
544                                         if (play_loop) {
545
546                                                 /* don't try to handle loop play when synced to JACK */
547
548                                                 if (!synced_to_jack()) {
549
550                                                         Location *location = _locations->auto_loop_location();
551
552                                                         if (location != 0) {
553                                                                 _transport_frame = location->start();
554                                                         } else {
555                                                                 _transport_frame = _last_roll_location;
556                                                         }
557                                                         do_locate = true;
558                                                 }
559
560                                         } else if (_play_range) {
561
562                                                 /* return to start of range */
563
564                                                 if (!current_audio_range.empty()) {
565                                                         _transport_frame = current_audio_range.front().start;
566                                                         do_locate = true;
567                                                 }
568
569                                         } else {
570
571                                                 /* regular auto-return */
572
573                                                 _transport_frame = _last_roll_location;
574                                                 do_locate = true;
575                                         }
576                                 }
577                         }
578
579                         _requested_return_frame = -1;
580
581                         if (do_locate) {
582                                 _engine.transport_locate (_transport_frame);
583                         }
584                 }
585
586         }
587
588         clear_clicks();
589
590         /* do this before seeking, because otherwise the tracks will do the wrong thing in seamless loop mode.
591         */
592
593         if (ptw & PostTransportClearSubstate) {
594                 _play_range = false;
595                 unset_play_loop ();
596         }
597
598         /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
599
600         DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
601         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
602                 DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
603                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
604                 if (tr && !tr->hidden()) {
605                         tr->non_realtime_locate (_transport_frame);
606                 }
607
608                 if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
609                         finished = false;
610                         /* we will be back */
611                         return;
612                 }
613         }
614
615         have_looped = false;
616
617         if (!_engine.freewheeling()) {
618                 send_full_time_code (_transport_frame);
619                 
620                 if (!dynamic_cast<MTC_Slave*>(_slave)) {
621                         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
622                         send_mmc_locate (_transport_frame);
623                 }
624         }
625
626         if ((ptw & PostTransportLocate) && get_record_enabled()) {
627                 /* capture start has been changed, so save pending state */
628                 save_state ("", true);
629                 saved = true;
630         }
631
632         /* always try to get rid of this */
633
634         remove_pending_capture_state ();
635
636         /* save the current state of things if appropriate */
637
638         if (did_record && !saved) {
639                 save_state (_current_snapshot_name);
640         }
641
642         if (ptw & PostTransportStop) {
643                 _play_range = false;
644                 play_loop = false;
645         }
646
647         PositionChanged (_transport_frame); /* EMIT SIGNAL */
648         TransportStateChange (); /* EMIT SIGNAL */
649
650         /* and start it up again if relevant */
651
652         if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
653                 request_transport_speed (1.0);
654                 pending_locate_roll = false;
655         }
656 }
657
658 void
659 Session::check_declick_out ()
660 {
661         bool locate_required = transport_sub_state & PendingLocate;
662
663         /* this is called after a process() iteration. if PendingDeclickOut was set,
664            it means that we were waiting to declick the output (which has just been
665            done) before maybe doing something else. this is where we do that "something else".
666
667            note: called from the audio thread.
668         */
669
670         if (transport_sub_state & PendingDeclickOut) {
671
672                 if (locate_required) {
673                         start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
674                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
675                 } else {
676                         stop_transport (pending_abort);
677                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
678                 }
679
680         } else if (transport_sub_state & PendingLoopDeclickOut) {
681                 /* Nothing else to do here; we've declicked, and the loop event will be along shortly */
682                 transport_sub_state &= ~PendingLoopDeclickOut;
683         }
684 }
685
686 void
687 Session::unset_play_loop ()
688 {
689         play_loop = false;
690         clear_events (SessionEvent::AutoLoop);
691         clear_events (SessionEvent::AutoLoopDeclick);
692
693         // set all tracks to NOT use internal looping
694         boost::shared_ptr<RouteList> rl = routes.reader ();
695         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
696                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
697                 if (tr && !tr->hidden()) {
698                         tr->set_loop (0);
699                 }
700         }
701 }
702
703 void
704 Session::set_play_loop (bool yn)
705 {
706         /* Called from event-handling context */
707
708         Location *loc;
709
710         if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
711                 /* nothing to do, or can't change loop status while recording */
712                 return;
713         }
714
715         if (yn && Config->get_seamless_loop() && synced_to_jack()) {
716                 warning << string_compose (
717                         _("Seamless looping cannot be supported while %1 is using JACK transport.\n"
718                           "Recommend changing the configured options"), PROGRAM_NAME)
719                         << endmsg;
720                 return;
721         }
722
723         if (yn) {
724
725                 play_loop = true;
726
727                 if (loc) {
728
729                         unset_play_range ();
730
731                         if (Config->get_seamless_loop()) {
732                                 // set all tracks to use internal looping
733                                 boost::shared_ptr<RouteList> rl = routes.reader ();
734                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
735                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
736                                         if (tr && !tr->hidden()) {
737                                                 tr->set_loop (loc);
738                                         }
739                                 }
740                         }
741                         else {
742                                 // set all tracks to NOT use internal looping
743                                 boost::shared_ptr<RouteList> rl = routes.reader ();
744                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
745                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
746                                         if (tr && !tr->hidden()) {
747                                                 tr->set_loop (0);
748                                         }
749                                 }
750                         }
751
752                         /* Put the delick and loop events in into the event list.  The declick event will
753                            cause a de-clicking fade-out just before the end of the loop, and it will also result
754                            in a fade-in when the loop restarts.  The AutoLoop event will peform the actual loop.
755                         */
756
757                         framepos_t dcp;
758                         framecnt_t dcl;
759                         auto_loop_declick_range (loc, dcp, dcl);
760                         merge_event (new SessionEvent (SessionEvent::AutoLoopDeclick, SessionEvent::Replace, dcp, dcl, 0.0f));
761                         merge_event (new SessionEvent (SessionEvent::AutoLoop, SessionEvent::Replace, loc->end(), loc->start(), 0.0f));
762
763                         /* locate to start of loop and roll. If doing seamless loop, force a
764                            locate+buffer refill even if we are positioned there already.
765                         */
766
767                         start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
768                 }
769
770         } else {
771
772                 unset_play_loop ();
773         }
774
775         TransportStateChange ();
776 }
777 void
778 Session::flush_all_inserts ()
779 {
780         boost::shared_ptr<RouteList> r = routes.reader ();
781
782         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
783                 (*i)->flush_processors ();
784         }
785 }
786
787 void
788 Session::start_locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
789 {
790         if (synced_to_jack()) {
791
792                 double sp;
793                 framepos_t pos;
794
795                 _slave->speed_and_position (sp, pos);
796
797                 if (target_frame != pos) {
798
799                         /* tell JACK to change transport position, and we will
800                            follow along later in ::follow_slave()
801                         */
802
803                         _engine.transport_locate (target_frame);
804
805                         if (sp != 1.0f && with_roll) {
806                                 _engine.transport_start ();
807                         }
808
809                 }
810
811         } else {
812                 locate (target_frame, with_roll, with_flush, with_loop, force);
813         }
814 }
815
816 int
817 Session::micro_locate (framecnt_t distance)
818 {
819         boost::shared_ptr<RouteList> rl = routes.reader();
820         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
821                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
822                 if (tr && !tr->can_internal_playback_seek (distance)) {
823                         return -1;
824                 }
825         }
826
827         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
828                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
829                 if (tr) {
830                         tr->internal_playback_seek (distance);
831                 }
832         }
833
834         _transport_frame += distance;
835         return 0;
836 }
837
838 /** @param with_mmc true to send a MMC locate command when the locate is done */
839 void
840 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force, bool with_mmc)
841 {
842         if (actively_recording() && !with_loop) {
843                 return;
844         }
845
846         if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
847                 if (with_roll) {
848                         set_transport_speed (1.0, false);
849                 }
850                 loop_changing = false;
851                 Located (); /* EMIT SIGNAL */
852                 return;
853         }
854
855         if (_transport_speed && !with_loop) {
856                 /* Schedule a declick.  We'll be called again when its done.
857                    We only do it this way for ordinary locates, not those
858                    due to loops.
859                 */
860
861                 if (!(transport_sub_state & PendingDeclickOut)) {
862                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
863                         pending_locate_frame = target_frame;
864                         pending_locate_roll = with_roll;
865                         pending_locate_flush = with_flush;
866                         return;
867                 }
868         }
869
870         // Update Timecode time
871         // [DR] FIXME: find out exactly where this should go below
872         _transport_frame = target_frame;
873         timecode_time(_transport_frame, transmitting_timecode_time);
874         outbound_mtc_timecode_frame = _transport_frame;
875         next_quarter_frame_to_send = 0;
876
877         /* do "stopped" stuff if:
878          *
879          * we are rolling AND
880          *    no autoplay in effect AND
881          *       we're not going to keep rolling after the locate AND
882          *           !(playing a loop with JACK sync)
883          *
884          */
885
886         if (transport_rolling() && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
887                 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
888         } else {
889                 /* otherwise tell the world that we located */
890                 realtime_locate ();
891         }
892
893         if (force || !with_loop || loop_changing) {
894
895                 PostTransportWork todo = PostTransportLocate;
896
897                 if (with_roll) {
898                         todo = PostTransportWork (todo | PostTransportRoll);
899                 }
900
901                 add_post_transport_work (todo);
902                 _butler->schedule_transport_work ();
903
904         } else {
905
906                 /* this is functionally what clear_clicks() does but with a tentative lock */
907
908                 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
909
910                 if (clickm.locked()) {
911
912                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
913                                 delete *i;
914                         }
915
916                         clicks.clear ();
917                 }
918         }
919
920         if (with_roll) {
921                 /* switch from input if we're going to roll */
922                 if (Config->get_monitoring_model() == HardwareMonitoring) {
923                         set_track_monitor_input_status (!config.get_auto_input());
924                 }
925         } else {
926                 /* otherwise we're going to stop, so do the opposite */
927                 if (Config->get_monitoring_model() == HardwareMonitoring) {
928                         set_track_monitor_input_status (true);
929                 }
930         }
931
932         /* cancel looped playback if transport pos outside of loop range */
933         if (play_loop) {
934                 Location* al = _locations->auto_loop_location();
935
936                 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
937                         // cancel looping directly, this is called from event handling context
938                         set_play_loop (false);
939                 }
940                 else if (al && _transport_frame == al->start()) {
941                         if (with_loop) {
942                                 // this is only necessary for seamless looping
943
944                                 boost::shared_ptr<RouteList> rl = routes.reader();
945                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
946                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
947                                         if (tr && tr->record_enabled ()) {
948                                                 // tell it we've looped, so it can deal with the record state
949                                                 tr->transport_looped(_transport_frame);
950                                         }
951                                 }
952                         }
953                         have_looped = true;
954                         TransportLooped(); // EMIT SIGNAL
955                 }
956         }
957
958         loop_changing = false;
959
960         _send_timecode_update = true;
961
962         if (with_mmc) {
963                 send_mmc_locate (_transport_frame);
964         }
965
966         Located (); /* EMIT SIGNAL */
967 }
968
969 /** Set the transport speed.
970  *  Called from the process thread.
971  *  @param speed New speed
972  */
973 void
974 Session::set_transport_speed (double speed, bool abort, bool clear_state)
975 {
976         DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4\n", 
977                                                        speed, abort, clear_state, _transport_speed, _transport_frame));
978
979         if (_transport_speed == speed) {
980                 return;
981         }
982
983         if (actively_recording() && speed != 1.0 && speed != 0.0) {
984                 /* no varispeed during recording */
985                 return;
986         }
987
988         _target_transport_speed = fabs(speed);
989
990         /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
991            and user needs. We really need CD-style "skip" playback for ffwd and rewind.
992         */
993
994         if (speed > 0) {
995                 speed = min (8.0, speed);
996         } else if (speed < 0) {
997                 speed = max (-8.0, speed);
998         }
999
1000         if (transport_rolling() && speed == 0.0) {
1001
1002                 /* we are rolling and we want to stop */
1003
1004                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1005                         set_track_monitor_input_status (true);
1006                 }
1007
1008                 if (synced_to_jack ()) {
1009                         if (clear_state) {
1010                                 /* do this here because our response to the slave won't
1011                                    take care of it.
1012                                 */
1013                                 _play_range = false;
1014                                 unset_play_loop ();
1015                         }
1016                         _engine.transport_stop ();
1017                 } else {
1018                         stop_transport (abort);
1019                 }
1020
1021                 unset_play_loop ();
1022
1023         } else if (transport_stopped() && speed == 1.0) {
1024
1025                 /* we are stopped and we want to start rolling at speed 1 */
1026
1027                 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1028                         set_track_monitor_input_status (false);
1029                 }
1030
1031                 if (synced_to_jack()) {
1032                         _engine.transport_start ();
1033                 } else {
1034                         start_transport ();
1035                 }
1036
1037         } else {
1038
1039                 /* not zero, not 1.0 ... varispeed */
1040
1041                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
1042                         warning << string_compose (
1043                                 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1044                                 PROGRAM_NAME)
1045                                 << endmsg;
1046                         return;
1047                 }
1048
1049                 if (actively_recording()) {
1050                         return;
1051                 }
1052
1053                 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1054                         return;
1055                 }
1056
1057                 if (speed < 0.0 && _transport_frame == 0) {
1058                         return;
1059                 }
1060
1061                 clear_clicks ();
1062
1063                 /* if we are reversing relative to the current speed, or relative to the speed
1064                    before the last stop, then we have to do extra work.
1065                 */
1066
1067                 PostTransportWork todo = PostTransportWork (0);
1068
1069                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1070                         todo = PostTransportWork (todo | PostTransportReverse);
1071                         _last_roll_or_reversal_location = _transport_frame;
1072                 }
1073
1074                 _last_transport_speed = _transport_speed;
1075                 _transport_speed = speed;
1076
1077                 boost::shared_ptr<RouteList> rl = routes.reader();
1078                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1079                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1080                         if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1081                                 todo = PostTransportWork (todo | PostTransportSpeed);
1082                         }
1083                 }
1084
1085                 if (todo) {
1086                         add_post_transport_work (todo);
1087                         _butler->schedule_transport_work ();
1088                 }
1089
1090                 TransportStateChange (); /* EMIT SIGNAL */
1091         }
1092 }
1093
1094
1095 /** Stop the transport.  */
1096 void
1097 Session::stop_transport (bool abort, bool clear_state)
1098 {
1099         if (_transport_speed == 0.0f) {
1100                 return;
1101         }
1102
1103         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && worst_input_latency() > current_block_size) {
1104
1105                 boost::shared_ptr<RouteList> rl = routes.reader();
1106                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1107                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1108                         if (tr) {
1109                                 tr->prepare_to_stop (_transport_frame);
1110                         }
1111                 }
1112
1113                 /* we need to capture the audio that has still not yet been received by the system
1114                    at the time the stop is requested, so we have to roll past that time.
1115
1116                    we want to declick before stopping, so schedule the autostop for one
1117                    block before the actual end. we'll declick in the subsequent block,
1118                    and then we'll really be stopped.
1119                 */
1120
1121                 DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 - %3 = %4, abort = %5\n",
1122                                                                _transport_frame, _worst_input_latency, current_block_size,
1123                                                                _transport_frame - _worst_input_latency - current_block_size,
1124                                                                abort));
1125
1126                 SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1127                                                      _transport_frame + _worst_input_latency - current_block_size,
1128                                                      0, 0, abort);
1129
1130                 merge_event (ev);
1131                 transport_sub_state |= StopPendingCapture;
1132                 pending_abort = abort;
1133                 return;
1134         }
1135
1136         if ((transport_sub_state & PendingDeclickOut) == 0) {
1137
1138                 if (!(transport_sub_state & StopPendingCapture)) {
1139                         boost::shared_ptr<RouteList> rl = routes.reader();
1140                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1141                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1142                                 if (tr) {
1143                                         tr->prepare_to_stop (_transport_frame);
1144                                 }
1145                         }
1146                 }
1147
1148                 transport_sub_state |= PendingDeclickOut;
1149                 /* we'll be called again after the declick */
1150                 pending_abort = abort;
1151                 return;
1152         }
1153
1154         realtime_stop (abort, clear_state);
1155         _butler->schedule_transport_work ();
1156 }
1157
1158 /** Called from the process thread */
1159 void
1160 Session::start_transport ()
1161 {
1162         DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1163
1164         _last_roll_location = _transport_frame;
1165         _last_roll_or_reversal_location = _transport_frame;
1166
1167         have_looped = false;
1168
1169         /* if record status is Enabled, move it to Recording. if its
1170            already Recording, move it to Disabled.
1171         */
1172
1173         switch (record_status()) {
1174         case Enabled:
1175                 if (!config.get_punch_in()) {
1176                         enable_record ();
1177                 }
1178                 break;
1179
1180         case Recording:
1181                 if (!play_loop) {
1182                         disable_record (false);
1183                 }
1184                 break;
1185
1186         default:
1187                 break;
1188         }
1189
1190         transport_sub_state |= PendingDeclickIn;
1191
1192         _transport_speed = 1.0;
1193         _target_transport_speed = 1.0;
1194
1195         boost::shared_ptr<RouteList> rl = routes.reader();
1196         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1197                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1198                 if (tr) {
1199                         tr->realtime_set_speed (tr->speed(), true);
1200                 }
1201                 (*i)->automation_snapshot (_transport_frame, true);
1202         }
1203
1204         if (!_engine.freewheeling()) {
1205                 Timecode::Time time;
1206                 timecode_time_subframes (_transport_frame, time);
1207                 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1208                         MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1209                 }
1210         }
1211
1212         TransportStateChange (); /* EMIT SIGNAL */
1213 }
1214
1215 /** Do any transport work in the audio thread that needs to be done after the
1216  * transport thread is finished.  Audio thread, realtime safe.
1217  */
1218 void
1219 Session::post_transport ()
1220 {
1221         PostTransportWork ptw = post_transport_work ();
1222
1223         if (ptw & PostTransportAudition) {
1224                 if (auditioner && auditioner->auditioning()) {
1225                         process_function = &Session::process_audition;
1226                 } else {
1227                         process_function = &Session::process_with_events;
1228                 }
1229         }
1230
1231         if (ptw & PostTransportStop) {
1232
1233                 transport_sub_state = 0;
1234         }
1235
1236         if (ptw & PostTransportLocate) {
1237
1238                 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1239                         start_transport ();
1240
1241                 } else {
1242                         transport_sub_state = 0;
1243                 }
1244         }
1245
1246         set_next_event ();
1247         /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1248            know were handled ?
1249         */
1250         set_post_transport_work (PostTransportWork (0));
1251 }
1252
1253 void
1254 Session::reset_rf_scale (framecnt_t motion)
1255 {
1256         cumulative_rf_motion += motion;
1257
1258         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1259                 rf_scale = 1;
1260         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1261                 rf_scale = 4;
1262         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1263                 rf_scale = 10;
1264         } else {
1265                 rf_scale = 100;
1266         }
1267
1268         if (motion != 0) {
1269                 set_dirty();
1270         }
1271 }
1272
1273 void
1274 Session::use_sync_source (Slave* new_slave)
1275 {
1276         /* Runs in process() context */
1277
1278         bool non_rt_required = false;
1279
1280         /* XXX this deletion is problematic because we're in RT context */
1281
1282         delete _slave;
1283         _slave = new_slave;
1284
1285         send_full_time_code (_transport_frame);
1286
1287         boost::shared_ptr<RouteList> rl = routes.reader();
1288         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1289                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1290                 if (tr && !tr->hidden()) {
1291                         if (tr->realtime_set_speed (tr->speed(), true)) {
1292                                 non_rt_required = true;
1293                         }
1294                         tr->set_slaved (_slave != 0);
1295                 }
1296         }
1297
1298         if (non_rt_required) {
1299                 add_post_transport_work (PostTransportSpeed);
1300                 _butler->schedule_transport_work ();
1301         }
1302
1303         set_dirty();
1304 }
1305
1306 void
1307 Session::drop_sync_source ()
1308 {
1309         request_sync_source (0);
1310 }
1311
1312 void
1313 Session::switch_to_sync_source (SyncSource src)
1314 {
1315         Slave* new_slave;
1316
1317         DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1318
1319         switch (src) {
1320         case MTC:
1321                 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1322                         return;
1323                 }
1324
1325                 try {
1326                         new_slave = new MTC_Slave (*this, *MIDI::Manager::instance()->mtc_input_port());
1327                 }
1328
1329                 catch (failed_constructor& err) {
1330                         return;
1331                 }
1332                 break;
1333
1334         case MIDIClock:
1335                 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1336                         return;
1337                 }
1338
1339                 try {
1340                         new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24);
1341                 }
1342
1343                 catch (failed_constructor& err) {
1344                         return;
1345                 }
1346                 break;
1347
1348         case JACK:
1349                 if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
1350                         return;
1351                 }
1352
1353                 if (config.get_video_pullup() != 0.0f) {
1354                         return;
1355                 }
1356
1357                 new_slave = new JACK_Slave (_engine.jack());
1358                 break;
1359
1360         default:
1361                 new_slave = 0;
1362                 break;
1363         };
1364
1365         request_sync_source (new_slave);
1366 }
1367
1368 void
1369 Session::set_track_speed (Track* track, double speed)
1370 {
1371         if (track->realtime_set_speed (speed, false)) {
1372                 add_post_transport_work (PostTransportSpeed);
1373                 _butler->schedule_transport_work ();
1374                 set_dirty ();
1375         }
1376 }
1377
1378 void
1379 Session::unset_play_range ()
1380 {
1381         _play_range = false;
1382         _clear_event_type (SessionEvent::RangeStop);
1383         _clear_event_type (SessionEvent::RangeLocate);
1384 }
1385
1386 void
1387 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1388 {
1389         SessionEvent* ev;
1390
1391         /* Called from event-processing context */
1392
1393         unset_play_range ();
1394
1395         if (range.empty()) {
1396                 /* _play_range set to false in unset_play_range()
1397                  */
1398                 if (!leave_rolling) {
1399                         /* stop transport */
1400                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1401                         merge_event (ev);
1402                 }
1403                 return;
1404         }
1405
1406         _play_range = true;
1407
1408         /* cancel loop play */
1409         unset_play_loop ();
1410
1411         list<AudioRange>::size_type sz = range.size();
1412
1413         if (sz > 1) {
1414
1415                 list<AudioRange>::iterator i = range.begin();
1416                 list<AudioRange>::iterator next;
1417
1418                 while (i != range.end()) {
1419
1420                         next = i;
1421                         ++next;
1422
1423                         /* locating/stopping is subject to delays for declicking.
1424                          */
1425
1426                         framepos_t requested_frame = i->end;
1427
1428                         if (requested_frame > current_block_size) {
1429                                 requested_frame -= current_block_size;
1430                         } else {
1431                                 requested_frame = 0;
1432                         }
1433
1434                         if (next == range.end()) {
1435                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1436                         } else {
1437                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1438                         }
1439
1440                         merge_event (ev);
1441
1442                         i = next;
1443                 }
1444
1445         } else if (sz == 1) {
1446
1447                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1448                 merge_event (ev);
1449
1450         }
1451
1452         /* save range so we can do auto-return etc. */
1453
1454         current_audio_range = range;
1455
1456         /* now start rolling at the right place */
1457
1458         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1459         merge_event (ev);
1460
1461         TransportStateChange ();
1462 }
1463
1464 void
1465 Session::request_bounded_roll (framepos_t start, framepos_t end)
1466 {
1467         AudioRange ar (start, end, 0);
1468         list<AudioRange> lar;
1469
1470         lar.push_back (ar);
1471         request_play_range (&lar, true);
1472 }
1473 void
1474 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1475 {
1476         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1477         ev->target2_frame = start;
1478         queue_event (ev);
1479 }
1480
1481 void
1482 Session::engine_halted ()
1483 {
1484         bool ignored;
1485
1486         /* there will be no more calls to process(), so
1487            we'd better clean up for ourselves, right now.
1488
1489            but first, make sure the butler is out of
1490            the picture.
1491         */
1492
1493         if (_butler) {
1494                 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1495                 set_post_transport_work (PostTransportWork (0));
1496                 _butler->stop ();
1497         }
1498
1499         realtime_stop (false, true);
1500         non_realtime_stop (false, 0, ignored);
1501         transport_sub_state = 0;
1502
1503         TransportStateChange (); /* EMIT SIGNAL */
1504 }
1505
1506
1507 void
1508 Session::xrun_recovery ()
1509 {
1510         Xrun (_transport_frame); /* EMIT SIGNAL */
1511
1512         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1513
1514                 /* it didn't actually halt, but we need
1515                    to handle things in the same way.
1516                 */
1517
1518                 engine_halted();
1519         }
1520 }
1521
1522 void
1523 Session::route_processors_changed (RouteProcessorChange c)
1524 {
1525         if (ignore_route_processor_changes) {
1526                 return;
1527         }
1528
1529         if (c.type == RouteProcessorChange::MeterPointChange) {
1530                 return;
1531         }
1532
1533         update_latency_compensation ();
1534         resort_routes ();
1535
1536         set_dirty ();
1537 }
1538
1539 void
1540 Session::allow_auto_play (bool yn)
1541 {
1542         auto_play_legal = yn;
1543 }
1544
1545 void
1546 Session::reset_jack_connection (jack_client_t* jack)
1547 {
1548         JACK_Slave* js;
1549
1550         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1551                 js->reset_client (jack);
1552         }
1553 }
1554
1555 bool
1556 Session::maybe_stop (framepos_t limit)
1557 {
1558         if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1559                 if (synced_to_jack () && config.get_jack_time_master ()) {
1560                         _engine.transport_stop ();
1561                 } else if (!synced_to_jack ()) {
1562                         stop_transport ();
1563                 }
1564                 return true;
1565         }
1566         return false;
1567 }
1568
1569 void
1570 Session::send_mmc_locate (framepos_t t)
1571 {
1572         if (!_engine.freewheeling()) {
1573                 Timecode::Time time;
1574                 timecode_time_subframes (t, time);
1575                 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
1576         }
1577 }
1578
1579 /** Ask the transport to not send timecode until further notice.  The suspension
1580  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1581  *  should be checked by the caller to find out when.
1582  */
1583 void
1584 Session::request_suspend_timecode_transmission ()
1585 {
1586         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1587         queue_event (ev);
1588 }
1589
1590 void
1591 Session::request_resume_timecode_transmission ()
1592 {
1593         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1594         queue_event (ev);
1595 }
1596
1597 bool
1598 Session::timecode_transmission_suspended () const
1599 {
1600         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1601 }