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 if (_transport_speed < 0.0f) {
138 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse);
140 post_transport_work = PostTransportWork (post_transport_work | PostTransportStop);
143 if (actively_recording()) {
145 /* move the transport position back to where the
146 request for a stop was noticed. we rolled
147 past that point to pick up delayed input.
150 #ifndef LEAVE_TRANSPORT_UNADJUSTED
151 decrement_transport_position (_worst_output_latency);
154 /* the duration change is not guaranteed to have happened, but is likely */
156 post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration);
160 post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort);
163 _clear_event_type (Event::StopOnce);
164 _clear_event_type (Event::RangeStop);
165 _clear_event_type (Event::RangeLocate);
167 disable_record (true);
169 reset_slave_state ();
171 _transport_speed = 0;
173 if (Config->get_use_video_sync()) {
174 waiting_for_sync_offset = true;
177 transport_sub_state = (Config->get_auto_return() ? AutoReturning : 0);
181 Session::butler_transport_work ()
183 boost::shared_ptr<RouteList> r = routes.reader ();
184 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
186 if (post_transport_work & PostTransportCurveRealloc) {
187 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
188 (*i)->curve_reallocate();
192 if (post_transport_work & PostTransportInputChange) {
193 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
194 (*i)->non_realtime_input_change ();
198 if (post_transport_work & PostTransportSpeed) {
199 non_realtime_set_speed ();
202 if (post_transport_work & PostTransportReverse) {
206 cumulative_rf_motion = 0;
209 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
210 if (!(*i)->hidden()) {
211 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
212 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
215 (*i)->seek (_transport_frame);
221 if (post_transport_work & (PostTransportStop|PostTransportLocate)) {
222 non_realtime_stop (post_transport_work & PostTransportAbort);
225 if (post_transport_work & PostTransportOverWrite) {
226 non_realtime_overwrite ();
229 if (post_transport_work & PostTransportAudition) {
230 non_realtime_set_audition ();
233 g_atomic_int_dec_and_test (&butler_should_do_transport_work);
237 Session::non_realtime_set_speed ()
239 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
241 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
242 (*i)->non_realtime_set_speed ();
247 Session::non_realtime_overwrite ()
249 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
251 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
252 if ((*i)->pending_overwrite) {
253 (*i)->overwrite_existing_buffers ();
259 Session::non_realtime_stop (bool abort)
267 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
269 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
270 if ((*i)->get_captured_frames () != 0) {
276 /* stop and locate are merged here because they share a lot of common stuff */
279 now = localtime (&xnow);
282 auditioner->cancel_audition ();
286 cumulative_rf_motion = 0;
290 begin_reversible_command ("capture");
292 Location* loc = _locations.end_location();
293 bool change_end = false;
295 if (_transport_frame < loc->end()) {
297 /* stopped recording before current end */
299 if (_end_location_is_free) {
301 /* first capture for this session, move end back to where we are */
306 } else if (_transport_frame > loc->end()) {
308 /* stopped recording after the current end, extend it */
314 XMLNode &before = loc->get_state();
315 loc->set_end(_transport_frame);
316 XMLNode &after = loc->get_state();
317 add_command (new MementoCommand<Location>(*loc, &before, &after));
320 _end_location_is_free = false;
321 _have_captured = true;
324 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
325 (*i)->transport_stopped (*now, xnow, abort);
328 boost::shared_ptr<RouteList> r = routes.reader ();
330 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
331 if (!(*i)->hidden()) {
332 (*i)->set_pending_declick (0);
337 commit_reversible_command ();
340 if (_engine.running()) {
341 update_latency_compensation (true, abort);
344 if (Config->get_auto_return() || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
346 if (pending_locate_flush) {
347 flush_all_redirects ();
350 if ((Config->get_auto_return() || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
352 _transport_frame = last_stop_frame;
354 if (synced_to_jack()) {
355 _engine.transport_locate (_transport_frame);
359 #ifndef LEAVE_TRANSPORT_UNADJUSTED
363 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
364 if (!(*i)->hidden()) {
365 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
366 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
369 (*i)->seek (_transport_frame);
374 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
376 #ifdef LEAVE_TRANSPORT_UNADJUSTED
380 last_stop_frame = _transport_frame;
382 send_full_time_code ();
383 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
384 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
388 /* XXX its a little odd that we're doing this here
389 when realtime_stop(), which has already executed,
393 if (!Config->get_latched_record_enable()) {
394 g_atomic_int_set (&_record_status, Disabled);
396 g_atomic_int_set (&_record_status, Enabled);
398 RecordStateChanged (); /* emit signal */
401 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
402 /* capture start has been changed, so save pending state */
403 save_state ("", true);
406 /* always try to get rid of this */
408 remove_pending_capture_state ();
410 /* save the current state of things if appropriate */
413 save_state (_current_snapshot_name);
416 if (post_transport_work & PostTransportDuration) {
417 DurationChanged (); /* EMIT SIGNAL */
420 if (post_transport_work & PostTransportStop) {
423 /* do not turn off autoloop on stop */
427 PositionChanged (_transport_frame); /* EMIT SIGNAL */
428 TransportStateChange (); /* EMIT SIGNAL */
430 /* and start it up again if relevant */
432 if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) {
433 request_transport_speed (1.0);
434 pending_locate_roll = false;
439 Session::check_declick_out ()
441 bool locate_required = transport_sub_state & PendingLocate;
443 /* this is called after a process() iteration. if PendingDeclickOut was set,
444 it means that we were waiting to declick the output (which has just been
445 done) before doing something else. this is where we do that "something else".
447 note: called from the audio thread.
450 if (transport_sub_state & PendingDeclickOut) {
452 if (locate_required) {
453 start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush);
454 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
456 stop_transport (pending_abort);
457 transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
463 Session::set_play_loop (bool yn)
465 /* Called from event-handling context */
467 if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) {
473 if (yn && Config->get_seamless_loop() && synced_to_jack()) {
474 warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n"
475 "Recommend changing the configured options")
481 if ((play_loop = yn)) {
486 if ((loc = _locations.auto_loop_location()) != 0) {
488 if (Config->get_seamless_loop()) {
489 // set all diskstreams to use internal looping
490 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
491 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
492 if (!(*i)->hidden()) {
493 (*i)->set_loop (loc);
498 // set all diskstreams to NOT use internal looping
499 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
500 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
501 if (!(*i)->hidden()) {
507 /* stick in the loop event */
509 Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f);
512 /* locate to start of loop and roll if current pos is outside of the loop range */
513 if (_transport_frame < loc->start() || _transport_frame > loc->end()) {
514 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack());
518 // locate to current position (+ 1 to force reload)
519 event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack());
527 clear_events (Event::AutoLoop);
529 // set all diskstreams to NOT use internal looping
530 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
531 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
532 if (!(*i)->hidden()) {
541 Session::flush_all_redirects ()
543 boost::shared_ptr<RouteList> r = routes.reader ();
545 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
546 (*i)->flush_redirects ();
551 Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
553 if (synced_to_jack()) {
558 _slave->speed_and_position (sp, pos);
560 if (target_frame != pos) {
562 /* tell JACK to change transport position, and we will
563 follow along later in ::follow_slave()
566 _engine.transport_locate (target_frame);
568 if (sp != 1.0f && with_roll) {
569 _engine.transport_start ();
576 locate (target_frame, with_roll, with_flush, with_loop);
581 Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop)
583 if (actively_recording()) {
587 if (_transport_frame == target_frame && !loop_changing && !with_loop) {
589 set_transport_speed (1.0, false);
591 loop_changing = false;
595 _transport_frame = target_frame;
597 if (_transport_speed && (!with_loop || loop_changing)) {
598 /* schedule a declick. we'll be called again when its done */
600 if (!(transport_sub_state & PendingDeclickOut)) {
601 transport_sub_state |= (PendingDeclickOut|PendingLocate);
602 pending_locate_frame = target_frame;
603 pending_locate_roll = with_roll;
604 pending_locate_flush = with_flush;
609 if (transport_rolling() && !Config->get_auto_play() && !with_roll && !(synced_to_jack() && play_loop)) {
610 realtime_stop (false);
613 if ( !with_loop || loop_changing) {
615 post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate);
618 post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll);
621 schedule_butler_transport_work ();
625 /* this is functionally what clear_clicks() does but with a tentative lock */
627 Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
629 if (clickm.locked()) {
631 for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) {
640 /* switch from input if we're going to roll */
641 if (Config->get_monitoring_model() == HardwareMonitoring) {
643 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
645 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
646 if ((*i)->record_enabled ()) {
647 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
648 (*i)->monitor_input (!Config->get_auto_input());
653 /* otherwise we're going to stop, so do the opposite */
654 if (Config->get_monitoring_model() == HardwareMonitoring) {
655 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
657 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
658 if ((*i)->record_enabled ()) {
659 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
660 (*i)->monitor_input (true);
666 /* cancel looped playback if transport pos outside of loop range */
668 Location* al = _locations.auto_loop_location();
670 if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
671 // cancel looping directly, this is called from event handling context
672 set_play_loop (false);
676 loop_changing = false;
680 Session::set_transport_speed (float speed, bool abort)
682 if (_transport_speed == speed) {
687 speed = min (8.0f, speed);
688 } else if (speed < 0) {
689 speed = max (-8.0f, speed);
692 if (transport_rolling() && speed == 0.0) {
694 if (Config->get_monitoring_model() == HardwareMonitoring)
696 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
698 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
699 if ((*i)->record_enabled ()) {
700 //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
701 (*i)->monitor_input (true);
706 if (synced_to_jack ()) {
707 _engine.transport_stop ();
709 stop_transport (abort);
712 } else if (transport_stopped() && speed == 1.0) {
714 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
718 if (Config->get_monitoring_model() == HardwareMonitoring) {
720 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
722 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
723 if (Config->get_auto_input() && (*i)->record_enabled ()) {
724 //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
725 (*i)->monitor_input (false);
730 if (synced_to_jack()) {
731 _engine.transport_start ();
738 if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) {
742 if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) {
743 warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control")
748 if (actively_recording()) {
752 if (speed > 0.0f && _transport_frame == current_end_frame()) {
756 if (speed < 0.0f && _transport_frame == 0) {
762 /* if we are reversing relative to the current speed, or relative to the speed
763 before the last stop, then we have to do extra work.
766 if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f)) {
767 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
770 _last_transport_speed = _transport_speed;
771 _transport_speed = speed;
773 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
774 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
775 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
776 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
780 if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) {
781 schedule_butler_transport_work ();
787 Session::stop_transport (bool abort)
789 if (_transport_speed == 0.0f) {
793 if (actively_recording() && !(transport_sub_state & StopPendingCapture) &&
794 _worst_output_latency > current_block_size)
797 /* we need to capture the audio that has still not yet been received by the system
798 at the time the stop is requested, so we have to roll past that time.
800 we want to declick before stopping, so schedule the autostop for one
801 block before the actual end. we'll declick in the subsequent block,
802 and then we'll really be stopped.
805 Event *ev = new Event (Event::StopOnce, Event::Replace,
806 _transport_frame + _worst_output_latency - current_block_size,
810 transport_sub_state |= StopPendingCapture;
811 pending_abort = abort;
815 if ((transport_sub_state & PendingDeclickOut) == 0) {
816 transport_sub_state |= PendingDeclickOut;
817 /* we'll be called again after the declick */
821 realtime_stop (abort);
822 schedule_butler_transport_work ();
826 Session::start_transport ()
828 _last_roll_location = _transport_frame;
830 /* if record status is Enabled, move it to Recording. if its
831 already Recording, move it to Disabled.
834 switch (record_status()) {
836 if (!Config->get_punch_in()) {
842 disable_record (false);
849 if (!synced_to_jack() || _exporting) {
850 actually_start_transport ();
852 waiting_to_start = true;
857 Session::actually_start_transport ()
859 waiting_to_start = false;
861 transport_sub_state |= PendingDeclickIn;
862 _transport_speed = 1.0;
864 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
865 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
866 (*i)->realtime_set_speed ((*i)->speed(), true);
869 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
871 TransportStateChange (); /* EMIT SIGNAL */
875 Session::post_transport ()
877 if (post_transport_work & PostTransportAudition) {
878 if (auditioner && auditioner->active()) {
879 process_function = &Session::process_audition;
881 process_function = &Session::process_with_events;
885 if (post_transport_work & PostTransportStop) {
887 transport_sub_state = 0;
890 if (post_transport_work & PostTransportLocate) {
892 if ((Config->get_auto_play() && !_exporting) || (post_transport_work & PostTransportRoll)) {
897 transport_sub_state = 0;
903 post_transport_work = PostTransportWork (0);
907 Session::reset_rf_scale (nframes_t motion)
909 cumulative_rf_motion += motion;
911 if (cumulative_rf_motion < 4 * _current_frame_rate) {
913 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
915 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
927 Session::set_slave_source (SlaveSource src)
929 bool reverse = false;
930 bool non_rt_required = false;
932 if (_transport_speed) {
933 error << _("please stop the transport before adjusting slave settings") << endmsg;
937 // if (src == JACK && Config->get_jack_time_master()) {
946 if (_transport_speed < 0.0) {
958 _slave = new MTC_Slave (*this, *_mtc_port);
961 catch (failed_constructor& err) {
966 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
969 _desired_transport_speed = _transport_speed;
973 _slave = new JACK_Slave (_engine.jack());
974 _desired_transport_speed = _transport_speed;
978 Config->set_slave_source (src);
980 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
981 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
982 if (!(*i)->hidden()) {
983 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
984 non_rt_required = true;
986 (*i)->set_slaved (_slave);
991 reverse_diskstream_buffers ();
994 if (non_rt_required) {
995 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
996 schedule_butler_transport_work ();
1003 Session::reverse_diskstream_buffers ()
1005 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1006 schedule_butler_transport_work ();
1010 Session::set_diskstream_speed (Diskstream* stream, float speed)
1012 if (stream->realtime_set_speed (speed, false)) {
1013 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1014 schedule_butler_transport_work ();
1020 Session::set_audio_range (list<AudioRange>& range)
1022 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1023 ev->audio_range = range;
1028 Session::request_play_range (bool yn)
1030 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1035 Session::set_play_range (bool yn)
1037 /* Called from event-processing context */
1039 if (_play_range != yn) {
1044 /* stop transport */
1045 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1052 Session::setup_auto_play ()
1054 /* Called from event-processing context */
1058 _clear_event_type (Event::RangeStop);
1059 _clear_event_type (Event::RangeLocate);
1065 list<AudioRange>::size_type sz = current_audio_range.size();
1069 list<AudioRange>::iterator i = current_audio_range.begin();
1070 list<AudioRange>::iterator next;
1072 while (i != current_audio_range.end()) {
1077 /* locating/stopping is subject to delays for declicking.
1080 nframes_t requested_frame = (*i).end;
1082 if (requested_frame > current_block_size) {
1083 requested_frame -= current_block_size;
1085 requested_frame = 0;
1088 if (next == current_audio_range.end()) {
1089 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1091 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1099 } else if (sz == 1) {
1101 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1106 /* now start rolling at the right place */
1108 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1113 Session::request_bounded_roll (nframes_t start, nframes_t end)
1116 Event *ev = new Event (Event::StopOnce, Event::Replace, Event::Immediate, end, 0.0);
1118 request_locate (start, true);
1122 Session::engine_halted ()
1124 /* there will be no more calls to process(), so
1125 we'd better clean up for ourselves, right now.
1127 but first, make sure the butler is out of
1131 g_atomic_int_set (&butler_should_do_transport_work, 0);
1132 post_transport_work = PostTransportWork (0);
1135 realtime_stop (false);
1136 non_realtime_stop (false);
1137 transport_sub_state = 0;
1139 TransportStateChange (); /* EMIT SIGNAL */
1144 Session::xrun_recovery ()
1146 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1148 HaltOnXrun (); /* EMIT SIGNAL */
1150 /* it didn't actually halt, but we need
1151 to handle things in the same way.
1159 Session::update_latency_compensation (bool with_stop, bool abort)
1161 bool update_jack = false;
1163 if (_state_of_the_state & Deletion) {
1167 _worst_track_latency = 0;
1169 boost::shared_ptr<RouteList> r = routes.reader ();
1171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1173 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1174 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1177 nframes_t old_latency = (*i)->signal_latency ();
1178 nframes_t track_latency = (*i)->update_total_latency ();
1180 if (old_latency != track_latency) {
1184 if (!(*i)->hidden() && ((*i)->active())) {
1185 _worst_track_latency = max (_worst_track_latency, track_latency);
1189 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1190 (*i)->set_latency_delay (_worst_track_latency);
1193 /* tell JACK to play catch up */
1196 _engine.update_total_latencies ();
1199 set_worst_io_latencies ();
1201 /* reflect any changes in latencies into capture offsets
1204 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1206 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1207 (*i)->set_capture_offset ();
1212 Session::update_latency_compensation_proxy (void* ignored)
1214 update_latency_compensation (false, false);