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