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 if (_process_graph) {
120 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
121 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
123 PT_TIMING_CHECK (10);
124 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
126 if ((*i)->is_hidden()) {
130 (*i)->set_pending_declick (declick);
132 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
133 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
138 PT_TIMING_CHECK (11);
145 /** @param need_butler to be set to true by this method if it needs the butler,
146 * otherwise it must be left alone.
149 Session::process_routes (pframes_t nframes, bool& need_butler)
151 int declick = get_transport_declick_required();
152 boost::shared_ptr<RouteList> r = routes.reader ();
154 if (transport_sub_state & StopPendingCapture) {
155 /* force a declick out */
159 const framepos_t start_frame = _transport_frame;
160 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
162 if (_process_graph) {
163 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
164 _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
167 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
171 if ((*i)->is_hidden()) {
175 (*i)->set_pending_declick (declick);
179 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
193 /** @param need_butler to be set to true by this method if it needs the butler,
194 * otherwise it must be left alone.
197 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
199 boost::shared_ptr<RouteList> r = routes.reader ();
201 const framepos_t start_frame = _transport_frame;
202 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
204 if (_process_graph) {
205 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
207 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
211 if ((*i)->is_hidden()) {
217 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
232 Session::get_track_statistics ()
237 boost::shared_ptr<RouteList> rl = routes.reader();
238 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
240 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
242 if (!tr || tr->hidden()) {
246 pworst = min (pworst, tr->playback_buffer_load());
247 cworst = min (cworst, tr->capture_buffer_load());
250 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
251 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
253 if (actively_recording()) {
258 /** Process callback used when the auditioner is not active */
260 Session::process_with_events (pframes_t nframes)
265 pframes_t this_nframes;
266 framepos_t end_frame;
267 bool session_needs_butler = false;
268 framecnt_t frames_moved;
270 /* make sure the auditioner is silent */
273 auditioner->silence (nframes);
276 /* handle any pending events */
278 while (pending_events.read (&ev, 1) == 1) {
282 /* if we are not in the middle of a state change,
283 and there are immediate events queued up,
287 while (!non_realtime_work_pending() && !immediate_events.empty()) {
288 SessionEvent *ev = immediate_events.front ();
289 immediate_events.pop_front ();
293 /* Decide on what to do with quarter-frame MTC during this cycle */
295 bool const was_sending_qf_mtc = _send_qf_mtc;
296 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
298 if (_transport_speed != 0) {
300 Config->get_send_mtc () &&
301 _transport_speed >= (1 - tolerance) &&
302 _transport_speed <= (1 + tolerance)
305 if (_send_qf_mtc && !was_sending_qf_mtc) {
306 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
307 _send_timecode_update = true;
310 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
311 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
312 a quarter of a second since we sent anything at all, so send a full MTC update
315 _send_timecode_update = true;
318 _pframes_since_last_mtc += nframes;
321 /* Events caused a transport change (or we re-started sending
322 * MTC), so send an MTC Full Frame (Timecode) message. This
323 * is sent whether rolling or not, to give slaves an idea of
324 * ardour time on locates (and allow slow slaves to position
325 * and prepare for rolling)
327 if (_send_timecode_update) {
328 send_full_time_code (_transport_frame);
331 if (!process_can_proceed()) {
336 if (events.empty() || next_event == events.end()) {
337 process_without_events (nframes);
341 if (_transport_speed == 1.0) {
342 frames_moved = (framecnt_t) nframes;
344 interpolation.set_target_speed (_target_transport_speed);
345 interpolation.set_speed (_transport_speed);
346 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
349 end_frame = _transport_frame + frames_moved;
352 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
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) {
807 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
813 if (_transport_speed == 1.0) {
814 frames_moved = (framecnt_t) nframes;
816 interpolation.set_target_speed (_target_transport_speed);
817 interpolation.set_speed (_transport_speed);
818 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
821 if (!_exporting && !timecode_transmission_suspended()) {
822 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
827 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
831 framepos_t const stop_limit = compute_stop_limit ();
833 if (maybe_stop (stop_limit)) {
838 if (maybe_sync_start (nframes)) {
842 click (_transport_frame, nframes);
844 if (process_routes (nframes, session_needs_butler)) {
849 get_track_statistics ();
851 if (frames_moved < 0) {
852 decrement_transport_position (-frames_moved);
854 increment_transport_position (frames_moved);
857 maybe_stop (stop_limit);
858 check_declick_out ();
860 if (session_needs_butler) {
865 /** Process callback used when the auditioner is active.
866 * @param nframes number of frames to process.
869 Session::process_audition (pframes_t nframes)
872 boost::shared_ptr<RouteList> r = routes.reader ();
874 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
875 if (!(*i)->is_hidden()) {
876 (*i)->silence (nframes);
880 /* run the auditioner, and if it says we need butler service, ask for it */
882 if (auditioner->play_audition (nframes) > 0) {
886 /* if using a monitor section, run it because otherwise we don't hear anything */
888 if (auditioner->needs_monitor()) {
889 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
892 /* handle pending events */
894 while (pending_events.read (&ev, 1) == 1) {
898 /* if we are not in the middle of a state change,
899 and there are immediate events queued up,
903 while (!non_realtime_work_pending() && !immediate_events.empty()) {
904 SessionEvent *ev = immediate_events.front ();
905 immediate_events.pop_front ();
909 if (!auditioner->auditioning()) {
910 /* auditioner no longer active, so go back to the normal process callback */
911 process_function = &Session::process_with_events;
916 Session::maybe_sync_start (pframes_t & nframes)
918 pframes_t sync_offset;
920 if (!waiting_for_sync_offset) {
924 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
926 /* generate silence up to the sync point, then
927 adjust nframes + offset to reflect whatever
931 no_roll (sync_offset);
932 nframes -= sync_offset;
933 Port::increment_global_port_buffer_offset (sync_offset);
934 waiting_for_sync_offset = false;
937 return true; // done, nothing left to process
942 /* sync offset point is not within this process()
943 cycle, so just generate silence. and don't bother
944 with any fancy stuff here, just the minimal silence.
949 if (Config->get_locate_while_waiting_for_sync()) {
950 if (micro_locate (nframes)) {
951 /* XXX ERROR !!! XXX */
955 return true; // done, nothing left to process
962 Session::queue_event (SessionEvent* ev)
964 if (_state_of_the_state & Deletion) {
966 } else if (_state_of_the_state & Loading) {
969 pending_events.write (&ev, 1);
974 Session::set_next_event ()
976 if (events.empty()) {
977 next_event = events.end();
981 if (next_event == events.end()) {
982 next_event = events.begin();
985 if ((*next_event)->action_frame > _transport_frame) {
986 next_event = events.begin();
989 for (; next_event != events.end(); ++next_event) {
990 if ((*next_event)->action_frame >= _transport_frame) {
997 Session::process_event (SessionEvent* ev)
1002 /* if we're in the middle of a state change (i.e. waiting
1003 for the butler thread to complete the non-realtime
1004 part of the change), we'll just have to queue this
1005 event for a time when the change is complete.
1008 if (non_realtime_work_pending()) {
1010 /* except locates, which we have the capability to handle */
1012 if (ev->type != SessionEvent::Locate) {
1013 immediate_events.insert (immediate_events.end(), ev);
1019 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1022 case SessionEvent::SetLoop:
1023 set_play_loop (ev->yes_or_no);
1026 case SessionEvent::AutoLoop:
1028 /* roll after locate, do not flush, set "with loop"
1029 true only if we are seamless looping
1031 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1037 case SessionEvent::AutoLoopDeclick:
1039 /* Request a declick fade-out and a fade-in; the fade-out will happen
1040 at the end of the loop, and the fade-in at the start.
1042 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1048 case SessionEvent::Locate:
1049 if (ev->yes_or_no) {
1050 /* args: do not roll after locate, do flush, not with loop */
1051 locate (ev->target_frame, false, true, false);
1053 /* args: do not roll after locate, do flush, not with loop */
1054 start_locate (ev->target_frame, false, true, false);
1056 _send_timecode_update = true;
1059 case SessionEvent::LocateRoll:
1060 if (ev->yes_or_no) {
1061 /* args: roll after locate, do flush, not with loop */
1062 locate (ev->target_frame, true, true, false);
1064 /* args: roll after locate, do flush, not with loop */
1065 start_locate (ev->target_frame, true, true, false);
1067 _send_timecode_update = true;
1070 case SessionEvent::LocateRollLocate:
1071 // locate is handled by ::request_roll_at_and_return()
1072 _requested_return_frame = ev->target_frame;
1073 request_locate (ev->target2_frame, true);
1077 case SessionEvent::SetTransportSpeed:
1078 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1081 case SessionEvent::PunchIn:
1082 // cerr << "PunchIN at " << transport_frame() << endl;
1083 if (config.get_punch_in() && record_status() == Enabled) {
1090 case SessionEvent::PunchOut:
1091 // cerr << "PunchOUT at " << transport_frame() << endl;
1092 if (config.get_punch_out()) {
1093 step_back_from_record ();
1099 case SessionEvent::StopOnce:
1100 if (!non_realtime_work_pending()) {
1101 stop_transport (ev->yes_or_no);
1102 _clear_event_type (SessionEvent::StopOnce);
1108 case SessionEvent::RangeStop:
1109 if (!non_realtime_work_pending()) {
1110 stop_transport (ev->yes_or_no);
1116 case SessionEvent::RangeLocate:
1117 /* args: roll after locate, do flush, not with loop */
1118 start_locate (ev->target_frame, true, true, false);
1123 case SessionEvent::Overwrite:
1124 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1127 case SessionEvent::SetTrackSpeed:
1128 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1131 case SessionEvent::SetSyncSource:
1132 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1133 use_sync_source (ev->slave);
1136 case SessionEvent::Audition:
1137 set_audition (ev->region);
1138 // drop reference to region
1139 ev->region.reset ();
1142 case SessionEvent::InputConfigurationChange:
1143 add_post_transport_work (PostTransportInputChange);
1144 _butler->schedule_transport_work ();
1147 case SessionEvent::SetPlayAudioRange:
1148 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1151 case SessionEvent::RealTimeOperation:
1153 del = false; // other side of RT request needs to clean up
1156 case SessionEvent::AdjustPlaybackBuffering:
1157 schedule_playback_buffering_adjustment ();
1160 case SessionEvent::AdjustCaptureBuffering:
1161 schedule_capture_buffering_adjustment ();
1164 case SessionEvent::SetTimecodeTransmission:
1165 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1169 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1175 del = del && !_remove_event (ev);
1184 Session::compute_stop_limit () const
1186 if (!Config->get_stop_at_session_end ()) {
1187 return max_framepos;
1190 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1191 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1193 if (actively_recording ()) {
1194 /* permanently recording */
1195 return max_framepos;
1196 } else if (punching_in && !punching_out) {
1197 /* punching in but never out */
1198 return max_framepos;
1199 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1200 /* punching in and punching out after session end */
1201 return max_framepos;
1204 return current_end_frame ();