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