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