ensure that the name used the control out IO for a route always uses the desired...
[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
778 void
779 Session::set_transport_speed (float speed, bool abort)
780 {
781         if (_transport_speed == speed) {
782                 return;
783         }
784
785         if (speed > 0) {
786                 speed = min (8.0f, speed);
787         } else if (speed < 0) {
788                 speed = max (-8.0f, speed);
789         }
790
791         if (transport_rolling() && speed == 0.0) {
792
793                 if (Config->get_monitoring_model() == HardwareMonitoring)
794                 {
795                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
796
797                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
798                                 if ((*i)->record_enabled ()) {
799                                         //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
800                                         (*i)->monitor_input (true);     
801                                 }
802                         }
803                 }
804
805                 if (synced_to_jack ()) {
806                         _engine.transport_stop ();
807                 } else {
808                         stop_transport (abort);
809                 }
810                 
811         } else if (transport_stopped() && speed == 1.0) {
812
813                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
814                         return;
815                 }
816
817                 if (Config->get_monitoring_model() == HardwareMonitoring) {
818
819                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
820
821                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
822                                 if (Config->get_auto_input() && (*i)->record_enabled ()) {
823                                         //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
824                                         (*i)->monitor_input (false);    
825                                 }
826                         }
827                 }
828
829                 if (synced_to_jack()) {
830                         _engine.transport_start ();
831                 } else {
832                         start_transport ();
833                 }
834
835         } else {
836
837                 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
838                         return;
839                 }
840
841                 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
842                         warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
843                                 << endmsg;
844                         return;
845                 }
846
847                 if (actively_recording()) {
848                         return;
849                 }
850
851                 if (speed > 0.0f && _transport_frame == current_end_frame()) {
852                         return;
853                 }
854
855                 if (speed < 0.0f && _transport_frame == 0) {
856                         return;
857                 }
858                 
859                 clear_clicks ();
860
861                 /* if we are reversing relative to the current speed, or relative to the speed
862                    before the last stop, then we have to do extra work.
863                 */
864
865                 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
866                         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
867                         last_stop_frame = _transport_frame;
868                 }
869                 
870                 _last_transport_speed = _transport_speed;
871                 _transport_speed = speed;
872                 
873                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
874                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
875                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
876                                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
877                         }
878                 }
879                 
880                 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
881                         schedule_butler_transport_work ();
882                 }
883         }
884 }
885
886 void
887 Session::stop_transport (bool abort)
888 {
889         if (_transport_speed == 0.0f) {
890                 return;
891         }
892         
893         if (actively_recording() && !(transport_sub_state & StopPendingCapture) && 
894             _worst_output_latency > current_block_size) 
895         {
896                 
897                 /* we need to capture the audio that has still not yet been received by the system
898                    at the time the stop is requested, so we have to roll past that time.
899
900                    we want to declick before stopping, so schedule the autostop for one
901                    block before the actual end. we'll declick in the subsequent block,
902                    and then we'll really be stopped.
903                 */
904                 
905                 Event *ev = new Event (Event::StopOnce, Event::Replace, 
906                                        _transport_frame + _worst_output_latency - current_block_size,
907                                        0, 0, abort);
908                 
909                 merge_event (ev);
910                 transport_sub_state |= StopPendingCapture;
911                 pending_abort = abort;
912                 return;
913         } 
914
915
916         if ((transport_sub_state & PendingDeclickOut) == 0) {
917                 transport_sub_state |= PendingDeclickOut;
918                 /* we'll be called again after the declick */
919                 pending_abort = abort;
920                 return;
921         }
922
923         realtime_stop (abort);
924         schedule_butler_transport_work ();
925 }
926
927 void
928 Session::start_transport ()
929 {
930         _last_roll_location = _transport_frame;
931         have_looped = false;
932
933         /* if record status is Enabled, move it to Recording. if its
934            already Recording, move it to Disabled. 
935         */
936
937         switch (record_status()) {
938         case Enabled:
939                 if (!Config->get_punch_in()) {
940                         enable_record ();
941                 }
942                 break;
943
944         case Recording:
945                 if (!play_loop) {
946                         disable_record (false);
947                 }
948                 break;
949
950         default:
951                 break;
952         }
953
954         transport_sub_state |= PendingDeclickIn;
955         _transport_speed = 1.0;
956         
957         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
958         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
959                 (*i)->realtime_set_speed ((*i)->speed(), true);
960         }
961
962         send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
963         
964         TransportStateChange (); /* EMIT SIGNAL */
965 }
966
967 void
968 Session::post_transport ()
969 {
970         if (post_transport_work & PostTransportAudition) {
971                 if (auditioner && auditioner->active()) {
972                         process_function = &Session::process_audition;
973                 } else {
974                         process_function = &Session::process_with_events;
975                 }
976         }
977
978         if (post_transport_work & PostTransportStop) {
979
980                 transport_sub_state = 0;
981         }
982
983         if (post_transport_work & PostTransportLocate) {
984
985                 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
986                         start_transport ();
987                         
988                 } else {
989                         transport_sub_state = 0;
990                 }
991         }
992
993         set_next_event ();
994
995         post_transport_work = PostTransportWork (0);
996 }
997
998 void
999 Session::reset_rf_scale (nframes_t motion)
1000 {
1001         cumulative_rf_motion += motion;
1002
1003         if (cumulative_rf_motion < 4 * _current_frame_rate) {
1004                 rf_scale = 1;
1005         } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1006                 rf_scale = 4;
1007         } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1008                 rf_scale = 10;
1009         } else {
1010                 rf_scale = 100;
1011         }
1012
1013         if (motion != 0) {
1014                 set_dirty();
1015         }
1016 }
1017
1018 void
1019 Session::set_slave_source (SlaveSource src)
1020 {
1021         bool reverse = false;
1022         bool non_rt_required = false;
1023
1024         if (_transport_speed) {
1025                 error << _("please stop the transport before adjusting slave settings") << endmsg;
1026                 return;
1027         }
1028
1029 //      if (src == JACK && Config->get_jack_time_master()) {
1030 //              return;
1031 //      }
1032         
1033         if (_slave) {
1034                 delete _slave;
1035                 _slave = 0;
1036         }
1037
1038         if (_transport_speed < 0.0) {
1039                 reverse = true;
1040         }
1041
1042         switch (src) {
1043         case None:
1044                 stop_transport ();
1045                 break;
1046                 
1047         case MTC:
1048                 if (_mtc_port) {
1049                         try {
1050                                 _slave = new MTC_Slave (*this, *_mtc_port);
1051                         }
1052
1053                         catch (failed_constructor& err) {
1054                                 return;
1055                         }
1056
1057                 } else {
1058                         error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1059                         return;
1060                 }
1061                 _desired_transport_speed = _transport_speed;
1062                 break;
1063                 
1064         case JACK:
1065                 _slave = new JACK_Slave (_engine.jack());
1066                 _desired_transport_speed = _transport_speed;
1067                 break;
1068         };
1069
1070         Config->set_slave_source (src);
1071         
1072         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1073         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1074                 if (!(*i)->hidden()) {
1075                         if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1076                                 non_rt_required = true;
1077                         }
1078                         (*i)->set_slaved (_slave);
1079                 }
1080         }
1081
1082         if (reverse) {
1083                 reverse_diskstream_buffers ();
1084         }
1085
1086         if (non_rt_required) {
1087                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1088                 schedule_butler_transport_work ();
1089         }
1090
1091         set_dirty();
1092 }
1093
1094 void
1095 Session::reverse_diskstream_buffers ()
1096 {
1097         post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1098         schedule_butler_transport_work ();
1099 }
1100
1101 void
1102 Session::set_diskstream_speed (Diskstream* stream, float speed)
1103 {
1104         if (stream->realtime_set_speed (speed, false)) {
1105                 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1106                 schedule_butler_transport_work ();
1107                 set_dirty ();
1108         }
1109 }
1110
1111 void
1112 Session::set_audio_range (list<AudioRange>& range)
1113 {
1114         Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1115         ev->audio_range = range;
1116         queue_event (ev);
1117 }
1118
1119 void
1120 Session::request_play_range (bool yn)
1121 {
1122         Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1123         queue_event (ev);
1124 }
1125
1126 void
1127 Session::set_play_range (bool yn)
1128 {
1129         /* Called from event-processing context */
1130
1131         if (_play_range != yn) {
1132                 _play_range = yn;
1133                 setup_auto_play ();
1134
1135                 if (!_play_range) {
1136                         /* stop transport */
1137                         Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1138                         merge_event (ev);
1139                 }
1140         }
1141 }
1142
1143 void
1144 Session::setup_auto_play ()
1145 {
1146         /* Called from event-processing context */
1147
1148         Event* ev;
1149         
1150         _clear_event_type (Event::RangeStop);
1151         _clear_event_type (Event::RangeLocate);
1152
1153         if (!_play_range) {
1154                 return;
1155         }
1156
1157         list<AudioRange>::size_type sz = current_audio_range.size();
1158         
1159         if (sz > 1) {
1160                 
1161                 list<AudioRange>::iterator i = current_audio_range.begin(); 
1162                 list<AudioRange>::iterator next;
1163                 
1164                 while (i != current_audio_range.end()) {
1165                         
1166                         next = i;
1167                         ++next;
1168                         
1169                         /* locating/stopping is subject to delays for declicking.
1170                          */
1171                         
1172                         nframes_t requested_frame = (*i).end;
1173                         
1174                         if (requested_frame > current_block_size) {
1175                                 requested_frame -= current_block_size;
1176                         } else {
1177                                 requested_frame = 0;
1178                         }
1179                         
1180                         if (next == current_audio_range.end()) {
1181                                 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1182                         } else {
1183                                 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1184                         }
1185                         
1186                         merge_event (ev);
1187                         
1188                         i = next;
1189                 }
1190                 
1191         } else if (sz == 1) {
1192                 
1193                 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1194                 merge_event (ev);
1195                 
1196         } 
1197
1198         /* now start rolling at the right place */
1199         
1200         ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1201         merge_event (ev);
1202 }
1203
1204 void
1205 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1206 {
1207         Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1208         ev->target2_frame = start;
1209         queue_event (ev);
1210 }
1211
1212 void
1213 Session::request_bounded_roll (nframes_t start, nframes_t end)
1214 {
1215         request_stop ();
1216         Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0);
1217         queue_event (ev);
1218         request_locate (start, true);
1219 }
1220
1221 void
1222 Session::engine_halted ()
1223 {
1224         bool ignored;
1225
1226         /* there will be no more calls to process(), so
1227            we'd better clean up for ourselves, right now.
1228
1229            but first, make sure the butler is out of 
1230            the picture.
1231         */
1232
1233         g_atomic_int_set (&butler_should_do_transport_work, 0);
1234         post_transport_work = PostTransportWork (0);
1235         stop_butler ();
1236         
1237         realtime_stop (false);
1238         non_realtime_stop (false, 0, ignored);
1239         transport_sub_state = 0;
1240
1241         TransportStateChange (); /* EMIT SIGNAL */
1242 }
1243
1244
1245 void
1246 Session::xrun_recovery ()
1247 {
1248         Xrun (transport_frame()); //EMIT SIGNAL
1249
1250         if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1251
1252                 /* it didn't actually halt, but we need
1253                    to handle things in the same way.
1254                 */
1255
1256                 engine_halted();
1257         } 
1258 }
1259
1260 void
1261 Session::update_latency_compensation (bool with_stop, bool abort)
1262 {
1263         bool update_jack = false;
1264
1265         if (_state_of_the_state & Deletion) {
1266                 return;
1267         }
1268
1269         _worst_track_latency = 0;
1270
1271 #undef DEBUG_LATENCY
1272 #ifdef DEBUG_LATENCY
1273         cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1274 #endif
1275
1276         boost::shared_ptr<RouteList> r = routes.reader ();
1277
1278         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1279                 if (with_stop) {
1280                         (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate), 
1281                                                         (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1282                 }
1283
1284                 nframes_t old_latency = (*i)->signal_latency ();
1285                 nframes_t track_latency = (*i)->update_total_latency ();
1286
1287                 if (old_latency != track_latency) {
1288                         update_jack = true;
1289                 }
1290                 
1291                 if (!(*i)->hidden() && ((*i)->active())) {
1292                         _worst_track_latency = max (_worst_track_latency, track_latency);
1293                 }
1294         }
1295
1296 #ifdef DEBUG_LATENCY
1297         cerr << "\tworst was " << _worst_track_latency << endl;
1298 #endif
1299
1300         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1301                 (*i)->set_latency_delay (_worst_track_latency);
1302         }
1303
1304         /* tell JACK to play catch up */
1305
1306         if (update_jack) {
1307                 _engine.update_total_latencies ();
1308         }
1309
1310         set_worst_io_latencies ();
1311
1312         /* reflect any changes in latencies into capture offsets
1313         */
1314         
1315         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1316
1317         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1318                 (*i)->set_capture_offset ();
1319         }
1320 }
1321
1322 void
1323 Session::update_latency_compensation_proxy (void* ignored)
1324 {
1325         update_latency_compensation (false, false);
1326 }
1327
1328 void
1329 Session::allow_auto_play (bool yn)
1330 {
1331         auto_play_legal = yn;
1332 }
1333
1334 void
1335 Session::reset_jack_connection (jack_client_t* jack)
1336 {
1337         JACK_Slave* js;
1338
1339         if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1340                 js->reset_client (jack);
1341         }
1342 }