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 (!_engine.freewheeling() && Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) {
92 midi_clock->tick (transport_at_start);
95 /* don't bother with a message */
98 SendFeedback (); /* EMIT SIGNAL */
100 MIDI::Manager::instance()->cycle_end();
104 Session::fail_roll (pframes_t nframes)
106 return no_roll (nframes);
110 Session::no_roll (pframes_t nframes)
114 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
116 bool declick = get_transport_declick_required();
117 boost::shared_ptr<RouteList> r = routes.reader ();
120 _click_io->silence (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 (fabs(_target_transport_speed));
349 interpolation.set_speed (fabs(_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 ((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 _slave_state = Running;
662 Location* al = _locations->auto_loop_location();
664 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
666 request_play_loop(false);
669 if (slave_transport_frame != _transport_frame) {
670 locate (slave_transport_frame, false, false);
680 if (_slave_state == Waiting) {
682 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
684 if (slave_transport_frame >= slave_wait_end) {
686 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
688 _slave_state = Running;
690 /* now perform a "micro-seek" within the disk buffers to realign ourselves
691 precisely with the master.
696 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
698 boost::shared_ptr<RouteList> rl = routes.reader();
699 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
700 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
701 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
708 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
709 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
711 tr->internal_playback_seek (frame_delta);
714 _transport_frame += frame_delta;
717 cerr << "cannot micro-seek\n";
721 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
722 average_slave_delta = 0L;
726 if (_slave_state == Running && _transport_speed == 0.0f) {
727 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
731 } else { // slave_speed is 0
733 /* slave has stopped */
735 if (_transport_speed != 0.0f) {
736 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
740 if (slave_transport_frame != _transport_frame) {
741 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
742 force_locate (slave_transport_frame, false);
745 _slave_state = Stopped;
750 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
752 if (slave_speed && _transport_speed) {
754 /* something isn't right, but we should move with the master
760 silent_process_routes (nframes, need_butler);
762 get_track_statistics ();
768 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
770 if (frames_moved < 0) {
771 decrement_transport_position (-frames_moved);
773 increment_transport_position (frames_moved);
776 framepos_t const stop_limit = compute_stop_limit ();
777 maybe_stop (stop_limit);
782 Session::process_without_events (pframes_t nframes)
784 bool session_needs_butler = false;
785 framecnt_t frames_moved;
787 if (!process_can_proceed()) {
792 if (!_exporting && _slave) {
793 if (!follow_slave (nframes)) {
798 if (_transport_speed == 0) {
803 if (_transport_speed == 1.0) {
804 frames_moved = (framecnt_t) nframes;
806 interpolation.set_target_speed (fabs(_target_transport_speed));
807 interpolation.set_speed (fabs(_transport_speed));
808 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
811 if (!_exporting && !timecode_transmission_suspended()) {
812 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
815 framepos_t const stop_limit = compute_stop_limit ();
817 if (maybe_stop (stop_limit)) {
822 if (maybe_sync_start (nframes)) {
826 click (_transport_frame, nframes);
828 if (process_routes (nframes, session_needs_butler)) {
833 get_track_statistics ();
835 /* XXX: I'm not sure whether this is correct, but at least it
836 matches process_with_events, so that this new frames_moved
837 is -ve when transport speed is -ve. This means that the
838 transport position is updated correctly when we are in
839 reverse. It seems a bit wrong that we're not using the
840 interpolator to compute this.
843 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
845 if (frames_moved < 0) {
846 decrement_transport_position (-frames_moved);
848 increment_transport_position (frames_moved);
851 maybe_stop (stop_limit);
852 check_declick_out ();
854 if (session_needs_butler) {
859 /** Process callback used when the auditioner is active.
860 * @param nframes number of frames to process.
863 Session::process_audition (pframes_t nframes)
866 boost::shared_ptr<RouteList> r = routes.reader ();
868 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
869 if (!(*i)->is_hidden()) {
870 (*i)->silence (nframes);
874 /* run the auditioner, and if it says we need butler service, ask for it */
876 if (auditioner->play_audition (nframes) > 0) {
880 /* if using a monitor section, run it because otherwise we don't hear anything */
882 if (auditioner->needs_monitor()) {
883 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
886 /* handle pending events */
888 while (pending_events.read (&ev, 1) == 1) {
892 /* if we are not in the middle of a state change,
893 and there are immediate events queued up,
897 while (!non_realtime_work_pending() && !immediate_events.empty()) {
898 SessionEvent *ev = immediate_events.front ();
899 immediate_events.pop_front ();
903 if (!auditioner->auditioning()) {
904 /* auditioner no longer active, so go back to the normal process callback */
905 process_function = &Session::process_with_events;
910 Session::maybe_sync_start (pframes_t & nframes)
912 pframes_t sync_offset;
914 if (!waiting_for_sync_offset) {
918 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
920 /* generate silence up to the sync point, then
921 adjust nframes + offset to reflect whatever
925 no_roll (sync_offset);
926 nframes -= sync_offset;
927 Port::increment_global_port_buffer_offset (sync_offset);
928 waiting_for_sync_offset = false;
931 return true; // done, nothing left to process
936 /* sync offset point is not within this process()
937 cycle, so just generate silence. and don't bother
938 with any fancy stuff here, just the minimal silence.
943 if (Config->get_locate_while_waiting_for_sync()) {
944 if (micro_locate (nframes)) {
945 /* XXX ERROR !!! XXX */
949 return true; // done, nothing left to process
956 Session::queue_event (SessionEvent* ev)
958 if (_state_of_the_state & Deletion) {
960 } else if (_state_of_the_state & Loading) {
963 pending_events.write (&ev, 1);
968 Session::set_next_event ()
970 if (events.empty()) {
971 next_event = events.end();
975 if (next_event == events.end()) {
976 next_event = events.begin();
979 if ((*next_event)->action_frame > _transport_frame) {
980 next_event = events.begin();
983 for (; next_event != events.end(); ++next_event) {
984 if ((*next_event)->action_frame >= _transport_frame) {
991 Session::process_event (SessionEvent* ev)
996 /* if we're in the middle of a state change (i.e. waiting
997 for the butler thread to complete the non-realtime
998 part of the change), we'll just have to queue this
999 event for a time when the change is complete.
1002 if (non_realtime_work_pending()) {
1004 /* except locates, which we have the capability to handle */
1006 if (ev->type != SessionEvent::Locate) {
1007 immediate_events.insert (immediate_events.end(), ev);
1013 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1016 case SessionEvent::SetLoop:
1017 set_play_loop (ev->yes_or_no);
1020 case SessionEvent::AutoLoop:
1022 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1028 case SessionEvent::Locate:
1029 if (ev->yes_or_no) {
1030 // cerr << "forced locate to " << ev->target_frame << endl;
1031 locate (ev->target_frame, false, true, false);
1033 // cerr << "soft locate to " << ev->target_frame << endl;
1034 start_locate (ev->target_frame, false, true, false);
1036 _send_timecode_update = true;
1039 case SessionEvent::LocateRoll:
1040 if (ev->yes_or_no) {
1041 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1042 locate (ev->target_frame, true, true, false);
1044 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1045 start_locate (ev->target_frame, true, true, false);
1047 _send_timecode_update = true;
1050 case SessionEvent::LocateRollLocate:
1051 // locate is handled by ::request_roll_at_and_return()
1052 _requested_return_frame = ev->target_frame;
1053 request_locate (ev->target2_frame, true);
1057 case SessionEvent::SetTransportSpeed:
1058 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1061 case SessionEvent::PunchIn:
1062 // cerr << "PunchIN at " << transport_frame() << endl;
1063 if (config.get_punch_in() && record_status() == Enabled) {
1070 case SessionEvent::PunchOut:
1071 // cerr << "PunchOUT at " << transport_frame() << endl;
1072 if (config.get_punch_out()) {
1073 step_back_from_record ();
1079 case SessionEvent::StopOnce:
1080 if (!non_realtime_work_pending()) {
1081 stop_transport (ev->yes_or_no);
1082 _clear_event_type (SessionEvent::StopOnce);
1088 case SessionEvent::RangeStop:
1089 if (!non_realtime_work_pending()) {
1090 stop_transport (ev->yes_or_no);
1096 case SessionEvent::RangeLocate:
1097 start_locate (ev->target_frame, true, true, false);
1102 case SessionEvent::Overwrite:
1103 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1106 case SessionEvent::SetTrackSpeed:
1107 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1110 case SessionEvent::SetSyncSource:
1111 use_sync_source (ev->slave);
1114 case SessionEvent::Audition:
1115 set_audition (ev->region);
1116 // drop reference to region
1117 ev->region.reset ();
1120 case SessionEvent::InputConfigurationChange:
1121 add_post_transport_work (PostTransportInputChange);
1122 _butler->schedule_transport_work ();
1125 case SessionEvent::SetPlayAudioRange:
1126 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1129 case SessionEvent::RealTimeOperation:
1131 del = false; // other side of RT request needs to clean up
1134 case SessionEvent::AdjustPlaybackBuffering:
1135 schedule_playback_buffering_adjustment ();
1138 case SessionEvent::AdjustCaptureBuffering:
1139 schedule_capture_buffering_adjustment ();
1142 case SessionEvent::SetTimecodeTransmission:
1143 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1147 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1153 del = del && !_remove_event (ev);
1162 Session::compute_stop_limit () const
1164 if (!Config->get_stop_at_session_end ()) {
1165 return max_framepos;
1168 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1169 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1171 if (actively_recording ()) {
1172 /* permanently recording */
1173 return max_framepos;
1174 } else if (punching_in && !punching_out) {
1175 /* punching in but never out */
1176 return max_framepos;
1177 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1178 /* punching in and punching out after session end */
1179 return max_framepos;
1182 return current_end_frame ();