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 (fabs(_target_transport_speed));
345 interpolation.set_speed (fabs(_transport_speed));
346 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
349 end_frame = _transport_frame + frames_moved;
352 SessionEvent* this_event;
353 Events::iterator the_next_one;
355 if (!process_can_proceed()) {
360 if (!_exporting && _slave) {
361 if (!follow_slave (nframes)) {
366 if (_transport_speed == 0) {
371 if (!_exporting && !timecode_transmission_suspended()) {
372 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
375 framepos_t stop_limit = compute_stop_limit ();
377 if (maybe_stop (stop_limit)) {
382 this_event = *next_event;
383 the_next_one = next_event;
386 /* yes folks, here it is, the actual loop where we really truly
392 this_nframes = nframes; /* real (jack) time relative */
393 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
395 /* running an event, position transport precisely to its time */
396 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
397 /* this isn't quite right for reverse play */
398 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
399 this_nframes = abs (floor(frames_moved / _transport_speed));
404 click (_transport_frame, this_nframes);
406 if (process_routes (this_nframes, session_needs_butler)) {
411 get_track_statistics ();
413 nframes -= this_nframes;
415 if (frames_moved < 0) {
416 decrement_transport_position (-frames_moved);
418 increment_transport_position (frames_moved);
421 maybe_stop (stop_limit);
422 check_declick_out ();
425 _engine.split_cycle (this_nframes);
427 /* now handle this event and all others scheduled for the same time */
429 while (this_event && this_event->action_frame == _transport_frame) {
430 process_event (this_event);
432 if (the_next_one == events.end()) {
435 this_event = *the_next_one;
440 /* if an event left our state changing, do the right thing */
442 if (nframes && non_realtime_work_pending()) {
447 /* this is necessary to handle the case of seamless looping */
448 end_frame = _transport_frame + floor (nframes * _transport_speed);
453 } /* implicit release of route lock */
455 if (session_needs_butler) {
461 Session::reset_slave_state ()
463 average_slave_delta = 1800;
464 delta_accumulator_cnt = 0;
465 have_first_delta_accumulator = false;
466 _slave_state = Stopped;
470 Session::transport_locked () const
474 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
482 Session::follow_slave (pframes_t nframes)
485 framepos_t slave_transport_frame;
486 framecnt_t this_delta;
491 config.set_external_sync (false);
495 _slave->speed_and_position (slave_speed, slave_transport_frame);
497 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
499 if (!_slave->locked()) {
500 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
504 if (slave_transport_frame > _transport_frame) {
505 this_delta = slave_transport_frame - _transport_frame;
508 this_delta = _transport_frame - slave_transport_frame;
512 if (_slave->starting()) {
516 if (_slave->is_always_synced() || Config->get_timecode_source_is_synced()) {
518 /* if the TC source is synced, then we assume that its
519 speed is binary: 0.0 or 1.0
522 if (slave_speed != 0.0f) {
528 /* if we are chasing and the average delta between us and the
529 master gets too big, we want to switch to silent
530 motion. so keep track of that here.
533 if (_slave_state == Running) {
534 calculate_moving_average_of_slave_delta(dir, this_delta);
538 track_slave_state (slave_speed, slave_transport_frame, this_delta);
540 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
541 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
544 if (_slave_state == Running && !_slave->is_always_synced() && !Config->get_timecode_source_is_synced()) {
546 if (_transport_speed != 0.0f) {
549 note that average_dir is +1 or -1
554 if (average_slave_delta == 0) {
558 delta = average_slave_delta;
559 delta *= average_dir;
563 if (slave_speed != 0.0) {
564 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
565 (int) (dir * this_delta),
569 slave_transport_frame,
570 average_slave_delta));
574 if (_slave->give_slave_full_control_over_transport_speed()) {
575 set_transport_speed (slave_speed, false, false);
576 //std::cout << "set speed = " << slave_speed << "\n";
578 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
579 request_transport_speed (adjusted_speed);
580 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
581 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
586 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
587 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
595 if (_slave_state == Running && !non_realtime_work_pending()) {
596 /* speed is set, we're locked, and good to go */
601 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
602 follow_slave_silently (nframes, slave_speed);
605 /* don't move at all */
606 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
612 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
614 if (delta_accumulator_cnt >= delta_accumulator_size) {
615 have_first_delta_accumulator = true;
616 delta_accumulator_cnt = 0;
619 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
620 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
623 if (have_first_delta_accumulator) {
624 average_slave_delta = 0L;
625 for (int i = 0; i < delta_accumulator_size; ++i) {
626 average_slave_delta += delta_accumulator[i];
628 average_slave_delta /= (int32_t) delta_accumulator_size;
629 if (average_slave_delta < 0L) {
631 average_slave_delta = abs(average_slave_delta);
639 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
641 if (slave_speed != 0.0f) {
643 /* slave is running */
645 switch (_slave_state) {
647 if (_slave->requires_seekahead()) {
648 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
649 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
650 /* we can call locate() here because we are in process context */
651 locate (slave_wait_end, false, false);
652 _slave_state = Waiting;
656 _slave_state = Running;
658 Location* al = _locations->auto_loop_location();
660 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
662 request_play_loop(false);
665 if (slave_transport_frame != _transport_frame) {
666 locate (slave_transport_frame, false, false);
676 if (_slave_state == Waiting) {
678 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
680 if (slave_transport_frame >= slave_wait_end) {
682 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
684 _slave_state = Running;
686 /* now perform a "micro-seek" within the disk buffers to realign ourselves
687 precisely with the master.
692 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
694 boost::shared_ptr<RouteList> rl = routes.reader();
695 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
696 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
697 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
704 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
705 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
707 tr->internal_playback_seek (frame_delta);
710 _transport_frame += frame_delta;
713 cerr << "cannot micro-seek\n";
717 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
718 average_slave_delta = 0L;
722 if (_slave_state == Running && _transport_speed == 0.0f) {
723 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
727 } else { // slave_speed is 0
729 /* slave has stopped */
731 if (_transport_speed != 0.0f) {
732 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
736 if (slave_transport_frame != _transport_frame) {
737 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
738 force_locate (slave_transport_frame, false);
741 _slave_state = Stopped;
746 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
748 if (slave_speed && _transport_speed) {
750 /* something isn't right, but we should move with the master
756 silent_process_routes (nframes, need_butler);
758 get_track_statistics ();
764 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
766 if (frames_moved < 0) {
767 decrement_transport_position (-frames_moved);
769 increment_transport_position (frames_moved);
772 framepos_t const stop_limit = compute_stop_limit ();
773 maybe_stop (stop_limit);
778 Session::process_without_events (pframes_t nframes)
780 bool session_needs_butler = false;
781 framecnt_t frames_moved;
783 if (!process_can_proceed()) {
788 if (!_exporting && _slave) {
789 if (!follow_slave (nframes)) {
794 if (_transport_speed == 0) {
799 if (_transport_speed == 1.0) {
800 frames_moved = (framecnt_t) nframes;
802 interpolation.set_target_speed (fabs(_target_transport_speed));
803 interpolation.set_speed (fabs(_transport_speed));
804 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
807 if (!_exporting && !timecode_transmission_suspended()) {
808 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
811 framepos_t const stop_limit = compute_stop_limit ();
813 if (maybe_stop (stop_limit)) {
818 if (maybe_sync_start (nframes)) {
822 click (_transport_frame, nframes);
824 if (process_routes (nframes, session_needs_butler)) {
829 get_track_statistics ();
831 /* XXX: I'm not sure whether this is correct, but at least it
832 matches process_with_events, so that this new frames_moved
833 is -ve when transport speed is -ve. This means that the
834 transport position is updated correctly when we are in
835 reverse. It seems a bit wrong that we're not using the
836 interpolator to compute this.
839 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
841 if (frames_moved < 0) {
842 decrement_transport_position (-frames_moved);
844 increment_transport_position (frames_moved);
847 maybe_stop (stop_limit);
848 check_declick_out ();
850 if (session_needs_butler) {
855 /** Process callback used when the auditioner is active.
856 * @param nframes number of frames to process.
859 Session::process_audition (pframes_t nframes)
862 boost::shared_ptr<RouteList> r = routes.reader ();
864 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
865 if (!(*i)->is_hidden()) {
866 (*i)->silence (nframes);
870 /* run the auditioner, and if it says we need butler service, ask for it */
872 if (auditioner->play_audition (nframes) > 0) {
876 /* if using a monitor section, run it because otherwise we don't hear anything */
878 if (auditioner->needs_monitor()) {
879 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
882 /* handle pending events */
884 while (pending_events.read (&ev, 1) == 1) {
888 /* if we are not in the middle of a state change,
889 and there are immediate events queued up,
893 while (!non_realtime_work_pending() && !immediate_events.empty()) {
894 SessionEvent *ev = immediate_events.front ();
895 immediate_events.pop_front ();
899 if (!auditioner->auditioning()) {
900 /* auditioner no longer active, so go back to the normal process callback */
901 process_function = &Session::process_with_events;
906 Session::maybe_sync_start (pframes_t & nframes)
908 pframes_t sync_offset;
910 if (!waiting_for_sync_offset) {
914 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
916 /* generate silence up to the sync point, then
917 adjust nframes + offset to reflect whatever
921 no_roll (sync_offset);
922 nframes -= sync_offset;
923 Port::increment_global_port_buffer_offset (sync_offset);
924 waiting_for_sync_offset = false;
927 return true; // done, nothing left to process
932 /* sync offset point is not within this process()
933 cycle, so just generate silence. and don't bother
934 with any fancy stuff here, just the minimal silence.
939 if (Config->get_locate_while_waiting_for_sync()) {
940 if (micro_locate (nframes)) {
941 /* XXX ERROR !!! XXX */
945 return true; // done, nothing left to process
952 Session::queue_event (SessionEvent* ev)
954 if (_state_of_the_state & Deletion) {
956 } else if (_state_of_the_state & Loading) {
959 pending_events.write (&ev, 1);
964 Session::set_next_event ()
966 if (events.empty()) {
967 next_event = events.end();
971 if (next_event == events.end()) {
972 next_event = events.begin();
975 if ((*next_event)->action_frame > _transport_frame) {
976 next_event = events.begin();
979 for (; next_event != events.end(); ++next_event) {
980 if ((*next_event)->action_frame >= _transport_frame) {
987 Session::process_event (SessionEvent* ev)
992 /* if we're in the middle of a state change (i.e. waiting
993 for the butler thread to complete the non-realtime
994 part of the change), we'll just have to queue this
995 event for a time when the change is complete.
998 if (non_realtime_work_pending()) {
1000 /* except locates, which we have the capability to handle */
1002 if (ev->type != SessionEvent::Locate) {
1003 immediate_events.insert (immediate_events.end(), ev);
1009 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1012 case SessionEvent::SetLoop:
1013 set_play_loop (ev->yes_or_no);
1016 case SessionEvent::AutoLoop:
1018 /* roll after locate, do not flush, set "with loop"
1019 true only if we are seamless looping
1021 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1027 case SessionEvent::AutoLoopDeclick:
1029 /* Request a declick fade-out and a fade-in; the fade-out will happen
1030 at the end of the loop, and the fade-in at the start.
1032 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1038 case SessionEvent::Locate:
1039 if (ev->yes_or_no) {
1040 /* args: do not roll after locate, do flush, not with loop */
1041 locate (ev->target_frame, false, true, false);
1043 /* args: do not roll after locate, do flush, not with loop */
1044 start_locate (ev->target_frame, false, true, false);
1046 _send_timecode_update = true;
1049 case SessionEvent::LocateRoll:
1050 if (ev->yes_or_no) {
1051 /* args: roll after locate, do flush, not with loop */
1052 locate (ev->target_frame, true, true, false);
1054 /* args: roll after locate, do flush, not with loop */
1055 start_locate (ev->target_frame, true, true, false);
1057 _send_timecode_update = true;
1060 case SessionEvent::LocateRollLocate:
1061 // locate is handled by ::request_roll_at_and_return()
1062 _requested_return_frame = ev->target_frame;
1063 request_locate (ev->target2_frame, true);
1067 case SessionEvent::SetTransportSpeed:
1068 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1071 case SessionEvent::PunchIn:
1072 // cerr << "PunchIN at " << transport_frame() << endl;
1073 if (config.get_punch_in() && record_status() == Enabled) {
1080 case SessionEvent::PunchOut:
1081 // cerr << "PunchOUT at " << transport_frame() << endl;
1082 if (config.get_punch_out()) {
1083 step_back_from_record ();
1089 case SessionEvent::StopOnce:
1090 if (!non_realtime_work_pending()) {
1091 stop_transport (ev->yes_or_no);
1092 _clear_event_type (SessionEvent::StopOnce);
1098 case SessionEvent::RangeStop:
1099 if (!non_realtime_work_pending()) {
1100 stop_transport (ev->yes_or_no);
1106 case SessionEvent::RangeLocate:
1107 /* args: roll after locate, do flush, not with loop */
1108 start_locate (ev->target_frame, true, true, false);
1113 case SessionEvent::Overwrite:
1114 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1117 case SessionEvent::SetTrackSpeed:
1118 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1121 case SessionEvent::SetSyncSource:
1122 use_sync_source (ev->slave);
1125 case SessionEvent::Audition:
1126 set_audition (ev->region);
1127 // drop reference to region
1128 ev->region.reset ();
1131 case SessionEvent::InputConfigurationChange:
1132 add_post_transport_work (PostTransportInputChange);
1133 _butler->schedule_transport_work ();
1136 case SessionEvent::SetPlayAudioRange:
1137 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1140 case SessionEvent::RealTimeOperation:
1142 del = false; // other side of RT request needs to clean up
1145 case SessionEvent::AdjustPlaybackBuffering:
1146 schedule_playback_buffering_adjustment ();
1149 case SessionEvent::AdjustCaptureBuffering:
1150 schedule_capture_buffering_adjustment ();
1153 case SessionEvent::SetTimecodeTransmission:
1154 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1158 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1164 del = del && !_remove_event (ev);
1173 Session::compute_stop_limit () const
1175 if (!Config->get_stop_at_session_end ()) {
1176 return max_framepos;
1179 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1180 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1182 if (actively_recording ()) {
1183 /* permanently recording */
1184 return max_framepos;
1185 } else if (punching_in && !punching_out) {
1186 /* punching in but never out */
1187 return max_framepos;
1188 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1189 /* punching in and punching out after session end */
1190 return max_framepos;
1193 return current_end_frame ();