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