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