correctly set track loop status when locating away from loop range (and later, when...
[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                                         /* jump to start and then roll from there */
1176                                         request_locate (location->start(), true);
1177                                         return;
1178                                 }
1179                         }
1180                 }
1181
1182                 if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
1183                         set_track_monitor_input_status (false);
1184                 }
1185
1186                 if (synced_to_engine()) {
1187                         _engine.transport_start ();
1188                 } else {
1189                         start_transport ();
1190                 }
1191
1192         } else {
1193
1194                 /* not zero, not 1.0 ... varispeed */
1195
1196                 if ((synced_to_engine()) && speed != 0.0 && speed != 1.0) {
1197                         warning << string_compose (
1198                                 _("Global varispeed cannot be supported while %1 is connected to JACK transport control"),
1199                                 PROGRAM_NAME)
1200                                 << endmsg;
1201                         return;
1202                 }
1203
1204                 if (actively_recording()) {
1205                         return;
1206                 }
1207
1208                 if (speed > 0.0 && _transport_frame == current_end_frame()) {
1209                         return;
1210                 }
1211
1212                 if (speed < 0.0 && _transport_frame == 0) {
1213                         return;
1214                 }
1215
1216                 clear_clicks ();
1217
1218                 /* if we are reversing relative to the current speed, or relative to the speed
1219                    before the last stop, then we have to do extra work.
1220                 */
1221
1222                 PostTransportWork todo = PostTransportWork (0);
1223
1224                 if ((_transport_speed && speed * _transport_speed < 0.0) || (_last_transport_speed * speed < 0.0) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
1225                         todo = PostTransportWork (todo | PostTransportReverse);
1226                         _last_roll_or_reversal_location = _transport_frame;
1227                 }
1228
1229                 _last_transport_speed = _transport_speed;
1230                 _transport_speed = speed;
1231
1232                 if (as_default) {
1233                         _default_transport_speed = speed;
1234                 }
1235
1236                 boost::shared_ptr<RouteList> rl = routes.reader();
1237                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1238                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1239                         if (tr && tr->realtime_set_speed (tr->speed(), true)) {
1240                                 todo = PostTransportWork (todo | PostTransportSpeed);
1241                         }
1242                 }
1243
1244                 if (todo) {
1245                         add_post_transport_work (todo);
1246                         _butler->schedule_transport_work ();
1247                 }
1248
1249                 DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC3 with speed = %1\n", _transport_speed));
1250                 TransportStateChange (); /* EMIT SIGNAL */
1251         }
1252 }
1253
1254
1255 /** Stop the transport.  */
1256 void
1257 Session::stop_transport (bool abort, bool clear_state)
1258 {
1259         if (_transport_speed == 0.0f) {
1260                 return;
1261         }
1262
1263         if (!get_transport_declick_required()) {
1264
1265                 /* stop has not yet been scheduled */
1266
1267                 boost::shared_ptr<RouteList> rl = routes.reader();
1268                 framepos_t stop_target = audible_frame();
1269
1270                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1271                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1272                         if (tr) {
1273                                 tr->prepare_to_stop (_transport_frame, stop_target);
1274                         }
1275                 }
1276
1277                 SubState new_bits;
1278                 
1279                 if (actively_recording() &&                           /* we are recording */
1280                     worst_input_latency() > current_block_size) {     /* input latency exceeds block size, so simple 1 cycle delay before stop is not enough */
1281                         
1282                         /* we need to capture the audio that is still somewhere in the pipeline between
1283                            wherever it was generated and the process callback. This means that even though
1284                            the user (or something else)  has asked us to stop, we have to roll
1285                            past this point and then reset the playhead/transport location to
1286                            the position at which the stop was requested.
1287
1288                            we still need playback to "stop" now, however, which is why we schedule
1289                            a declick below.
1290                         */
1291                         
1292                         DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 = %3, abort = %4\n",
1293                                                                        _transport_frame, _worst_input_latency,
1294                                                                        _transport_frame + _worst_input_latency,
1295                                                                        abort));
1296                         
1297                         SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
1298                                                              _transport_frame + _worst_input_latency,
1299                                                              0, 0, abort);
1300                         
1301                         merge_event (ev);
1302
1303                         /* request a declick at the start of the next process cycle() so that playback ceases.
1304                            It will remain silent until we actually stop (at the StopOnce event somewhere in 
1305                            the future). The extra flag (StopPendingCapture) is set to ensure that check_declick_out()
1306                            does not stop the transport too early.
1307                          */
1308                         new_bits = SubState (PendingDeclickOut|StopPendingCapture);
1309                         
1310                 } else {
1311                         
1312                         /* Not recording, schedule a declick in the next process() cycle and then stop at its end */
1313                         
1314                         new_bits = PendingDeclickOut;
1315                 }
1316
1317                 
1318                 /* we'll be called again after the declick */
1319                 transport_sub_state = SubState (transport_sub_state|new_bits);
1320                 pending_abort = abort;
1321
1322                 return;
1323
1324         } else {
1325                 
1326                 /* declick was scheduled, but we've been called again, which means it is really time to stop
1327                    
1328                    XXX: we should probably split this off into its own method and call it explicitly.
1329                 */
1330
1331                 realtime_stop (abort, clear_state);
1332                 _butler->schedule_transport_work ();
1333         }
1334 }
1335
1336 /** Called from the process thread */
1337 void
1338 Session::start_transport ()
1339 {
1340         DEBUG_TRACE (DEBUG::Transport, "start_transport\n");
1341
1342         _last_roll_location = _transport_frame;
1343         _last_roll_or_reversal_location = _transport_frame;
1344
1345         have_looped = false;
1346
1347         /* if record status is Enabled, move it to Recording. if its
1348            already Recording, move it to Disabled.
1349         */
1350
1351         switch (record_status()) {
1352         case Enabled:
1353                 if (!config.get_punch_in()) {
1354                         enable_record ();
1355                 }
1356                 break;
1357
1358         case Recording:
1359                 if (!play_loop) {
1360                         disable_record (false);
1361                 }
1362                 break;
1363
1364         default:
1365                 break;
1366         }
1367
1368         transport_sub_state |= PendingDeclickIn;
1369
1370         _transport_speed = _default_transport_speed;
1371         _target_transport_speed = _transport_speed;
1372
1373         boost::shared_ptr<RouteList> rl = routes.reader();
1374         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1375                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1376                 if (tr) {
1377                         tr->realtime_set_speed (tr->speed(), true);
1378                 }
1379         }
1380
1381         if (!_engine.freewheeling()) {
1382                 Timecode::Time time;
1383                 timecode_time_subframes (_transport_frame, time);
1384                 if (!dynamic_cast<MTC_Slave*>(_slave)) {
1385                         send_immediate_mmc (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
1386                 }
1387         }
1388
1389         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC4 with speed = %1\n", _transport_speed));
1390         TransportStateChange (); /* EMIT SIGNAL */
1391 }
1392
1393 /** Do any transport work in the audio thread that needs to be done after the
1394  * transport thread is finished.  Audio thread, realtime safe.
1395  */
1396 void
1397 Session::post_transport ()
1398 {
1399         PostTransportWork ptw = post_transport_work ();
1400
1401         if (ptw & PostTransportAudition) {
1402                 if (auditioner && auditioner->auditioning()) {
1403                         process_function = &Session::process_audition;
1404                 } else {
1405                         process_function = &Session::process_with_events;
1406                 }
1407         }
1408
1409         if (ptw & PostTransportStop) {
1410
1411                 transport_sub_state = 0;
1412         }
1413
1414         if (ptw & PostTransportLocate) {
1415
1416                 if (((!config.get_external_sync() && (auto_play_legal && config.get_auto_play())) && !_exporting) || (ptw & PostTransportRoll)) {
1417                         start_transport ();
1418                 } else {
1419                         transport_sub_state = 0;
1420                 }
1421         }
1422
1423         set_next_event ();
1424         /* XXX is this really safe? shouldn't we just be unsetting the bits that we actually
1425            know were handled ?
1426         */
1427         set_post_transport_work (PostTransportWork (0));
1428 }
1429
1430 void
1431 Session::reset_rf_scale (framecnt_t motion)
1432 {
1433         cumulative_rf_motion += motion;
1434
1435         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1436                 rf_scale = 1;
1437         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1438                 rf_scale = 4;
1439         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1440                 rf_scale = 10;
1441         } else {
1442                 rf_scale = 100;
1443         }
1444
1445         if (motion != 0) {
1446                 set_dirty();
1447         }
1448 }
1449
1450 void
1451 Session::use_sync_source (Slave* new_slave)
1452 {
1453         /* Runs in process() context */
1454
1455         bool non_rt_required = false;
1456
1457         /* XXX this deletion is problematic because we're in RT context */
1458
1459         delete _slave;
1460         _slave = new_slave;
1461
1462         DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
1463         
1464         // need to queue this for next process() cycle
1465         _send_timecode_update = true;
1466
1467         boost::shared_ptr<RouteList> rl = routes.reader();
1468         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
1469                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
1470                 if (tr && !tr->hidden()) {
1471                         if (tr->realtime_set_speed (tr->speed(), true)) {
1472                                 non_rt_required = true;
1473                         }
1474                         tr->set_slaved (_slave != 0);
1475                 }
1476         }
1477
1478         if (non_rt_required) {
1479                 add_post_transport_work (PostTransportSpeed);
1480                 _butler->schedule_transport_work ();
1481         }
1482
1483         set_dirty();
1484 }
1485
1486 void
1487 Session::drop_sync_source ()
1488 {
1489         request_sync_source (0);
1490 }
1491
1492 void
1493 Session::switch_to_sync_source (SyncSource src)
1494 {
1495         Slave* new_slave;
1496
1497         DEBUG_TRACE (DEBUG::Slave, string_compose ("Setting up sync source %1\n", enum_2_string (src)));
1498
1499         switch (src) {
1500         case MTC:
1501                 if (_slave && dynamic_cast<MTC_Slave*>(_slave)) {
1502                         return;
1503                 }
1504
1505                 try {
1506                         new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
1507                 }
1508
1509                 catch (failed_constructor& err) {
1510                         return;
1511                 }
1512                 break;
1513
1514         case LTC:
1515                 if (_slave && dynamic_cast<LTC_Slave*>(_slave)) {
1516                         return;
1517                 }
1518
1519                 try {
1520                         new_slave = new LTC_Slave (*this);
1521                 }
1522
1523                 catch (failed_constructor& err) {
1524                         return;
1525                 }
1526
1527                 break;
1528
1529         case MIDIClock:
1530                 if (_slave && dynamic_cast<MIDIClock_Slave*>(_slave)) {
1531                         return;
1532                 }
1533
1534                 try {
1535                         new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
1536                 }
1537
1538                 catch (failed_constructor& err) {
1539                         return;
1540                 }
1541                 break;
1542
1543         case Engine:
1544                 if (_slave && dynamic_cast<Engine_Slave*>(_slave)) {
1545                         return;
1546                 }
1547
1548                 if (config.get_video_pullup() != 0.0f) {
1549                         return;
1550                 }
1551
1552                 new_slave = new Engine_Slave (*AudioEngine::instance());
1553                 break;
1554
1555         default:
1556                 new_slave = 0;
1557                 break;
1558         };
1559
1560         request_sync_source (new_slave);
1561 }
1562
1563 void
1564 Session::set_track_speed (Track* track, double speed)
1565 {
1566         if (track->realtime_set_speed (speed, false)) {
1567                 add_post_transport_work (PostTransportSpeed);
1568                 _butler->schedule_transport_work ();
1569                 set_dirty ();
1570         }
1571 }
1572
1573 void
1574 Session::unset_play_range ()
1575 {
1576         _play_range = false;
1577         _clear_event_type (SessionEvent::RangeStop);
1578         _clear_event_type (SessionEvent::RangeLocate);
1579 }
1580
1581 void
1582 Session::set_play_range (list<AudioRange>& range, bool leave_rolling)
1583 {
1584         SessionEvent* ev;
1585
1586         /* Called from event-processing context */
1587
1588         unset_play_range ();
1589
1590         if (range.empty()) {
1591                 /* _play_range set to false in unset_play_range()
1592                  */
1593                 if (!leave_rolling) {
1594                         /* stop transport */
1595                         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0f, false);
1596                         merge_event (ev);
1597                 }
1598                 return;
1599         }
1600
1601         _play_range = true;
1602
1603         /* cancel loop play */
1604         unset_play_loop ();
1605
1606         list<AudioRange>::size_type sz = range.size();
1607
1608         if (sz > 1) {
1609
1610                 list<AudioRange>::iterator i = range.begin();
1611                 list<AudioRange>::iterator next;
1612
1613                 while (i != range.end()) {
1614
1615                         next = i;
1616                         ++next;
1617
1618                         /* locating/stopping is subject to delays for declicking.
1619                          */
1620
1621                         framepos_t requested_frame = i->end;
1622
1623                         if (requested_frame > current_block_size) {
1624                                 requested_frame -= current_block_size;
1625                         } else {
1626                                 requested_frame = 0;
1627                         }
1628
1629                         if (next == range.end()) {
1630                                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, requested_frame, 0, 0.0f);
1631                         } else {
1632                                 ev = new SessionEvent (SessionEvent::RangeLocate, SessionEvent::Add, requested_frame, (*next).start, 0.0f);
1633                         }
1634
1635                         merge_event (ev);
1636
1637                         i = next;
1638                 }
1639
1640         } else if (sz == 1) {
1641
1642                 ev = new SessionEvent (SessionEvent::RangeStop, SessionEvent::Add, range.front().end, 0, 0.0f);
1643                 merge_event (ev);
1644
1645         }
1646
1647         /* save range so we can do auto-return etc. */
1648
1649         current_audio_range = range;
1650
1651         /* now start rolling at the right place */
1652
1653         ev = new SessionEvent (SessionEvent::LocateRoll, SessionEvent::Add, SessionEvent::Immediate, range.front().start, 0.0f, false);
1654         merge_event (ev);
1655
1656         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC5 with speed = %1\n", _transport_speed));
1657         TransportStateChange ();
1658 }
1659
1660 void
1661 Session::request_bounded_roll (framepos_t start, framepos_t end)
1662 {
1663         AudioRange ar (start, end, 0);
1664         list<AudioRange> lar;
1665
1666         lar.push_back (ar);
1667         request_play_range (&lar, true);
1668 }
1669
1670 void
1671 Session::set_requested_return_frame (framepos_t return_to)
1672 {
1673         _requested_return_frame = return_to;
1674 }
1675
1676 void
1677 Session::request_roll_at_and_return (framepos_t start, framepos_t return_to)
1678 {
1679         SessionEvent *ev = new SessionEvent (SessionEvent::LocateRollLocate, SessionEvent::Add, SessionEvent::Immediate, return_to, 1.0);
1680         ev->target2_frame = start;
1681         queue_event (ev);
1682 }
1683
1684 void
1685 Session::engine_halted ()
1686 {
1687         bool ignored;
1688
1689         /* there will be no more calls to process(), so
1690            we'd better clean up for ourselves, right now.
1691
1692            but first, make sure the butler is out of
1693            the picture.
1694         */
1695
1696         if (_butler) {
1697                 g_atomic_int_set (&_butler->should_do_transport_work, 0);
1698                 set_post_transport_work (PostTransportWork (0));
1699                 _butler->stop ();
1700         }
1701
1702         realtime_stop (false, true);
1703         non_realtime_stop (false, 0, ignored);
1704         transport_sub_state = 0;
1705
1706         DEBUG_TRACE (DEBUG::Transport, string_compose ("send TSC6 with speed = %1\n", _transport_speed));
1707         TransportStateChange (); /* EMIT SIGNAL */
1708 }
1709
1710
1711 void
1712 Session::xrun_recovery ()
1713 {
1714         Xrun (_transport_frame); /* EMIT SIGNAL */
1715
1716         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1717
1718                 /* it didn't actually halt, but we need
1719                    to handle things in the same way.
1720                 */
1721
1722                 engine_halted();
1723         }
1724 }
1725
1726 void
1727 Session::route_processors_changed (RouteProcessorChange c)
1728 {
1729         if (ignore_route_processor_changes) {
1730                 return;
1731         }
1732
1733         if (c.type == RouteProcessorChange::MeterPointChange) {
1734                 return;
1735         }
1736
1737         update_latency_compensation ();
1738         resort_routes ();
1739
1740         set_dirty ();
1741 }
1742
1743 void
1744 Session::allow_auto_play (bool yn)
1745 {
1746         auto_play_legal = yn;
1747 }
1748
1749 bool
1750 Session::maybe_stop (framepos_t limit)
1751 {
1752         if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1753                 if (synced_to_engine () && config.get_jack_time_master ()) {
1754                         _engine.transport_stop ();
1755                 } else if (!synced_to_engine ()) {
1756                         stop_transport ();
1757                 }
1758                 return true;
1759         }
1760         return false;
1761 }
1762
1763 void
1764 Session::send_mmc_locate (framepos_t t)
1765 {
1766         if (t < 0) {
1767                 return;
1768         }
1769
1770         if (!_engine.freewheeling()) {
1771                 Timecode::Time time;
1772                 timecode_time_subframes (t, time);
1773                 send_immediate_mmc (MIDI::MachineControlCommand (time));
1774         }
1775 }
1776
1777 /** Ask the transport to not send timecode until further notice.  The suspension
1778  *  will come into effect some finite time after this call, and timecode_transmission_suspended()
1779  *  should be checked by the caller to find out when.
1780  */
1781 void
1782 Session::request_suspend_timecode_transmission ()
1783 {
1784         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, false);
1785         queue_event (ev);
1786 }
1787
1788 void
1789 Session::request_resume_timecode_transmission ()
1790 {
1791         SessionEvent* ev = new SessionEvent (SessionEvent::SetTimecodeTransmission, SessionEvent::Add, SessionEvent::Immediate, 0, 0, true);
1792         queue_event (ev);
1793 }
1794
1795 bool
1796 Session::timecode_transmission_suspended () const
1797 {
1798         return g_atomic_int_get (&_suspend_timecode_transmission) == 1;
1799 }