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