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