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