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