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