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