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