2 Copyright (C) 1999-2003 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.
25 #include <sigc++/bind.h>
26 #include <sigc++/retype.h>
29 #include <pbd/error.h>
30 #include <glibmm/thread.h>
31 #include <pbd/pthread_utils.h>
32 #include <pbd/memento_command.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 Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0);
60 Session::request_slave_source (SlaveSource src)
62 Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0);
65 /* could set_seamless_loop() be disposed of entirely?*/
66 Config->set_seamless_loop (false);
68 Config->set_seamless_loop (true);
75 Session::request_transport_speed (float speed)
77 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed);
82 Session::request_diskstream_speed (Diskstream& ds, float speed)
84 Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
90 Session::request_stop (bool abort)
92 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort);
97 Session::request_locate (nframes_t target_frame, bool with_roll)
99 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false);
104 Session::force_locate (nframes_t target_frame, bool with_roll)
106 Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true);
111 Session::request_play_loop (bool yn)
114 Location *location = _locations.auto_loop_location();
116 if (location == 0 && yn) {
117 error << _("Cannot loop - no loop range defined")
122 ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn);
125 if (!yn && Config->get_seamless_loop() && transport_rolling()) {
126 // request an immediate locate to refresh the diskstreams
127 // after disabling looping
128 request_locate (_transport_frame-1, true);
133 Session::realtime_stop (bool abort)
135 /* assume that when we start, we'll be moving forwards */
137 // FIXME: where should this really be? [DR]
138 //send_full_time_code();
139 deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame);
140 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
142 if (_transport_speed < 0.0f) {
143 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
145 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
148 if (actively_recording()) {
150 /* move the transport position back to where the
151 request for a stop was noticed. we rolled
152 past that point to pick up delayed input.
155 #ifndef LEAVE_TRANSPORT_UNADJUSTED
156 decrement_transport_position (_worst_output_latency);
159 /* the duration change is not guaranteed to have happened, but is likely */
161 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
165 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
168 _clear_event_type (Event::StopOnce);
169 _clear_event_type (Event::RangeStop);
170 _clear_event_type (Event::RangeLocate);
172 disable_record (true);
174 reset_slave_state ();
176 _transport_speed = 0;
178 if (Config->get_use_video_sync()) {
179 waiting_for_sync_offset = true;
182 transport_sub_state = (Config->get_auto_return() ? AutoReturning : 0);
186 Session::butler_transport_work ()
188 boost::shared_ptr<RouteList> r = routes.reader ();
189 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
191 if (post_transport_work & PostTransportCurveRealloc) {
192 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
193 (*i)->curve_reallocate();
197 if (post_transport_work & PostTransportInputChange) {
198 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
199 (*i)->non_realtime_input_change ();
203 if (post_transport_work & PostTransportSpeed) {
204 non_realtime_set_speed ();
207 if (post_transport_work & PostTransportReverse) {
211 cumulative_rf_motion = 0;
214 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
215 if (!(*i)->hidden()) {
216 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
217 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
220 (*i)->seek (_transport_frame);
226 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
227 non_realtime_stop (post_transport_work & PostTransportAbort);
230 if (post_transport_work & PostTransportOverWrite) {
231 non_realtime_overwrite ();
234 if (post_transport_work & PostTransportAudition) {
235 non_realtime_set_audition ();
238 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
242 Session::non_realtime_set_speed ()
244 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
246 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
247 (*i)->non_realtime_set_speed ();
252 Session::non_realtime_overwrite ()
254 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
256 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
257 if ((*i)->pending_overwrite) {
258 (*i)->overwrite_existing_buffers ();
264 Session::non_realtime_stop (bool abort)
274 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
276 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
277 if ((*i)->get_captured_frames () != 0) {
283 /* stop and locate are merged here because they share a lot of common stuff */
286 now = localtime (&xnow);
289 auditioner->cancel_audition ();
293 cumulative_rf_motion = 0;
297 begin_reversible_command ("capture");
299 Location* loc = _locations.end_location();
300 bool change_end = false;
302 if (_transport_frame < loc->end()) {
304 /* stopped recording before current end */
306 if (_end_location_is_free) {
308 /* first capture for this session, move end back to where we are */
313 } else if (_transport_frame > loc->end()) {
315 /* stopped recording after the current end, extend it */
321 XMLNode &before = loc->get_state();
322 loc->set_end(_transport_frame);
323 XMLNode &after = loc->get_state();
324 add_command (new MementoCommand<Location>(*loc, &before, &after));
327 _end_location_is_free = false;
328 _have_captured = true;
331 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
332 (*i)->transport_stopped (*now, xnow, abort);
335 boost::shared_ptr<RouteList> r = routes.reader ();
337 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
338 if (!(*i)->hidden()) {
339 (*i)->set_pending_declick (0);
344 commit_reversible_command ();
347 if (_engine.running()) {
348 update_latency_compensation (true, abort);
351 if (Config->get_auto_return() || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
353 if (pending_locate_flush) {
354 flush_all_redirects ();
357 if ((Config->get_auto_return() || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
359 _transport_frame = last_stop_frame;
361 if (synced_to_jack()) {
362 _engine.transport_locate (_transport_frame);
366 #ifndef LEAVE_TRANSPORT_UNADJUSTED
370 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
371 if (!(*i)->hidden()) {
372 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
373 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
376 (*i)->seek (_transport_frame);
382 //deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
384 #ifdef LEAVE_TRANSPORT_UNADJUSTED
388 last_stop_frame = _transport_frame;
392 /* XXX its a little odd that we're doing this here
393 when realtime_stop(), which has already executed,
397 if (!Config->get_latched_record_enable()) {
398 g_atomic_int_set (&_record_status, Disabled);
400 g_atomic_int_set (&_record_status, Enabled);
402 RecordStateChanged (); /* emit signal */
405 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
406 /* capture start has been changed, so save pending state */
407 save_state ("", true);
411 /* always try to get rid of this */
413 remove_pending_capture_state ();
415 /* save the current state of things if appropriate */
417 if (did_record && !saved) {
418 save_state (_current_snapshot_name);
421 if (post_transport_work & PostTransportDuration) {
422 DurationChanged (); /* EMIT SIGNAL */
425 if (post_transport_work & PostTransportStop) {
428 /* do not turn off autoloop on stop */
432 PositionChanged (_transport_frame); /* EMIT SIGNAL */
433 TransportStateChange (); /* EMIT SIGNAL */
435 /* and start it up again if relevant */
437 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
438 request_transport_speed (1.0);
439 pending_locate_roll = false;
444 Session::check_declick_out ()
446 bool locate_required = transport_sub_state & PendingLocate;
448 /* this is called after a process() iteration. if PendingDeclickOut was set,
449 it means that we were waiting to declick the output (which has just been
450 done) before doing something else. this is where we do that "something else".
452 note: called from the audio thread.
455 if (transport_sub_state & PendingDeclickOut) {
457 if (locate_required) {
458 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
459 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
461 stop_transport (pending_abort);
462 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
468 Session::set_play_loop (bool yn)
470 /* Called from event-handling context */
472 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
478 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
479 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
480 "Recommend changing the configured options")
486 if ((play_loop = yn)) {
491 if ((loc = _locations.auto_loop_location()) != 0) {
493 if (Config->get_seamless_loop()) {
494 // set all diskstreams to use internal looping
495 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
496 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
497 if (!(*i)->hidden()) {
498 (*i)->set_loop (loc);
503 // set all diskstreams to NOT use internal looping
504 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
505 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
506 if (!(*i)->hidden()) {
512 /* stick in the loop event */
514 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
517 /* locate to start of loop and roll if current pos is outside of the loop range */
518 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
519 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
523 // locate to current position (+ 1 to force reload)
524 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
532 clear_events (Event::AutoLoop);
534 // set all diskstreams to NOT use internal looping
535 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
536 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
537 if (!(*i)->hidden()) {
546 Session::flush_all_redirects ()
548 boost::shared_ptr<RouteList> r = routes.reader ();
550 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
551 (*i)->flush_redirects ();
556 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
558 if (synced_to_jack()) {
563 _slave->speed_and_position (sp, pos);
565 if (target_frame != pos) {
567 /* tell JACK to change transport position, and we will
568 follow along later in ::follow_slave()
571 _engine.transport_locate (target_frame);
573 if (sp != 1.0f && with_roll) {
574 _engine.transport_start ();
581 locate (target_frame, with_roll, with_flush, with_loop);
586 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
588 if (actively_recording()) {
592 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
594 set_transport_speed (1.0, false);
596 loop_changing = false;
601 // [DR] FIXME: find out exactly where this should go below
602 _transport_frame = target_frame;
603 smpte_time(_transport_frame, transmitting_smpte_time);
604 outbound_mtc_smpte_frame = _transport_frame;
605 next_quarter_frame_to_send = 0;
607 if (_transport_speed && (!with_loop || loop_changing)) {
608 /* schedule a declick. we'll be called again when its done */
610 if (!(transport_sub_state & PendingDeclickOut)) {
611 transport_sub_state |= (PendingDeclickOut|PendingLocate);
612 pending_locate_frame = target_frame;
613 pending_locate_roll = with_roll;
614 pending_locate_flush = with_flush;
619 if (transport_rolling() && !Config->get_auto_play() && !with_roll && !(synced_to_jack() && play_loop)) {
620 realtime_stop (false);
623 if ( !with_loop || loop_changing) {
625 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
628 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
631 schedule_butler_transport_work ();
635 /* this is functionally what clear_clicks() does but with a tentative lock */
637 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
639 if (clickm.locked()) {
641 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
650 /* switch from input if we're going to roll */
651 if (Config->get_monitoring_model() == HardwareMonitoring) {
653 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
655 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
656 if ((*i)->record_enabled ()) {
657 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
658 (*i)->monitor_input (!Config->get_auto_input());
663 /* otherwise we're going to stop, so do the opposite */
664 if (Config->get_monitoring_model() == HardwareMonitoring) {
665 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
667 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
668 if ((*i)->record_enabled ()) {
669 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
670 (*i)->monitor_input (true);
676 /* cancel looped playback if transport pos outside of loop range */
678 Location* al = _locations.auto_loop_location();
680 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
681 // cancel looping directly, this is called from event handling context
682 set_play_loop (false);
686 loop_changing = false;
688 _send_smpte_update = true;
692 Session::set_transport_speed (float speed, bool abort)
694 if (_transport_speed == speed) {
699 speed = min (8.0f, speed);
700 } else if (speed < 0) {
701 speed = max (-8.0f, speed);
704 if (transport_rolling() && speed == 0.0) {
706 if (Config->get_monitoring_model() == HardwareMonitoring)
708 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
710 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
711 if ((*i)->record_enabled ()) {
712 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
713 (*i)->monitor_input (true);
718 if (synced_to_jack ()) {
719 _engine.transport_stop ();
721 stop_transport (abort);
724 } else if (transport_stopped() && speed == 1.0) {
726 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
730 if (Config->get_monitoring_model() == HardwareMonitoring) {
732 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
734 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
735 if (Config->get_auto_input() && (*i)->record_enabled ()) {
736 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
737 (*i)->monitor_input (false);
742 if (synced_to_jack()) {
743 _engine.transport_start ();
750 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
754 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
755 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
760 if (actively_recording()) {
764 if (speed > 0.0f && _transport_frame == current_end_frame()) {
768 if (speed < 0.0f && _transport_frame == 0) {
774 /* if we are reversing relative to the current speed, or relative to the speed
775 before the last stop, then we have to do extra work.
778 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f)) {
779 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
782 _last_transport_speed = _transport_speed;
783 _transport_speed = speed;
785 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
786 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
787 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
788 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
792 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
793 schedule_butler_transport_work ();
799 Session::stop_transport (bool abort)
801 if (_transport_speed == 0.0f) {
805 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
806 _worst_output_latency > current_block_size)
809 /* we need to capture the audio that has still not yet been received by the system
810 at the time the stop is requested, so we have to roll past that time.
812 we want to declick before stopping, so schedule the autostop for one
813 block before the actual end. we'll declick in the subsequent block,
814 and then we'll really be stopped.
817 Event *ev = new Event (Event::StopOnce, Event::Replace,
818 _transport_frame + _worst_output_latency - current_block_size,
822 transport_sub_state |= StopPendingCapture;
823 pending_abort = abort;
828 if ((transport_sub_state & PendingDeclickOut) == 0) {
829 transport_sub_state |= PendingDeclickOut;
830 /* we'll be called again after the declick */
831 pending_abort = abort;
835 realtime_stop (abort);
836 schedule_butler_transport_work ();
840 Session::start_transport ()
842 _last_roll_location = _transport_frame;
844 /* if record status is Enabled, move it to Recording. if its
845 already Recording, move it to Disabled.
848 switch (record_status()) {
850 if (!Config->get_punch_in()) {
856 disable_record (false);
863 if (!synced_to_jack() || _exporting) {
864 actually_start_transport ();
866 waiting_to_start = true;
871 Session::actually_start_transport ()
873 waiting_to_start = false;
875 transport_sub_state |= PendingDeclickIn;
876 _transport_speed = 1.0;
878 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
879 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
880 (*i)->realtime_set_speed ((*i)->speed(), true);
883 deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame);
885 TransportStateChange (); /* EMIT SIGNAL */
888 /** Do any transport work in the audio thread that needs to be done after the
889 * transport thread is finished. Audio thread, realtime safe.
892 Session::post_transport ()
894 if (post_transport_work & PostTransportAudition) {
895 if (auditioner && auditioner->active()) {
896 process_function = &Session::process_audition;
898 process_function = &Session::process_with_events;
902 if (post_transport_work & PostTransportStop) {
904 transport_sub_state = 0;
907 if (post_transport_work & PostTransportLocate) {
909 if ((Config->get_auto_play() && !_exporting) || (post_transport_work & PostTransportRoll)) {
914 transport_sub_state = 0;
920 post_transport_work = PostTransportWork (0);
924 Session::reset_rf_scale (nframes_t motion)
926 cumulative_rf_motion += motion;
928 if (cumulative_rf_motion < 4 * _current_frame_rate) {
930 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
932 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
944 Session::set_slave_source (SlaveSource src)
946 bool reverse = false;
947 bool non_rt_required = false;
949 if (_transport_speed) {
950 error << _("please stop the transport before adjusting slave settings") << endmsg;
954 // if (src == JACK && Config->get_jack_time_master()) {
963 if (_transport_speed < 0.0) {
975 _slave = new MTC_Slave (*this, *_mtc_port);
978 catch (failed_constructor& err) {
983 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
986 _desired_transport_speed = _transport_speed;
990 _slave = new JACK_Slave (_engine.jack());
991 _desired_transport_speed = _transport_speed;
995 Config->set_slave_source (src);
997 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
998 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
999 if (!(*i)->hidden()) {
1000 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
1001 non_rt_required = true;
1003 (*i)->set_slaved (_slave);
1008 reverse_diskstream_buffers ();
1011 if (non_rt_required) {
1012 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1013 schedule_butler_transport_work ();
1020 Session::reverse_diskstream_buffers ()
1022 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1023 schedule_butler_transport_work ();
1027 Session::set_diskstream_speed (Diskstream* stream, float speed)
1029 if (stream->realtime_set_speed (speed, false)) {
1030 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1031 schedule_butler_transport_work ();
1037 Session::set_audio_range (list<AudioRange>& range)
1039 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1040 ev->audio_range = range;
1045 Session::request_play_range (bool yn)
1047 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1052 Session::set_play_range (bool yn)
1054 /* Called from event-processing context */
1056 if (_play_range != yn) {
1061 /* stop transport */
1062 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1069 Session::setup_auto_play ()
1071 /* Called from event-processing context */
1075 _clear_event_type (Event::RangeStop);
1076 _clear_event_type (Event::RangeLocate);
1082 list<AudioRange>::size_type sz = current_audio_range.size();
1086 list<AudioRange>::iterator i = current_audio_range.begin();
1087 list<AudioRange>::iterator next;
1089 while (i != current_audio_range.end()) {
1094 /* locating/stopping is subject to delays for declicking.
1097 nframes_t requested_frame = (*i).end;
1099 if (requested_frame > current_block_size) {
1100 requested_frame -= current_block_size;
1102 requested_frame = 0;
1105 if (next == current_audio_range.end()) {
1106 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1108 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1116 } else if (sz == 1) {
1118 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1123 /* now start rolling at the right place */
1125 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1130 Session::request_bounded_roll (nframes_t start, nframes_t end)
1133 Event *ev = new Event (Event::StopOnce, Event::Replace, Event::Immediate, end, 0.0);
1135 request_locate (start, true);
1139 Session::engine_halted ()
1141 /* there will be no more calls to process(), so
1142 we'd better clean up for ourselves, right now.
1144 but first, make sure the butler is out of
1148 g_atomic_int_set (&butler_should_do_transport_work, 0);
1149 post_transport_work = PostTransportWork (0);
1152 realtime_stop (false);
1153 non_realtime_stop (false);
1154 transport_sub_state = 0;
1156 TransportStateChange (); /* EMIT SIGNAL */
1161 Session::xrun_recovery ()
1163 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1165 HaltOnXrun (); /* EMIT SIGNAL */
1167 /* it didn't actually halt, but we need
1168 to handle things in the same way.
1176 Session::update_latency_compensation (bool with_stop, bool abort)
1178 bool update_jack = false;
1180 if (_state_of_the_state & Deletion) {
1184 _worst_track_latency = 0;
1186 boost::shared_ptr<RouteList> r = routes.reader ();
1188 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1190 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1191 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1194 nframes_t old_latency = (*i)->signal_latency ();
1195 nframes_t track_latency = (*i)->update_total_latency ();
1197 if (old_latency != track_latency) {
1201 if (!(*i)->hidden() && ((*i)->active())) {
1202 _worst_track_latency = max (_worst_track_latency, track_latency);
1206 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1207 (*i)->set_latency_delay (_worst_track_latency);
1210 /* tell JACK to play catch up */
1213 _engine.update_total_latencies ();
1216 set_worst_io_latencies ();
1218 /* reflect any changes in latencies into capture offsets
1221 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1223 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1224 (*i)->set_capture_offset ();
1229 Session::update_latency_compensation_proxy (void* ignored)
1231 update_latency_compensation (false, false);