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