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