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