2 Copyright (C) 1999-2009 Paul Davis
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.
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.
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.
24 #include <sigc++/bind.h>
25 #include <sigc++/retype.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>
34 #include <midi++/mmc.h>
35 #include <midi++/port.h>
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>
48 using namespace ARDOUR;
53 Session::request_input_change_handling ()
55 if (!(_state_of_the_state & (InitialConnecting|Deletion))) {
56 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
62 Session::request_slave_source (SlaveSource src)
64 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
67 seamless = Config->get_seamless_loop ();
70 /* JACK cannot support seamless looping at present */
71 Config->set_seamless_loop (false);
73 /* reset to whatever the value was before we last switched slaves */
74 Config->set_seamless_loop (_was_seamless);
77 /* save value of seamless from before the switch */
78 _was_seamless = seamless;
85 Session::request_transport_speed (float speed)
87 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
92 Session::request_diskstream_speed (Diskstream& ds, float speed)
94 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
100 Session::request_stop (bool abort, bool clear_state)
102 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort, clear_state);
107 Session::request_locate (nframes_t target_frame, bool with_roll)
109 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
114 Session::force_locate (nframes_t target_frame, bool with_roll)
116 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
121 Session::request_play_loop (bool yn, bool leave_rolling)
124 Location *location = _locations.auto_loop_location();
126 if (location == 0 && yn) {
127 error << _("Cannot loop - no loop range defined")
132 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
135 if (!leave_rolling && !yn && Config->get_seamless_loop() && transport_rolling()) {
136 // request an immediate locate to refresh the diskstreams
137 // after disabling looping
138 request_locate (_transport_frame-1, false);
143 Session::request_play_range (bool yn, bool leave_rolling)
145 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, (leave_rolling ? 1.0 : 0.0), yn);
150 Session::realtime_stop (bool abort, bool clear_state)
152 PostTransportWork todo = PostTransportWork (0);
154 /* assume that when we start, we'll be moving forwards */
156 if (_transport_speed < 0.0f) {
157 todo = PostTransportWork (todo | PostTransportStop | PostTransportReverse);
159 todo = PostTransportWork (todo | PostTransportStop);
162 if (actively_recording()) {
164 /* move the transport position back to where the
165 request for a stop was noticed. we rolled
166 past that point to pick up delayed input.
169 #ifndef LEAVE_TRANSPORT_UNADJUSTED
170 decrement_transport_position (_worst_output_latency);
173 /* the duration change is not guaranteed to have happened, but is likely */
175 todo = PostTransportWork (todo | PostTransportDuration);
179 todo = PostTransportWork (todo | PostTransportAbort);
183 todo = PostTransportWork (todo | PostTransportClearSubstate);
187 post_transport_work = PostTransportWork (post_transport_work | todo);
190 _clear_event_type (Event::StopOnce);
191 _clear_event_type (Event::RangeStop);
192 _clear_event_type (Event::RangeLocate);
194 disable_record (true);
196 reset_slave_state ();
198 _transport_speed = 0;
200 if (Config->get_use_video_sync()) {
201 waiting_for_sync_offset = true;
204 transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0);
208 Session::butler_transport_work ()
212 boost::shared_ptr<RouteList> r = routes.reader ();
213 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
215 int on_entry = g_atomic_int_get (&butler_should_do_transport_work);
218 if (post_transport_work & PostTransportCurveRealloc) {
219 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
220 (*i)->curve_reallocate();
224 if (post_transport_work & PostTransportInputChange) {
225 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
226 (*i)->non_realtime_input_change ();
230 if (post_transport_work & PostTransportSpeed) {
231 non_realtime_set_speed ();
234 if (post_transport_work & PostTransportReverse) {
237 cumulative_rf_motion = 0;
240 /* don't seek if locate will take care of that in non_realtime_stop() */
242 if (!(post_transport_work & PostTransportLocate)) {
244 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
245 if (!(*i)->hidden()) {
246 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
247 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
250 (*i)->seek (_transport_frame);
253 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
254 /* new request, stop seeking, and start again */
255 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
262 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
263 non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished);
265 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
270 if (post_transport_work & PostTransportOverWrite) {
271 non_realtime_overwrite (on_entry, finished);
273 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
278 if (post_transport_work & PostTransportAudition) {
279 non_realtime_set_audition ();
282 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
286 Session::non_realtime_set_speed ()
288 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
290 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
291 (*i)->non_realtime_set_speed ();
296 Session::non_realtime_overwrite (int on_entry, bool& finished)
298 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
300 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
301 if ((*i)->pending_overwrite) {
302 (*i)->overwrite_existing_buffers ();
304 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
312 Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
322 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
324 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
325 if ((*i)->get_captured_frames () != 0) {
331 /* stop and locate are merged here because they share a lot of common stuff */
334 now = localtime (&xnow);
337 auditioner->cancel_audition ();
341 cumulative_rf_motion = 0;
345 begin_reversible_command ("capture");
347 Location* loc = _locations.end_location();
348 bool change_end = false;
350 if (_transport_frame < loc->end()) {
352 /* stopped recording before current end */
354 if (_end_location_is_free) {
356 /* first capture for this session, move end back to where we are */
361 } else if (_transport_frame > loc->end()) {
363 /* stopped recording after the current end, extend it */
369 XMLNode &before = loc->get_state();
370 loc->set_end(_transport_frame);
371 XMLNode &after = loc->get_state();
372 add_command (new MementoCommand<Location>(*loc, &before, &after));
375 _end_location_is_free = false;
376 _have_captured = true;
379 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
380 (*i)->transport_stopped (*now, xnow, abort);
383 boost::shared_ptr<RouteList> r = routes.reader ();
385 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
386 if (!(*i)->hidden()) {
387 (*i)->set_pending_declick (0);
392 commit_reversible_command ();
395 if (_engine.running()) {
396 update_latency_compensation (true, abort);
399 if ((Config->get_slave_source() == None && Config->get_auto_return()) ||
400 (post_transport_work & PostTransportLocate) ||
401 (_requested_return_frame >= 0) ||
404 if (pending_locate_flush) {
405 flush_all_redirects ();
408 if (((Config->get_slave_source() == None && Config->get_auto_return()) ||
410 _requested_return_frame >= 0) &&
411 !(post_transport_work & PostTransportLocate)) {
413 /* no explicit locate queued */
415 bool do_locate = false;
417 if (_requested_return_frame >= 0) {
419 /* explicit return request pre-queued in event list. overrides everything else */
421 _transport_frame = _requested_return_frame;
425 if (Config->get_auto_return()) {
429 /* don't try to handle loop play when synced to JACK */
431 if (!synced_to_jack()) {
433 Location *location = _locations.auto_loop_location();
436 _transport_frame = location->start();
438 _transport_frame = _last_roll_location;
443 } else if (_play_range) {
445 /* return to start of range */
447 if (!current_audio_range.empty()) {
448 _transport_frame = current_audio_range.front().start;
454 /* regular auto-return */
456 _transport_frame = _last_roll_location;
462 _requested_return_frame = -1;
465 _engine.transport_locate (_transport_frame);
471 /* do this before seeking, because otherwise the Diskstreams will do the wrong thing in seamless loop mode.
474 if (post_transport_work & PostTransportClearSubstate) {
479 /* this for() block can be put inside the previous if() and has the effect of ... ??? what */
481 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
482 if (!(*i)->hidden()) {
483 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
484 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
487 (*i)->seek (_transport_frame);
490 if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) {
492 /* we will be back */
499 send_full_time_code ();
500 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
501 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
505 /* XXX its a little odd that we're doing this here
506 when realtime_stop(), which has already executed,
508 JLC - so let's not because it seems unnecessary and breaks loop record
511 if (!Config->get_latched_record_enable()) {
512 g_atomic_int_set (&_record_status, Disabled);
514 g_atomic_int_set (&_record_status, Enabled);
516 RecordStateChanged (); /* emit signal */
520 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
521 /* capture start has been changed, so save pending state */
522 save_state ("", true);
526 /* always try to get rid of this */
528 remove_pending_capture_state ();
530 /* save the current state of things if appropriate */
532 if (did_record && !saved) {
533 save_state (_current_snapshot_name);
536 if (post_transport_work & PostTransportDuration) {
537 DurationChanged (); /* EMIT SIGNAL */
540 nframes_t tf = _transport_frame;
542 PositionChanged (tf); /* EMIT SIGNAL */
543 TransportStateChange (); /* EMIT SIGNAL */
545 /* and start it up again if relevant */
547 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
548 request_transport_speed (1.0);
549 pending_locate_roll = false;
554 Session::check_declick_out ()
556 bool locate_required = transport_sub_state & PendingLocate;
558 /* this is called after a process() iteration. if PendingDeclickOut was set,
559 it means that we were waiting to declick the output (which has just been
560 done) before doing something else. this is where we do that "something else".
562 note: called from the audio thread.
565 if (transport_sub_state & PendingDeclickOut) {
567 if (locate_required) {
568 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
569 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
571 stop_transport (pending_abort, pending_clear_substate);
572 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
578 Session::unset_play_loop ()
581 clear_events (Event::AutoLoop);
583 // set all diskstreams to NOT use internal looping
584 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
585 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
586 if (!(*i)->hidden()) {
593 Session::set_play_loop (bool yn)
595 /* Called from event-handling context */
599 if (yn == play_loop || (actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
600 /* nothing to do, or can't change loop status while recording */
606 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
607 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
608 "Recommend changing the configured options")
619 set_play_range (false, true);
621 if (Config->get_seamless_loop()) {
622 // set all diskstreams to use internal looping
623 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
624 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
625 if (!(*i)->hidden()) {
626 (*i)->set_loop (loc);
631 // set all diskstreams to NOT use internal looping
632 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
633 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
634 if (!(*i)->hidden()) {
640 /* put the loop event into the event list */
642 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
645 /* locate to start of loop and roll. If doing seamless loop, force a
646 locate+buffer refill even if we are positioned there already.
649 start_locate (loc->start(), true, true, false, Config->get_seamless_loop());
657 TransportStateChange ();
661 Session::flush_all_redirects ()
663 boost::shared_ptr<RouteList> r = routes.reader ();
665 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
666 (*i)->flush_redirects ();
671 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
673 if (synced_to_jack()) {
678 _slave->speed_and_position (sp, pos);
680 if (target_frame != pos) {
682 /* tell JACK to change transport position, and we will
683 follow along later in ::follow_slave()
686 _engine.transport_locate (target_frame);
689 if (sp != 1.0f && with_roll) {
690 _engine.transport_start ();
695 locate (target_frame, with_roll, with_flush, with_loop, force);
700 Session::micro_locate (nframes_t distance)
702 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
704 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
705 if (!(*i)->can_internal_playback_seek (distance)) {
710 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
711 (*i)->internal_playback_seek (distance);
714 _transport_frame += distance;
719 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop, bool force)
721 if (actively_recording() && !with_loop) {
725 if (!force && _transport_frame == target_frame && !loop_changing && !with_loop) {
727 set_transport_speed (1.0, false);
729 loop_changing = false;
733 _transport_frame = target_frame;
735 if (_transport_speed && (!with_loop || loop_changing)) {
736 /* schedule a declick. we'll be called again when its done */
738 if (!(transport_sub_state & PendingDeclickOut)) {
739 transport_sub_state |= (PendingDeclickOut|PendingLocate);
740 pending_locate_frame = target_frame;
741 pending_locate_roll = with_roll;
742 pending_locate_flush = with_flush;
747 /* stop if we are rolling and we're not doing autoplay and we don't plan to roll when done and we not looping while synced to
751 if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) {
752 realtime_stop (false, true); // XXX paul - check if the 2nd arg is really correct
755 if (force || !with_loop || loop_changing) {
757 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
760 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
763 schedule_butler_transport_work ();
767 /* this is functionally what clear_clicks() does but with a tentative lock */
769 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
771 if (clickm.locked()) {
773 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
782 /* switch from input if we're going to roll */
783 if (Config->get_monitoring_model() == HardwareMonitoring) {
785 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
787 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
788 if ((*i)->record_enabled ()) {
789 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
790 (*i)->monitor_input (!Config->get_auto_input());
795 /* otherwise we're going to stop, so do the opposite */
796 if (Config->get_monitoring_model() == HardwareMonitoring) {
797 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
799 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
800 if ((*i)->record_enabled ()) {
801 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
802 (*i)->monitor_input (true);
808 /* cancel looped playback if transport pos outside of loop range */
810 Location* al = _locations.auto_loop_location();
812 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
813 // cancel looping directly, this is called from event handling context
814 set_play_loop (false);
816 else if (al && _transport_frame == al->start()) {
818 // this is only necessary for seamless looping
820 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
822 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
823 if ((*i)->record_enabled ()) {
824 // tell it we've looped, so it can deal with the record state
825 (*i)->transport_looped(_transport_frame);
830 TransportLooped(); // EMIT SIGNAL
834 loop_changing = false;
836 _send_smpte_update = true;
840 Session::set_transport_speed (float speed, bool abort, bool clear_state)
842 if (_transport_speed == speed) {
847 speed = min (8.0f, speed);
848 } else if (speed < 0) {
849 speed = max (-8.0f, speed);
852 if (transport_rolling() && speed == 0.0) {
854 if (Config->get_monitoring_model() == HardwareMonitoring)
856 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
858 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
859 if ((*i)->record_enabled ()) {
860 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
861 (*i)->monitor_input (true);
866 if (synced_to_jack ()) {
868 /* do this here because our response to the slave won't
874 _engine.transport_stop ();
876 stop_transport (abort, clear_state);
879 } else if (transport_stopped() && speed == 1.0) {
881 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
885 if (Config->get_monitoring_model() == HardwareMonitoring) {
887 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
889 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
890 if (Config->get_auto_input() && (*i)->record_enabled ()) {
891 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
892 (*i)->monitor_input (false);
897 if (synced_to_jack()) {
898 _engine.transport_start ();
905 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
909 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
910 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
915 if (actively_recording()) {
919 if (speed > 0.0f && _transport_frame == current_end_frame()) {
923 if (speed < 0.0f && _transport_frame == 0) {
929 /* if we are reversing relative to the current speed, or relative to the speed
930 before the last stop, then we have to do extra work.
933 PostTransportWork todo = PostTransportWork (0);
935 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) {
936 todo = PostTransportWork (todo | PostTransportReverse);
937 last_stop_frame = _transport_frame;
940 _last_transport_speed = _transport_speed;
941 _transport_speed = speed;
943 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
944 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
945 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
946 todo = PostTransportWork (todo | PostTransportSpeed);
952 post_transport_work = PostTransportWork (post_transport_work | todo);
953 schedule_butler_transport_work ();
959 Session::stop_transport (bool abort, bool clear_state)
961 if (_transport_speed == 0.0f) {
965 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
966 _worst_output_latency > current_block_size)
969 /* we need to capture the audio that has still not yet been received by the system
970 at the time the stop is requested, so we have to roll past that time.
972 we want to declick before stopping, so schedule the autostop for one
973 block before the actual end. we'll declick in the subsequent block,
974 and then we'll really be stopped.
977 Event *ev = new Event (Event::StopOnce, Event::Replace,
978 _transport_frame + _worst_output_latency - current_block_size,
982 transport_sub_state |= StopPendingCapture;
983 pending_abort = abort;
984 pending_clear_substate = clear_state;
988 if ((transport_sub_state & PendingDeclickOut) == 0) {
989 transport_sub_state |= PendingDeclickOut;
990 /* we'll be called again after the declick */
991 pending_abort = abort;
992 pending_clear_substate = clear_state;
996 realtime_stop (abort, clear_state);
997 schedule_butler_transport_work ();
1001 Session::start_transport ()
1003 _last_roll_location = _transport_frame;
1004 have_looped = false;
1006 /* if record status is Enabled, move it to Recording. if its
1007 already Recording, move it to Disabled.
1010 switch (record_status()) {
1012 if (!Config->get_punch_in()) {
1019 disable_record (false);
1027 transport_sub_state |= PendingDeclickIn;
1028 _transport_speed = 1.0;
1030 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1031 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1032 (*i)->realtime_set_speed ((*i)->speed(), true);
1035 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
1037 TransportStateChange (); /* EMIT SIGNAL */
1041 Session::post_transport ()
1043 if (post_transport_work & PostTransportAudition) {
1044 if (auditioner && auditioner->active()) {
1045 process_function = &Session::process_audition;
1047 process_function = &Session::process_with_events;
1051 if (post_transport_work & PostTransportStop) {
1053 transport_sub_state = 0;
1056 if (post_transport_work & PostTransportLocate) {
1058 if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) {
1062 transport_sub_state = 0;
1068 post_transport_work = PostTransportWork (0);
1072 Session::reset_rf_scale (nframes_t motion)
1074 cumulative_rf_motion += motion;
1076 if (cumulative_rf_motion < 4 * _current_frame_rate) {
1078 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
1080 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
1092 Session::set_slave_source (SlaveSource src, bool stop_the_transport)
1094 bool reverse = false;
1095 bool non_rt_required = false;
1097 if (_transport_speed) {
1098 error << _("please stop the transport before adjusting slave settings") << endmsg;
1102 // if (src == JACK && Config->get_jack_time_master()) {
1111 if (_transport_speed < 0.0) {
1117 if (stop_the_transport) {
1125 _slave = new MTC_Slave (*this, *_mtc_port);
1128 catch (failed_constructor& err) {
1133 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
1136 _desired_transport_speed = _transport_speed;
1140 _slave = new JACK_Slave (_engine.jack());
1141 _desired_transport_speed = _transport_speed;
1145 Config->set_slave_source (src);
1147 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1148 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1149 if (!(*i)->hidden()) {
1150 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1151 non_rt_required = true;
1153 (*i)->set_slaved (_slave);
1158 reverse_diskstream_buffers ();
1161 if (non_rt_required) {
1162 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1163 schedule_butler_transport_work ();
1170 Session::reverse_diskstream_buffers ()
1172 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1173 schedule_butler_transport_work ();
1177 Session::set_diskstream_speed (Diskstream* stream, float speed)
1179 if (stream->realtime_set_speed (speed, false)) {
1180 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1181 schedule_butler_transport_work ();
1187 Session::set_audio_range (list<AudioRange>& range)
1189 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1190 ev->audio_range = range;
1195 Session::set_play_range (bool yn, bool leave_rolling)
1197 /* Called from event-processing context */
1200 /* cancel loop play */
1208 if (!_play_range && !leave_rolling) {
1209 /* stop transport */
1210 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1214 TransportStateChange ();
1218 Session::request_bounded_roll (nframes_t start, nframes_t end)
1220 AudioRange ar (start, end, 0);
1221 list<AudioRange> lar;
1223 set_audio_range (lar);
1224 request_play_range (true, true);
1228 Session::setup_auto_play ()
1230 /* Called from event-processing context */
1234 _clear_event_type (Event::RangeStop);
1235 _clear_event_type (Event::RangeLocate);
1241 list<AudioRange>::size_type sz = current_audio_range.size();
1245 list<AudioRange>::iterator i = current_audio_range.begin();
1246 list<AudioRange>::iterator next;
1248 while (i != current_audio_range.end()) {
1253 /* locating/stopping is subject to delays for declicking.
1256 nframes_t requested_frame = (*i).end;
1258 if (requested_frame > current_block_size) {
1259 requested_frame -= current_block_size;
1261 requested_frame = 0;
1264 if (next == current_audio_range.end()) {
1265 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1267 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1275 } else if (sz == 1) {
1277 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1282 /* now start rolling at the right place */
1284 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1289 Session::request_roll_at_and_return (nframes_t start, nframes_t return_to)
1291 Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0);
1292 ev->target2_frame = start;
1297 Session::engine_halted ()
1301 /* there will be no more calls to process(), so
1302 we'd better clean up for ourselves, right now.
1304 but first, make sure the butler is out of
1308 g_atomic_int_set (&butler_should_do_transport_work, 0);
1309 post_transport_work = PostTransportWork (0);
1312 realtime_stop (false, true);
1313 non_realtime_stop (false, 0, ignored);
1314 transport_sub_state = 0;
1316 if (synced_to_jack()) {
1317 /* transport is already stopped, hence the second argument */
1318 set_slave_source (None, false);
1321 TransportStateChange (); /* EMIT SIGNAL */
1326 Session::xrun_recovery ()
1328 Xrun (transport_frame()); //EMIT SIGNAL
1330 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1332 /* it didn't actually halt, but we need
1333 to handle things in the same way.
1341 Session::update_latency_compensation (bool with_stop, bool abort)
1343 bool update_jack = false;
1345 if (_state_of_the_state & Deletion) {
1349 _worst_track_latency = 0;
1351 #undef DEBUG_LATENCY
1352 #ifdef DEBUG_LATENCY
1353 cerr << "\n---------------------------------\nUPDATE LATENCY\n";
1356 boost::shared_ptr<RouteList> r = routes.reader ();
1358 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1360 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1361 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1364 nframes_t old_latency = (*i)->signal_latency ();
1365 nframes_t track_latency = (*i)->update_total_latency ();
1367 if (old_latency != track_latency) {
1371 if (!(*i)->hidden() && ((*i)->active())) {
1372 _worst_track_latency = max (_worst_track_latency, track_latency);
1376 #ifdef DEBUG_LATENCY
1377 cerr << "\tworst was " << _worst_track_latency << endl;
1380 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1381 (*i)->set_latency_delay (_worst_track_latency);
1384 /* tell JACK to play catch up */
1387 _engine.update_total_latencies ();
1390 set_worst_io_latencies ();
1392 /* reflect any changes in latencies into capture offsets
1395 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1397 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1398 (*i)->set_capture_offset ();
1403 Session::update_latency_compensation_proxy (void* ignored)
1405 update_latency_compensation (false, false);
1409 Session::allow_auto_play (bool yn)
1411 auto_play_legal = yn;
1415 Session::reset_jack_connection (jack_client_t* jack)
1419 if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
1420 js->reset_client (jack);
1425 Session::maybe_stop (nframes_t limit)
1427 if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
1428 if (synced_to_jack () && Config->get_jack_time_master ()) {
1429 _engine.transport_stop ();
1430 } else if (!synced_to_jack ()) {