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