do not start transport on first locate if auto-play is on; wait till GUI says its OK
[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
33 #include <midi++/mmc.h>
34 #include <midi++/port.h>
35
36 #include <ardour/ardour.h>
37 #include <ardour/audioengine.h>
38 #include <ardour/session.h>
39 #include <ardour/audio_diskstream.h>
40 #include <ardour/auditioner.h>
41 #include <ardour/slave.h>
42 #include <ardour/location.h>
43
44 #include "i18n.h"
45
46 using namespace std;
47 using namespace ARDOUR;
48 using namespace sigc;
49 using namespace PBD;
50
51 void
52 Session::request_input_change_handling ()
53 {
54         if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
55                 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
56                 queue_event (ev);
57         }
58 }
59
60 void
61 Session::request_slave_source (SlaveSource src)
62 {
63         Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
64
65         if (src == JACK) {
66                 /* could set_seamless_loop() be disposed of entirely?*/
67                 Config->set_seamless_loop (false);
68         } else {
69                 Config->set_seamless_loop (true);
70         }
71         ev->slave = src;
72         queue_event (ev);
73 }
74
75 void
76 Session::request_transport_speed (float speed)
77 {
78         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
79         queue_event (ev);
80 }
81
82 void
83 Session::request_diskstream_speed (Diskstream& ds, float speed)
84 {
85         Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
86         ev->set_ptr (&ds);
87         queue_event (ev);
88 }
89
90 void
91 Session::request_stop (bool abort)
92 {
93         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
94         queue_event (ev);
95 }
96
97 void
98 Session::request_locate (nframes_t target_frame, bool with_roll)
99 {
100         Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
101         queue_event (ev);
102 }
103
104 void
105 Session::force_locate (nframes_t target_frame, bool with_roll)
106 {
107         Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
108         queue_event (ev);
109 }
110
111 void
112 Session::request_play_loop (bool yn)
113 {
114         Event* ev;      
115         Location *location = _locations.auto_loop_location();
116
117         if (location == 0 && yn) {
118                 error << _("Cannot loop - no loop range defined")
119                       << endmsg;
120                 return;
121         }
122
123         ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
124         queue_event (ev);
125
126         if (!yn && Config->get_seamless_loop() && transport_rolling()) {
127                 // request an immediate locate to refresh the diskstreams
128                 // after disabling looping
129                 request_locate (_transport_frame-1, false);
130         }
131 }
132
133 void
134 Session::realtime_stop (bool abort)
135 {
136         /* assume that when we start, we'll be moving forwards */
137
138         if (_transport_speed < 0.0f) {
139                 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
140         } else {
141                 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
142         }
143
144         if (actively_recording()) {
145
146                 /* move the transport position back to where the
147                    request for a stop was noticed. we rolled
148                    past that point to pick up delayed input.
149                 */
150
151 #ifndef LEAVE_TRANSPORT_UNADJUSTED
152                 decrement_transport_position (_worst_output_latency);
153 #endif
154
155                 /* the duration change is not guaranteed to have happened, but is likely */
156
157                 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
158         }
159
160         if (abort) {
161                 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
162         }
163
164         _clear_event_type (Event::StopOnce);
165         _clear_event_type (Event::RangeStop);
166         _clear_event_type (Event::RangeLocate);
167
168         disable_record (true);
169
170         reset_slave_state ();
171                 
172         _transport_speed = 0;
173
174         if (Config->get_use_video_sync()) {
175                 waiting_for_sync_offset = true;
176         }
177
178         transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
179 }
180
181 void
182 Session::butler_transport_work ()
183 {
184   restart:
185         bool finished;
186         boost::shared_ptr<RouteList> r = routes.reader ();
187         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
188
189         int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
190         finished = true;
191
192         if (post_transport_work & PostTransportCurveRealloc) {
193                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
194                         (*i)->curve_reallocate();
195                 }
196         }
197
198         if (post_transport_work & PostTransportInputChange) {
199                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
200                         (*i)->non_realtime_input_change ();
201                 }
202         }
203
204         if (post_transport_work & PostTransportSpeed) {
205                 non_realtime_set_speed ();
206         }
207
208         if (post_transport_work & PostTransportReverse) {
209
210
211                 clear_clicks();
212                 cumulative_rf_motion = 0;
213                 reset_rf_scale (0);
214
215                 /* don't seek if locate will take care of that in non_realtime_stop() */
216
217                 if (!(post_transport_work & PostTransportLocate)) {
218                         
219                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
220                                 if (!(*i)->hidden()) {
221                                         if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
222                                                 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
223                                         }
224                                         else {
225                                                 (*i)->seek (_transport_frame);
226                                         }
227                                 }
228                                 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
229                                         /* new request, stop seeking, and start again */
230                                         g_atomic_int_dec_and_test (&butler_should_do_transport_work);
231                                         goto restart;
232                                 }
233                         }
234                 }
235         }
236
237         if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
238                 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
239                 if (!finished) {
240                         g_atomic_int_dec_and_test (&butler_should_do_transport_work);
241                         goto restart;
242                 }
243         }
244
245         if (post_transport_work & PostTransportOverWrite) {
246                 non_realtime_overwrite (on_entry, finished);
247                 if (!finished) {
248                         g_atomic_int_dec_and_test (&butler_should_do_transport_work);
249                         goto restart;
250                 }
251         }
252
253         if (post_transport_work & PostTransportAudition) {
254                 non_realtime_set_audition ();
255         }
256         
257         g_atomic_int_dec_and_test (&butler_should_do_transport_work);
258 }
259
260 void
261 Session::non_realtime_set_speed ()
262 {
263         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
264
265         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
266                 (*i)->non_realtime_set_speed ();
267         }
268 }
269
270 void
271 Session::non_realtime_overwrite (int on_entry, bool& finished)
272 {
273         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
274
275         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
276                 if ((*i)->pending_overwrite) {
277                         (*i)->overwrite_existing_buffers ();
278                 }
279                 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
280                         finished = false;
281                         return;
282                 }
283         }
284 }
285
286 void
287 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
288 {
289         struct tm* now;
290         time_t     xnow;
291         bool       did_record;
292         bool       saved;
293
294         did_record = false;
295         saved = false;
296
297         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
298         
299         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
300                 if ((*i)->get_captured_frames () != 0) {
301                         did_record = true;
302                         break;
303                 }
304         }
305
306         /* stop and locate are merged here because they share a lot of common stuff */
307         
308         time (&xnow);
309         now = localtime (&xnow);
310
311         if (auditioner) {
312                 auditioner->cancel_audition ();
313         }
314
315         clear_clicks();
316         cumulative_rf_motion = 0;
317         reset_rf_scale (0);
318
319         if (did_record) {
320                 begin_reversible_command ("capture");
321                 
322                 Location* loc = _locations.end_location();
323                 bool change_end = false;
324                 
325                 if (_transport_frame < loc->end()) {
326
327                         /* stopped recording before current end */
328
329                         if (_end_location_is_free) {
330
331                                 /* first capture for this session, move end back to where we are */
332
333                                 change_end = true;
334                         } 
335
336                 } else if (_transport_frame > loc->end()) {
337                         
338                         /* stopped recording after the current end, extend it */
339
340                         change_end = true;
341                 }
342                 
343                 if (change_end) {
344                         XMLNode &before = loc->get_state();
345                         loc->set_end(_transport_frame);
346                         XMLNode &after = loc->get_state();
347                         add_command (new MementoCommand<Location>(*loc, &before, &after));
348                 }
349
350                 _end_location_is_free = false;
351                 _have_captured = true;
352         }
353
354         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
355                 (*i)->transport_stopped (*now, xnow, abort);
356         }
357         
358         boost::shared_ptr<RouteList> r = routes.reader ();
359
360         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
361                 if (!(*i)->hidden()) {
362                         (*i)->set_pending_declick (0);
363                 }
364         }
365         
366         if (did_record) {
367                 commit_reversible_command ();
368         }       
369         
370         if (_engine.running()) {
371                 update_latency_compensation (true, abort);
372         }
373
374         if ((Config->get_slave_source() == None && Config->get_auto_return()) || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
375                 
376                 if (pending_locate_flush) {
377                         flush_all_redirects ();
378                 }
379                 
380                 if (((Config->get_slave_source() == None && Config->get_auto_return()) || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
381
382                         _transport_frame = last_stop_frame;
383
384                         if (synced_to_jack()) {
385                                 _engine.transport_locate (_transport_frame);
386                         }
387                 } 
388
389 #ifndef LEAVE_TRANSPORT_UNADJUSTED
390         }
391 #endif
392
393                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
394                         if (!(*i)->hidden()) {
395                                 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
396                                         (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
397                                 }
398                                 else {
399                                         (*i)->seek (_transport_frame);
400                                 }
401                         }
402                         if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
403                                 finished = false;
404                                 /* we will be back */
405                                 return;
406                         }
407                 }
408 #ifdef LEAVE_TRANSPORT_UNADJUSTED
409         }
410 #endif
411
412         last_stop_frame = _transport_frame;
413
414         send_full_time_code ();
415         deliver_mmc (MIDI::MachineControl::cmdStop, 0);
416         deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
417
418         if (did_record) {
419
420                 /* XXX its a little odd that we're doing this here
421                    when realtime_stop(), which has already executed,
422                    will have done this.
423                 */
424                 
425                 if (!Config->get_latched_record_enable()) {
426                         g_atomic_int_set (&_record_status, Disabled);
427                 } else {
428                         g_atomic_int_set (&_record_status, Enabled);
429                 }
430                 RecordStateChanged (); /* emit signal */
431         }
432         
433         if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
434                 /* capture start has been changed, so save pending state */
435                 save_state ("", true);
436                 saved = true;
437         }
438
439         /* always try to get rid of this */
440
441         remove_pending_capture_state ();
442         
443         /* save the current state of things if appropriate */
444
445         if (did_record && !saved) {
446                 save_state (_current_snapshot_name);
447         }
448
449         if (post_transport_work & PostTransportDuration) {
450                 DurationChanged (); /* EMIT SIGNAL */
451         }
452
453         if (post_transport_work & PostTransportStop) { 
454                 _play_range = false;
455
456                 /* do not turn off autoloop on stop */
457                 
458         }
459
460         PositionChanged (_transport_frame); /* EMIT SIGNAL */
461         TransportStateChange (); /* EMIT SIGNAL */
462
463         /* and start it up again if relevant */
464
465         if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
466                 request_transport_speed (1.0);
467                 pending_locate_roll = false;
468         }
469 }
470
471 void
472 Session::check_declick_out ()
473 {
474         bool locate_required = transport_sub_state & PendingLocate;
475
476         /* this is called after a process() iteration. if PendingDeclickOut was set,
477            it means that we were waiting to declick the output (which has just been
478            done) before doing something else. this is where we do that "something else".
479            
480            note: called from the audio thread.
481         */
482
483         if (transport_sub_state & PendingDeclickOut) {
484
485                 if (locate_required) {
486                         start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
487                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
488                 } else {
489                         stop_transport (pending_abort);
490                         transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
491                 }
492         }
493 }
494
495 void
496 Session::set_play_loop (bool yn)
497 {
498         /* Called from event-handling context */
499         
500         if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
501                 return;
502         }
503         
504         set_dirty();
505
506         if (yn && Config->get_seamless_loop() && synced_to_jack()) {
507                 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
508                              "Recommend changing the configured options")
509                         << endmsg;
510                 return;
511         }
512
513         
514         if ((play_loop = yn)) {
515
516                 Location *loc;
517
518                 
519                 if ((loc = _locations.auto_loop_location()) != 0) {
520
521                         if (Config->get_seamless_loop()) {
522                                 // set all diskstreams to use internal looping
523                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
524                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
525                                         if (!(*i)->hidden()) {
526                                                 (*i)->set_loop (loc);
527                                         }
528                                 }
529                         }
530                         else {
531                                 // set all diskstreams to NOT use internal looping
532                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
533                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
534                                         if (!(*i)->hidden()) {
535                                                 (*i)->set_loop (0);
536                                         }
537                                 }
538                         }
539                         
540                         /* stick in the loop event */
541                         
542                         Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
543                         merge_event (event);
544
545                         /* locate to start of loop and roll if current pos is outside of the loop range */
546                         if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
547                                 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
548                                 merge_event (event);
549                         }
550                         else {
551                                 // locate to current position (+ 1 to force reload)
552                                 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
553                                 merge_event (event);
554                         }
555                 }
556
557
558
559         } else {
560                 clear_events (Event::AutoLoop);
561
562                 // set all diskstreams to NOT use internal looping
563                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
564                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
565                         if (!(*i)->hidden()) {
566                                 (*i)->set_loop (0);
567                         }
568                 }
569                 
570         }
571 }
572
573 void
574 Session::flush_all_redirects ()
575 {
576         boost::shared_ptr<RouteList> r = routes.reader ();
577
578         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
579                 (*i)->flush_redirects ();
580         }
581 }
582
583 void
584 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
585 {
586         if (synced_to_jack()) {
587
588                 float sp;
589                 nframes_t pos;
590
591                 _slave->speed_and_position (sp, pos);
592
593                 if (target_frame != pos) {
594
595                         /* tell JACK to change transport position, and we will
596                            follow along later in ::follow_slave()
597                         */
598
599                         _engine.transport_locate (target_frame);
600
601                         if (sp != 1.0f && with_roll) {
602                                 _engine.transport_start ();
603                         }
604
605                 }
606
607         } else {
608
609                 locate (target_frame, with_roll, with_flush, with_loop);
610         }
611 }
612
613 void
614 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
615 {
616         if (actively_recording()) {
617                 return;
618         }
619
620         if (_transport_frame == target_frame && !loop_changing && !with_loop) {
621                 if (with_roll) {
622                         set_transport_speed (1.0, false);
623                 }
624                 loop_changing = false;
625                 return;
626         }
627
628         _transport_frame = target_frame;
629
630         if (_transport_speed && (!with_loop || loop_changing)) {
631                 /* schedule a declick. we'll be called again when its done */
632
633                 if (!(transport_sub_state & PendingDeclickOut)) {
634                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
635                         pending_locate_frame = target_frame;
636                         pending_locate_roll = with_roll;
637                         pending_locate_flush = with_flush;
638                         return;
639                 } 
640         }
641
642         if (transport_rolling() && (!auto_play_legal || Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
643                 realtime_stop (false);
644         } 
645
646         if ( !with_loop || loop_changing) {
647
648                 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
649                 
650                 if (with_roll) {
651                         post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
652                 }
653
654                 schedule_butler_transport_work ();
655
656         } else {
657
658                 /* this is functionally what clear_clicks() does but with a tentative lock */
659
660                 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
661         
662                 if (clickm.locked()) {
663                         
664                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
665                                 delete *i;
666                         }
667                 
668                         clicks.clear ();
669                 }
670         }
671
672         if (with_roll) {
673                 /* switch from input if we're going to roll */
674                 if (Config->get_monitoring_model() == HardwareMonitoring) {
675
676                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
677
678                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
679                                 if ((*i)->record_enabled ()) {
680                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
681                                         (*i)->monitor_input (!Config->get_auto_input());
682                                 }
683                         }
684                 }
685         } else {
686                 /* otherwise we're going to stop, so do the opposite */
687                 if (Config->get_monitoring_model() == HardwareMonitoring) {
688                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
689
690                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
691                                 if ((*i)->record_enabled ()) {
692                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
693                                         (*i)->monitor_input (true);
694                                 }
695                         }
696                 }
697         }
698
699         /* cancel looped playback if transport pos outside of loop range */
700         if (play_loop) {
701                 Location* al = _locations.auto_loop_location();
702                 
703                 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
704                         // cancel looping directly, this is called from event handling context
705                         set_play_loop (false);
706                 }
707         }
708         
709         loop_changing = false;
710 }
711
712 void
713 Session::set_transport_speed (float speed, bool abort)
714 {
715         if (_transport_speed == speed) {
716                 return;
717         }
718
719         if (speed > 0) {
720                 speed = min (8.0f, speed);
721         } else if (speed < 0) {
722                 speed = max (-8.0f, speed);
723         }
724
725         if (transport_rolling() && speed == 0.0) {
726
727                 if (Config->get_monitoring_model() == HardwareMonitoring)
728                 {
729                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
730
731                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
732                                 if ((*i)->record_enabled ()) {
733                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
734                                         (*i)->monitor_input (true);     
735                                 }
736                         }
737                 }
738
739                 if (synced_to_jack ()) {
740                         _engine.transport_stop ();
741                 } else {
742                         stop_transport (abort);
743                 }
744                 
745         } else if (transport_stopped() && speed == 1.0) {
746
747                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
748                         return;
749                 }
750
751                 if (Config->get_monitoring_model() == HardwareMonitoring) {
752
753                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
754
755                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
756                                 if (Config->get_auto_input() && (*i)->record_enabled ()) {
757                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
758                                         (*i)->monitor_input (false);    
759                                 }
760                         }
761                 }
762
763                 if (synced_to_jack()) {
764                         _engine.transport_start ();
765                 } else {
766                         start_transport ();
767                 }
768
769         } else {
770
771                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
772                         return;
773                 }
774
775                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
776                         warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
777                                 << endmsg;
778                         return;
779                 }
780
781                 if (actively_recording()) {
782                         return;
783                 }
784
785                 if (speed > 0.0f && _transport_frame == current_end_frame()) {
786                         return;
787                 }
788
789                 if (speed < 0.0f && _transport_frame == 0) {
790                         return;
791                 }
792                 
793                 clear_clicks ();
794
795                 /* if we are reversing relative to the current speed, or relative to the speed
796                    before the last stop, then we have to do extra work.
797                 */
798
799                 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
800                         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
801                 }
802                 
803                 _last_transport_speed = _transport_speed;
804                 _transport_speed = speed;
805                 
806                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
807                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
808                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
809                                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
810                         }
811                 }
812                 
813                 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
814                         schedule_butler_transport_work ();
815                 }
816         }
817 }
818
819 void
820 Session::stop_transport (bool abort)
821 {
822         if (_transport_speed == 0.0f) {
823                 return;
824         }
825         
826         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && 
827             _worst_output_latency > current_block_size) 
828         {
829                 
830                 /* we need to capture the audio that has still not yet been received by the system
831                    at the time the stop is requested, so we have to roll past that time.
832
833                    we want to declick before stopping, so schedule the autostop for one
834                    block before the actual end. we'll declick in the subsequent block,
835                    and then we'll really be stopped.
836                 */
837                 
838                 Event *ev = new Event (Event::StopOnce, Event::Replace, 
839                                        _transport_frame + _worst_output_latency - current_block_size,
840                                        0, 0, abort);
841                 
842                 merge_event (ev);
843                 transport_sub_state |= StopPendingCapture;
844                 pending_abort = abort;
845                 return;
846         } 
847
848
849         if ((transport_sub_state & PendingDeclickOut) == 0) {
850                 transport_sub_state |= PendingDeclickOut;
851                 /* we'll be called again after the declick */
852                 pending_abort = abort;
853                 return;
854         }
855
856         realtime_stop (abort);
857         schedule_butler_transport_work ();
858 }
859
860 void
861 Session::start_transport ()
862 {
863         _last_roll_location = _transport_frame;
864
865         /* if record status is Enabled, move it to Recording. if its
866            already Recording, move it to Disabled. 
867         */
868
869         switch (record_status()) {
870         case Enabled:
871                 if (!Config->get_punch_in()) {
872                         enable_record ();
873                 }
874                 break;
875
876         case Recording:
877                 disable_record (false);
878                 break;
879
880         default:
881                 break;
882         }
883
884         if (!synced_to_jack() || _exporting) {
885                 actually_start_transport ();
886         } else {
887                 waiting_to_start = true;
888         }
889 }
890
891 void
892 Session::actually_start_transport ()
893 {
894         waiting_to_start = false;
895
896         transport_sub_state |= PendingDeclickIn;
897         _transport_speed = 1.0;
898         
899         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
900         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
901                 (*i)->realtime_set_speed ((*i)->speed(), true);
902         }
903
904         send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
905         
906         TransportStateChange (); /* EMIT SIGNAL */
907 }
908
909 void
910 Session::post_transport ()
911 {
912         if (post_transport_work & PostTransportAudition) {
913                 if (auditioner && auditioner->active()) {
914                         process_function = &Session::process_audition;
915                 } else {
916                         process_function = &Session::process_with_events;
917                 }
918         }
919
920         if (post_transport_work & PostTransportStop) {
921
922                 transport_sub_state = 0;
923         }
924
925         if (post_transport_work & PostTransportLocate) {
926
927                 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
928                         start_transport ();
929                         
930                 } else {
931                         transport_sub_state = 0;
932                 }
933         }
934
935         set_next_event ();
936
937         post_transport_work = PostTransportWork (0);
938 }
939
940 void
941 Session::reset_rf_scale (nframes_t motion)
942 {
943         cumulative_rf_motion += motion;
944
945         if (cumulative_rf_motion < 4 * _current_frame_rate) {
946                 rf_scale = 1;
947         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
948                 rf_scale = 4;
949         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
950                 rf_scale = 10;
951         } else {
952                 rf_scale = 100;
953         }
954
955         if (motion != 0) {
956                 set_dirty();
957         }
958 }
959
960 void
961 Session::set_slave_source (SlaveSource src)
962 {
963         bool reverse = false;
964         bool non_rt_required = false;
965
966         if (_transport_speed) {
967                 error << _("please stop the transport before adjusting slave settings") << endmsg;
968                 return;
969         }
970
971 //      if (src == JACK && Config->get_jack_time_master()) {
972 //              return;
973 //      }
974         
975         if (_slave) {
976                 delete _slave;
977                 _slave = 0;
978         }
979
980         if (_transport_speed < 0.0) {
981                 reverse = true;
982         }
983
984         switch (src) {
985         case None:
986                 stop_transport ();
987                 break;
988                 
989         case MTC:
990                 if (_mtc_port) {
991                         try {
992                                 _slave = new MTC_Slave (*this, *_mtc_port);
993                         }
994
995                         catch (failed_constructor& err) {
996                                 return;
997                         }
998
999                 } else {
1000                         error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1001                         return;
1002                 }
1003                 _desired_transport_speed = _transport_speed;
1004                 break;
1005                 
1006         case JACK:
1007                 _slave = new JACK_Slave (_engine.jack());
1008                 _desired_transport_speed = _transport_speed;
1009                 break;
1010         };
1011
1012         Config->set_slave_source (src);
1013         
1014         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1015         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1016                 if (!(*i)->hidden()) {
1017                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1018                                 non_rt_required = true;
1019                         }
1020                         (*i)->set_slaved (_slave);
1021                 }
1022         }
1023
1024         if (reverse) {
1025                 reverse_diskstream_buffers ();
1026         }
1027
1028         if (non_rt_required) {
1029                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1030                 schedule_butler_transport_work ();
1031         }
1032
1033         set_dirty();
1034 }
1035
1036 void
1037 Session::reverse_diskstream_buffers ()
1038 {
1039         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1040         schedule_butler_transport_work ();
1041 }
1042
1043 void
1044 Session::set_diskstream_speed (Diskstream* stream, float speed)
1045 {
1046         if (stream->realtime_set_speed (speed, false)) {
1047                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1048                 schedule_butler_transport_work ();
1049                 set_dirty ();
1050         }
1051 }
1052
1053 void
1054 Session::set_audio_range (list<AudioRange>& range)
1055 {
1056         Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1057         ev->audio_range = range;
1058         queue_event (ev);
1059 }
1060
1061 void
1062 Session::request_play_range (bool yn)
1063 {
1064         Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1065         queue_event (ev);
1066 }
1067
1068 void
1069 Session::set_play_range (bool yn)
1070 {
1071         /* Called from event-processing context */
1072
1073         if (_play_range != yn) {
1074                 _play_range = yn;
1075                 setup_auto_play ();
1076
1077                 if (!_play_range) {
1078                         /* stop transport */
1079                         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1080                         merge_event (ev);
1081                 }
1082         }
1083 }
1084
1085 void
1086 Session::setup_auto_play ()
1087 {
1088         /* Called from event-processing context */
1089
1090         Event* ev;
1091         
1092         _clear_event_type (Event::RangeStop);
1093         _clear_event_type (Event::RangeLocate);
1094
1095         if (!_play_range) {
1096                 return;
1097         }
1098
1099         list<AudioRange>::size_type sz = current_audio_range.size();
1100         
1101         if (sz > 1) {
1102                 
1103                 list<AudioRange>::iterator i = current_audio_range.begin(); 
1104                 list<AudioRange>::iterator next;
1105                 
1106                 while (i != current_audio_range.end()) {
1107                         
1108                         next = i;
1109                         ++next;
1110                         
1111                         /* locating/stopping is subject to delays for declicking.
1112                          */
1113                         
1114                         nframes_t requested_frame = (*i).end;
1115                         
1116                         if (requested_frame > current_block_size) {
1117                                 requested_frame -= current_block_size;
1118                         } else {
1119                                 requested_frame = 0;
1120                         }
1121                         
1122                         if (next == current_audio_range.end()) {
1123                                 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1124                         } else {
1125                                 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1126                         }
1127                         
1128                         merge_event (ev);
1129                         
1130                         i = next;
1131                 }
1132                 
1133         } else if (sz == 1) {
1134                 
1135                 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1136                 merge_event (ev);
1137                 
1138         } 
1139
1140         /* now start rolling at the right place */
1141         
1142         ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1143         merge_event (ev);
1144 }
1145
1146 void
1147 Session::request_bounded_roll (nframes_t start, nframes_t end)
1148 {
1149         request_stop ();
1150         Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1151         queue_event (ev);
1152         request_locate (start, true);
1153 }
1154
1155 void
1156 Session::engine_halted ()
1157 {
1158         bool ignored;
1159
1160         /* there will be no more calls to process(), so
1161            we'd better clean up for ourselves, right now.
1162
1163            but first, make sure the butler is out of 
1164            the picture.
1165         */
1166
1167         g_atomic_int_set (&butler_should_do_transport_work, 0);
1168         post_transport_work = PostTransportWork (0);
1169         stop_butler ();
1170         
1171         realtime_stop (false);
1172         non_realtime_stop (false, 0, ignored);
1173         transport_sub_state = 0;
1174
1175         TransportStateChange (); /* EMIT SIGNAL */
1176 }
1177
1178
1179 void
1180 Session::xrun_recovery ()
1181 {
1182         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1183
1184                  HaltOnXrun (); /* EMIT SIGNAL */
1185
1186                 /* it didn't actually halt, but we need
1187                    to handle things in the same way.
1188                 */
1189
1190                 engine_halted();
1191         } 
1192 }
1193
1194 void
1195 Session::update_latency_compensation (bool with_stop, bool abort)
1196 {
1197         bool update_jack = false;
1198
1199         if (_state_of_the_state & Deletion) {
1200                 return;
1201         }
1202
1203         _worst_track_latency = 0;
1204
1205         boost::shared_ptr<RouteList> r = routes.reader ();
1206
1207         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1208                 if (with_stop) {
1209                         (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate), 
1210                                                         (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1211                 }
1212
1213                 nframes_t old_latency = (*i)->signal_latency ();
1214                 nframes_t track_latency = (*i)->update_total_latency ();
1215
1216                 if (old_latency != track_latency) {
1217                         update_jack = true;
1218                 }
1219                 
1220                 if (!(*i)->hidden() && ((*i)->active())) {
1221                         _worst_track_latency = max (_worst_track_latency, track_latency);
1222                 }
1223         }
1224
1225         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1226                 (*i)->set_latency_delay (_worst_track_latency);
1227         }
1228
1229         /* tell JACK to play catch up */
1230
1231         if (update_jack) {
1232                 _engine.update_total_latencies ();
1233         }
1234
1235         set_worst_io_latencies ();
1236
1237         /* reflect any changes in latencies into capture offsets
1238         */
1239         
1240         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1241
1242         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1243                 (*i)->set_capture_offset ();
1244         }
1245 }
1246
1247 void
1248 Session::update_latency_compensation_proxy (void* ignored)
1249 {
1250         update_latency_compensation (false, false);
1251 }
1252
1253 void
1254 Session::allow_auto_play (bool yn)
1255 {
1256         auto_play_legal = yn;
1257 }