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