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 /* realtime-safe meter-position changes
80 * ideally this would be done in
81 * Route::process_output_buffers() but various functions
82 * callig it hold a _processor_lock reader-lock
84 boost::shared_ptr<RouteList> r = routes.reader ();
85 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
86 (*i)->apply_meter_change_rt();
89 _engine.main_thread()->drop_buffers ();
91 /* deliver MIDI clock. Note that we need to use the transport frame
92 * position at the start of process(), not the value at the end of
93 * it. We may already have ticked() because of a transport state
94 * change, for example.
98 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
99 midi_clock->tick (transport_at_start, nframes);
102 _scene_changer->run (transport_at_start, transport_at_start + nframes);
105 /* don't bother with a message */
108 SendFeedback (); /* EMIT SIGNAL */
112 Session::fail_roll (pframes_t nframes)
114 return no_roll (nframes);
118 Session::no_roll (pframes_t nframes)
122 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
124 int declick = get_transport_declick_required();
125 boost::shared_ptr<RouteList> r = routes.reader ();
128 _click_io->silence (nframes);
131 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
133 if (_process_graph) {
134 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
135 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
137 PT_TIMING_CHECK (10);
138 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
140 if ((*i)->is_auditioner()) {
144 (*i)->set_pending_declick (declick);
146 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
147 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
152 PT_TIMING_CHECK (11);
159 /** @param need_butler to be set to true by this method if it needs the butler,
160 * otherwise it must be left alone.
163 Session::process_routes (pframes_t nframes, bool& need_butler)
165 int declick = get_transport_declick_required();
166 boost::shared_ptr<RouteList> r = routes.reader ();
168 const framepos_t start_frame = _transport_frame;
169 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
171 if (_process_graph) {
172 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
173 if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
179 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
183 if ((*i)->is_auditioner()) {
187 (*i)->set_pending_declick (declick);
191 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
205 /** @param need_butler to be set to true by this method if it needs the butler,
206 * otherwise it must be left alone.
209 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
211 boost::shared_ptr<RouteList> r = routes.reader ();
213 const framepos_t start_frame = _transport_frame;
214 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
216 if (_process_graph) {
217 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
219 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
223 if ((*i)->is_auditioner()) {
229 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
244 Session::get_track_statistics ()
249 boost::shared_ptr<RouteList> rl = routes.reader();
250 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
252 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
254 if (!tr || tr->hidden()) {
258 pworst = min (pworst, tr->playback_buffer_load());
259 cworst = min (cworst, tr->capture_buffer_load());
262 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
263 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
265 if (actively_recording()) {
270 /** Process callback used when the auditioner is not active */
272 Session::process_with_events (pframes_t nframes)
277 pframes_t this_nframes;
278 framepos_t end_frame;
279 bool session_needs_butler = false;
280 framecnt_t frames_moved;
282 /* make sure the auditioner is silent */
285 auditioner->silence (nframes);
288 /* handle any pending events */
290 while (pending_events.read (&ev, 1) == 1) {
294 /* if we are not in the middle of a state change,
295 and there are immediate events queued up,
299 while (!non_realtime_work_pending() && !immediate_events.empty()) {
300 SessionEvent *ev = immediate_events.front ();
301 immediate_events.pop_front ();
305 /* Decide on what to do with quarter-frame MTC during this cycle */
307 bool const was_sending_qf_mtc = _send_qf_mtc;
308 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
310 if (_transport_speed != 0) {
312 Config->get_send_mtc () &&
313 _transport_speed >= (1 - tolerance) &&
314 _transport_speed <= (1 + tolerance)
317 if (_send_qf_mtc && !was_sending_qf_mtc) {
318 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
319 _send_timecode_update = true;
322 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
323 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
324 a quarter of a second since we sent anything at all, so send a full MTC update
327 _send_timecode_update = true;
330 _pframes_since_last_mtc += nframes;
333 /* Events caused a transport change (or we re-started sending
334 * MTC), so send an MTC Full Frame (Timecode) message. This
335 * is sent whether rolling or not, to give slaves an idea of
336 * ardour time on locates (and allow slow slaves to position
337 * and prepare for rolling)
339 if (_send_timecode_update) {
340 send_full_time_code (_transport_frame, nframes);
343 if (!process_can_proceed()) {
348 if (events.empty() || next_event == events.end()) {
349 process_without_events (nframes);
353 if (_transport_speed == 1.0) {
354 frames_moved = (framecnt_t) nframes;
356 interpolation.set_target_speed (_target_transport_speed);
357 interpolation.set_speed (_transport_speed);
358 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
361 end_frame = _transport_frame + frames_moved;
364 SessionEvent* this_event;
365 Events::iterator the_next_one;
367 if (!process_can_proceed()) {
372 if (!_exporting && _slave) {
373 if (!follow_slave (nframes)) {
378 if (_transport_speed == 0) {
383 if (!_exporting && !timecode_transmission_suspended()) {
384 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
387 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
389 framepos_t stop_limit = compute_stop_limit ();
391 if (maybe_stop (stop_limit)) {
396 this_event = *next_event;
397 the_next_one = next_event;
400 /* yes folks, here it is, the actual loop where we really truly
406 this_nframes = nframes; /* real (jack) time relative */
407 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
409 /* running an event, position transport precisely to its time */
410 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
411 /* this isn't quite right for reverse play */
412 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
413 this_nframes = abs (floor(frames_moved / _transport_speed));
418 click (_transport_frame, this_nframes);
420 if (process_routes (this_nframes, session_needs_butler)) {
425 get_track_statistics ();
427 nframes -= this_nframes;
429 if (frames_moved < 0) {
430 decrement_transport_position (-frames_moved);
432 increment_transport_position (frames_moved);
435 maybe_stop (stop_limit);
436 check_declick_out ();
440 _engine.split_cycle (this_nframes);
443 /* now handle this event and all others scheduled for the same time */
445 while (this_event && this_event->action_frame == _transport_frame) {
446 process_event (this_event);
448 if (the_next_one == events.end()) {
451 this_event = *the_next_one;
456 /* if an event left our state changing, do the right thing */
458 if (nframes && non_realtime_work_pending()) {
463 /* this is necessary to handle the case of seamless looping */
464 end_frame = _transport_frame + floor (nframes * _transport_speed);
469 } /* implicit release of route lock */
471 if (session_needs_butler) {
477 Session::reset_slave_state ()
479 average_slave_delta = 1800;
480 delta_accumulator_cnt = 0;
481 have_first_delta_accumulator = false;
482 _slave_state = Stopped;
486 Session::transport_locked () const
490 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
498 Session::follow_slave (pframes_t nframes)
501 framepos_t slave_transport_frame;
502 framecnt_t this_delta;
507 config.set_external_sync (false);
511 _slave->speed_and_position (slave_speed, slave_transport_frame);
513 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
515 if (!_slave->locked()) {
516 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
520 if (slave_transport_frame > _transport_frame) {
521 this_delta = slave_transport_frame - _transport_frame;
524 this_delta = _transport_frame - slave_transport_frame;
528 if (_slave->starting()) {
532 if (_slave->is_always_synced() ||
533 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
536 /* if the TC source is synced, then we assume that its
537 speed is binary: 0.0 or 1.0
540 if (slave_speed != 0.0f) {
546 /* if we are chasing and the average delta between us and the
547 master gets too big, we want to switch to silent
548 motion. so keep track of that here.
551 if (_slave_state == Running) {
552 calculate_moving_average_of_slave_delta(dir, this_delta);
556 track_slave_state (slave_speed, slave_transport_frame, this_delta);
558 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
559 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
562 if (_slave_state == Running && !_slave->is_always_synced() &&
563 !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
566 if (_transport_speed != 0.0f) {
569 note that average_dir is +1 or -1
574 if (average_slave_delta == 0) {
578 delta = average_slave_delta;
579 delta *= average_dir;
583 if (slave_speed != 0.0) {
584 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
585 (int) (dir * this_delta),
589 slave_transport_frame,
590 average_slave_delta));
594 if (_slave->give_slave_full_control_over_transport_speed()) {
595 set_transport_speed (slave_speed, 0, false, false);
596 //std::cout << "set speed = " << slave_speed << "\n";
598 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
599 request_transport_speed (adjusted_speed);
600 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
601 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
606 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
607 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
615 if (_slave_state == Running && !non_realtime_work_pending()) {
616 /* speed is set, we're locked, and good to go */
621 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
622 follow_slave_silently (nframes, slave_speed);
625 /* don't move at all */
626 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
632 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
634 if (delta_accumulator_cnt >= delta_accumulator_size) {
635 have_first_delta_accumulator = true;
636 delta_accumulator_cnt = 0;
639 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
640 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
643 if (have_first_delta_accumulator) {
644 average_slave_delta = 0L;
645 for (int i = 0; i < delta_accumulator_size; ++i) {
646 average_slave_delta += delta_accumulator[i];
648 average_slave_delta /= (int32_t) delta_accumulator_size;
649 if (average_slave_delta < 0L) {
651 average_slave_delta = abs(average_slave_delta);
659 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
661 if (slave_speed != 0.0f) {
663 /* slave is running */
665 switch (_slave_state) {
667 if (_slave->requires_seekahead()) {
668 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
669 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
670 /* we can call locate() here because we are in process context */
671 locate (slave_wait_end, false, false);
672 _slave_state = Waiting;
676 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
678 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
679 average_slave_delta = 0L;
681 Location* al = _locations->auto_loop_location();
683 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
685 request_play_loop(false);
688 if (slave_transport_frame != _transport_frame) {
689 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
690 locate (slave_transport_frame, false, false);
692 _slave_state = Running;
701 if (_slave_state == Waiting) {
703 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
705 if (slave_transport_frame >= slave_wait_end) {
707 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
709 _slave_state = Running;
711 /* now perform a "micro-seek" within the disk buffers to realign ourselves
712 precisely with the master.
717 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
719 boost::shared_ptr<RouteList> rl = routes.reader();
720 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
721 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
722 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
729 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
730 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
732 tr->internal_playback_seek (frame_delta);
735 _transport_frame += frame_delta;
738 cerr << "cannot micro-seek\n";
744 if (_slave_state == Running && _transport_speed == 0.0f) {
745 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
749 } else { // slave_speed is 0
751 /* slave has stopped */
753 if (_transport_speed != 0.0f) {
754 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
758 if (slave_transport_frame != _transport_frame) {
759 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
760 force_locate (slave_transport_frame, false);
768 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
770 if (slave_speed && _transport_speed) {
772 /* something isn't right, but we should move with the master
776 bool need_butler = false;
778 silent_process_routes (nframes, need_butler);
780 get_track_statistics ();
786 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
788 if (frames_moved < 0) {
789 decrement_transport_position (-frames_moved);
791 increment_transport_position (frames_moved);
794 framepos_t const stop_limit = compute_stop_limit ();
795 maybe_stop (stop_limit);
800 Session::process_without_events (pframes_t nframes)
802 bool session_needs_butler = false;
803 framecnt_t frames_moved;
805 if (!process_can_proceed()) {
810 if (!_exporting && _slave) {
811 if (!follow_slave (nframes)) {
812 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
817 if (_transport_speed == 0) {
822 if (_transport_speed == 1.0) {
823 frames_moved = (framecnt_t) nframes;
825 interpolation.set_target_speed (_target_transport_speed);
826 interpolation.set_speed (_transport_speed);
827 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
830 if (!_exporting && !timecode_transmission_suspended()) {
831 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
834 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
836 framepos_t const stop_limit = compute_stop_limit ();
838 if (maybe_stop (stop_limit)) {
843 if (maybe_sync_start (nframes)) {
847 click (_transport_frame, nframes);
849 if (process_routes (nframes, session_needs_butler)) {
854 get_track_statistics ();
856 if (frames_moved < 0) {
857 decrement_transport_position (-frames_moved);
859 increment_transport_position (frames_moved);
862 maybe_stop (stop_limit);
863 check_declick_out ();
865 if (session_needs_butler) {
870 /** Process callback used when the auditioner is active.
871 * @param nframes number of frames to process.
874 Session::process_audition (pframes_t nframes)
877 boost::shared_ptr<RouteList> r = routes.reader ();
879 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
880 if (!(*i)->is_auditioner()) {
881 (*i)->silence (nframes);
885 /* run the auditioner, and if it says we need butler service, ask for it */
887 if (auditioner->play_audition (nframes) > 0) {
891 /* if using a monitor section, run it because otherwise we don't hear anything */
893 if (_monitor_out && auditioner->needs_monitor()) {
894 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
897 /* handle pending events */
899 while (pending_events.read (&ev, 1) == 1) {
903 /* if we are not in the middle of a state change,
904 and there are immediate events queued up,
908 while (!non_realtime_work_pending() && !immediate_events.empty()) {
909 SessionEvent *ev = immediate_events.front ();
910 immediate_events.pop_front ();
914 if (!auditioner->auditioning()) {
915 /* auditioner no longer active, so go back to the normal process callback */
916 process_function = &Session::process_with_events;
921 Session::maybe_sync_start (pframes_t & nframes)
923 pframes_t sync_offset;
925 if (!waiting_for_sync_offset) {
929 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
931 /* generate silence up to the sync point, then
932 adjust nframes + offset to reflect whatever
936 no_roll (sync_offset);
937 nframes -= sync_offset;
938 Port::increment_global_port_buffer_offset (sync_offset);
939 waiting_for_sync_offset = false;
942 return true; // done, nothing left to process
947 /* sync offset point is not within this process()
948 cycle, so just generate silence. and don't bother
949 with any fancy stuff here, just the minimal silence.
954 if (Config->get_locate_while_waiting_for_sync()) {
955 if (micro_locate (nframes)) {
956 /* XXX ERROR !!! XXX */
960 return true; // done, nothing left to process
967 Session::queue_event (SessionEvent* ev)
969 if (_state_of_the_state & Deletion) {
971 } else if (_state_of_the_state & Loading) {
974 pending_events.write (&ev, 1);
979 Session::set_next_event ()
981 if (events.empty()) {
982 next_event = events.end();
986 if (next_event == events.end()) {
987 next_event = events.begin();
990 if ((*next_event)->action_frame > _transport_frame) {
991 next_event = events.begin();
994 for (; next_event != events.end(); ++next_event) {
995 if ((*next_event)->action_frame >= _transport_frame) {
1002 Session::process_event (SessionEvent* ev)
1007 /* if we're in the middle of a state change (i.e. waiting
1008 for the butler thread to complete the non-realtime
1009 part of the change), we'll just have to queue this
1010 event for a time when the change is complete.
1013 if (non_realtime_work_pending()) {
1015 /* except locates, which we have the capability to handle */
1017 if (ev->type != SessionEvent::Locate) {
1018 immediate_events.insert (immediate_events.end(), ev);
1024 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1027 case SessionEvent::SetLoop:
1028 set_play_loop (ev->yes_or_no, ev->speed);
1031 case SessionEvent::AutoLoop:
1033 /* roll after locate, do not flush, set "with loop"
1034 true only if we are seamless looping
1036 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1042 case SessionEvent::AutoLoopDeclick:
1044 /* Request a declick fade-out and a fade-in; the fade-out will happen
1045 at the end of the loop, and the fade-in at the start.
1047 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1053 case SessionEvent::Locate:
1054 if (ev->yes_or_no) {
1055 /* args: do not roll after locate, do flush, not with loop */
1056 locate (ev->target_frame, false, true, false);
1058 /* args: do not roll after locate, do flush, not with loop */
1059 start_locate (ev->target_frame, false, true, false);
1061 _send_timecode_update = true;
1064 case SessionEvent::LocateRoll:
1065 if (ev->yes_or_no) {
1066 /* args: roll after locate, do flush, not with loop */
1067 locate (ev->target_frame, true, true, false);
1069 /* args: roll after locate, do flush, not with loop */
1070 start_locate (ev->target_frame, true, true, false);
1072 _send_timecode_update = true;
1075 case SessionEvent::Skip:
1076 if (Config->get_skip_playback()) {
1077 start_locate (ev->target_frame, true, true, false);
1078 _send_timecode_update = true;
1084 case SessionEvent::LocateRollLocate:
1085 // locate is handled by ::request_roll_at_and_return()
1086 _requested_return_frame = ev->target_frame;
1087 request_locate (ev->target2_frame, true);
1091 case SessionEvent::SetTransportSpeed:
1092 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1095 case SessionEvent::PunchIn:
1096 // cerr << "PunchIN at " << transport_frame() << endl;
1097 if (config.get_punch_in() && record_status() == Enabled) {
1104 case SessionEvent::PunchOut:
1105 // cerr << "PunchOUT at " << transport_frame() << endl;
1106 if (config.get_punch_out()) {
1107 step_back_from_record ();
1113 case SessionEvent::StopOnce:
1114 if (!non_realtime_work_pending()) {
1115 _clear_event_type (SessionEvent::StopOnce);
1116 stop_transport (ev->yes_or_no);
1122 case SessionEvent::RangeStop:
1123 if (!non_realtime_work_pending()) {
1124 stop_transport (ev->yes_or_no);
1130 case SessionEvent::RangeLocate:
1131 /* args: roll after locate, do flush, not with loop */
1132 start_locate (ev->target_frame, true, true, false);
1137 case SessionEvent::Overwrite:
1138 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1141 case SessionEvent::SetTrackSpeed:
1142 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1145 case SessionEvent::SetSyncSource:
1146 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1147 use_sync_source (ev->slave);
1150 case SessionEvent::Audition:
1151 set_audition (ev->region);
1152 // drop reference to region
1153 ev->region.reset ();
1156 case SessionEvent::InputConfigurationChange:
1157 add_post_transport_work (PostTransportInputChange);
1158 _butler->schedule_transport_work ();
1161 case SessionEvent::SetPlayAudioRange:
1162 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1165 case SessionEvent::CancelPlayAudioRange:
1169 case SessionEvent::RealTimeOperation:
1171 del = false; // other side of RT request needs to clean up
1174 case SessionEvent::AdjustPlaybackBuffering:
1175 schedule_playback_buffering_adjustment ();
1178 case SessionEvent::AdjustCaptureBuffering:
1179 schedule_capture_buffering_adjustment ();
1182 case SessionEvent::SetTimecodeTransmission:
1183 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1187 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1188 abort(); /*NOTREACHED*/
1193 del = del && !_remove_event (ev);
1202 Session::compute_stop_limit () const
1204 if (!Config->get_stop_at_session_end ()) {
1205 return max_framepos;
1209 return max_framepos;
1213 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1214 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1216 if (actively_recording ()) {
1217 /* permanently recording */
1218 return max_framepos;
1219 } else if (punching_in && !punching_out) {
1220 /* punching in but never out */
1221 return max_framepos;
1222 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1223 /* punching in and punching out after session end */
1224 return max_framepos;
1227 return current_end_frame ();