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/thread.h>
30 #include "ardour/ardour.h"
31 #include "ardour/audioengine.h"
32 #include "ardour/auditioner.h"
33 #include "ardour/butler.h"
34 #include "ardour/debug.h"
35 #include "ardour/process_thread.h"
36 #include "ardour/session.h"
37 #include "ardour/slave.h"
38 #include "ardour/timestamps.h"
39 #include "ardour/graph.h"
40 #include "ardour/audio_port.h"
41 #include "ardour/tempo.h"
42 #include "ardour/ticker.h"
43 #include "ardour/cycle_timer.h"
45 #include "midi++/manager.h"
46 #include "midi++/mmc.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;
63 MIDI::Manager::instance()->cycle_start(nframes);
67 if (processing_blocked()) {
72 if (non_realtime_work_pending()) {
73 if (!_butler->transport_work_requested ()) {
78 _engine.main_thread()->get_buffers ();
80 (this->*process_function) (nframes);
82 _engine.main_thread()->drop_buffers ();
84 /* deliver MIDI clock. Note that we need to use the transport frame
85 * position at the start of process(), not the value at the end of
86 * it. We may already have ticked() because of a transport state
87 * change, for example.
91 if (Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) {
93 /* As of january 26th 2012, MidiClockTicker::tick()
94 * doesn't actually these variables, so don't waste
95 * cycles computing them.
98 Timecode::BBT_Time transport_bbt;
99 Timecode::Time transport_timecode;
100 // _tempo_map->bbt_time_rt (transport_at_start, transport_bbt);
101 // timecode_time (transport_at_start, transport_timecode);
103 midi_clock->tick (transport_at_start, transport_bbt, transport_timecode);
106 /* don't bother with a message */
109 SendFeedback (); /* EMIT SIGNAL */
111 MIDI::Manager::instance()->cycle_end();
115 Session::fail_roll (pframes_t nframes)
117 return no_roll (nframes);
121 Session::no_roll (pframes_t nframes)
125 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
127 bool declick = get_transport_declick_required();
128 boost::shared_ptr<RouteList> r = routes.reader ();
131 _click_io->silence (nframes);
134 if (_process_graph) {
135 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
136 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
138 PT_TIMING_CHECK (10);
139 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
141 if ((*i)->is_hidden()) {
145 (*i)->set_pending_declick (declick);
147 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
148 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
153 PT_TIMING_CHECK (11);
161 Session::process_routes (pframes_t nframes, bool& need_butler)
163 int declick = get_transport_declick_required();
164 boost::shared_ptr<RouteList> r = routes.reader ();
166 if (transport_sub_state & StopPendingCapture) {
167 /* force a declick out */
171 const framepos_t start_frame = _transport_frame;
172 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
174 if (_process_graph) {
175 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
176 _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
179 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
183 if ((*i)->is_hidden()) {
187 (*i)->set_pending_declick (declick);
189 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, need_butler)) < 0) {
200 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
202 boost::shared_ptr<RouteList> r = routes.reader ();
204 const framepos_t start_frame = _transport_frame;
205 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
207 if (_process_graph) {
208 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
210 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
214 if ((*i)->is_hidden()) {
218 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, need_butler)) < 0) {
229 Session::get_track_statistics ()
234 boost::shared_ptr<RouteList> rl = routes.reader();
235 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
237 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
239 if (!tr || tr->hidden()) {
243 pworst = min (pworst, tr->playback_buffer_load());
244 cworst = min (cworst, tr->capture_buffer_load());
247 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
248 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
250 if (actively_recording()) {
255 /** Process callback used when the auditioner is not active */
257 Session::process_with_events (pframes_t nframes)
262 pframes_t this_nframes;
263 framepos_t end_frame;
264 bool session_needs_butler = false;
265 framecnt_t frames_moved;
267 /* make sure the auditioner is silent */
270 auditioner->silence (nframes);
273 /* handle any pending events */
275 while (pending_events.read (&ev, 1) == 1) {
279 /* if we are not in the middle of a state change,
280 and there are immediate events queued up,
284 while (!non_realtime_work_pending() && !immediate_events.empty()) {
285 SessionEvent *ev = immediate_events.front ();
286 immediate_events.pop_front ();
290 /* Decide on what to do with quarter-frame MTC during this cycle */
292 bool const was_sending_qf_mtc = _send_qf_mtc;
293 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
295 if (_transport_speed != 0) {
297 Config->get_send_mtc () &&
298 _transport_speed >= (1 - tolerance) &&
299 _transport_speed <= (1 + tolerance)
302 if (_send_qf_mtc && !was_sending_qf_mtc) {
303 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
304 _send_timecode_update = true;
307 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
308 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
309 a quarter of a second since we sent anything at all, so send a full MTC update
312 _send_timecode_update = true;
315 _pframes_since_last_mtc += nframes;
318 /* Events caused a transport change (or we re-started sending
319 * MTC), so send an MTC Full Frame (Timecode) message. This
320 * is sent whether rolling or not, to give slaves an idea of
321 * ardour time on locates (and allow slow slaves to position
322 * and prepare for rolling)
324 if (_send_timecode_update) {
325 send_full_time_code (_transport_frame);
328 if (!process_can_proceed()) {
333 if (events.empty() || next_event == events.end()) {
334 process_without_events (nframes);
338 if (_transport_speed == 1.0) {
339 frames_moved = (framecnt_t) nframes;
341 interpolation.set_target_speed (fabs(_target_transport_speed));
342 interpolation.set_speed (fabs(_transport_speed));
343 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
346 end_frame = _transport_frame + frames_moved;
349 SessionEvent* this_event;
350 Events::iterator the_next_one;
352 if (!process_can_proceed()) {
357 if (!_exporting && _slave) {
358 if (!follow_slave (nframes)) {
363 if (_transport_speed == 0) {
368 if (!_exporting && !timecode_transmission_suspended()) {
369 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
372 framepos_t stop_limit = compute_stop_limit ();
374 if (maybe_stop (stop_limit)) {
379 this_event = *next_event;
380 the_next_one = next_event;
383 /* yes folks, here it is, the actual loop where we really truly
389 this_nframes = nframes; /* real (jack) time relative */
390 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
392 /* running an event, position transport precisely to its time */
393 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
394 /* this isn't quite right for reverse play */
395 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
396 this_nframes = abs (floor(frames_moved / _transport_speed));
401 click (_transport_frame, this_nframes);
403 if (process_routes (this_nframes, session_needs_butler)) {
408 get_track_statistics ();
410 nframes -= this_nframes;
412 if (frames_moved < 0) {
413 decrement_transport_position (-frames_moved);
415 increment_transport_position (frames_moved);
418 maybe_stop (stop_limit);
419 check_declick_out ();
422 _engine.split_cycle (this_nframes);
424 /* now handle this event and all others scheduled for the same time */
426 while (this_event && this_event->action_frame == _transport_frame) {
427 process_event (this_event);
429 if (the_next_one == events.end()) {
432 this_event = *the_next_one;
437 /* if an event left our state changing, do the right thing */
439 if (nframes && non_realtime_work_pending()) {
444 /* this is necessary to handle the case of seamless looping */
445 end_frame = _transport_frame + floor (nframes * _transport_speed);
450 } /* implicit release of route lock */
452 if (session_needs_butler) {
458 Session::reset_slave_state ()
460 average_slave_delta = 1800;
461 delta_accumulator_cnt = 0;
462 have_first_delta_accumulator = false;
463 _slave_state = Stopped;
467 Session::transport_locked () const
471 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
479 Session::follow_slave (pframes_t nframes)
482 framepos_t slave_transport_frame;
483 framecnt_t this_delta;
488 config.set_external_sync (false);
492 _slave->speed_and_position (slave_speed, slave_transport_frame);
494 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
496 if (!_slave->locked()) {
497 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
501 if (slave_transport_frame > _transport_frame) {
502 this_delta = slave_transport_frame - _transport_frame;
505 this_delta = _transport_frame - slave_transport_frame;
509 if (_slave->starting()) {
513 if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
515 /* if the TC source is synced, then we assume that its
516 speed is binary: 0.0 or 1.0
519 if (slave_speed != 0.0f) {
525 /* if we are chasing and the average delta between us and the
526 master gets too big, we want to switch to silent
527 motion. so keep track of that here.
530 if (_slave_state == Running) {
531 calculate_moving_average_of_slave_delta(dir, this_delta);
535 track_slave_state (slave_speed, slave_transport_frame, this_delta);
537 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
538 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
541 if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
543 if (_transport_speed != 0.0f) {
546 note that average_dir is +1 or -1
551 if (average_slave_delta == 0) {
555 delta = average_slave_delta;
556 delta *= average_dir;
560 if (slave_speed != 0.0) {
561 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
562 (int) (dir * this_delta),
566 slave_transport_frame,
567 average_slave_delta));
571 if (_slave->give_slave_full_control_over_transport_speed()) {
572 set_transport_speed (slave_speed, false, false);
573 //std::cout << "set speed = " << slave_speed << "\n";
575 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
576 request_transport_speed (adjusted_speed);
577 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
578 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
583 if ((framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
584 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
592 if (_slave_state == Running && !non_realtime_work_pending()) {
593 /* speed is set, we're locked, and good to go */
598 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
599 follow_slave_silently (nframes, slave_speed);
602 /* don't move at all */
603 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
609 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
611 if (delta_accumulator_cnt >= delta_accumulator_size) {
612 have_first_delta_accumulator = true;
613 delta_accumulator_cnt = 0;
616 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
617 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
620 if (have_first_delta_accumulator) {
621 average_slave_delta = 0L;
622 for (int i = 0; i < delta_accumulator_size; ++i) {
623 average_slave_delta += delta_accumulator[i];
625 average_slave_delta /= (int32_t) delta_accumulator_size;
626 if (average_slave_delta < 0L) {
628 average_slave_delta = abs(average_slave_delta);
636 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
638 if (slave_speed != 0.0f) {
640 /* slave is running */
642 switch (_slave_state) {
644 if (_slave->requires_seekahead()) {
645 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
646 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
647 /* we can call locate() here because we are in process context */
648 locate (slave_wait_end, false, false);
649 _slave_state = Waiting;
653 _slave_state = Running;
655 Location* al = _locations->auto_loop_location();
657 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
659 request_play_loop(false);
662 if (slave_transport_frame != _transport_frame) {
663 locate (slave_transport_frame, false, false);
673 if (_slave_state == Waiting) {
675 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
677 if (slave_transport_frame >= slave_wait_end) {
679 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
681 _slave_state = Running;
683 /* now perform a "micro-seek" within the disk buffers to realign ourselves
684 precisely with the master.
689 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
691 boost::shared_ptr<RouteList> rl = routes.reader();
692 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
693 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
694 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
701 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
702 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
704 tr->internal_playback_seek (frame_delta);
707 _transport_frame += frame_delta;
710 cerr << "cannot micro-seek\n";
714 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
715 average_slave_delta = 0L;
719 if (_slave_state == Running && _transport_speed == 0.0f) {
720 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
724 } else { // slave_speed is 0
726 /* slave has stopped */
728 if (_transport_speed != 0.0f) {
729 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
733 if (slave_transport_frame != _transport_frame) {
734 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
735 force_locate (slave_transport_frame, false);
738 _slave_state = Stopped;
743 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
745 if (slave_speed && _transport_speed) {
747 /* something isn't right, but we should move with the master
753 silent_process_routes (nframes, need_butler);
755 get_track_statistics ();
761 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
763 if (frames_moved < 0) {
764 decrement_transport_position (-frames_moved);
766 increment_transport_position (frames_moved);
769 framepos_t const stop_limit = compute_stop_limit ();
770 maybe_stop (stop_limit);
775 Session::process_without_events (pframes_t nframes)
777 bool session_needs_butler = false;
778 framecnt_t frames_moved;
780 if (!process_can_proceed()) {
785 if (!_exporting && _slave) {
786 if (!follow_slave (nframes)) {
791 if (_transport_speed == 0) {
796 if (_transport_speed == 1.0) {
797 frames_moved = (framecnt_t) nframes;
799 interpolation.set_target_speed (fabs(_target_transport_speed));
800 interpolation.set_speed (fabs(_transport_speed));
801 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
804 if (!_exporting && !timecode_transmission_suspended()) {
805 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
808 framepos_t const stop_limit = compute_stop_limit ();
810 if (maybe_stop (stop_limit)) {
815 if (maybe_sync_start (nframes)) {
819 click (_transport_frame, nframes);
821 if (process_routes (nframes, session_needs_butler)) {
826 get_track_statistics ();
828 /* XXX: I'm not sure whether this is correct, but at least it
829 matches process_with_events, so that this new frames_moved
830 is -ve when transport speed is -ve. This means that the
831 transport position is updated correctly when we are in
832 reverse. It seems a bit wrong that we're not using the
833 interpolator to compute this.
836 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
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->passthru (_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 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1021 case SessionEvent::Locate:
1022 if (ev->yes_or_no) {
1023 // cerr << "forced locate to " << ev->target_frame << endl;
1024 locate (ev->target_frame, false, true, false);
1026 // cerr << "soft locate to " << ev->target_frame << endl;
1027 start_locate (ev->target_frame, false, true, false);
1029 _send_timecode_update = true;
1032 case SessionEvent::LocateRoll:
1033 if (ev->yes_or_no) {
1034 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1035 locate (ev->target_frame, true, true, false);
1037 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1038 start_locate (ev->target_frame, true, true, false);
1040 _send_timecode_update = true;
1043 case SessionEvent::LocateRollLocate:
1044 // locate is handled by ::request_roll_at_and_return()
1045 _requested_return_frame = ev->target_frame;
1046 request_locate (ev->target2_frame, true);
1050 case SessionEvent::SetTransportSpeed:
1051 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1054 case SessionEvent::PunchIn:
1055 // cerr << "PunchIN at " << transport_frame() << endl;
1056 if (config.get_punch_in() && record_status() == Enabled) {
1063 case SessionEvent::PunchOut:
1064 // cerr << "PunchOUT at " << transport_frame() << endl;
1065 if (config.get_punch_out()) {
1066 step_back_from_record ();
1072 case SessionEvent::StopOnce:
1073 if (!non_realtime_work_pending()) {
1074 stop_transport (ev->yes_or_no);
1075 _clear_event_type (SessionEvent::StopOnce);
1081 case SessionEvent::RangeStop:
1082 if (!non_realtime_work_pending()) {
1083 stop_transport (ev->yes_or_no);
1089 case SessionEvent::RangeLocate:
1090 start_locate (ev->target_frame, true, true, false);
1095 case SessionEvent::Overwrite:
1096 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1099 case SessionEvent::SetTrackSpeed:
1100 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1103 case SessionEvent::SetSyncSource:
1104 use_sync_source (ev->slave);
1107 case SessionEvent::Audition:
1108 set_audition (ev->region);
1109 // drop reference to region
1110 ev->region.reset ();
1113 case SessionEvent::InputConfigurationChange:
1114 add_post_transport_work (PostTransportInputChange);
1115 _butler->schedule_transport_work ();
1118 case SessionEvent::SetPlayAudioRange:
1119 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1122 case SessionEvent::RealTimeOperation:
1124 del = false; // other side of RT request needs to clean up
1127 case SessionEvent::AdjustPlaybackBuffering:
1128 schedule_playback_buffering_adjustment ();
1131 case SessionEvent::AdjustCaptureBuffering:
1132 schedule_capture_buffering_adjustment ();
1135 case SessionEvent::SetTimecodeTransmission:
1136 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1140 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1146 del = del && !_remove_event (ev);
1155 Session::compute_stop_limit () const
1157 if (!Config->get_stop_at_session_end ()) {
1158 return max_framepos;
1161 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1162 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1164 if (actively_recording ()) {
1165 /* permanently recording */
1166 return max_framepos;
1167 } else if (punching_in && !punching_out) {
1168 /* punching in but never out */
1169 return max_framepos;
1170 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1171 /* punching in and punching out after session end */
1172 return max_framepos;
1175 return current_end_frame ();