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