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