2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "pbd/error.h"
26 #include "pbd/enumwriter.h"
28 #include <glibmm/thread.h>
30 #include "ardour/ardour.h"
31 #include "ardour/audioengine.h"
32 #include "ardour/auditioner.h"
33 #include "ardour/butler.h"
34 #include "ardour/debug.h"
35 #include "ardour/process_thread.h"
36 #include "ardour/session.h"
37 #include "ardour/slave.h"
38 #include "ardour/timestamps.h"
39 #include "ardour/graph.h"
40 #include "ardour/audio_port.h"
41 #include "ardour/tempo.h"
42 #include "ardour/ticker.h"
43 #include "ardour/cycle_timer.h"
45 #include "midi++/manager.h"
46 #include "midi++/mmc.h"
50 #include <xmmintrin.h>
52 using namespace ARDOUR;
56 /** Called by the audio engine when there is work to be done with JACK.
57 * @param nframes Number of frames to process.
61 Session::process (pframes_t nframes)
63 framepos_t transport_at_start = _transport_frame;
65 MIDI::Manager::instance()->cycle_start(nframes);
69 if (processing_blocked()) {
74 if (non_realtime_work_pending()) {
75 if (!_butler->transport_work_requested ()) {
80 _engine.main_thread()->get_buffers ();
82 (this->*process_function) (nframes);
84 _engine.main_thread()->drop_buffers ();
86 /* deliver MIDI clock. Note that we need to use the transport frame
87 * position at the start of process(), not the value at the end of
88 * it. We may already have ticked() because of a transport state
89 * change, for example.
93 if (!_engine.freewheeling() && Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) {
94 midi_clock->tick (transport_at_start);
97 /* don't bother with a message */
100 SendFeedback (); /* EMIT SIGNAL */
102 MIDI::Manager::instance()->cycle_end();
106 Session::fail_roll (pframes_t nframes)
108 return no_roll (nframes);
112 Session::no_roll (pframes_t nframes)
116 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
118 bool declick = get_transport_declick_required();
119 boost::shared_ptr<RouteList> r = routes.reader ();
122 _click_io->silence (nframes);
125 if (_process_graph) {
126 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
127 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
129 PT_TIMING_CHECK (10);
130 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
132 if ((*i)->is_hidden()) {
136 (*i)->set_pending_declick (declick);
138 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
139 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
144 PT_TIMING_CHECK (11);
151 /** @param need_butler to be set to true by this method if it needs the butler,
152 * otherwise it must be left alone.
155 Session::process_routes (pframes_t nframes, bool& need_butler)
157 int declick = get_transport_declick_required();
158 boost::shared_ptr<RouteList> r = routes.reader ();
160 if (transport_sub_state & StopPendingCapture) {
161 /* force a declick out */
165 const framepos_t start_frame = _transport_frame;
166 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
168 if (_process_graph) {
169 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
170 _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
173 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
177 if ((*i)->is_hidden()) {
181 (*i)->set_pending_declick (declick);
185 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
199 /** @param need_butler to be set to true by this method if it needs the butler,
200 * otherwise it must be left alone.
203 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
205 boost::shared_ptr<RouteList> r = routes.reader ();
207 const framepos_t start_frame = _transport_frame;
208 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
210 if (_process_graph) {
211 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
213 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
217 if ((*i)->is_hidden()) {
223 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
238 Session::get_track_statistics ()
243 boost::shared_ptr<RouteList> rl = routes.reader();
244 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
246 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
248 if (!tr || tr->hidden()) {
252 pworst = min (pworst, tr->playback_buffer_load());
253 cworst = min (cworst, tr->capture_buffer_load());
256 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
257 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
259 if (actively_recording()) {
264 /** Process callback used when the auditioner is not active */
266 Session::process_with_events (pframes_t nframes)
271 pframes_t this_nframes;
272 framepos_t end_frame;
273 bool session_needs_butler = false;
274 framecnt_t frames_moved;
276 /* make sure the auditioner is silent */
279 auditioner->silence (nframes);
282 /* handle any pending events */
284 while (pending_events.read (&ev, 1) == 1) {
288 /* if we are not in the middle of a state change,
289 and there are immediate events queued up,
293 while (!non_realtime_work_pending() && !immediate_events.empty()) {
294 SessionEvent *ev = immediate_events.front ();
295 immediate_events.pop_front ();
299 /* Decide on what to do with quarter-frame MTC during this cycle */
301 bool const was_sending_qf_mtc = _send_qf_mtc;
302 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
304 if (_transport_speed != 0) {
306 Config->get_send_mtc () &&
307 _transport_speed >= (1 - tolerance) &&
308 _transport_speed <= (1 + tolerance)
311 if (_send_qf_mtc && !was_sending_qf_mtc) {
312 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
313 _send_timecode_update = true;
316 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
317 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
318 a quarter of a second since we sent anything at all, so send a full MTC update
321 _send_timecode_update = true;
324 _pframes_since_last_mtc += nframes;
327 /* Events caused a transport change (or we re-started sending
328 * MTC), so send an MTC Full Frame (Timecode) message. This
329 * is sent whether rolling or not, to give slaves an idea of
330 * ardour time on locates (and allow slow slaves to position
331 * and prepare for rolling)
333 if (_send_timecode_update) {
334 send_full_time_code (_transport_frame);
337 if (!process_can_proceed()) {
342 if (events.empty() || next_event == events.end()) {
343 process_without_events (nframes);
347 if (_transport_speed == 1.0) {
348 frames_moved = (framecnt_t) nframes;
350 interpolation.set_target_speed (fabs(_target_transport_speed));
351 interpolation.set_speed (fabs(_transport_speed));
352 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
355 end_frame = _transport_frame + frames_moved;
358 SessionEvent* this_event;
359 Events::iterator the_next_one;
361 if (!process_can_proceed()) {
366 if (!_exporting && _slave) {
367 if (!follow_slave (nframes)) {
372 if (_transport_speed == 0) {
377 if (!_exporting && !timecode_transmission_suspended()) {
378 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
381 framepos_t stop_limit = compute_stop_limit ();
383 if (maybe_stop (stop_limit)) {
388 this_event = *next_event;
389 the_next_one = next_event;
392 /* yes folks, here it is, the actual loop where we really truly
398 this_nframes = nframes; /* real (jack) time relative */
399 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
401 /* running an event, position transport precisely to its time */
402 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
403 /* this isn't quite right for reverse play */
404 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
405 this_nframes = abs (floor(frames_moved / _transport_speed));
410 click (_transport_frame, this_nframes);
412 if (process_routes (this_nframes, session_needs_butler)) {
417 get_track_statistics ();
419 nframes -= this_nframes;
421 if (frames_moved < 0) {
422 decrement_transport_position (-frames_moved);
424 increment_transport_position (frames_moved);
427 maybe_stop (stop_limit);
428 check_declick_out ();
431 _engine.split_cycle (this_nframes);
433 /* now handle this event and all others scheduled for the same time */
435 while (this_event && this_event->action_frame == _transport_frame) {
436 process_event (this_event);
438 if (the_next_one == events.end()) {
441 this_event = *the_next_one;
446 /* if an event left our state changing, do the right thing */
448 if (nframes && non_realtime_work_pending()) {
453 /* this is necessary to handle the case of seamless looping */
454 end_frame = _transport_frame + floor (nframes * _transport_speed);
459 } /* implicit release of route lock */
461 if (session_needs_butler) {
467 Session::reset_slave_state ()
469 average_slave_delta = 1800;
470 delta_accumulator_cnt = 0;
471 have_first_delta_accumulator = false;
472 _slave_state = Stopped;
476 Session::transport_locked () const
480 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
488 Session::follow_slave (pframes_t nframes)
491 framepos_t slave_transport_frame;
492 framecnt_t this_delta;
497 config.set_external_sync (false);
501 _slave->speed_and_position (slave_speed, slave_transport_frame);
503 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
505 if (!_slave->locked()) {
506 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
510 if (slave_transport_frame > _transport_frame) {
511 this_delta = slave_transport_frame - _transport_frame;
514 this_delta = _transport_frame - slave_transport_frame;
518 if (_slave->starting()) {
522 if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
524 /* if the TC source is synced, then we assume that its
525 speed is binary: 0.0 or 1.0
528 if (slave_speed != 0.0f) {
534 /* if we are chasing and the average delta between us and the
535 master gets too big, we want to switch to silent
536 motion. so keep track of that here.
539 if (_slave_state == Running) {
540 calculate_moving_average_of_slave_delta(dir, this_delta);
544 track_slave_state (slave_speed, slave_transport_frame, this_delta);
546 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
547 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
550 if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
552 if (_transport_speed != 0.0f) {
555 note that average_dir is +1 or -1
560 if (average_slave_delta == 0) {
564 delta = average_slave_delta;
565 delta *= average_dir;
569 if (slave_speed != 0.0) {
570 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
571 (int) (dir * this_delta),
575 slave_transport_frame,
576 average_slave_delta));
580 if (_slave->give_slave_full_control_over_transport_speed()) {
581 set_transport_speed (slave_speed, false, false);
582 //std::cout << "set speed = " << slave_speed << "\n";
584 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
585 request_transport_speed (adjusted_speed);
586 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
587 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
592 if ((framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
593 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
601 if (_slave_state == Running && !non_realtime_work_pending()) {
602 /* speed is set, we're locked, and good to go */
607 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
608 follow_slave_silently (nframes, slave_speed);
611 /* don't move at all */
612 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
618 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
620 if (delta_accumulator_cnt >= delta_accumulator_size) {
621 have_first_delta_accumulator = true;
622 delta_accumulator_cnt = 0;
625 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
626 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
629 if (have_first_delta_accumulator) {
630 average_slave_delta = 0L;
631 for (int i = 0; i < delta_accumulator_size; ++i) {
632 average_slave_delta += delta_accumulator[i];
634 average_slave_delta /= (int32_t) delta_accumulator_size;
635 if (average_slave_delta < 0L) {
637 average_slave_delta = abs(average_slave_delta);
645 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
647 if (slave_speed != 0.0f) {
649 /* slave is running */
651 switch (_slave_state) {
653 if (_slave->requires_seekahead()) {
654 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
655 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
656 /* we can call locate() here because we are in process context */
657 locate (slave_wait_end, false, false);
658 _slave_state = Waiting;
662 _slave_state = Running;
664 Location* al = _locations->auto_loop_location();
666 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
668 request_play_loop(false);
671 if (slave_transport_frame != _transport_frame) {
672 locate (slave_transport_frame, false, false);
682 if (_slave_state == Waiting) {
684 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
686 if (slave_transport_frame >= slave_wait_end) {
688 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
690 _slave_state = Running;
692 /* now perform a "micro-seek" within the disk buffers to realign ourselves
693 precisely with the master.
698 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
700 boost::shared_ptr<RouteList> rl = routes.reader();
701 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
702 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
703 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
710 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
711 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
713 tr->internal_playback_seek (frame_delta);
716 _transport_frame += frame_delta;
719 cerr << "cannot micro-seek\n";
723 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
724 average_slave_delta = 0L;
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);
747 _slave_state = Stopped;
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)) {
800 if (_transport_speed == 0) {
805 if (_transport_speed == 1.0) {
806 frames_moved = (framecnt_t) nframes;
808 interpolation.set_target_speed (fabs(_target_transport_speed));
809 interpolation.set_speed (fabs(_transport_speed));
810 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
813 if (!_exporting && !timecode_transmission_suspended()) {
814 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
817 framepos_t const stop_limit = compute_stop_limit ();
819 if (maybe_stop (stop_limit)) {
824 if (maybe_sync_start (nframes)) {
828 click (_transport_frame, nframes);
830 if (process_routes (nframes, session_needs_butler)) {
835 get_track_statistics ();
837 /* XXX: I'm not sure whether this is correct, but at least it
838 matches process_with_events, so that this new frames_moved
839 is -ve when transport speed is -ve. This means that the
840 transport position is updated correctly when we are in
841 reverse. It seems a bit wrong that we're not using the
842 interpolator to compute this.
845 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
847 if (frames_moved < 0) {
848 decrement_transport_position (-frames_moved);
850 increment_transport_position (frames_moved);
853 maybe_stop (stop_limit);
854 check_declick_out ();
856 if (session_needs_butler) {
861 /** Process callback used when the auditioner is active.
862 * @param nframes number of frames to process.
865 Session::process_audition (pframes_t nframes)
868 boost::shared_ptr<RouteList> r = routes.reader ();
870 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
871 if (!(*i)->is_hidden()) {
872 (*i)->silence (nframes);
876 /* run the auditioner, and if it says we need butler service, ask for it */
878 if (auditioner->play_audition (nframes) > 0) {
882 /* if using a monitor section, run it because otherwise we don't hear anything */
884 if (auditioner->needs_monitor()) {
885 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
888 /* handle pending events */
890 while (pending_events.read (&ev, 1) == 1) {
894 /* if we are not in the middle of a state change,
895 and there are immediate events queued up,
899 while (!non_realtime_work_pending() && !immediate_events.empty()) {
900 SessionEvent *ev = immediate_events.front ();
901 immediate_events.pop_front ();
905 if (!auditioner->auditioning()) {
906 /* auditioner no longer active, so go back to the normal process callback */
907 process_function = &Session::process_with_events;
912 Session::maybe_sync_start (pframes_t & nframes)
914 pframes_t sync_offset;
916 if (!waiting_for_sync_offset) {
920 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
922 /* generate silence up to the sync point, then
923 adjust nframes + offset to reflect whatever
927 no_roll (sync_offset);
928 nframes -= sync_offset;
929 Port::increment_global_port_buffer_offset (sync_offset);
930 waiting_for_sync_offset = false;
933 return true; // done, nothing left to process
938 /* sync offset point is not within this process()
939 cycle, so just generate silence. and don't bother
940 with any fancy stuff here, just the minimal silence.
945 if (Config->get_locate_while_waiting_for_sync()) {
946 if (micro_locate (nframes)) {
947 /* XXX ERROR !!! XXX */
951 return true; // done, nothing left to process
958 Session::queue_event (SessionEvent* ev)
960 if (_state_of_the_state & Deletion) {
962 } else if (_state_of_the_state & Loading) {
965 pending_events.write (&ev, 1);
970 Session::set_next_event ()
972 if (events.empty()) {
973 next_event = events.end();
977 if (next_event == events.end()) {
978 next_event = events.begin();
981 if ((*next_event)->action_frame > _transport_frame) {
982 next_event = events.begin();
985 for (; next_event != events.end(); ++next_event) {
986 if ((*next_event)->action_frame >= _transport_frame) {
993 Session::process_event (SessionEvent* ev)
998 /* if we're in the middle of a state change (i.e. waiting
999 for the butler thread to complete the non-realtime
1000 part of the change), we'll just have to queue this
1001 event for a time when the change is complete.
1004 if (non_realtime_work_pending()) {
1006 /* except locates, which we have the capability to handle */
1008 if (ev->type != SessionEvent::Locate) {
1009 immediate_events.insert (immediate_events.end(), ev);
1015 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1018 case SessionEvent::SetLoop:
1019 set_play_loop (ev->yes_or_no);
1022 case SessionEvent::AutoLoop:
1024 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1030 case SessionEvent::Locate:
1031 if (ev->yes_or_no) {
1032 // cerr << "forced locate to " << ev->target_frame << endl;
1033 locate (ev->target_frame, false, true, false);
1035 // cerr << "soft locate to " << ev->target_frame << endl;
1036 start_locate (ev->target_frame, false, true, false);
1038 _send_timecode_update = true;
1041 case SessionEvent::LocateRoll:
1042 if (ev->yes_or_no) {
1043 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1044 locate (ev->target_frame, true, true, false);
1046 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1047 start_locate (ev->target_frame, true, true, false);
1049 _send_timecode_update = true;
1052 case SessionEvent::LocateRollLocate:
1053 // locate is handled by ::request_roll_at_and_return()
1054 _requested_return_frame = ev->target_frame;
1055 request_locate (ev->target2_frame, true);
1059 case SessionEvent::SetTransportSpeed:
1060 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1063 case SessionEvent::PunchIn:
1064 // cerr << "PunchIN at " << transport_frame() << endl;
1065 if (config.get_punch_in() && record_status() == Enabled) {
1072 case SessionEvent::PunchOut:
1073 // cerr << "PunchOUT at " << transport_frame() << endl;
1074 if (config.get_punch_out()) {
1075 step_back_from_record ();
1081 case SessionEvent::StopOnce:
1082 if (!non_realtime_work_pending()) {
1083 stop_transport (ev->yes_or_no);
1084 _clear_event_type (SessionEvent::StopOnce);
1090 case SessionEvent::RangeStop:
1091 if (!non_realtime_work_pending()) {
1092 stop_transport (ev->yes_or_no);
1098 case SessionEvent::RangeLocate:
1099 start_locate (ev->target_frame, true, true, false);
1104 case SessionEvent::Overwrite:
1105 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1108 case SessionEvent::SetTrackSpeed:
1109 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1112 case SessionEvent::SetSyncSource:
1113 use_sync_source (ev->slave);
1116 case SessionEvent::Audition:
1117 set_audition (ev->region);
1118 // drop reference to region
1119 ev->region.reset ();
1122 case SessionEvent::InputConfigurationChange:
1123 add_post_transport_work (PostTransportInputChange);
1124 _butler->schedule_transport_work ();
1127 case SessionEvent::SetPlayAudioRange:
1128 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1131 case SessionEvent::RealTimeOperation:
1133 del = false; // other side of RT request needs to clean up
1136 case SessionEvent::AdjustPlaybackBuffering:
1137 schedule_playback_buffering_adjustment ();
1140 case SessionEvent::AdjustCaptureBuffering:
1141 schedule_capture_buffering_adjustment ();
1144 case SessionEvent::SetTimecodeTransmission:
1145 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1149 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1155 del = del && !_remove_event (ev);
1164 Session::compute_stop_limit () const
1166 if (!Config->get_stop_at_session_end ()) {
1167 return max_framepos;
1170 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1171 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1173 if (actively_recording ()) {
1174 /* permanently recording */
1175 return max_framepos;
1176 } else if (punching_in && !punching_out) {
1177 /* punching in but never out */
1178 return max_framepos;
1179 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1180 /* punching in and punching out after session end */
1181 return max_framepos;
1184 return current_end_frame ();