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 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
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 (!actively_recording() && (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 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
662 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
663 average_slave_delta = 0L;
665 Location* al = _locations->auto_loop_location();
667 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
669 request_play_loop(false);
672 if (slave_transport_frame != _transport_frame) {
673 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
674 locate (slave_transport_frame, false, false);
676 _slave_state = Running;
685 if (_slave_state == Waiting) {
687 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
689 if (slave_transport_frame >= slave_wait_end) {
691 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
693 _slave_state = Running;
695 /* now perform a "micro-seek" within the disk buffers to realign ourselves
696 precisely with the master.
701 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
703 boost::shared_ptr<RouteList> rl = routes.reader();
704 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
705 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
706 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
713 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
714 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
716 tr->internal_playback_seek (frame_delta);
719 _transport_frame += frame_delta;
722 cerr << "cannot micro-seek\n";
728 if (_slave_state == Running && _transport_speed == 0.0f) {
729 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
733 } else { // slave_speed is 0
735 /* slave has stopped */
737 if (_transport_speed != 0.0f) {
738 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
742 if (slave_transport_frame != _transport_frame) {
743 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
744 force_locate (slave_transport_frame, false);
752 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
754 if (slave_speed && _transport_speed) {
756 /* something isn't right, but we should move with the master
762 silent_process_routes (nframes, need_butler);
764 get_track_statistics ();
770 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
772 if (frames_moved < 0) {
773 decrement_transport_position (-frames_moved);
775 increment_transport_position (frames_moved);
778 framepos_t const stop_limit = compute_stop_limit ();
779 maybe_stop (stop_limit);
784 Session::process_without_events (pframes_t nframes)
786 bool session_needs_butler = false;
787 framecnt_t frames_moved;
789 if (!process_can_proceed()) {
794 if (!_exporting && _slave) {
795 if (!follow_slave (nframes)) {
797 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
803 if (_transport_speed == 0) {
807 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
813 if (_transport_speed == 1.0) {
814 frames_moved = (framecnt_t) nframes;
816 interpolation.set_target_speed (fabs(_target_transport_speed));
817 interpolation.set_speed (fabs(_transport_speed));
818 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
821 if (!_exporting && !timecode_transmission_suspended()) {
822 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
827 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
831 framepos_t const stop_limit = compute_stop_limit ();
833 if (maybe_stop (stop_limit)) {
838 if (maybe_sync_start (nframes)) {
842 click (_transport_frame, nframes);
844 if (process_routes (nframes, session_needs_butler)) {
849 get_track_statistics ();
851 /* XXX: I'm not sure whether this is correct, but at least it
852 matches process_with_events, so that this new frames_moved
853 is -ve when transport speed is -ve. This means that the
854 transport position is updated correctly when we are in
855 reverse. It seems a bit wrong that we're not using the
856 interpolator to compute this.
859 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
861 if (frames_moved < 0) {
862 decrement_transport_position (-frames_moved);
864 increment_transport_position (frames_moved);
867 maybe_stop (stop_limit);
868 check_declick_out ();
870 if (session_needs_butler) {
875 /** Process callback used when the auditioner is active.
876 * @param nframes number of frames to process.
879 Session::process_audition (pframes_t nframes)
882 boost::shared_ptr<RouteList> r = routes.reader ();
884 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
885 if (!(*i)->is_hidden()) {
886 (*i)->silence (nframes);
890 /* run the auditioner, and if it says we need butler service, ask for it */
892 if (auditioner->play_audition (nframes) > 0) {
896 /* if using a monitor section, run it because otherwise we don't hear anything */
898 if (auditioner->needs_monitor()) {
899 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
902 /* handle pending events */
904 while (pending_events.read (&ev, 1) == 1) {
908 /* if we are not in the middle of a state change,
909 and there are immediate events queued up,
913 while (!non_realtime_work_pending() && !immediate_events.empty()) {
914 SessionEvent *ev = immediate_events.front ();
915 immediate_events.pop_front ();
919 if (!auditioner->auditioning()) {
920 /* auditioner no longer active, so go back to the normal process callback */
921 process_function = &Session::process_with_events;
926 Session::maybe_sync_start (pframes_t & nframes)
928 pframes_t sync_offset;
930 if (!waiting_for_sync_offset) {
934 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
936 /* generate silence up to the sync point, then
937 adjust nframes + offset to reflect whatever
941 no_roll (sync_offset);
942 nframes -= sync_offset;
943 Port::increment_global_port_buffer_offset (sync_offset);
944 waiting_for_sync_offset = false;
947 return true; // done, nothing left to process
952 /* sync offset point is not within this process()
953 cycle, so just generate silence. and don't bother
954 with any fancy stuff here, just the minimal silence.
959 if (Config->get_locate_while_waiting_for_sync()) {
960 if (micro_locate (nframes)) {
961 /* XXX ERROR !!! XXX */
965 return true; // done, nothing left to process
972 Session::queue_event (SessionEvent* ev)
974 if (_state_of_the_state & Deletion) {
976 } else if (_state_of_the_state & Loading) {
979 pending_events.write (&ev, 1);
984 Session::set_next_event ()
986 if (events.empty()) {
987 next_event = events.end();
991 if (next_event == events.end()) {
992 next_event = events.begin();
995 if ((*next_event)->action_frame > _transport_frame) {
996 next_event = events.begin();
999 for (; next_event != events.end(); ++next_event) {
1000 if ((*next_event)->action_frame >= _transport_frame) {
1007 Session::process_event (SessionEvent* ev)
1012 /* if we're in the middle of a state change (i.e. waiting
1013 for the butler thread to complete the non-realtime
1014 part of the change), we'll just have to queue this
1015 event for a time when the change is complete.
1018 if (non_realtime_work_pending()) {
1020 /* except locates, which we have the capability to handle */
1022 if (ev->type != SessionEvent::Locate) {
1023 immediate_events.insert (immediate_events.end(), ev);
1029 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1032 case SessionEvent::SetLoop:
1033 set_play_loop (ev->yes_or_no);
1036 case SessionEvent::AutoLoop:
1038 /* roll after locate, do not flush, set "with loop"
1039 true only if we are seamless looping
1041 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1047 case SessionEvent::AutoLoopDeclick:
1049 /* Request a declick fade-out and a fade-in; the fade-out will happen
1050 at the end of the loop, and the fade-in at the start.
1052 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1058 case SessionEvent::Locate:
1059 if (ev->yes_or_no) {
1060 /* args: do not roll after locate, do flush, not with loop */
1061 locate (ev->target_frame, false, true, false);
1063 /* args: do not roll after locate, do flush, not with loop */
1064 start_locate (ev->target_frame, false, true, false);
1066 _send_timecode_update = true;
1069 case SessionEvent::LocateRoll:
1070 if (ev->yes_or_no) {
1071 /* args: roll after locate, do flush, not with loop */
1072 locate (ev->target_frame, true, true, false);
1074 /* args: roll after locate, do flush, not with loop */
1075 start_locate (ev->target_frame, true, true, false);
1077 _send_timecode_update = true;
1080 case SessionEvent::LocateRollLocate:
1081 // locate is handled by ::request_roll_at_and_return()
1082 _requested_return_frame = ev->target_frame;
1083 request_locate (ev->target2_frame, true);
1087 case SessionEvent::SetTransportSpeed:
1088 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1091 case SessionEvent::PunchIn:
1092 // cerr << "PunchIN at " << transport_frame() << endl;
1093 if (config.get_punch_in() && record_status() == Enabled) {
1100 case SessionEvent::PunchOut:
1101 // cerr << "PunchOUT at " << transport_frame() << endl;
1102 if (config.get_punch_out()) {
1103 step_back_from_record ();
1109 case SessionEvent::StopOnce:
1110 if (!non_realtime_work_pending()) {
1111 stop_transport (ev->yes_or_no);
1112 _clear_event_type (SessionEvent::StopOnce);
1118 case SessionEvent::RangeStop:
1119 if (!non_realtime_work_pending()) {
1120 stop_transport (ev->yes_or_no);
1126 case SessionEvent::RangeLocate:
1127 /* args: roll after locate, do flush, not with loop */
1128 start_locate (ev->target_frame, true, true, false);
1133 case SessionEvent::Overwrite:
1134 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1137 case SessionEvent::SetTrackSpeed:
1138 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1141 case SessionEvent::SetSyncSource:
1142 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1143 use_sync_source (ev->slave);
1146 case SessionEvent::Audition:
1147 set_audition (ev->region);
1148 // drop reference to region
1149 ev->region.reset ();
1152 case SessionEvent::InputConfigurationChange:
1153 add_post_transport_work (PostTransportInputChange);
1154 _butler->schedule_transport_work ();
1157 case SessionEvent::SetPlayAudioRange:
1158 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1161 case SessionEvent::RealTimeOperation:
1163 del = false; // other side of RT request needs to clean up
1166 case SessionEvent::AdjustPlaybackBuffering:
1167 schedule_playback_buffering_adjustment ();
1170 case SessionEvent::AdjustCaptureBuffering:
1171 schedule_capture_buffering_adjustment ();
1174 case SessionEvent::SetTimecodeTransmission:
1175 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1179 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1185 del = del && !_remove_event (ev);
1194 Session::compute_stop_limit () const
1196 if (!Config->get_stop_at_session_end ()) {
1197 return max_framepos;
1200 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1201 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1203 if (actively_recording ()) {
1204 /* permanently recording */
1205 return max_framepos;
1206 } else if (punching_in && !punching_out) {
1207 /* punching in but never out */
1208 return max_framepos;
1209 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1210 /* punching in and punching out after session end */
1211 return max_framepos;
1214 return current_end_frame ();