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