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() ||
519 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
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() &&
549 !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
552 if (_transport_speed != 0.0f) {
555 note that average_dir is +1 or -1
560 if (average_slave_delta == 0) {
564 delta = average_slave_delta;
565 delta *= average_dir;
569 if (slave_speed != 0.0) {
570 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
571 (int) (dir * this_delta),
575 slave_transport_frame,
576 average_slave_delta));
580 if (_slave->give_slave_full_control_over_transport_speed()) {
581 set_transport_speed (slave_speed, false, false);
582 //std::cout << "set speed = " << slave_speed << "\n";
584 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
585 request_transport_speed (adjusted_speed);
586 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
587 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
592 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
593 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
601 if (_slave_state == Running && !non_realtime_work_pending()) {
602 /* speed is set, we're locked, and good to go */
607 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
608 follow_slave_silently (nframes, slave_speed);
611 /* don't move at all */
612 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
618 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
620 if (delta_accumulator_cnt >= delta_accumulator_size) {
621 have_first_delta_accumulator = true;
622 delta_accumulator_cnt = 0;
625 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
626 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
629 if (have_first_delta_accumulator) {
630 average_slave_delta = 0L;
631 for (int i = 0; i < delta_accumulator_size; ++i) {
632 average_slave_delta += delta_accumulator[i];
634 average_slave_delta /= (int32_t) delta_accumulator_size;
635 if (average_slave_delta < 0L) {
637 average_slave_delta = abs(average_slave_delta);
645 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
647 if (slave_speed != 0.0f) {
649 /* slave is running */
651 switch (_slave_state) {
653 if (_slave->requires_seekahead()) {
654 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
655 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
656 /* we can call locate() here because we are in process context */
657 locate (slave_wait_end, false, false);
658 _slave_state = Waiting;
662 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
664 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
665 average_slave_delta = 0L;
667 Location* al = _locations->auto_loop_location();
669 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
671 request_play_loop(false);
674 if (slave_transport_frame != _transport_frame) {
675 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
676 locate (slave_transport_frame, false, false);
678 _slave_state = Running;
687 if (_slave_state == Waiting) {
689 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
691 if (slave_transport_frame >= slave_wait_end) {
693 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
695 _slave_state = Running;
697 /* now perform a "micro-seek" within the disk buffers to realign ourselves
698 precisely with the master.
703 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
705 boost::shared_ptr<RouteList> rl = routes.reader();
706 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
707 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
708 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
715 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
716 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
718 tr->internal_playback_seek (frame_delta);
721 _transport_frame += frame_delta;
724 cerr << "cannot micro-seek\n";
730 if (_slave_state == Running && _transport_speed == 0.0f) {
731 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
735 } else { // slave_speed is 0
737 /* slave has stopped */
739 if (_transport_speed != 0.0f) {
740 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
744 if (slave_transport_frame != _transport_frame) {
745 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
746 force_locate (slave_transport_frame, false);
754 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
756 if (slave_speed && _transport_speed) {
758 /* something isn't right, but we should move with the master
764 silent_process_routes (nframes, need_butler);
766 get_track_statistics ();
772 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
774 if (frames_moved < 0) {
775 decrement_transport_position (-frames_moved);
777 increment_transport_position (frames_moved);
780 framepos_t const stop_limit = compute_stop_limit ();
781 maybe_stop (stop_limit);
786 Session::process_without_events (pframes_t nframes)
788 bool session_needs_butler = false;
789 framecnt_t frames_moved;
791 if (!process_can_proceed()) {
796 if (!_exporting && _slave) {
797 if (!follow_slave (nframes)) {
798 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);
820 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
822 framepos_t const stop_limit = compute_stop_limit ();
824 if (maybe_stop (stop_limit)) {
829 if (maybe_sync_start (nframes)) {
833 click (_transport_frame, nframes);
835 if (process_routes (nframes, session_needs_butler)) {
840 get_track_statistics ();
842 if (frames_moved < 0) {
843 decrement_transport_position (-frames_moved);
845 increment_transport_position (frames_moved);
848 maybe_stop (stop_limit);
849 check_declick_out ();
851 if (session_needs_butler) {
856 /** Process callback used when the auditioner is active.
857 * @param nframes number of frames to process.
860 Session::process_audition (pframes_t nframes)
863 boost::shared_ptr<RouteList> r = routes.reader ();
865 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
866 if (!(*i)->is_hidden()) {
867 (*i)->silence (nframes);
871 /* run the auditioner, and if it says we need butler service, ask for it */
873 if (auditioner->play_audition (nframes) > 0) {
877 /* if using a monitor section, run it because otherwise we don't hear anything */
879 if (auditioner->needs_monitor()) {
880 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
883 /* handle pending events */
885 while (pending_events.read (&ev, 1) == 1) {
889 /* if we are not in the middle of a state change,
890 and there are immediate events queued up,
894 while (!non_realtime_work_pending() && !immediate_events.empty()) {
895 SessionEvent *ev = immediate_events.front ();
896 immediate_events.pop_front ();
900 if (!auditioner->auditioning()) {
901 /* auditioner no longer active, so go back to the normal process callback */
902 process_function = &Session::process_with_events;
907 Session::maybe_sync_start (pframes_t & nframes)
909 pframes_t sync_offset;
911 if (!waiting_for_sync_offset) {
915 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
917 /* generate silence up to the sync point, then
918 adjust nframes + offset to reflect whatever
922 no_roll (sync_offset);
923 nframes -= sync_offset;
924 Port::increment_global_port_buffer_offset (sync_offset);
925 waiting_for_sync_offset = false;
928 return true; // done, nothing left to process
933 /* sync offset point is not within this process()
934 cycle, so just generate silence. and don't bother
935 with any fancy stuff here, just the minimal silence.
940 if (Config->get_locate_while_waiting_for_sync()) {
941 if (micro_locate (nframes)) {
942 /* XXX ERROR !!! XXX */
946 return true; // done, nothing left to process
953 Session::queue_event (SessionEvent* ev)
955 if (_state_of_the_state & Deletion) {
957 } else if (_state_of_the_state & Loading) {
960 pending_events.write (&ev, 1);
965 Session::set_next_event ()
967 if (events.empty()) {
968 next_event = events.end();
972 if (next_event == events.end()) {
973 next_event = events.begin();
976 if ((*next_event)->action_frame > _transport_frame) {
977 next_event = events.begin();
980 for (; next_event != events.end(); ++next_event) {
981 if ((*next_event)->action_frame >= _transport_frame) {
988 Session::process_event (SessionEvent* ev)
993 /* if we're in the middle of a state change (i.e. waiting
994 for the butler thread to complete the non-realtime
995 part of the change), we'll just have to queue this
996 event for a time when the change is complete.
999 if (non_realtime_work_pending()) {
1001 /* except locates, which we have the capability to handle */
1003 if (ev->type != SessionEvent::Locate) {
1004 immediate_events.insert (immediate_events.end(), ev);
1010 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1013 case SessionEvent::SetLoop:
1014 set_play_loop (ev->yes_or_no);
1017 case SessionEvent::AutoLoop:
1019 /* roll after locate, do not flush, set "with loop"
1020 true only if we are seamless looping
1022 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1028 case SessionEvent::AutoLoopDeclick:
1030 /* Request a declick fade-out and a fade-in; the fade-out will happen
1031 at the end of the loop, and the fade-in at the start.
1033 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1039 case SessionEvent::Locate:
1040 if (ev->yes_or_no) {
1041 /* args: do not roll after locate, do flush, not with loop */
1042 locate (ev->target_frame, false, true, false);
1044 /* args: do not roll after locate, do flush, not with loop */
1045 start_locate (ev->target_frame, false, true, false);
1047 _send_timecode_update = true;
1050 case SessionEvent::LocateRoll:
1051 if (ev->yes_or_no) {
1052 /* args: roll after locate, do flush, not with loop */
1053 locate (ev->target_frame, true, true, false);
1055 /* args: roll after locate, do flush, not with loop */
1056 start_locate (ev->target_frame, true, true, false);
1058 _send_timecode_update = true;
1061 case SessionEvent::LocateRollLocate:
1062 // locate is handled by ::request_roll_at_and_return()
1063 _requested_return_frame = ev->target_frame;
1064 request_locate (ev->target2_frame, true);
1068 case SessionEvent::SetTransportSpeed:
1069 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1072 case SessionEvent::PunchIn:
1073 // cerr << "PunchIN at " << transport_frame() << endl;
1074 if (config.get_punch_in() && record_status() == Enabled) {
1081 case SessionEvent::PunchOut:
1082 // cerr << "PunchOUT at " << transport_frame() << endl;
1083 if (config.get_punch_out()) {
1084 step_back_from_record ();
1090 case SessionEvent::StopOnce:
1091 if (!non_realtime_work_pending()) {
1092 stop_transport (ev->yes_or_no);
1093 _clear_event_type (SessionEvent::StopOnce);
1099 case SessionEvent::RangeStop:
1100 if (!non_realtime_work_pending()) {
1101 stop_transport (ev->yes_or_no);
1107 case SessionEvent::RangeLocate:
1108 /* args: roll after locate, do flush, not with loop */
1109 start_locate (ev->target_frame, true, true, false);
1114 case SessionEvent::Overwrite:
1115 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1118 case SessionEvent::SetTrackSpeed:
1119 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1122 case SessionEvent::SetSyncSource:
1123 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1124 use_sync_source (ev->slave);
1127 case SessionEvent::Audition:
1128 set_audition (ev->region);
1129 // drop reference to region
1130 ev->region.reset ();
1133 case SessionEvent::InputConfigurationChange:
1134 add_post_transport_work (PostTransportInputChange);
1135 _butler->schedule_transport_work ();
1138 case SessionEvent::SetPlayAudioRange:
1139 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1142 case SessionEvent::RealTimeOperation:
1144 del = false; // other side of RT request needs to clean up
1147 case SessionEvent::AdjustPlaybackBuffering:
1148 schedule_playback_buffering_adjustment ();
1151 case SessionEvent::AdjustCaptureBuffering:
1152 schedule_capture_buffering_adjustment ();
1155 case SessionEvent::SetTimecodeTransmission:
1156 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1160 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1166 del = del && !_remove_event (ev);
1175 Session::compute_stop_limit () const
1177 if (!Config->get_stop_at_session_end ()) {
1178 return max_framepos;
1182 return max_framepos;
1186 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1187 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1189 if (actively_recording ()) {
1190 /* permanently recording */
1191 return max_framepos;
1192 } else if (punching_in && !punching_out) {
1193 /* punching in but never out */
1194 return max_framepos;
1195 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1196 /* punching in and punching out after session end */
1197 return max_framepos;
1200 return current_end_frame ();