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