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