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