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