subtle changes to accomplish two goals (1) playhead should stop where the user presse...
[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 (synced_to_engine()) {
869
870                 double sp;
871                 framepos_t pos;
872
873                 _slave->speed_and_position (sp, pos);
874
875                 if (target_frame != pos) {
876
877                         if (config.get_jack_time_master()) {
878                                 /* actually locate now, since otherwise jack_timebase_callback
879                                    will use the incorrect _transport_frame and report an old
880                                    and incorrect time to Jack transport
881                                 */
882                                 locate (target_frame, with_roll, with_flush, with_loop, force);
883                         }
884
885                         /* tell JACK to change transport position, and we will
886                            follow along later in ::follow_slave()
887                         */
888
889                         _engine.transport_locate (target_frame);
890
891                         if (sp != 1.0f && with_roll) {
892                                 _engine.transport_start ();
893                         }
894
895                 }
896
897         } else {
898                 locate (target_frame, with_roll, with_flush, with_loop, force);
899         }
900 }
901
902 int
903 Session::micro_locate (framecnt_t distance)
904 {
905         boost::shared_ptr<RouteList> rl = routes.reader();
906         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
907                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
908                 if (tr && !tr->can_internal_playback_seek (distance)) {
909                         return -1;
910                 }
911         }
912
913         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
914                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
915                 if (tr) {
916                         tr->internal_playback_seek (distance);
917                 }
918         }
919
920         _transport_frame += distance;
921         return 0;
922 }
923
924 /** @param with_mmc true to send a MMC locate command when the locate is done */
925 void
926 Session::locate (framepos_t target_frame, bool with_roll, bool with_flush, bool for_seamless_loop, bool force, bool with_mmc)
927 {
928         /* Locates for seamless looping are fairly different from other
929          * locates. They assume that the diskstream buffers for each track
930          * already have the correct data in them, and thus there is no need to
931          * actually tell the tracks to locate. What does need to be done,
932          * though, is all the housekeeping that is associated with non-linear
933          * changes in the value of _transport_frame. 
934          */
935
936         if (actively_recording() && !for_seamless_loop) {
937                 return;
938         }
939
940         if (!force && _transport_frame == target_frame && !loop_changing && !for_seamless_loop) {
941                 if (with_roll) {
942                         set_transport_speed (1.0, 0, false);
943                 }
944                 loop_changing = false;
945                 Located (); /* EMIT SIGNAL */
946                 return;
947         }
948
949         if (_transport_speed && !for_seamless_loop) {
950                 /* Schedule a declick.  We'll be called again when its done.
951                    We only do it this way for ordinary locates, not those
952                    due to **seamless** loops.
953                 */
954
955                 if (!(transport_sub_state & PendingDeclickOut)) {
956                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
957                         pending_locate_frame = target_frame;
958                         pending_locate_roll = with_roll;
959                         pending_locate_flush = with_flush;
960                         return;
961                 }
962         }
963
964         // Update Timecode time
965         // [DR] FIXME: find out exactly where this should go below
966         _transport_frame = target_frame;
967         _last_roll_or_reversal_location = target_frame;
968         timecode_time(_transport_frame, transmitting_timecode_time);
969         outbound_mtc_timecode_frame = _transport_frame;
970         next_quarter_frame_to_send = 0;
971
972         /* do "stopped" stuff if:
973          *
974          * we are rolling AND
975          *    no autoplay in effect AND
976          *       we're not going to keep rolling after the locate AND
977          *           !(playing a loop with JACK sync)
978          *
979          */
980
981         bool transport_was_stopped = !transport_rolling();
982
983         if (transport_was_stopped && (!auto_play_legal || !config.get_auto_play()) && !with_roll && !(synced_to_engine() && play_loop)) {
984                 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
985                 transport_was_stopped = true;
986         } else {
987                 /* otherwise tell the world that we located */
988                 realtime_locate ();
989         }
990
991         if (force || !for_seamless_loop || loop_changing) {
992
993                 PostTransportWork todo = PostTransportLocate;
994
995                 if (with_roll && transport_was_stopped) {
996                         todo = PostTransportWork (todo | PostTransportRoll);
997                 }
998
999                 add_post_transport_work (todo);
1000                 _butler->schedule_transport_work ();
1001
1002         } else {
1003
1004                 /* this is functionally what clear_clicks() does but with a tentative lock */
1005
1006                 Glib::Threads::RWLock::WriterLock clickm (click_lock, Glib::Threads::TRY_LOCK);
1007
1008                 if (clickm.locked()) {
1009
1010                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
1011                                 delete *i;
1012                         }
1013
1014                         clicks.clear ();
1015                 }
1016         }
1017
1018         if (with_roll) {
1019                 /* switch from input if we're going to roll */
1020                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1021                         set_track_monitor_input_status (!config.get_auto_input());
1022                 }
1023         } else {
1024                 /* otherwise we're going to stop, so do the opposite */
1025                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1026                         set_track_monitor_input_status (true);
1027                 }
1028         }
1029
1030         /* cancel looped playback if transport pos outside of loop range */
1031         if (play_loop) {
1032
1033                 Location* al = _locations->auto_loop_location();
1034
1035                 if (al) {
1036                         if (_transport_frame < al->start() || _transport_frame > al->end()) {
1037
1038                                 // located outside the loop: cancel looping directly, this is called from event handling context
1039
1040                                 if (!Config->get_loop_is_mode()) {
1041                                         set_play_loop (false, _transport_speed);
1042                                 }
1043                                 
1044                         } else if (_transport_frame == al->start()) {
1045
1046                                 // located to start of loop - this is looping, basically
1047
1048                                 if (for_seamless_loop) {
1049
1050                                         // this is only necessary for seamless looping
1051                                         
1052                                         boost::shared_ptr<RouteList> rl = routes.reader();
1053
1054                                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1055                                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1056
1057                                                 if (tr && tr->record_enabled ()) {
1058                                                         // tell it we've looped, so it can deal with the record state
1059                                                         tr->transport_looped (_transport_frame);
1060                                                 }
1061                                         }
1062                                 }
1063
1064                                 have_looped = true;
1065                                 TransportLooped(); // EMIT SIGNAL
1066                         }
1067                 }
1068         }
1069
1070         loop_changing = false;
1071
1072         _send_timecode_update = true;
1073
1074         if (with_mmc) {
1075                 send_mmc_locate (_transport_frame);
1076         }
1077
1078         _last_roll_location = _last_roll_or_reversal_location =  _transport_frame;
1079         Located (); /* EMIT SIGNAL */
1080 }
1081
1082 /** Set the transport speed.
1083  *  Called from the process thread.
1084  *  @param speed New speed
1085  */
1086 void
1087 Session::set_transport_speed (double speed, framepos_t destination_frame, bool abort, bool clear_state, bool as_default)
1088 {
1089         DEBUG_TRACE (DEBUG::Transport, string_compose ("@ %5 Set transport speed to %1, abort = %2 clear_state = %3, current = %4 as_default %6\n", 
1090                                                        speed, abort, clear_state, _transport_speed, _transport_frame, as_default));
1091
1092         if (_transport_speed == speed) {
1093                 if (as_default && speed == 0.0) { // => reset default transport speed. hacky or what?
1094                         _default_transport_speed = 1.0;
1095                 }
1096                 return;
1097         }
1098
1099         if (actively_recording() && speed != 1.0 && speed != 0.0) {
1100                 /* no varispeed during recording */
1101                 DEBUG_TRACE (DEBUG::Transport, string_compose ("No varispeed during recording cur_speed %1, frame %2\n", 
1102                                                        _transport_speed, _transport_frame));
1103                 return;
1104         }
1105
1106         _target_transport_speed = fabs(speed);
1107
1108         /* 8.0 max speed is somewhat arbitrary but based on guestimates regarding disk i/o capability
1109            and user needs. We really need CD-style "skip" playback for ffwd and rewind.
1110         */
1111
1112         if (speed > 0) {
1113                 speed = min (8.0, speed);
1114         } else if (speed < 0) {
1115                 speed = max (-8.0, speed);
1116         }
1117
1118         if (transport_rolling() && speed == 0.0) {
1119
1120                 /* we are rolling and we want to stop */
1121
1122                 if (Config->get_monitoring_model() == HardwareMonitoring) {
1123                         set_track_monitor_input_status (true);
1124                 }
1125                 
1126                 if (synced_to_engine ()) {
1127                         if (clear_state) {
1128                                 /* do this here because our response to the slave won't
1129                                    take care of it.
1130                                 */
1131                                 _play_range = false;
1132                                 unset_play_loop ();
1133                         }
1134                         _engine.transport_stop ();
1135                 } else {
1136                         bool const auto_return_enabled = (!config.get_external_sync() && (config.get_auto_return() || abort));
1137
1138                         if (!auto_return_enabled) {
1139                                 _requested_return_frame = destination_frame;
1140                         }
1141
1142                         stop_transport (abort);
1143                 }
1144
1145                 if (!Config->get_loop_is_mode()) {
1146                         unset_play_loop ();
1147                 }
1148
1149         } else if (transport_stopped() && speed == 1.0) {
1150
1151                 /* we are stopped and we want to start rolling at speed 1 */
1152
1153                 if (Config->get_loop_is_mode() && play_loop) {
1154
1155                         Location *location = _locations->auto_loop_location();
1156                         
1157                         if (location != 0) {
1158                                 if (_transport_frame != location->start()) {
1159                                         /* jump to start and then roll from there */
1160                                         request_locate (location->start(), true);
1161                                         return;
1162                                 }
1163                         }
1164                 }
1165
1166                 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1167                         set_track_monitor_input_status (false);
1168                 }
1169
1170                 if (synced_to_engine()) {
1171                         _engine.transport_start ();
1172                 } else {
1173                         start_transport ();
1174                 }
1175
1176         } else {
1177
1178                 /* not zero, not 1.0 ... varispeed */
1179
1180                 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1181                         warning << string_compose (
1182                                 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1183                                 PROGRAM_NAME)
1184                                 << endmsg;
1185                         return;
1186                 }
1187
1188                 if (actively_recording()) {
1189                         return;
1190                 }
1191
1192                 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1193                         return;
1194                 }
1195
1196                 if (speed < 0.0 && _transport_frame == 0) {
1197                         return;
1198                 }
1199
1200                 clear_clicks ();
1201
1202                 /* if we are reversing relative to the current speed, or relative to the speed
1203                    before the last stop, then we have to do extra work.
1204                 */
1205
1206                 PostTransportWork todo = PostTransportWork (0);
1207
1208                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1209                         todo = PostTransportWork (todo | PostTransportReverse);
1210                         _last_roll_or_reversal_location = _transport_frame;
1211                 }
1212
1213                 _last_transport_speed = _transport_speed;
1214                 _transport_speed = speed;
1215
1216                 if (as_default) {
1217                         _default_transport_speed = speed;
1218                 }
1219
1220                 boost::shared_ptr<RouteList> rl = routes.reader();
1221                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1222                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1223                         if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1224                                 todo = PostTransportWork (todo | PostTransportSpeed);
1225                         }
1226                 }
1227
1228                 if (todo) {
1229                         add_post_transport_work (todo);
1230                         _butler->schedule_transport_work ();
1231                 }
1232
1233                 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1234                 TransportStateChange (); /* EMIT SIGNAL */
1235         }
1236 }
1237
1238
1239 /** Stop the transport.  */
1240 void
1241 Session::stop_transport (bool abort, bool clear_state)
1242 {
1243         if (_transport_speed == 0.0f) {
1244                 return;
1245         }
1246
1247         if (!get_transport_declick_required()) {
1248
1249                 /* stop has not yet been scheduled */
1250
1251                 boost::shared_ptr<RouteList> rl = routes.reader();
1252                 framepos_t stop_target = audible_frame();
1253
1254                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1255                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1256                         if (tr) {
1257                                 tr->prepare_to_stop (_transport_frame, stop_target);
1258                         }
1259                 }
1260
1261                 SubState new_bits;
1262                 
1263                 if (actively_recording() &&                           /* we are recording */
1264                     worst_input_latency() > current_block_size) {     /* input latency exceeds block size, so simple 1 cycle delay before stop is not enough */
1265                         
1266                         /* we need to capture the audio that is still somewhere in the pipeline between
1267                            wherever it was generated and the process callback. This means that even though
1268                            the user (or something else)  has asked us to stop, we have to roll
1269                            past this point and then reset the playhead/transport location to
1270                            the position at which the stop was requested.
1271
1272                            we still need playback to "stop" now, however, which is why we schedule
1273                            a declick below.
1274                         */
1275                         
1276                         DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 = %3, abort = %4\n",
1277                                                                        _transport_frame, _worst_input_latency,
1278                                                                        _transport_frame + _worst_input_latency,
1279                                                                        abort));
1280                         
1281                         SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1282                                                              _transport_frame + _worst_input_latency,
1283                                                              0, 0, abort);
1284                         
1285                         merge_event (ev);
1286
1287                         /* request a declick at the start of the next process cycle() so that playback ceases.
1288                            It will remain silent until we actually stop (at the StopOnce event somewhere in 
1289                            the future). The extra flag (StopPendingCapture) is set to ensure that check_declick_out()
1290                            does not stop the transport too early.
1291                          */
1292                         new_bits = SubState (PendingDeclickOut|StopPendingCapture);
1293                         
1294                 } else {
1295                         
1296                         /* Not recording, schedule a declick in the next process() cycle and then stop at its end */
1297                         
1298                         new_bits = PendingDeclickOut;
1299                 }
1300
1301                 
1302                 /* we'll be called again after the declick */
1303                 transport_sub_state = SubState (transport_sub_state|new_bits);
1304                 pending_abort = abort;
1305
1306                 return;
1307
1308         } else {
1309                 
1310                 /* declick was scheduled, but we've been called again, which means it is really time to stop
1311                    
1312                    XXX: we should probably split this off into its own method and call it explicitly.
1313                 */
1314
1315                 realtime_stop (abort, clear_state);
1316                 _butler->schedule_transport_work ();
1317         }
1318 }
1319
1320 /** Called from the process thread */
1321 void
1322 Session::start_transport ()
1323 {
1324         DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1325
1326         _last_roll_location = _transport_frame;
1327         _last_roll_or_reversal_location = _transport_frame;
1328
1329         have_looped = false;
1330
1331         /* if record status is Enabled, move it to Recording. if its
1332            already Recording, move it to Disabled.
1333         */
1334
1335         switch (record_status()) {
1336         case Enabled:
1337                 if (!config.get_punch_in()) {
1338                         enable_record ();
1339                 }
1340                 break;
1341
1342         case Recording:
1343                 if (!play_loop) {
1344                         disable_record (false);
1345                 }
1346                 break;
1347
1348         default:
1349                 break;
1350         }
1351
1352         transport_sub_state |= PendingDeclickIn;
1353
1354         _transport_speed = _default_transport_speed;
1355         _target_transport_speed = _transport_speed;
1356
1357         boost::shared_ptr<RouteList> rl = routes.reader();
1358         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1359                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1360                 if (tr) {
1361                         tr->realtime_set_speed (tr->speed(), true);
1362                 }
1363         }
1364
1365         if (!_engine.freewheeling()) {
1366                 Timecode::Time time;
1367                 timecode_time_subframes (_transport_frame, time);
1368                 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1369                         _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1370                 }
1371         }
1372
1373         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1374         TransportStateChange (); /* EMIT SIGNAL */
1375 }
1376
1377 /** Do any transport work in the audio thread that needs to be done after the
1378  * transport thread is finished.  Audio thread, realtime safe.
1379  */
1380 void
1381 Session::post_transport ()
1382 {
1383         PostTransportWork ptw = post_transport_work ();
1384
1385         if (ptw & PostTransportAudition) {
1386                 if (auditioner && auditioner->auditioning()) {
1387                         process_function = &Session::process_audition;
1388                 } else {
1389                         process_function = &Session::process_with_events;
1390                 }
1391         }
1392
1393         if (ptw & PostTransportStop) {
1394
1395                 transport_sub_state = 0;
1396         }
1397
1398         if (ptw & PostTransportLocate) {
1399
1400                 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1401                         start_transport ();
1402                 } else {
1403                         transport_sub_state = 0;
1404                 }
1405         }
1406
1407         set_next_event ();
1408         /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1409            know were handled ?
1410         */
1411         set_post_transport_work (PostTransportWork (0));
1412 }
1413
1414 void
1415 Session::reset_rf_scale (framecnt_t motion)
1416 {
1417         cumulative_rf_motion += motion;
1418
1419         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1420                 rf_scale = 1;
1421         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1422                 rf_scale = 4;
1423         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1424                 rf_scale = 10;
1425         } else {
1426                 rf_scale = 100;
1427         }
1428
1429         if (motion != 0) {
1430                 set_dirty();
1431         }
1432 }
1433
1434 void
1435 Session::use_sync_source (Slave* new_slave)
1436 {
1437         /* Runs in process() context */
1438
1439         bool non_rt_required = false;
1440
1441         /* XXX this deletion is problematic because we're in RT context */
1442
1443         delete _slave;
1444         _slave = new_slave;
1445
1446         DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1447         
1448         // need to queue this for next process() cycle
1449         _send_timecode_update = true;
1450
1451         boost::shared_ptr<RouteList> rl = routes.reader();
1452         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1453                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1454                 if (tr && !tr->hidden()) {
1455                         if (tr->realtime_set_speed (tr->speed(), true)) {
1456                                 non_rt_required = true;
1457                         }
1458                         tr->set_slaved (_slave != 0);
1459                 }
1460         }
1461
1462         if (non_rt_required) {
1463                 add_post_transport_work (PostTransportSpeed);
1464                 _butler->schedule_transport_work ();
1465         }
1466
1467         set_dirty();
1468 }
1469
1470 void
1471 Session::drop_sync_source ()
1472 {
1473         request_sync_source (0);
1474 }
1475
1476 void
1477 Session::switch_to_sync_source (SyncSource src)
1478 {
1479         Slave* new_slave;
1480
1481         DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1482
1483         switch (src) {
1484         case MTC:
1485                 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1486                         return;
1487                 }
1488
1489                 try {
1490                         new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
1491                 }
1492
1493                 catch (failed_constructor& err) {
1494                         return;
1495                 }
1496                 break;
1497
1498         case LTC:
1499                 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1500                         return;
1501                 }
1502
1503                 try {
1504                         new_slave = new LTC_Slave (*this);
1505                 }
1506
1507                 catch (failed_constructor& err) {
1508                         return;
1509                 }
1510
1511                 break;
1512
1513         case MIDIClock:
1514                 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1515                         return;
1516                 }
1517
1518                 try {
1519                         new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
1520                 }
1521
1522                 catch (failed_constructor& err) {
1523                         return;
1524                 }
1525                 break;
1526
1527         case Engine:
1528                 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1529                         return;
1530                 }
1531
1532                 if (config.get_video_pullup() != 0.0f) {
1533                         return;
1534                 }
1535
1536                 new_slave = new Engine_Slave (*AudioEngine::instance());
1537                 break;
1538
1539         default:
1540                 new_slave = 0;
1541                 break;
1542         };
1543
1544         request_sync_source (new_slave);
1545 }
1546
1547 void
1548 Session::set_track_speed (Track* track, double speed)
1549 {
1550         if (track->realtime_set_speed (speed, false)) {
1551                 add_post_transport_work (PostTransportSpeed);
1552                 _butler->schedule_transport_work ();
1553                 set_dirty ();
1554         }
1555 }
1556
1557 void
1558 Session::unset_play_range ()
1559 {
1560         _play_range = false;
1561         _clear_event_type (SessionEvent::RangeStop);
1562         _clear_event_type (SessionEvent::RangeLocate);
1563 }
1564
1565 void
1566 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1567 {
1568         SessionEvent* ev;
1569
1570         /* Called from event-processing context */
1571
1572         unset_play_range ();
1573
1574         if (range.empty()) {
1575                 /* _play_range set to false in unset_play_range()
1576                  */
1577                 if (!leave_rolling) {
1578                         /* stop transport */
1579                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1580                         merge_event (ev);
1581                 }
1582                 return;
1583         }
1584
1585         _play_range = true;
1586
1587         /* cancel loop play */
1588         unset_play_loop ();
1589
1590         list<AudioRange>::size_type sz = range.size();
1591
1592         if (sz > 1) {
1593
1594                 list<AudioRange>::iterator i = range.begin();
1595                 list<AudioRange>::iterator next;
1596
1597                 while (i != range.end()) {
1598
1599                         next = i;
1600                         ++next;
1601
1602                         /* locating/stopping is subject to delays for declicking.
1603                          */
1604
1605                         framepos_t requested_frame = i->end;
1606
1607                         if (requested_frame > current_block_size) {
1608                                 requested_frame -= current_block_size;
1609                         } else {
1610                                 requested_frame = 0;
1611                         }
1612
1613                         if (next == range.end()) {
1614                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1615                         } else {
1616                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1617                         }
1618
1619                         merge_event (ev);
1620
1621                         i = next;
1622                 }
1623
1624         } else if (sz == 1) {
1625
1626                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1627                 merge_event (ev);
1628
1629         }
1630
1631         /* save range so we can do auto-return etc. */
1632
1633         current_audio_range = range;
1634
1635         /* now start rolling at the right place */
1636
1637         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1638         merge_event (ev);
1639
1640         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1641         TransportStateChange ();
1642 }
1643
1644 void
1645 Session::request_bounded_roll (framepos_t start, framepos_t end)
1646 {
1647         AudioRange ar (start, end, 0);
1648         list<AudioRange> lar;
1649
1650         lar.push_back (ar);
1651         request_play_range (&lar, true);
1652 }
1653
1654 void
1655 Session::set_requested_return_frame (framepos_t return_to)
1656 {
1657         _requested_return_frame = return_to;
1658 }
1659
1660 void
1661 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1662 {
1663         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1664         ev->target2_frame = start;
1665         queue_event (ev);
1666 }
1667
1668 void
1669 Session::engine_halted ()
1670 {
1671         bool ignored;
1672
1673         /* there will be no more calls to process(), so
1674            we'd better clean up for ourselves, right now.
1675
1676            but first, make sure the butler is out of
1677            the picture.
1678         */
1679
1680         if (_butler) {
1681                 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1682                 set_post_transport_work (PostTransportWork (0));
1683                 _butler->stop ();
1684         }
1685
1686         realtime_stop (false, true);
1687         non_realtime_stop (false, 0, ignored);
1688         transport_sub_state = 0;
1689
1690         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
1691         TransportStateChange (); /* EMIT SIGNAL */
1692 }
1693
1694
1695 void
1696 Session::xrun_recovery ()
1697 {
1698         Xrun (_transport_frame); /* EMIT SIGNAL */
1699
1700         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1701
1702                 /* it didn't actually halt, but we need
1703                    to handle things in the same way.
1704                 */
1705
1706                 engine_halted();
1707         }
1708 }
1709
1710 void
1711 Session::route_processors_changed (RouteProcessorChange c)
1712 {
1713         if (ignore_route_processor_changes) {
1714                 return;
1715         }
1716
1717         if (c.type == RouteProcessorChange::MeterPointChange) {
1718                 return;
1719         }
1720
1721         update_latency_compensation ();
1722         resort_routes ();
1723
1724         set_dirty ();
1725 }
1726
1727 void
1728 Session::allow_auto_play (bool yn)
1729 {
1730         auto_play_legal = yn;
1731 }
1732
1733 bool
1734 Session::maybe_stop (framepos_t limit)
1735 {
1736         if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1737                 if (synced_to_engine () && config.get_jack_time_master ()) {
1738                         _engine.transport_stop ();
1739                 } else if (!synced_to_engine ()) {
1740                         stop_transport ();
1741                 }
1742                 return true;
1743         }
1744         return false;
1745 }
1746
1747 void
1748 Session::send_mmc_locate (framepos_t t)
1749 {
1750         if (!_engine.freewheeling()) {
1751                 Timecode::Time time;
1752                 timecode_time_subframes (t, time);
1753                 _mmc->send (MIDI::MachineControlCommand (time));
1754         }
1755 }
1756
1757 /** Ask the transport to not send timecode until further notice.  The suspension
1758  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1759  *  should be checked by the caller to find out when.
1760  */
1761 void
1762 Session::request_suspend_timecode_transmission ()
1763 {
1764         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1765         queue_event (ev);
1766 }
1767
1768 void
1769 Session::request_resume_timecode_transmission ()
1770 {
1771         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1772         queue_event (ev);
1773 }
1774
1775 bool
1776 Session::timecode_transmission_suspended () const
1777 {
1778         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1779 }