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)
269 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
271 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
272 if ((*i)->get_captured_frames () != 0) {
278 /* stop and locate are merged here because they share a lot of common stuff */
281 now = localtime (&xnow);
284 auditioner->cancel_audition ();
288 cumulative_rf_motion = 0;
292 begin_reversible_command ("capture");
294 Location* loc = _locations.end_location();
295 bool change_end = false;
297 if (_transport_frame < loc->end()) {
299 /* stopped recording before current end */
301 if (_end_location_is_free) {
303 /* first capture for this session, move end back to where we are */
308 } else if (_transport_frame > loc->end()) {
310 /* stopped recording after the current end, extend it */
316 XMLNode &before = loc->get_state();
317 loc->set_end(_transport_frame);
318 XMLNode &after = loc->get_state();
319 add_command (new MementoCommand<Location>(*loc, &before, &after));
322 _end_location_is_free = false;
323 _have_captured = true;
326 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
327 (*i)->transport_stopped (*now, xnow, abort);
330 boost::shared_ptr<RouteList> r = routes.reader ();
332 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
333 if (!(*i)->hidden()) {
334 (*i)->set_pending_declick (0);
339 commit_reversible_command ();
342 if (_engine.running()) {
343 update_latency_compensation (true, abort);
346 if (Config->get_auto_return() || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
348 if (pending_locate_flush) {
349 flush_all_redirects ();
352 if ((Config->get_auto_return() || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
354 _transport_frame = last_stop_frame;
356 if (synced_to_jack()) {
357 _engine.transport_locate (_transport_frame);
361 #ifndef LEAVE_TRANSPORT_UNADJUSTED
365 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
366 if (!(*i)->hidden()) {
367 if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
368 (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed()));
371 (*i)->seek (_transport_frame);
375 #ifdef LEAVE_TRANSPORT_UNADJUSTED
379 last_stop_frame = _transport_frame;
381 send_full_time_code ();
382 deliver_mmc (MIDI::MachineControl::cmdStop, 0);
383 deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame);
387 /* XXX its a little odd that we're doing this here
388 when realtime_stop(), which has already executed,
392 if (!Config->get_latched_record_enable()) {
393 g_atomic_int_set (&_record_status, Disabled);
395 g_atomic_int_set (&_record_status, Enabled);
397 RecordStateChanged (); /* emit signal */
400 if ((post_transport_work & PostTransportLocate) && get_record_enabled()) {
401 /* capture start has been changed, so save pending state */
402 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 */
412 if (did_record && !saved) {
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;
816 if ((transport_sub_state & PendingDeclickOut) == 0) {
817 transport_sub_state |= PendingDeclickOut;
818 /* we'll be called again after the declick */
819 pending_abort = abort;
823 realtime_stop (abort);
824 schedule_butler_transport_work ();
828 Session::start_transport ()
830 _last_roll_location = _transport_frame;
832 /* if record status is Enabled, move it to Recording. if its
833 already Recording, move it to Disabled.
836 switch (record_status()) {
838 if (!Config->get_punch_in()) {
844 disable_record (false);
851 if (!synced_to_jack() || _exporting) {
852 actually_start_transport ();
854 waiting_to_start = true;
859 Session::actually_start_transport ()
861 waiting_to_start = false;
863 transport_sub_state |= PendingDeclickIn;
864 _transport_speed = 1.0;
866 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
867 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
868 (*i)->realtime_set_speed ((*i)->speed(), true);
871 send_mmc_in_another_thread (MIDI::MachineControl::cmdDeferredPlay, 0);
873 TransportStateChange (); /* EMIT SIGNAL */
877 Session::post_transport ()
879 if (post_transport_work & PostTransportAudition) {
880 if (auditioner && auditioner->active()) {
881 process_function = &Session::process_audition;
883 process_function = &Session::process_with_events;
887 if (post_transport_work & PostTransportStop) {
889 transport_sub_state = 0;
892 if (post_transport_work & PostTransportLocate) {
894 if ((Config->get_auto_play() && !_exporting) || (post_transport_work & PostTransportRoll)) {
899 transport_sub_state = 0;
905 post_transport_work = PostTransportWork (0);
909 Session::reset_rf_scale (nframes_t motion)
911 cumulative_rf_motion += motion;
913 if (cumulative_rf_motion < 4 * _current_frame_rate) {
915 } else if (cumulative_rf_motion < 8 * _current_frame_rate) {
917 } else if (cumulative_rf_motion < 16 * _current_frame_rate) {
929 Session::set_slave_source (SlaveSource src)
931 bool reverse = false;
932 bool non_rt_required = false;
934 if (_transport_speed) {
935 error << _("please stop the transport before adjusting slave settings") << endmsg;
939 // if (src == JACK && Config->get_jack_time_master()) {
948 if (_transport_speed < 0.0) {
960 _slave = new MTC_Slave (*this, *_mtc_port);
963 catch (failed_constructor& err) {
968 error << _("No MTC port defined: MTC slaving is impossible.") << endmsg;
971 _desired_transport_speed = _transport_speed;
975 _slave = new JACK_Slave (_engine.jack());
976 _desired_transport_speed = _transport_speed;
980 Config->set_slave_source (src);
982 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
983 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
984 if (!(*i)->hidden()) {
985 if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
986 non_rt_required = true;
988 (*i)->set_slaved (_slave);
993 reverse_diskstream_buffers ();
996 if (non_rt_required) {
997 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
998 schedule_butler_transport_work ();
1005 Session::reverse_diskstream_buffers ()
1007 post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse);
1008 schedule_butler_transport_work ();
1012 Session::set_diskstream_speed (Diskstream* stream, float speed)
1014 if (stream->realtime_set_speed (speed, false)) {
1015 post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
1016 schedule_butler_transport_work ();
1022 Session::set_audio_range (list<AudioRange>& range)
1024 Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f);
1025 ev->audio_range = range;
1030 Session::request_play_range (bool yn)
1032 Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn);
1037 Session::set_play_range (bool yn)
1039 /* Called from event-processing context */
1041 if (_play_range != yn) {
1046 /* stop transport */
1047 Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false);
1054 Session::setup_auto_play ()
1056 /* Called from event-processing context */
1060 _clear_event_type (Event::RangeStop);
1061 _clear_event_type (Event::RangeLocate);
1067 list<AudioRange>::size_type sz = current_audio_range.size();
1071 list<AudioRange>::iterator i = current_audio_range.begin();
1072 list<AudioRange>::iterator next;
1074 while (i != current_audio_range.end()) {
1079 /* locating/stopping is subject to delays for declicking.
1082 nframes_t requested_frame = (*i).end;
1084 if (requested_frame > current_block_size) {
1085 requested_frame -= current_block_size;
1087 requested_frame = 0;
1090 if (next == current_audio_range.end()) {
1091 ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f);
1093 ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f);
1101 } else if (sz == 1) {
1103 ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f);
1108 /* now start rolling at the right place */
1110 ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false);
1115 Session::request_bounded_roll (nframes_t start, nframes_t end)
1118 Event *ev = new Event (Event::StopOnce, Event::Replace, Event::Immediate, end, 0.0);
1120 request_locate (start, true);
1124 Session::engine_halted ()
1126 /* there will be no more calls to process(), so
1127 we'd better clean up for ourselves, right now.
1129 but first, make sure the butler is out of
1133 g_atomic_int_set (&butler_should_do_transport_work, 0);
1134 post_transport_work = PostTransportWork (0);
1137 realtime_stop (false);
1138 non_realtime_stop (false);
1139 transport_sub_state = 0;
1141 TransportStateChange (); /* EMIT SIGNAL */
1146 Session::xrun_recovery ()
1148 if (Config->get_stop_recording_on_xrun() && actively_recording()) {
1150 HaltOnXrun (); /* EMIT SIGNAL */
1152 /* it didn't actually halt, but we need
1153 to handle things in the same way.
1161 Session::update_latency_compensation (bool with_stop, bool abort)
1163 bool update_jack = false;
1165 if (_state_of_the_state & Deletion) {
1169 _worst_track_latency = 0;
1171 boost::shared_ptr<RouteList> r = routes.reader ();
1173 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1175 (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
1176 (!(post_transport_work & PostTransportLocate) || pending_locate_flush));
1179 nframes_t old_latency = (*i)->signal_latency ();
1180 nframes_t track_latency = (*i)->update_total_latency ();
1182 if (old_latency != track_latency) {
1186 if (!(*i)->hidden() && ((*i)->active())) {
1187 _worst_track_latency = max (_worst_track_latency, track_latency);
1191 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
1192 (*i)->set_latency_delay (_worst_track_latency);
1195 /* tell JACK to play catch up */
1198 _engine.update_total_latencies ();
1201 set_worst_io_latencies ();
1203 /* reflect any changes in latencies into capture offsets
1206 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1208 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1209 (*i)->set_capture_offset ();
1214 Session::update_latency_compensation_proxy (void* ignored)
1216 update_latency_compensation (false, false);