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