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