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);
120 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
123 if (_process_graph) {
124 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
125 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
127 PT_TIMING_CHECK (10);
128 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
130 if ((*i)->is_hidden()) {
134 (*i)->set_pending_declick (declick);
136 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
137 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
142 PT_TIMING_CHECK (11);
149 /** @param need_butler to be set to true by this method if it needs the butler,
150 * otherwise it must be left alone.
153 Session::process_routes (pframes_t nframes, bool& need_butler)
155 int declick = get_transport_declick_required();
156 boost::shared_ptr<RouteList> r = routes.reader ();
158 if (transport_sub_state & StopPendingCapture) {
159 /* force a declick out */
163 const framepos_t start_frame = _transport_frame;
164 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
166 if (_process_graph) {
167 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
168 _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
171 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
175 if ((*i)->is_hidden()) {
179 (*i)->set_pending_declick (declick);
183 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
197 /** @param need_butler to be set to true by this method if it needs the butler,
198 * otherwise it must be left alone.
201 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
203 boost::shared_ptr<RouteList> r = routes.reader ();
205 const framepos_t start_frame = _transport_frame;
206 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
208 if (_process_graph) {
209 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
211 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
215 if ((*i)->is_hidden()) {
221 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
236 Session::get_track_statistics ()
241 boost::shared_ptr<RouteList> rl = routes.reader();
242 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
244 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
246 if (!tr || tr->hidden()) {
250 pworst = min (pworst, tr->playback_buffer_load());
251 cworst = min (cworst, tr->capture_buffer_load());
254 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
255 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
257 if (actively_recording()) {
262 /** Process callback used when the auditioner is not active */
264 Session::process_with_events (pframes_t nframes)
269 pframes_t this_nframes;
270 framepos_t end_frame;
271 bool session_needs_butler = false;
272 framecnt_t frames_moved;
274 /* make sure the auditioner is silent */
277 auditioner->silence (nframes);
280 /* handle any pending events */
282 while (pending_events.read (&ev, 1) == 1) {
286 /* if we are not in the middle of a state change,
287 and there are immediate events queued up,
291 while (!non_realtime_work_pending() && !immediate_events.empty()) {
292 SessionEvent *ev = immediate_events.front ();
293 immediate_events.pop_front ();
297 /* Decide on what to do with quarter-frame MTC during this cycle */
299 bool const was_sending_qf_mtc = _send_qf_mtc;
300 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
302 if (_transport_speed != 0) {
304 Config->get_send_mtc () &&
305 _transport_speed >= (1 - tolerance) &&
306 _transport_speed <= (1 + tolerance)
309 if (_send_qf_mtc && !was_sending_qf_mtc) {
310 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
311 _send_timecode_update = true;
314 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
315 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
316 a quarter of a second since we sent anything at all, so send a full MTC update
319 _send_timecode_update = true;
322 _pframes_since_last_mtc += nframes;
325 /* Events caused a transport change (or we re-started sending
326 * MTC), so send an MTC Full Frame (Timecode) message. This
327 * is sent whether rolling or not, to give slaves an idea of
328 * ardour time on locates (and allow slow slaves to position
329 * and prepare for rolling)
331 if (_send_timecode_update) {
332 send_full_time_code (_transport_frame);
335 if (!process_can_proceed()) {
340 if (events.empty() || next_event == events.end()) {
341 process_without_events (nframes);
345 if (_transport_speed == 1.0) {
346 frames_moved = (framecnt_t) nframes;
348 interpolation.set_target_speed (_target_transport_speed);
349 interpolation.set_speed (_transport_speed);
350 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
353 end_frame = _transport_frame + frames_moved;
356 SessionEvent* this_event;
357 Events::iterator the_next_one;
359 if (!process_can_proceed()) {
364 if (!_exporting && _slave) {
365 if (!follow_slave (nframes)) {
370 if (_transport_speed == 0) {
375 if (!_exporting && !timecode_transmission_suspended()) {
376 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
379 framepos_t stop_limit = compute_stop_limit ();
381 if (maybe_stop (stop_limit)) {
386 this_event = *next_event;
387 the_next_one = next_event;
390 /* yes folks, here it is, the actual loop where we really truly
396 this_nframes = nframes; /* real (jack) time relative */
397 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
399 /* running an event, position transport precisely to its time */
400 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
401 /* this isn't quite right for reverse play */
402 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
403 this_nframes = abs (floor(frames_moved / _transport_speed));
408 click (_transport_frame, this_nframes);
410 if (process_routes (this_nframes, session_needs_butler)) {
415 get_track_statistics ();
417 nframes -= this_nframes;
419 if (frames_moved < 0) {
420 decrement_transport_position (-frames_moved);
422 increment_transport_position (frames_moved);
425 maybe_stop (stop_limit);
426 check_declick_out ();
429 _engine.split_cycle (this_nframes);
431 /* now handle this event and all others scheduled for the same time */
433 while (this_event && this_event->action_frame == _transport_frame) {
434 process_event (this_event);
436 if (the_next_one == events.end()) {
439 this_event = *the_next_one;
444 /* if an event left our state changing, do the right thing */
446 if (nframes && non_realtime_work_pending()) {
451 /* this is necessary to handle the case of seamless looping */
452 end_frame = _transport_frame + floor (nframes * _transport_speed);
457 } /* implicit release of route lock */
459 if (session_needs_butler) {
465 Session::reset_slave_state ()
467 average_slave_delta = 1800;
468 delta_accumulator_cnt = 0;
469 have_first_delta_accumulator = false;
470 _slave_state = Stopped;
474 Session::transport_locked () const
478 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
486 Session::follow_slave (pframes_t nframes)
489 framepos_t slave_transport_frame;
490 framecnt_t this_delta;
495 config.set_external_sync (false);
499 _slave->speed_and_position (slave_speed, slave_transport_frame);
501 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
503 if (!_slave->locked()) {
504 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
508 if (slave_transport_frame > _transport_frame) {
509 this_delta = slave_transport_frame - _transport_frame;
512 this_delta = _transport_frame - slave_transport_frame;
516 if (_slave->starting()) {
520 if (_slave->is_always_synced() || Config->get_timecode_source_is_synced()) {
522 /* if the TC source is synced, then we assume that its
523 speed is binary: 0.0 or 1.0
526 if (slave_speed != 0.0f) {
532 /* if we are chasing and the average delta between us and the
533 master gets too big, we want to switch to silent
534 motion. so keep track of that here.
537 if (_slave_state == Running) {
538 calculate_moving_average_of_slave_delta(dir, this_delta);
542 track_slave_state (slave_speed, slave_transport_frame, this_delta);
544 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
545 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
548 if (_slave_state == Running && !_slave->is_always_synced() && !Config->get_timecode_source_is_synced()) {
550 if (_transport_speed != 0.0f) {
553 note that average_dir is +1 or -1
558 if (average_slave_delta == 0) {
562 delta = average_slave_delta;
563 delta *= average_dir;
567 if (slave_speed != 0.0) {
568 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
569 (int) (dir * this_delta),
573 slave_transport_frame,
574 average_slave_delta));
578 if (_slave->give_slave_full_control_over_transport_speed()) {
579 set_transport_speed (slave_speed, false, false);
580 //std::cout << "set speed = " << slave_speed << "\n";
582 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
583 request_transport_speed (adjusted_speed);
584 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
585 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
590 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
591 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
599 if (_slave_state == Running && !non_realtime_work_pending()) {
600 /* speed is set, we're locked, and good to go */
605 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
606 follow_slave_silently (nframes, slave_speed);
609 /* don't move at all */
610 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
616 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
618 if (delta_accumulator_cnt >= delta_accumulator_size) {
619 have_first_delta_accumulator = true;
620 delta_accumulator_cnt = 0;
623 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
624 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
627 if (have_first_delta_accumulator) {
628 average_slave_delta = 0L;
629 for (int i = 0; i < delta_accumulator_size; ++i) {
630 average_slave_delta += delta_accumulator[i];
632 average_slave_delta /= (int32_t) delta_accumulator_size;
633 if (average_slave_delta < 0L) {
635 average_slave_delta = abs(average_slave_delta);
643 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
645 if (slave_speed != 0.0f) {
647 /* slave is running */
649 switch (_slave_state) {
651 if (_slave->requires_seekahead()) {
652 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
653 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
654 /* we can call locate() here because we are in process context */
655 locate (slave_wait_end, false, false);
656 _slave_state = Waiting;
660 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
662 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
663 average_slave_delta = 0L;
665 Location* al = _locations->auto_loop_location();
667 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
669 request_play_loop(false);
672 if (slave_transport_frame != _transport_frame) {
673 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
674 locate (slave_transport_frame, false, false);
676 _slave_state = Running;
685 if (_slave_state == Waiting) {
687 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
689 if (slave_transport_frame >= slave_wait_end) {
691 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
693 _slave_state = Running;
695 /* now perform a "micro-seek" within the disk buffers to realign ourselves
696 precisely with the master.
701 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
703 boost::shared_ptr<RouteList> rl = routes.reader();
704 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
705 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
706 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
713 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
714 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
716 tr->internal_playback_seek (frame_delta);
719 _transport_frame += frame_delta;
722 cerr << "cannot micro-seek\n";
728 if (_slave_state == Running && _transport_speed == 0.0f) {
729 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
733 } else { // slave_speed is 0
735 /* slave has stopped */
737 if (_transport_speed != 0.0f) {
738 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
742 if (slave_transport_frame != _transport_frame) {
743 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
744 force_locate (slave_transport_frame, false);
752 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
754 if (slave_speed && _transport_speed) {
756 /* something isn't right, but we should move with the master
762 silent_process_routes (nframes, need_butler);
764 get_track_statistics ();
770 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
772 if (frames_moved < 0) {
773 decrement_transport_position (-frames_moved);
775 increment_transport_position (frames_moved);
778 framepos_t const stop_limit = compute_stop_limit ();
779 maybe_stop (stop_limit);
784 Session::process_without_events (pframes_t nframes)
786 bool session_needs_butler = false;
787 framecnt_t frames_moved;
789 if (!process_can_proceed()) {
794 if (!_exporting && _slave) {
795 if (!follow_slave (nframes)) {
797 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
803 if (_transport_speed == 0) {
808 if (_transport_speed == 1.0) {
809 frames_moved = (framecnt_t) nframes;
811 interpolation.set_target_speed (_target_transport_speed);
812 interpolation.set_speed (_transport_speed);
813 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
816 if (!_exporting && !timecode_transmission_suspended()) {
817 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
821 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
824 framepos_t const stop_limit = compute_stop_limit ();
826 if (maybe_stop (stop_limit)) {
831 if (maybe_sync_start (nframes)) {
835 click (_transport_frame, nframes);
837 if (process_routes (nframes, session_needs_butler)) {
842 get_track_statistics ();
844 if (frames_moved < 0) {
845 decrement_transport_position (-frames_moved);
847 increment_transport_position (frames_moved);
850 maybe_stop (stop_limit);
851 check_declick_out ();
853 if (session_needs_butler) {
858 /** Process callback used when the auditioner is active.
859 * @param nframes number of frames to process.
862 Session::process_audition (pframes_t nframes)
865 boost::shared_ptr<RouteList> r = routes.reader ();
867 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
868 if (!(*i)->is_hidden()) {
869 (*i)->silence (nframes);
873 /* run the auditioner, and if it says we need butler service, ask for it */
875 if (auditioner->play_audition (nframes) > 0) {
879 /* if using a monitor section, run it because otherwise we don't hear anything */
881 if (auditioner->needs_monitor()) {
882 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
885 /* handle pending events */
887 while (pending_events.read (&ev, 1) == 1) {
891 /* if we are not in the middle of a state change,
892 and there are immediate events queued up,
896 while (!non_realtime_work_pending() && !immediate_events.empty()) {
897 SessionEvent *ev = immediate_events.front ();
898 immediate_events.pop_front ();
902 if (!auditioner->auditioning()) {
903 /* auditioner no longer active, so go back to the normal process callback */
904 process_function = &Session::process_with_events;
909 Session::maybe_sync_start (pframes_t & nframes)
911 pframes_t sync_offset;
913 if (!waiting_for_sync_offset) {
917 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
919 /* generate silence up to the sync point, then
920 adjust nframes + offset to reflect whatever
924 no_roll (sync_offset);
925 nframes -= sync_offset;
926 Port::increment_global_port_buffer_offset (sync_offset);
927 waiting_for_sync_offset = false;
930 return true; // done, nothing left to process
935 /* sync offset point is not within this process()
936 cycle, so just generate silence. and don't bother
937 with any fancy stuff here, just the minimal silence.
942 if (Config->get_locate_while_waiting_for_sync()) {
943 if (micro_locate (nframes)) {
944 /* XXX ERROR !!! XXX */
948 return true; // done, nothing left to process
955 Session::queue_event (SessionEvent* ev)
957 if (_state_of_the_state & Deletion) {
959 } else if (_state_of_the_state & Loading) {
962 pending_events.write (&ev, 1);
967 Session::set_next_event ()
969 if (events.empty()) {
970 next_event = events.end();
974 if (next_event == events.end()) {
975 next_event = events.begin();
978 if ((*next_event)->action_frame > _transport_frame) {
979 next_event = events.begin();
982 for (; next_event != events.end(); ++next_event) {
983 if ((*next_event)->action_frame >= _transport_frame) {
990 Session::process_event (SessionEvent* ev)
995 /* if we're in the middle of a state change (i.e. waiting
996 for the butler thread to complete the non-realtime
997 part of the change), we'll just have to queue this
998 event for a time when the change is complete.
1001 if (non_realtime_work_pending()) {
1003 /* except locates, which we have the capability to handle */
1005 if (ev->type != SessionEvent::Locate) {
1006 immediate_events.insert (immediate_events.end(), ev);
1012 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1015 case SessionEvent::SetLoop:
1016 set_play_loop (ev->yes_or_no);
1019 case SessionEvent::AutoLoop:
1021 /* roll after locate, do not flush, set "with loop"
1022 true only if we are seamless looping
1024 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1030 case SessionEvent::AutoLoopDeclick:
1032 /* Request a declick fade-out and a fade-in; the fade-out will happen
1033 at the end of the loop, and the fade-in at the start.
1035 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1041 case SessionEvent::Locate:
1042 if (ev->yes_or_no) {
1043 /* args: do not roll after locate, do flush, not with loop */
1044 locate (ev->target_frame, false, true, false);
1046 /* args: do not roll after locate, do flush, not with loop */
1047 start_locate (ev->target_frame, false, true, false);
1049 _send_timecode_update = true;
1052 case SessionEvent::LocateRoll:
1053 if (ev->yes_or_no) {
1054 /* args: roll after locate, do flush, not with loop */
1055 locate (ev->target_frame, true, true, false);
1057 /* args: roll after locate, do flush, not with loop */
1058 start_locate (ev->target_frame, true, true, false);
1060 _send_timecode_update = true;
1063 case SessionEvent::LocateRollLocate:
1064 // locate is handled by ::request_roll_at_and_return()
1065 _requested_return_frame = ev->target_frame;
1066 request_locate (ev->target2_frame, true);
1070 case SessionEvent::SetTransportSpeed:
1071 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1074 case SessionEvent::PunchIn:
1075 // cerr << "PunchIN at " << transport_frame() << endl;
1076 if (config.get_punch_in() && record_status() == Enabled) {
1083 case SessionEvent::PunchOut:
1084 // cerr << "PunchOUT at " << transport_frame() << endl;
1085 if (config.get_punch_out()) {
1086 step_back_from_record ();
1092 case SessionEvent::StopOnce:
1093 if (!non_realtime_work_pending()) {
1094 stop_transport (ev->yes_or_no);
1095 _clear_event_type (SessionEvent::StopOnce);
1101 case SessionEvent::RangeStop:
1102 if (!non_realtime_work_pending()) {
1103 stop_transport (ev->yes_or_no);
1109 case SessionEvent::RangeLocate:
1110 /* args: roll after locate, do flush, not with loop */
1111 start_locate (ev->target_frame, true, true, false);
1116 case SessionEvent::Overwrite:
1117 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1120 case SessionEvent::SetTrackSpeed:
1121 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1124 case SessionEvent::SetSyncSource:
1125 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1126 use_sync_source (ev->slave);
1129 case SessionEvent::Audition:
1130 set_audition (ev->region);
1131 // drop reference to region
1132 ev->region.reset ();
1135 case SessionEvent::InputConfigurationChange:
1136 add_post_transport_work (PostTransportInputChange);
1137 _butler->schedule_transport_work ();
1140 case SessionEvent::SetPlayAudioRange:
1141 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1144 case SessionEvent::RealTimeOperation:
1146 del = false; // other side of RT request needs to clean up
1149 case SessionEvent::AdjustPlaybackBuffering:
1150 schedule_playback_buffering_adjustment ();
1153 case SessionEvent::AdjustCaptureBuffering:
1154 schedule_capture_buffering_adjustment ();
1157 case SessionEvent::SetTimecodeTransmission:
1158 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1162 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1168 del = del && !_remove_event (ev);
1177 Session::compute_stop_limit () const
1179 if (!Config->get_stop_at_session_end ()) {
1180 return max_framepos;
1183 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1184 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1186 if (actively_recording ()) {
1187 /* permanently recording */
1188 return max_framepos;
1189 } else if (punching_in && !punching_out) {
1190 /* punching in but never out */
1191 return max_framepos;
1192 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1193 /* punching in and punching out after session end */
1194 return max_framepos;
1197 return current_end_frame ();