2 Copyright (C) 1999-2002 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 "pbd/error.h"
26 #include "pbd/enumwriter.h"
28 #include <glibmm/threads.h>
30 #include "ardour/audioengine.h"
31 #include "ardour/auditioner.h"
32 #include "ardour/butler.h"
33 #include "ardour/cycle_timer.h"
34 #include "ardour/debug.h"
35 #include "ardour/graph.h"
36 #include "ardour/port.h"
37 #include "ardour/process_thread.h"
38 #include "ardour/session.h"
39 #include "ardour/slave.h"
40 #include "ardour/ticker.h"
41 #include "ardour/types.h"
43 #include "midi++/manager.h"
44 #include "midi++/mmc.h"
48 #include <xmmintrin.h>
50 using namespace ARDOUR;
54 /** Called by the audio engine when there is work to be done with JACK.
55 * @param nframes Number of frames to process.
59 Session::process (pframes_t nframes)
61 framepos_t transport_at_start = _transport_frame;
65 if (processing_blocked()) {
70 if (non_realtime_work_pending()) {
71 if (!_butler->transport_work_requested ()) {
76 _engine.main_thread()->get_buffers ();
78 (this->*process_function) (nframes);
80 _engine.main_thread()->drop_buffers ();
82 /* deliver MIDI clock. Note that we need to use the transport frame
83 * position at the start of process(), not the value at the end of
84 * it. We may already have ticked() because of a transport state
85 * change, for example.
89 if (!_engine.freewheeling() && Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) {
90 midi_clock->tick (transport_at_start);
93 /* don't bother with a message */
96 SendFeedback (); /* EMIT SIGNAL */
100 Session::fail_roll (pframes_t nframes)
102 return no_roll (nframes);
106 Session::no_roll (pframes_t nframes)
110 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
112 int declick = get_transport_declick_required();
113 boost::shared_ptr<RouteList> r = routes.reader ();
116 _click_io->silence (nframes);
119 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
121 if (_process_graph) {
122 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
123 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
125 PT_TIMING_CHECK (10);
126 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
128 if ((*i)->is_hidden()) {
132 (*i)->set_pending_declick (declick);
134 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
135 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
140 PT_TIMING_CHECK (11);
147 /** @param need_butler to be set to true by this method if it needs the butler,
148 * otherwise it must be left alone.
151 Session::process_routes (pframes_t nframes, bool& need_butler)
153 int declick = get_transport_declick_required();
154 boost::shared_ptr<RouteList> r = routes.reader ();
156 if (transport_sub_state & StopPendingCapture) {
157 /* force a declick out */
161 const framepos_t start_frame = _transport_frame;
162 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
164 if (_process_graph) {
165 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
166 _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
169 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
173 if ((*i)->is_hidden()) {
177 (*i)->set_pending_declick (declick);
181 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
195 /** @param need_butler to be set to true by this method if it needs the butler,
196 * otherwise it must be left alone.
199 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
201 boost::shared_ptr<RouteList> r = routes.reader ();
203 const framepos_t start_frame = _transport_frame;
204 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
206 if (_process_graph) {
207 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
209 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
213 if ((*i)->is_hidden()) {
219 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
234 Session::get_track_statistics ()
239 boost::shared_ptr<RouteList> rl = routes.reader();
240 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
242 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
244 if (!tr || tr->hidden()) {
248 pworst = min (pworst, tr->playback_buffer_load());
249 cworst = min (cworst, tr->capture_buffer_load());
252 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
253 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
255 if (actively_recording()) {
260 /** Process callback used when the auditioner is not active */
262 Session::process_with_events (pframes_t nframes)
267 pframes_t this_nframes;
268 framepos_t end_frame;
269 bool session_needs_butler = false;
270 framecnt_t frames_moved;
272 /* make sure the auditioner is silent */
275 auditioner->silence (nframes);
278 /* handle any pending events */
280 while (pending_events.read (&ev, 1) == 1) {
284 /* if we are not in the middle of a state change,
285 and there are immediate events queued up,
289 while (!non_realtime_work_pending() && !immediate_events.empty()) {
290 SessionEvent *ev = immediate_events.front ();
291 immediate_events.pop_front ();
295 /* Decide on what to do with quarter-frame MTC during this cycle */
297 bool const was_sending_qf_mtc = _send_qf_mtc;
298 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
300 if (_transport_speed != 0) {
302 Config->get_send_mtc () &&
303 _transport_speed >= (1 - tolerance) &&
304 _transport_speed <= (1 + tolerance)
307 if (_send_qf_mtc && !was_sending_qf_mtc) {
308 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
309 _send_timecode_update = true;
312 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
313 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
314 a quarter of a second since we sent anything at all, so send a full MTC update
317 _send_timecode_update = true;
320 _pframes_since_last_mtc += nframes;
323 /* Events caused a transport change (or we re-started sending
324 * MTC), so send an MTC Full Frame (Timecode) message. This
325 * is sent whether rolling or not, to give slaves an idea of
326 * ardour time on locates (and allow slow slaves to position
327 * and prepare for rolling)
329 if (_send_timecode_update) {
330 send_full_time_code (_transport_frame);
333 if (!process_can_proceed()) {
338 if (events.empty() || next_event == events.end()) {
339 process_without_events (nframes);
343 if (_transport_speed == 1.0) {
344 frames_moved = (framecnt_t) nframes;
346 interpolation.set_target_speed (_target_transport_speed);
347 interpolation.set_speed (_transport_speed);
348 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
351 end_frame = _transport_frame + frames_moved;
354 SessionEvent* this_event;
355 Events::iterator the_next_one;
357 if (!process_can_proceed()) {
362 if (!_exporting && _slave) {
363 if (!follow_slave (nframes)) {
368 if (_transport_speed == 0) {
373 if (!_exporting && !timecode_transmission_suspended()) {
374 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
377 framepos_t stop_limit = compute_stop_limit ();
379 if (maybe_stop (stop_limit)) {
384 this_event = *next_event;
385 the_next_one = next_event;
388 /* yes folks, here it is, the actual loop where we really truly
394 this_nframes = nframes; /* real (jack) time relative */
395 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
397 /* running an event, position transport precisely to its time */
398 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
399 /* this isn't quite right for reverse play */
400 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
401 this_nframes = abs (floor(frames_moved / _transport_speed));
406 click (_transport_frame, this_nframes);
408 if (process_routes (this_nframes, session_needs_butler)) {
413 get_track_statistics ();
415 nframes -= this_nframes;
417 if (frames_moved < 0) {
418 decrement_transport_position (-frames_moved);
420 increment_transport_position (frames_moved);
423 maybe_stop (stop_limit);
424 check_declick_out ();
427 _engine.split_cycle (this_nframes);
429 /* now handle this event and all others scheduled for the same time */
431 while (this_event && this_event->action_frame == _transport_frame) {
432 process_event (this_event);
434 if (the_next_one == events.end()) {
437 this_event = *the_next_one;
442 /* if an event left our state changing, do the right thing */
444 if (nframes && non_realtime_work_pending()) {
449 /* this is necessary to handle the case of seamless looping */
450 end_frame = _transport_frame + floor (nframes * _transport_speed);
455 } /* implicit release of route lock */
457 if (session_needs_butler) {
463 Session::reset_slave_state ()
465 average_slave_delta = 1800;
466 delta_accumulator_cnt = 0;
467 have_first_delta_accumulator = false;
468 _slave_state = Stopped;
472 Session::transport_locked () const
476 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
484 Session::follow_slave (pframes_t nframes)
487 framepos_t slave_transport_frame;
488 framecnt_t this_delta;
493 config.set_external_sync (false);
497 _slave->speed_and_position (slave_speed, slave_transport_frame);
499 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
501 if (!_slave->locked()) {
502 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
506 if (slave_transport_frame > _transport_frame) {
507 this_delta = slave_transport_frame - _transport_frame;
510 this_delta = _transport_frame - slave_transport_frame;
514 if (_slave->starting()) {
518 if (_slave->is_always_synced() || Config->get_timecode_source_is_synced()) {
520 /* if the TC source is synced, then we assume that its
521 speed is binary: 0.0 or 1.0
524 if (slave_speed != 0.0f) {
530 /* if we are chasing and the average delta between us and the
531 master gets too big, we want to switch to silent
532 motion. so keep track of that here.
535 if (_slave_state == Running) {
536 calculate_moving_average_of_slave_delta(dir, this_delta);
540 track_slave_state (slave_speed, slave_transport_frame, this_delta);
542 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
543 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
546 if (_slave_state == Running && !_slave->is_always_synced() && !Config->get_timecode_source_is_synced()) {
548 if (_transport_speed != 0.0f) {
551 note that average_dir is +1 or -1
556 if (average_slave_delta == 0) {
560 delta = average_slave_delta;
561 delta *= average_dir;
565 if (slave_speed != 0.0) {
566 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
567 (int) (dir * this_delta),
571 slave_transport_frame,
572 average_slave_delta));
576 if (_slave->give_slave_full_control_over_transport_speed()) {
577 set_transport_speed (slave_speed, false, false);
578 //std::cout << "set speed = " << slave_speed << "\n";
580 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
581 request_transport_speed (adjusted_speed);
582 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
583 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
588 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
589 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
597 if (_slave_state == Running && !non_realtime_work_pending()) {
598 /* speed is set, we're locked, and good to go */
603 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
604 follow_slave_silently (nframes, slave_speed);
607 /* don't move at all */
608 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
614 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
616 if (delta_accumulator_cnt >= delta_accumulator_size) {
617 have_first_delta_accumulator = true;
618 delta_accumulator_cnt = 0;
621 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
622 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
625 if (have_first_delta_accumulator) {
626 average_slave_delta = 0L;
627 for (int i = 0; i < delta_accumulator_size; ++i) {
628 average_slave_delta += delta_accumulator[i];
630 average_slave_delta /= (int32_t) delta_accumulator_size;
631 if (average_slave_delta < 0L) {
633 average_slave_delta = abs(average_slave_delta);
641 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
643 if (slave_speed != 0.0f) {
645 /* slave is running */
647 switch (_slave_state) {
649 if (_slave->requires_seekahead()) {
650 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
651 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
652 /* we can call locate() here because we are in process context */
653 locate (slave_wait_end, false, false);
654 _slave_state = Waiting;
658 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
660 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
661 average_slave_delta = 0L;
663 Location* al = _locations->auto_loop_location();
665 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
667 request_play_loop(false);
670 if (slave_transport_frame != _transport_frame) {
671 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
672 locate (slave_transport_frame, false, false);
674 _slave_state = Running;
683 if (_slave_state == Waiting) {
685 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
687 if (slave_transport_frame >= slave_wait_end) {
689 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
691 _slave_state = Running;
693 /* now perform a "micro-seek" within the disk buffers to realign ourselves
694 precisely with the master.
699 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
701 boost::shared_ptr<RouteList> rl = routes.reader();
702 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
703 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
704 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
711 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
712 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
714 tr->internal_playback_seek (frame_delta);
717 _transport_frame += frame_delta;
720 cerr << "cannot micro-seek\n";
726 if (_slave_state == Running && _transport_speed == 0.0f) {
727 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
731 } else { // slave_speed is 0
733 /* slave has stopped */
735 if (_transport_speed != 0.0f) {
736 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
740 if (slave_transport_frame != _transport_frame) {
741 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
742 force_locate (slave_transport_frame, false);
750 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
752 if (slave_speed && _transport_speed) {
754 /* something isn't right, but we should move with the master
760 silent_process_routes (nframes, need_butler);
762 get_track_statistics ();
768 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
770 if (frames_moved < 0) {
771 decrement_transport_position (-frames_moved);
773 increment_transport_position (frames_moved);
776 framepos_t const stop_limit = compute_stop_limit ();
777 maybe_stop (stop_limit);
782 Session::process_without_events (pframes_t nframes)
784 bool session_needs_butler = false;
785 framecnt_t frames_moved;
787 if (!process_can_proceed()) {
792 if (!_exporting && _slave) {
793 if (!follow_slave (nframes)) {
794 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
799 if (_transport_speed == 0) {
804 if (_transport_speed == 1.0) {
805 frames_moved = (framecnt_t) nframes;
807 interpolation.set_target_speed (_target_transport_speed);
808 interpolation.set_speed (_transport_speed);
809 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
812 if (!_exporting && !timecode_transmission_suspended()) {
813 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
816 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
818 framepos_t const stop_limit = compute_stop_limit ();
820 if (maybe_stop (stop_limit)) {
825 if (maybe_sync_start (nframes)) {
829 click (_transport_frame, nframes);
831 if (process_routes (nframes, session_needs_butler)) {
836 get_track_statistics ();
838 if (frames_moved < 0) {
839 decrement_transport_position (-frames_moved);
841 increment_transport_position (frames_moved);
844 maybe_stop (stop_limit);
845 check_declick_out ();
847 if (session_needs_butler) {
852 /** Process callback used when the auditioner is active.
853 * @param nframes number of frames to process.
856 Session::process_audition (pframes_t nframes)
859 boost::shared_ptr<RouteList> r = routes.reader ();
861 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
862 if (!(*i)->is_hidden()) {
863 (*i)->silence (nframes);
867 /* run the auditioner, and if it says we need butler service, ask for it */
869 if (auditioner->play_audition (nframes) > 0) {
873 /* if using a monitor section, run it because otherwise we don't hear anything */
875 if (auditioner->needs_monitor()) {
876 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
879 /* handle pending events */
881 while (pending_events.read (&ev, 1) == 1) {
885 /* if we are not in the middle of a state change,
886 and there are immediate events queued up,
890 while (!non_realtime_work_pending() && !immediate_events.empty()) {
891 SessionEvent *ev = immediate_events.front ();
892 immediate_events.pop_front ();
896 if (!auditioner->auditioning()) {
897 /* auditioner no longer active, so go back to the normal process callback */
898 process_function = &Session::process_with_events;
903 Session::maybe_sync_start (pframes_t & nframes)
905 pframes_t sync_offset;
907 if (!waiting_for_sync_offset) {
911 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
913 /* generate silence up to the sync point, then
914 adjust nframes + offset to reflect whatever
918 no_roll (sync_offset);
919 nframes -= sync_offset;
920 Port::increment_global_port_buffer_offset (sync_offset);
921 waiting_for_sync_offset = false;
924 return true; // done, nothing left to process
929 /* sync offset point is not within this process()
930 cycle, so just generate silence. and don't bother
931 with any fancy stuff here, just the minimal silence.
936 if (Config->get_locate_while_waiting_for_sync()) {
937 if (micro_locate (nframes)) {
938 /* XXX ERROR !!! XXX */
942 return true; // done, nothing left to process
949 Session::queue_event (SessionEvent* ev)
951 if (_state_of_the_state & Deletion) {
953 } else if (_state_of_the_state & Loading) {
956 pending_events.write (&ev, 1);
961 Session::set_next_event ()
963 if (events.empty()) {
964 next_event = events.end();
968 if (next_event == events.end()) {
969 next_event = events.begin();
972 if ((*next_event)->action_frame > _transport_frame) {
973 next_event = events.begin();
976 for (; next_event != events.end(); ++next_event) {
977 if ((*next_event)->action_frame >= _transport_frame) {
984 Session::process_event (SessionEvent* ev)
989 /* if we're in the middle of a state change (i.e. waiting
990 for the butler thread to complete the non-realtime
991 part of the change), we'll just have to queue this
992 event for a time when the change is complete.
995 if (non_realtime_work_pending()) {
997 /* except locates, which we have the capability to handle */
999 if (ev->type != SessionEvent::Locate) {
1000 immediate_events.insert (immediate_events.end(), ev);
1006 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1009 case SessionEvent::SetLoop:
1010 set_play_loop (ev->yes_or_no);
1013 case SessionEvent::AutoLoop:
1015 /* roll after locate, do not flush, set "with loop"
1016 true only if we are seamless looping
1018 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1024 case SessionEvent::AutoLoopDeclick:
1026 /* Request a declick fade-out and a fade-in; the fade-out will happen
1027 at the end of the loop, and the fade-in at the start.
1029 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1035 case SessionEvent::Locate:
1036 if (ev->yes_or_no) {
1037 /* args: do not roll after locate, do flush, not with loop */
1038 locate (ev->target_frame, false, true, false);
1040 /* args: do not roll after locate, do flush, not with loop */
1041 start_locate (ev->target_frame, false, true, false);
1043 _send_timecode_update = true;
1046 case SessionEvent::LocateRoll:
1047 if (ev->yes_or_no) {
1048 /* args: roll after locate, do flush, not with loop */
1049 locate (ev->target_frame, true, true, false);
1051 /* args: roll after locate, do flush, not with loop */
1052 start_locate (ev->target_frame, true, true, false);
1054 _send_timecode_update = true;
1057 case SessionEvent::LocateRollLocate:
1058 // locate is handled by ::request_roll_at_and_return()
1059 _requested_return_frame = ev->target_frame;
1060 request_locate (ev->target2_frame, true);
1064 case SessionEvent::SetTransportSpeed:
1065 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1068 case SessionEvent::PunchIn:
1069 // cerr << "PunchIN at " << transport_frame() << endl;
1070 if (config.get_punch_in() && record_status() == Enabled) {
1077 case SessionEvent::PunchOut:
1078 // cerr << "PunchOUT at " << transport_frame() << endl;
1079 if (config.get_punch_out()) {
1080 step_back_from_record ();
1086 case SessionEvent::StopOnce:
1087 if (!non_realtime_work_pending()) {
1088 stop_transport (ev->yes_or_no);
1089 _clear_event_type (SessionEvent::StopOnce);
1095 case SessionEvent::RangeStop:
1096 if (!non_realtime_work_pending()) {
1097 stop_transport (ev->yes_or_no);
1103 case SessionEvent::RangeLocate:
1104 /* args: roll after locate, do flush, not with loop */
1105 start_locate (ev->target_frame, true, true, false);
1110 case SessionEvent::Overwrite:
1111 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1114 case SessionEvent::SetTrackSpeed:
1115 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1118 case SessionEvent::SetSyncSource:
1119 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1120 use_sync_source (ev->slave);
1123 case SessionEvent::Audition:
1124 set_audition (ev->region);
1125 // drop reference to region
1126 ev->region.reset ();
1129 case SessionEvent::InputConfigurationChange:
1130 add_post_transport_work (PostTransportInputChange);
1131 _butler->schedule_transport_work ();
1134 case SessionEvent::SetPlayAudioRange:
1135 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1138 case SessionEvent::RealTimeOperation:
1140 del = false; // other side of RT request needs to clean up
1143 case SessionEvent::AdjustPlaybackBuffering:
1144 schedule_playback_buffering_adjustment ();
1147 case SessionEvent::AdjustCaptureBuffering:
1148 schedule_capture_buffering_adjustment ();
1151 case SessionEvent::SetTimecodeTransmission:
1152 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1156 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1162 del = del && !_remove_event (ev);
1171 Session::compute_stop_limit () const
1173 if (!Config->get_stop_at_session_end ()) {
1174 return max_framepos;
1178 return max_framepos;
1182 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1183 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1185 if (actively_recording ()) {
1186 /* permanently recording */
1187 return max_framepos;
1188 } else if (punching_in && !punching_out) {
1189 /* punching in but never out */
1190 return max_framepos;
1191 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1192 /* punching in and punching out after session end */
1193 return max_framepos;
1196 return current_end_frame ();