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/scene_changer.h"
39 #include "ardour/session.h"
40 #include "ardour/slave.h"
41 #include "ardour/ticker.h"
42 #include "ardour/types.h"
44 #include "midi++/mmc.h"
48 using namespace ARDOUR;
52 /** Called by the audio engine when there is work to be done with JACK.
53 * @param nframes Number of frames to process.
57 Session::process (pframes_t nframes)
59 framepos_t transport_at_start = _transport_frame;
63 if (processing_blocked()) {
68 if (non_realtime_work_pending()) {
69 if (!_butler->transport_work_requested ()) {
74 _engine.main_thread()->get_buffers ();
76 (this->*process_function) (nframes);
78 _engine.main_thread()->drop_buffers ();
80 /* deliver MIDI clock. Note that we need to use the transport frame
81 * position at the start of process(), not the value at the end of
82 * it. We may already have ticked() because of a transport state
83 * change, for example.
87 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
88 midi_clock->tick (transport_at_start, nframes);
91 _scene_changer->run (transport_at_start, transport_at_start + nframes);
94 /* don't bother with a message */
97 SendFeedback (); /* EMIT SIGNAL */
101 Session::fail_roll (pframes_t nframes)
103 return no_roll (nframes);
107 Session::no_roll (pframes_t nframes)
111 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
113 int declick = get_transport_declick_required();
114 boost::shared_ptr<RouteList> r = routes.reader ();
117 _click_io->silence (nframes);
120 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
122 if (_process_graph) {
123 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
124 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
126 PT_TIMING_CHECK (10);
127 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
129 if ((*i)->is_auditioner()) {
133 (*i)->set_pending_declick (declick);
135 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
136 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
141 PT_TIMING_CHECK (11);
148 /** @param need_butler to be set to true by this method if it needs the butler,
149 * otherwise it must be left alone.
152 Session::process_routes (pframes_t nframes, bool& need_butler)
154 int declick = get_transport_declick_required();
155 boost::shared_ptr<RouteList> r = routes.reader ();
157 const framepos_t start_frame = _transport_frame;
158 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
160 if (_process_graph) {
161 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
162 if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
168 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
172 if ((*i)->is_auditioner()) {
176 (*i)->set_pending_declick (declick);
180 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
194 /** @param need_butler to be set to true by this method if it needs the butler,
195 * otherwise it must be left alone.
198 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
200 boost::shared_ptr<RouteList> r = routes.reader ();
202 const framepos_t start_frame = _transport_frame;
203 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
205 if (_process_graph) {
206 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
208 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
212 if ((*i)->is_auditioner()) {
218 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
233 Session::get_track_statistics ()
238 boost::shared_ptr<RouteList> rl = routes.reader();
239 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
241 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
243 if (!tr || tr->hidden()) {
247 pworst = min (pworst, tr->playback_buffer_load());
248 cworst = min (cworst, tr->capture_buffer_load());
251 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
252 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
254 if (actively_recording()) {
259 /** Process callback used when the auditioner is not active */
261 Session::process_with_events (pframes_t nframes)
266 pframes_t this_nframes;
267 framepos_t end_frame;
268 bool session_needs_butler = false;
269 framecnt_t frames_moved;
271 /* make sure the auditioner is silent */
274 auditioner->silence (nframes);
277 /* handle any pending events */
279 while (pending_events.read (&ev, 1) == 1) {
283 /* if we are not in the middle of a state change,
284 and there are immediate events queued up,
288 while (!non_realtime_work_pending() && !immediate_events.empty()) {
289 SessionEvent *ev = immediate_events.front ();
290 immediate_events.pop_front ();
294 /* Decide on what to do with quarter-frame MTC during this cycle */
296 bool const was_sending_qf_mtc = _send_qf_mtc;
297 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
299 if (_transport_speed != 0) {
301 Config->get_send_mtc () &&
302 _transport_speed >= (1 - tolerance) &&
303 _transport_speed <= (1 + tolerance)
306 if (_send_qf_mtc && !was_sending_qf_mtc) {
307 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
308 _send_timecode_update = true;
311 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
312 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
313 a quarter of a second since we sent anything at all, so send a full MTC update
316 _send_timecode_update = true;
319 _pframes_since_last_mtc += nframes;
322 /* Events caused a transport change (or we re-started sending
323 * MTC), so send an MTC Full Frame (Timecode) message. This
324 * is sent whether rolling or not, to give slaves an idea of
325 * ardour time on locates (and allow slow slaves to position
326 * and prepare for rolling)
328 if (_send_timecode_update) {
329 send_full_time_code (_transport_frame, nframes);
332 if (!process_can_proceed()) {
337 if (events.empty() || next_event == events.end()) {
338 process_without_events (nframes);
342 if (_transport_speed == 1.0) {
343 frames_moved = (framecnt_t) nframes;
345 interpolation.set_target_speed (_target_transport_speed);
346 interpolation.set_speed (_transport_speed);
347 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
350 end_frame = _transport_frame + frames_moved;
353 SessionEvent* this_event;
354 Events::iterator the_next_one;
356 if (!process_can_proceed()) {
361 if (!_exporting && _slave) {
362 if (!follow_slave (nframes)) {
367 if (_transport_speed == 0) {
372 if (!_exporting && !timecode_transmission_suspended()) {
373 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
376 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
378 framepos_t stop_limit = compute_stop_limit ();
380 if (maybe_stop (stop_limit)) {
385 this_event = *next_event;
386 the_next_one = next_event;
389 /* yes folks, here it is, the actual loop where we really truly
395 this_nframes = nframes; /* real (jack) time relative */
396 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
398 /* running an event, position transport precisely to its time */
399 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
400 /* this isn't quite right for reverse play */
401 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
402 this_nframes = abs (floor(frames_moved / _transport_speed));
407 click (_transport_frame, this_nframes);
409 if (process_routes (this_nframes, session_needs_butler)) {
414 get_track_statistics ();
416 nframes -= this_nframes;
418 if (frames_moved < 0) {
419 decrement_transport_position (-frames_moved);
421 increment_transport_position (frames_moved);
424 maybe_stop (stop_limit);
425 check_declick_out ();
429 _engine.split_cycle (this_nframes);
432 /* now handle this event and all others scheduled for the same time */
434 while (this_event && this_event->action_frame == _transport_frame) {
435 process_event (this_event);
437 if (the_next_one == events.end()) {
440 this_event = *the_next_one;
445 /* if an event left our state changing, do the right thing */
447 if (nframes && non_realtime_work_pending()) {
452 /* this is necessary to handle the case of seamless looping */
453 end_frame = _transport_frame + floor (nframes * _transport_speed);
458 } /* implicit release of route lock */
460 if (session_needs_butler) {
466 Session::reset_slave_state ()
468 average_slave_delta = 1800;
469 delta_accumulator_cnt = 0;
470 have_first_delta_accumulator = false;
471 _slave_state = Stopped;
475 Session::transport_locked () const
479 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
487 Session::follow_slave (pframes_t nframes)
490 framepos_t slave_transport_frame;
491 framecnt_t this_delta;
496 config.set_external_sync (false);
500 _slave->speed_and_position (slave_speed, slave_transport_frame);
502 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
504 if (!_slave->locked()) {
505 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
509 if (slave_transport_frame > _transport_frame) {
510 this_delta = slave_transport_frame - _transport_frame;
513 this_delta = _transport_frame - slave_transport_frame;
517 if (_slave->starting()) {
521 if (_slave->is_always_synced() ||
522 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
525 /* if the TC source is synced, then we assume that its
526 speed is binary: 0.0 or 1.0
529 if (slave_speed != 0.0f) {
535 /* if we are chasing and the average delta between us and the
536 master gets too big, we want to switch to silent
537 motion. so keep track of that here.
540 if (_slave_state == Running) {
541 calculate_moving_average_of_slave_delta(dir, this_delta);
545 track_slave_state (slave_speed, slave_transport_frame, this_delta);
547 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
548 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
551 if (_slave_state == Running && !_slave->is_always_synced() &&
552 !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
555 if (_transport_speed != 0.0f) {
558 note that average_dir is +1 or -1
563 if (average_slave_delta == 0) {
567 delta = average_slave_delta;
568 delta *= average_dir;
572 if (slave_speed != 0.0) {
573 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
574 (int) (dir * this_delta),
578 slave_transport_frame,
579 average_slave_delta));
583 if (_slave->give_slave_full_control_over_transport_speed()) {
584 set_transport_speed (slave_speed, 0, false, false);
585 //std::cout << "set speed = " << slave_speed << "\n";
587 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
588 request_transport_speed (adjusted_speed);
589 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
590 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
595 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
596 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
604 if (_slave_state == Running && !non_realtime_work_pending()) {
605 /* speed is set, we're locked, and good to go */
610 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
611 follow_slave_silently (nframes, slave_speed);
614 /* don't move at all */
615 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
621 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
623 if (delta_accumulator_cnt >= delta_accumulator_size) {
624 have_first_delta_accumulator = true;
625 delta_accumulator_cnt = 0;
628 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
629 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
632 if (have_first_delta_accumulator) {
633 average_slave_delta = 0L;
634 for (int i = 0; i < delta_accumulator_size; ++i) {
635 average_slave_delta += delta_accumulator[i];
637 average_slave_delta /= (int32_t) delta_accumulator_size;
638 if (average_slave_delta < 0L) {
640 average_slave_delta = abs(average_slave_delta);
648 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
650 if (slave_speed != 0.0f) {
652 /* slave is running */
654 switch (_slave_state) {
656 if (_slave->requires_seekahead()) {
657 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
658 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
659 /* we can call locate() here because we are in process context */
660 locate (slave_wait_end, false, false);
661 _slave_state = Waiting;
665 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
667 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
668 average_slave_delta = 0L;
670 Location* al = _locations->auto_loop_location();
672 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
674 request_play_loop(false);
677 if (slave_transport_frame != _transport_frame) {
678 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
679 locate (slave_transport_frame, false, false);
681 _slave_state = Running;
690 if (_slave_state == Waiting) {
692 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
694 if (slave_transport_frame >= slave_wait_end) {
696 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
698 _slave_state = Running;
700 /* now perform a "micro-seek" within the disk buffers to realign ourselves
701 precisely with the master.
706 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
708 boost::shared_ptr<RouteList> rl = routes.reader();
709 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
710 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
711 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
718 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
719 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
721 tr->internal_playback_seek (frame_delta);
724 _transport_frame += frame_delta;
727 cerr << "cannot micro-seek\n";
733 if (_slave_state == Running && _transport_speed == 0.0f) {
734 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
738 } else { // slave_speed is 0
740 /* slave has stopped */
742 if (_transport_speed != 0.0f) {
743 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
747 if (slave_transport_frame != _transport_frame) {
748 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
749 force_locate (slave_transport_frame, false);
757 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
759 if (slave_speed && _transport_speed) {
761 /* something isn't right, but we should move with the master
765 bool need_butler = false;
767 silent_process_routes (nframes, need_butler);
769 get_track_statistics ();
775 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
777 if (frames_moved < 0) {
778 decrement_transport_position (-frames_moved);
780 increment_transport_position (frames_moved);
783 framepos_t const stop_limit = compute_stop_limit ();
784 maybe_stop (stop_limit);
789 Session::process_without_events (pframes_t nframes)
791 bool session_needs_butler = false;
792 framecnt_t frames_moved;
794 if (!process_can_proceed()) {
799 if (!_exporting && _slave) {
800 if (!follow_slave (nframes)) {
801 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
806 if (_transport_speed == 0) {
811 if (_transport_speed == 1.0) {
812 frames_moved = (framecnt_t) nframes;
814 interpolation.set_target_speed (_target_transport_speed);
815 interpolation.set_speed (_transport_speed);
816 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
819 if (!_exporting && !timecode_transmission_suspended()) {
820 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
823 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
825 framepos_t const stop_limit = compute_stop_limit ();
827 if (maybe_stop (stop_limit)) {
832 if (maybe_sync_start (nframes)) {
836 click (_transport_frame, nframes);
838 if (process_routes (nframes, session_needs_butler)) {
843 get_track_statistics ();
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_auditioner()) {
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 (_monitor_out && auditioner->needs_monitor()) {
883 _monitor_out->monitor_run (_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, ev->speed);
1020 case SessionEvent::AutoLoop:
1022 /* roll after locate, do not flush, set "with loop"
1023 true only if we are seamless looping
1025 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1031 case SessionEvent::AutoLoopDeclick:
1033 /* Request a declick fade-out and a fade-in; the fade-out will happen
1034 at the end of the loop, and the fade-in at the start.
1036 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1042 case SessionEvent::Locate:
1043 if (ev->yes_or_no) {
1044 /* args: do not roll after locate, do flush, not with loop */
1045 locate (ev->target_frame, false, true, false);
1047 /* args: do not roll after locate, do flush, not with loop */
1048 start_locate (ev->target_frame, false, true, false);
1050 _send_timecode_update = true;
1053 case SessionEvent::LocateRoll:
1054 if (ev->yes_or_no) {
1055 /* args: roll after locate, do flush, not with loop */
1056 locate (ev->target_frame, true, true, false);
1058 /* args: roll after locate, do flush, not with loop */
1059 start_locate (ev->target_frame, true, true, false);
1061 _send_timecode_update = true;
1064 case SessionEvent::Skip:
1065 if (Config->get_skip_playback()) {
1066 start_locate (ev->target_frame, true, true, false);
1067 _send_timecode_update = true;
1073 case SessionEvent::LocateRollLocate:
1074 // locate is handled by ::request_roll_at_and_return()
1075 _requested_return_frame = ev->target_frame;
1076 request_locate (ev->target2_frame, true);
1080 case SessionEvent::SetTransportSpeed:
1081 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1084 case SessionEvent::PunchIn:
1085 // cerr << "PunchIN at " << transport_frame() << endl;
1086 if (config.get_punch_in() && record_status() == Enabled) {
1093 case SessionEvent::PunchOut:
1094 // cerr << "PunchOUT at " << transport_frame() << endl;
1095 if (config.get_punch_out()) {
1096 step_back_from_record ();
1102 case SessionEvent::StopOnce:
1103 if (!non_realtime_work_pending()) {
1104 _clear_event_type (SessionEvent::StopOnce);
1105 stop_transport (ev->yes_or_no);
1111 case SessionEvent::RangeStop:
1112 if (!non_realtime_work_pending()) {
1113 stop_transport (ev->yes_or_no);
1119 case SessionEvent::RangeLocate:
1120 /* args: roll after locate, do flush, not with loop */
1121 start_locate (ev->target_frame, true, true, false);
1126 case SessionEvent::Overwrite:
1127 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1130 case SessionEvent::SetTrackSpeed:
1131 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1134 case SessionEvent::SetSyncSource:
1135 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1136 use_sync_source (ev->slave);
1139 case SessionEvent::Audition:
1140 set_audition (ev->region);
1141 // drop reference to region
1142 ev->region.reset ();
1145 case SessionEvent::InputConfigurationChange:
1146 add_post_transport_work (PostTransportInputChange);
1147 _butler->schedule_transport_work ();
1150 case SessionEvent::SetPlayAudioRange:
1151 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1154 case SessionEvent::CancelPlayAudioRange:
1158 case SessionEvent::RealTimeOperation:
1160 del = false; // other side of RT request needs to clean up
1163 case SessionEvent::AdjustPlaybackBuffering:
1164 schedule_playback_buffering_adjustment ();
1167 case SessionEvent::AdjustCaptureBuffering:
1168 schedule_capture_buffering_adjustment ();
1171 case SessionEvent::SetTimecodeTransmission:
1172 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1176 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1177 abort(); /*NOTREACHED*/
1182 del = del && !_remove_event (ev);
1191 Session::compute_stop_limit () const
1193 if (!Config->get_stop_at_session_end ()) {
1194 return max_framepos;
1198 return max_framepos;
1202 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1203 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1205 if (actively_recording ()) {
1206 /* permanently recording */
1207 return max_framepos;
1208 } else if (punching_in && !punching_out) {
1209 /* punching in but never out */
1210 return max_framepos;
1211 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1212 /* punching in and punching out after session end */
1213 return max_framepos;
1216 return current_end_frame ();