remove offset from process callback tree. some breakage may have occured. yes, really.
[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         } else {
647                 locate (target_frame, with_roll, with_flush, with_loop);
648         }
649
650         /* XXX: not sure if this should be emitted here in the synced_to_jack () case;
651          * perhaps it should happen when the slave is actually followed */
652         Located (); /* EMIT SIGNAL */
653 }
654
655 int
656 Session::micro_locate (nframes_t distance)
657 {
658         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
659         
660         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
661                 if (!(*i)->can_internal_playback_seek (distance)) {
662                         return -1;
663                 }
664         }
665
666         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
667                 (*i)->internal_playback_seek (distance);
668         }
669         
670         _transport_frame += distance;
671         return 0;
672 }
673
674 void
675 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
676 {
677         if (actively_recording() && !with_loop) {
678                 return;
679         }
680
681         if (_transport_frame == target_frame && !loop_changing && !with_loop) {
682                 if (with_roll) {
683                         set_transport_speed (1.0, false);
684                 }
685                 loop_changing = false;
686                 return;
687         }
688
689         // Update SMPTE time
690         // [DR] FIXME: find out exactly where this should go below
691         _transport_frame = target_frame;
692         smpte_time(_transport_frame, transmitting_smpte_time);
693         outbound_mtc_smpte_frame = _transport_frame;
694         next_quarter_frame_to_send = 0;
695
696         if (_transport_speed && (!with_loop || loop_changing)) {
697                 /* schedule a declick. we'll be called again when its done */
698
699                 if (!(transport_sub_state & PendingDeclickOut)) {
700                         transport_sub_state |= (PendingDeclickOut|PendingLocate);
701                         pending_locate_frame = target_frame;
702                         pending_locate_roll = with_roll;
703                         pending_locate_flush = with_flush;
704                         return;
705                 }
706         }
707
708         if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
709                 realtime_stop (false);
710         }
711
712         if ( !with_loop || loop_changing) {
713
714                 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
715
716                 if (with_roll) {
717                         post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
718                 }
719
720                 schedule_butler_transport_work ();
721
722         } else {
723
724                 /* this is functionally what clear_clicks() does but with a tentative lock */
725
726                 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
727
728                 if (clickm.locked()) {
729
730                         for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
731                                 delete *i;
732                         }
733
734                         clicks.clear ();
735                 }
736         }
737
738         if (with_roll) {
739                 /* switch from input if we're going to roll */
740                 if (Config->get_monitoring_model() == HardwareMonitoring) {
741
742                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
743
744                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
745                                 if ((*i)->record_enabled ()) {
746                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
747                                         (*i)->monitor_input (!Config->get_auto_input());
748                                 }
749                         }
750                 }
751         } else {
752                 /* otherwise we're going to stop, so do the opposite */
753                 if (Config->get_monitoring_model() == HardwareMonitoring) {
754                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
755
756                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
757                                 if ((*i)->record_enabled ()) {
758                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
759                                         (*i)->monitor_input (true);
760                                 }
761                         }
762                 }
763         }
764
765         /* cancel looped playback if transport pos outside of loop range */
766         if (play_loop) {
767                 Location* al = _locations.auto_loop_location();
768
769                 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
770                         // cancel looping directly, this is called from event handling context
771                         set_play_loop (false);
772                 }
773                 else if (al && _transport_frame == al->start()) {
774                         if (with_loop) {
775                                 // this is only necessary for seamless looping
776
777                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
778
779                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
780                                         if ((*i)->record_enabled ()) {
781                                                 // tell it we've looped, so it can deal with the record state
782                                                 (*i)->transport_looped(_transport_frame);
783                                         }
784                                 }
785                         }
786                         have_looped = true;
787                         TransportLooped(); // EMIT SIGNAL
788                 }
789         }
790
791         loop_changing = false;
792
793         _send_smpte_update = true;
794 }
795
796 /** Set the transport speed.
797  * @param speed New speed
798  * @param abort
799  */
800 void
801 Session::set_transport_speed (double speed, bool abort)
802 {
803         if (_transport_speed == speed) {
804                 return;
805         }
806
807         target_phi = (uint64_t) (0x1000000 * fabs(speed));
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_phi       = 0x1000000; // speed = 1
987         phi              = target_phi;
988         phase            = 0;
989
990         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
991         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
992                 (*i)->realtime_set_speed ((*i)->speed(), true);
993         }
994
995         deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
996
997         TransportStateChange (); /* EMIT SIGNAL */
998 }
999
1000 /** Do any transport work in the audio thread that needs to be done after the
1001  * transport thread is finished.  Audio thread, realtime safe.
1002  */
1003 void
1004 Session::post_transport ()
1005 {
1006         if (post_transport_work & PostTransportAudition) {
1007                 if (auditioner && auditioner->active()) {
1008                         process_function = &Session::process_audition;
1009                 } else {
1010                         process_function = &Session::process_with_events;
1011                 }
1012         }
1013
1014         if (post_transport_work & PostTransportStop) {
1015
1016                 transport_sub_state = 0;
1017         }
1018
1019         if (post_transport_work & PostTransportLocate) {
1020
1021                 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1022                         start_transport ();
1023
1024                 } else {
1025                         transport_sub_state = 0;
1026                 }
1027         }
1028
1029         set_next_event ();
1030
1031         post_transport_work = PostTransportWork (0);
1032 }
1033
1034 void
1035 Session::reset_rf_scale (nframes_t motion)
1036 {
1037         cumulative_rf_motion += motion;
1038
1039         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1040                 rf_scale = 1;
1041         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1042                 rf_scale = 4;
1043         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1044                 rf_scale = 10;
1045         } else {
1046                 rf_scale = 100;
1047         }
1048
1049         if (motion != 0) {
1050                 set_dirty();
1051         }
1052 }
1053
1054 void
1055 Session::set_slave_source (SlaveSource src)
1056 {
1057         bool reverse = false;
1058         bool non_rt_required = false;
1059
1060         if (_transport_speed) {
1061                 error << _("please stop the transport before adjusting slave settings") << endmsg;
1062                 return;
1063         }
1064
1065 //      if (src == JACK && Config->get_jack_time_master()) {
1066 //              return;
1067 //      }
1068
1069         delete _slave;
1070         _slave = 0;
1071
1072         if (_transport_speed < 0.0) {
1073                 reverse = true;
1074         }
1075
1076         switch (src) {
1077         case None:
1078                 stop_transport ();
1079                 break;
1080
1081         case MTC:
1082                 if (_mtc_port) {
1083                         try {
1084                                 _slave = new MTC_Slave (*this, *_mtc_port);
1085                         }
1086
1087                         catch (failed_constructor& err) {
1088                                 return;
1089                         }
1090
1091                 } else {
1092                         error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1093                         return;
1094                 }
1095                 break;
1096
1097         case MIDIClock:
1098                 if (_midi_clock_port) {
1099                         try {
1100                                 _slave = new MIDIClock_Slave (*this, *_midi_clock_port, 24);
1101                         }
1102
1103                         catch (failed_constructor& err) {
1104                                 return;
1105                         }
1106
1107                 } else {
1108                         error << _("No MIDI Clock port defined: MIDI Clock slaving is impossible.") << endmsg;
1109                         return;
1110                 }
1111                 break;
1112
1113         case JACK:
1114                 _slave = new JACK_Slave (_engine.jack());
1115                 break;
1116
1117         };
1118
1119         Config->set_slave_source (src);
1120
1121         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1122         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1123                 if (!(*i)->hidden()) {
1124                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1125                                 non_rt_required = true;
1126                         }
1127                         (*i)->set_slaved (_slave);
1128                 }
1129         }
1130
1131         if (reverse) {
1132                 reverse_diskstream_buffers ();
1133         }
1134
1135         if (non_rt_required) {
1136                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1137                 schedule_butler_transport_work ();
1138         }
1139
1140         set_dirty();
1141 }
1142
1143 void
1144 Session::reverse_diskstream_buffers ()
1145 {
1146         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1147         schedule_butler_transport_work ();
1148 }
1149
1150 void
1151 Session::set_diskstream_speed (Diskstream* stream, double speed)
1152 {
1153         if (stream->realtime_set_speed (speed, false)) {
1154                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1155                 schedule_butler_transport_work ();
1156                 set_dirty ();
1157         }
1158 }
1159
1160 void
1161 Session::set_audio_range (list<AudioRange>& range)
1162 {
1163         Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1164         ev->audio_range = range;
1165         queue_event (ev);
1166 }
1167
1168 void
1169 Session::request_play_range (bool yn)
1170 {
1171         Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1172         queue_event (ev);
1173 }
1174
1175 void
1176 Session::set_play_range (bool yn)
1177 {
1178         /* Called from event-processing context */
1179
1180         if (_play_range != yn) {
1181                 _play_range = yn;
1182                 setup_auto_play ();
1183
1184                 if (!_play_range) {
1185                         /* stop transport */
1186                         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1187                         merge_event (ev);
1188                 }
1189         }
1190 }
1191
1192 void
1193 Session::setup_auto_play ()
1194 {
1195         /* Called from event-processing context */
1196
1197         Event* ev;
1198
1199         _clear_event_type (Event::RangeStop);
1200         _clear_event_type (Event::RangeLocate);
1201
1202         if (!_play_range) {
1203                 return;
1204         }
1205
1206         list<AudioRange>::size_type sz = current_audio_range.size();
1207
1208         if (sz > 1) {
1209
1210                 list<AudioRange>::iterator i = current_audio_range.begin();
1211                 list<AudioRange>::iterator next;
1212
1213                 while (i != current_audio_range.end()) {
1214
1215                         next = i;
1216                         ++next;
1217
1218                         /* locating/stopping is subject to delays for declicking.
1219                          */
1220
1221                         nframes_t requested_frame = (*i).end;
1222
1223                         if (requested_frame > current_block_size) {
1224                                 requested_frame -= current_block_size;
1225                         } else {
1226                                 requested_frame = 0;
1227                         }
1228
1229                         if (next == current_audio_range.end()) {
1230                                 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1231                         } else {
1232                                 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1233                         }
1234
1235                         merge_event (ev);
1236
1237                         i = next;
1238                 }
1239
1240         } else if (sz == 1) {
1241
1242                 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1243                 merge_event (ev);
1244
1245         }
1246
1247         /* now start rolling at the right place */
1248
1249         ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1250         merge_event (ev);
1251 }
1252
1253 void
1254 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1255 {
1256         Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1257         ev->target2_frame = start;
1258         queue_event (ev);
1259 }
1260
1261 void
1262 Session::request_bounded_roll (nframes_t start, nframes_t end)
1263 {
1264         request_stop ();
1265         Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1266         queue_event (ev);
1267         request_locate (start, true);
1268 }
1269
1270 void
1271 Session::engine_halted ()
1272 {
1273         bool ignored;
1274
1275         /* there will be no more calls to process(), so
1276            we'd better clean up for ourselves, right now.
1277
1278            but first, make sure the butler is out of
1279            the picture.
1280         */
1281
1282         g_atomic_int_set (&butler_should_do_transport_work, 0);
1283         post_transport_work = PostTransportWork (0);
1284         stop_butler ();
1285
1286         realtime_stop (false);
1287         non_realtime_stop (false, 0, ignored);
1288         transport_sub_state = 0;
1289
1290         TransportStateChange (); /* EMIT SIGNAL */
1291 }
1292
1293
1294 void
1295 Session::xrun_recovery ()
1296 {
1297         Xrun (transport_frame()); //EMIT SIGNAL
1298
1299         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1300
1301                 /* it didn't actually halt, but we need
1302                    to handle things in the same way.
1303                 */
1304
1305                 engine_halted();
1306         }
1307 }
1308
1309 void
1310 Session::update_latency_compensation (bool with_stop, bool abort)
1311 {
1312         bool update_jack = false;
1313
1314         if (_state_of_the_state & Deletion) {
1315                 return;
1316         }
1317
1318         _worst_track_latency = 0;
1319
1320 #undef DEBUG_LATENCY
1321 #ifdef DEBUG_LATENCY
1322         cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1323 #endif
1324
1325         boost::shared_ptr<RouteList> r = routes.reader ();
1326
1327         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1328
1329                 if (with_stop) {
1330                         (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1331                                                         (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1332                 }
1333
1334                 nframes_t old_latency = (*i)->signal_latency ();
1335                 nframes_t track_latency = (*i)->update_total_latency ();
1336
1337                 if (old_latency != track_latency) {
1338                         (*i)->update_port_total_latencies ();
1339                         update_jack = true;
1340                 }
1341
1342                 if (!(*i)->is_hidden() && ((*i)->active())) {
1343                         _worst_track_latency = max (_worst_track_latency, track_latency);
1344                 }
1345         }
1346
1347         if (update_jack) {
1348                 _engine.update_total_latencies ();
1349         }
1350
1351 #ifdef DEBUG_LATENCY
1352         cerr << "\tworst was " << _worst_track_latency << endl;
1353 #endif
1354
1355         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1356                 (*i)->set_latency_delay (_worst_track_latency);
1357         }
1358
1359         set_worst_io_latencies ();
1360
1361         /* reflect any changes in latencies into capture offsets
1362         */
1363
1364         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1365
1366         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1367                 (*i)->set_capture_offset ();
1368         }
1369 }
1370
1371 void
1372 Session::allow_auto_play (bool yn)
1373 {
1374         auto_play_legal = yn;
1375 }
1376
1377 void
1378 Session::reset_jack_connection (jack_client_t* jack)
1379 {
1380         JACK_Slave* js;
1381
1382         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1383                 js->reset_client (jack);
1384         }
1385 }