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