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