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