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