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