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"
42 #include "midi++/manager.h"
43 #include "midi++/mmc.h"
47 using namespace ARDOUR;
51 /** Called by the audio engine when there is work to be done with JACK.
52 * @param nframes Number of frames to process.
56 Session::process (pframes_t nframes)
58 MIDI::Manager::instance()->cycle_start(nframes);
62 if (processing_blocked()) {
67 if (non_realtime_work_pending()) {
68 if (!_butler->transport_work_requested ()) {
73 _engine.main_thread()->get_buffers ();
75 (this->*process_function) (nframes);
77 _engine.main_thread()->drop_buffers ();
79 // the ticker is for sending time information like MidiClock
80 framepos_t transport_frames = transport_frame();
81 Timecode::BBT_Time transport_bbt;
82 bbt_time(transport_frames, transport_bbt);
83 Timecode::Time transport_timecode;
84 timecode_time(transport_frames, transport_timecode);
85 tick (transport_frames, transport_bbt, transport_timecode); /* EMIT SIGNAL */
87 SendFeedback (); /* EMIT SIGNAL */
89 MIDI::Manager::instance()->cycle_end();
93 Session::fail_roll (pframes_t nframes)
95 return no_roll (nframes);
99 Session::no_roll (pframes_t nframes)
101 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
103 bool declick = get_transport_declick_required();
104 boost::shared_ptr<RouteList> r = routes.reader ();
107 _click_io->silence (nframes);
110 if (route_graph->threads_in_use() > 0) {
111 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
112 route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), actively_recording(), declick);
114 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
116 if ((*i)->is_hidden()) {
120 (*i)->set_pending_declick (declick);
122 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(),
123 actively_recording(), declick)) {
124 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
135 Session::process_routes (pframes_t nframes, bool& need_butler)
138 int declick = get_transport_declick_required();
139 bool rec_monitors = get_rec_monitors_input();
140 boost::shared_ptr<RouteList> r = routes.reader ();
142 if (transport_sub_state & StopPendingCapture) {
143 /* force a declick out */
147 record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
149 const framepos_t start_frame = _transport_frame;
150 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
152 /* XXX this is hack to force use of the graph even if we are only
153 using 1 thread. its needed because otherwise when we remove
154 tracks, the graph never gets updated.
156 if (1 || route_graph->threads_in_use() > 0) {
157 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
158 route_graph->process_routes( nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler);
161 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
165 if ((*i)->is_hidden()) {
169 (*i)->set_pending_declick (declick);
171 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler)) < 0) {
182 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
184 bool record_active = actively_recording();
185 bool rec_monitors = get_rec_monitors_input();
186 boost::shared_ptr<RouteList> r = routes.reader ();
188 const framepos_t start_frame = _transport_frame;
189 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
191 /* XXX this is hack to force use of the graph even if we are only
192 using 1 thread. its needed because otherwise when we remove
193 tracks, the graph never gets updated.
195 if (1 || route_graph->threads_in_use() > 0) {
196 route_graph->silent_process_routes( nframes, start_frame, end_frame, record_active, rec_monitors, need_butler);
198 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
202 if ((*i)->is_hidden()) {
206 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) {
217 Session::get_track_statistics ()
222 boost::shared_ptr<RouteList> rl = routes.reader();
223 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
225 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
227 if (!tr || tr->hidden()) {
231 pworst = min (pworst, tr->playback_buffer_load());
232 cworst = min (cworst, tr->capture_buffer_load());
235 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
236 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
238 if (actively_recording()) {
243 /** Process callback used when the auditioner is not active */
245 Session::process_with_events (pframes_t nframes)
248 pframes_t this_nframes;
249 framepos_t end_frame;
250 bool session_needs_butler = false;
251 framecnt_t frames_moved;
253 /* make sure the auditioner is silent */
256 auditioner->silence (nframes);
259 /* handle any pending events */
261 while (pending_events.read (&ev, 1) == 1) {
265 /* if we are not in the middle of a state change,
266 and there are immediate events queued up,
270 while (!non_realtime_work_pending() && !immediate_events.empty()) {
271 SessionEvent *ev = immediate_events.front ();
272 immediate_events.pop_front ();
276 /* Decide on what to do with quarter-frame MTC during this cycle */
278 bool const was_sending_qf_mtc = _send_qf_mtc;
279 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
281 if (_transport_speed != 0) {
283 Config->get_send_mtc () &&
284 _transport_speed >= (1 - tolerance) &&
285 _transport_speed <= (1 + tolerance)
288 if (_send_qf_mtc && !was_sending_qf_mtc) {
289 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
290 _send_timecode_update = true;
293 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
294 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
295 a quarter of a second since we sent anything at all, so send a full MTC update
298 _send_timecode_update = true;
301 _pframes_since_last_mtc += nframes;
304 /* Events caused a transport change (or we re-started sending
305 * MTC), so send an MTC Full Frame (Timecode) message. This
306 * is sent whether rolling or not, to give slaves an idea of
307 * ardour time on locates (and allow slow slaves to position
308 * and prepare for rolling)
310 if (_send_timecode_update) {
311 send_full_time_code (_transport_frame);
314 if (!process_can_proceed()) {
319 if (events.empty() || next_event == events.end()) {
320 process_without_events (nframes);
324 if (_transport_speed == 1.0) {
325 frames_moved = (framecnt_t) nframes;
327 interpolation.set_target_speed (fabs(_target_transport_speed));
328 interpolation.set_speed (fabs(_transport_speed));
329 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
332 end_frame = _transport_frame + frames_moved;
335 SessionEvent* this_event;
336 Events::iterator the_next_one;
338 if (!process_can_proceed()) {
343 if (!_exporting && _slave) {
344 if (!follow_slave (nframes)) {
349 if (_transport_speed == 0) {
354 if (!_exporting && !timecode_transmission_suspended()) {
355 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
358 framepos_t stop_limit = compute_stop_limit ();
360 if (maybe_stop (stop_limit)) {
365 this_event = *next_event;
366 the_next_one = next_event;
369 /* yes folks, here it is, the actual loop where we really truly
375 this_nframes = nframes; /* real (jack) time relative */
376 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
378 /* running an event, position transport precisely to its time */
379 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
380 /* this isn't quite right for reverse play */
381 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
382 this_nframes = abs (floor(frames_moved / _transport_speed));
387 click (_transport_frame, this_nframes);
389 if (process_routes (this_nframes, session_needs_butler)) {
394 get_track_statistics ();
396 nframes -= this_nframes;
398 if (frames_moved < 0) {
399 decrement_transport_position (-frames_moved);
401 increment_transport_position (frames_moved);
404 maybe_stop (stop_limit);
405 check_declick_out ();
408 _engine.split_cycle (this_nframes);
410 /* now handle this event and all others scheduled for the same time */
412 while (this_event && this_event->action_frame == _transport_frame) {
413 process_event (this_event);
415 if (the_next_one == events.end()) {
418 this_event = *the_next_one;
423 /* if an event left our state changing, do the right thing */
425 if (nframes && non_realtime_work_pending()) {
430 /* this is necessary to handle the case of seamless looping */
431 end_frame = _transport_frame + floor (nframes * _transport_speed);
436 } /* implicit release of route lock */
438 if (session_needs_butler) {
444 Session::reset_slave_state ()
446 average_slave_delta = 1800;
447 delta_accumulator_cnt = 0;
448 have_first_delta_accumulator = false;
449 _slave_state = Stopped;
453 Session::transport_locked () const
457 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
465 Session::follow_slave (pframes_t nframes)
468 framepos_t slave_transport_frame;
469 framecnt_t this_delta;
474 config.set_external_sync (false);
478 _slave->speed_and_position (slave_speed, slave_transport_frame);
480 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
482 if (!_slave->locked()) {
483 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
487 if (slave_transport_frame > _transport_frame) {
488 this_delta = slave_transport_frame - _transport_frame;
491 this_delta = _transport_frame - slave_transport_frame;
495 if (_slave->starting()) {
499 if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
501 /* if the TC source is synced, then we assume that its
502 speed is binary: 0.0 or 1.0
505 if (slave_speed != 0.0f) {
511 /* if we are chasing and the average delta between us and the
512 master gets too big, we want to switch to silent
513 motion. so keep track of that here.
516 if (_slave_state == Running) {
517 calculate_moving_average_of_slave_delta(dir, this_delta);
521 track_slave_state (slave_speed, slave_transport_frame, this_delta);
523 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
524 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
527 if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
529 if (_transport_speed != 0.0f) {
532 note that average_dir is +1 or -1
537 if (average_slave_delta == 0) {
541 delta = average_slave_delta;
542 delta *= average_dir;
546 if (slave_speed != 0.0) {
547 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
548 (int) (dir * this_delta),
552 slave_transport_frame,
553 average_slave_delta));
557 if (_slave->give_slave_full_control_over_transport_speed()) {
558 set_transport_speed (slave_speed, false, false);
559 //std::cout << "set speed = " << slave_speed << "\n";
561 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
562 request_transport_speed (adjusted_speed);
563 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
564 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
569 if ((framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
570 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
578 if (_slave_state == Running && !non_realtime_work_pending()) {
579 /* speed is set, we're locked, and good to go */
584 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
585 follow_slave_silently (nframes, slave_speed);
588 /* don't move at all */
589 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
595 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
597 if (delta_accumulator_cnt >= delta_accumulator_size) {
598 have_first_delta_accumulator = true;
599 delta_accumulator_cnt = 0;
602 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
603 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
606 if (have_first_delta_accumulator) {
607 average_slave_delta = 0L;
608 for (int i = 0; i < delta_accumulator_size; ++i) {
609 average_slave_delta += delta_accumulator[i];
611 average_slave_delta /= (int32_t) delta_accumulator_size;
612 if (average_slave_delta < 0L) {
614 average_slave_delta = abs(average_slave_delta);
622 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t this_delta)
624 if (slave_speed != 0.0f) {
626 /* slave is running */
628 switch (_slave_state) {
630 if (_slave->requires_seekahead()) {
631 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
632 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
633 /* we can call locate() here because we are in process context */
634 locate (slave_wait_end, false, false);
635 _slave_state = Waiting;
639 _slave_state = Running;
641 Location* al = _locations->auto_loop_location();
643 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
645 request_play_loop(false);
648 if (slave_transport_frame != _transport_frame) {
649 locate (slave_transport_frame, false, false);
659 if (_slave_state == Waiting) {
661 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
663 if (slave_transport_frame >= slave_wait_end) {
665 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
667 _slave_state = Running;
669 /* now perform a "micro-seek" within the disk buffers to realign ourselves
670 precisely with the master.
675 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
677 boost::shared_ptr<RouteList> rl = routes.reader();
678 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
679 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
680 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
687 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
688 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
690 tr->internal_playback_seek (frame_delta);
693 _transport_frame += frame_delta;
696 cerr << "cannot micro-seek\n";
700 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
701 average_slave_delta = 0L;
705 if (_slave_state == Running && _transport_speed == 0.0f) {
706 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
710 } else { // slave_speed is 0
712 /* slave has stopped */
714 if (_transport_speed != 0.0f) {
715 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
719 if (slave_transport_frame != _transport_frame) {
720 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
721 force_locate (slave_transport_frame, false);
724 _slave_state = Stopped;
729 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
731 if (slave_speed && _transport_speed) {
733 /* something isn't right, but we should move with the master
739 silent_process_routes (nframes, need_butler);
741 get_track_statistics ();
747 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
749 if (frames_moved < 0) {
750 decrement_transport_position (-frames_moved);
752 increment_transport_position (frames_moved);
755 framepos_t const stop_limit = compute_stop_limit ();
756 maybe_stop (stop_limit);
761 Session::process_without_events (pframes_t nframes)
763 bool session_needs_butler = false;
764 framecnt_t frames_moved;
766 if (!process_can_proceed()) {
771 if (!_exporting && _slave) {
772 if (!follow_slave (nframes)) {
777 if (_transport_speed == 0) {
782 if (_transport_speed == 1.0) {
783 frames_moved = (framecnt_t) nframes;
785 interpolation.set_target_speed (fabs(_target_transport_speed));
786 interpolation.set_speed (fabs(_transport_speed));
787 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
790 if (!_exporting && !timecode_transmission_suspended()) {
791 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
794 framepos_t const stop_limit = compute_stop_limit ();
796 if (maybe_stop (stop_limit)) {
801 if (maybe_sync_start (nframes)) {
805 click (_transport_frame, nframes);
807 if (process_routes (nframes, session_needs_butler)) {
812 get_track_statistics ();
814 /* XXX: I'm not sure whether this is correct, but at least it
815 matches process_with_events, so that this new frames_moved
816 is -ve when transport speed is -ve. This means that the
817 transport position is updated correctly when we are in
818 reverse. It seems a bit wrong that we're not using the
819 interpolator to compute this.
822 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
824 if (frames_moved < 0) {
825 decrement_transport_position (-frames_moved);
827 increment_transport_position (frames_moved);
830 maybe_stop (stop_limit);
831 check_declick_out ();
833 if (session_needs_butler) {
838 /** Process callback used when the auditioner is active.
839 * @param nframes number of frames to process.
842 Session::process_audition (pframes_t nframes)
845 boost::shared_ptr<RouteList> r = routes.reader ();
847 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
848 if (!(*i)->is_hidden()) {
849 (*i)->silence (nframes);
853 /* run the auditioner, and if it says we need butler service, ask for it */
855 if (auditioner->play_audition (nframes) > 0) {
859 /* if using a monitor section, run it because otherwise we don't hear anything */
861 if (auditioner->needs_monitor()) {
862 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
865 /* handle pending events */
867 while (pending_events.read (&ev, 1) == 1) {
871 /* if we are not in the middle of a state change,
872 and there are immediate events queued up,
876 while (!non_realtime_work_pending() && !immediate_events.empty()) {
877 SessionEvent *ev = immediate_events.front ();
878 immediate_events.pop_front ();
882 if (!auditioner->auditioning()) {
883 /* auditioner no longer active, so go back to the normal process callback */
884 process_function = &Session::process_with_events;
889 Session::maybe_sync_start (pframes_t & nframes)
891 pframes_t sync_offset;
893 if (!waiting_for_sync_offset) {
897 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
899 /* generate silence up to the sync point, then
900 adjust nframes + offset to reflect whatever
904 no_roll (sync_offset);
905 nframes -= sync_offset;
906 Port::increment_global_port_buffer_offset (sync_offset);
907 waiting_for_sync_offset = false;
910 return true; // done, nothing left to process
915 /* sync offset point is not within this process()
916 cycle, so just generate silence. and don't bother
917 with any fancy stuff here, just the minimal silence.
922 if (Config->get_locate_while_waiting_for_sync()) {
923 if (micro_locate (nframes)) {
924 /* XXX ERROR !!! XXX */
928 return true; // done, nothing left to process
935 Session::queue_event (SessionEvent* ev)
937 if (_state_of_the_state & Deletion) {
939 } else if (_state_of_the_state & Loading) {
942 pending_events.write (&ev, 1);
947 Session::set_next_event ()
949 if (events.empty()) {
950 next_event = events.end();
954 if (next_event == events.end()) {
955 next_event = events.begin();
958 if ((*next_event)->action_frame > _transport_frame) {
959 next_event = events.begin();
962 for (; next_event != events.end(); ++next_event) {
963 if ((*next_event)->action_frame >= _transport_frame) {
970 Session::process_event (SessionEvent* ev)
975 /* if we're in the middle of a state change (i.e. waiting
976 for the butler thread to complete the non-realtime
977 part of the change), we'll just have to queue this
978 event for a time when the change is complete.
981 if (non_realtime_work_pending()) {
983 /* except locates, which we have the capability to handle */
985 if (ev->type != SessionEvent::Locate) {
986 immediate_events.insert (immediate_events.end(), ev);
992 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
995 case SessionEvent::SetLoop:
996 set_play_loop (ev->yes_or_no);
999 case SessionEvent::AutoLoop:
1001 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1007 case SessionEvent::Locate:
1008 if (ev->yes_or_no) {
1009 // cerr << "forced locate to " << ev->target_frame << endl;
1010 locate (ev->target_frame, false, true, false);
1012 // cerr << "soft locate to " << ev->target_frame << endl;
1013 start_locate (ev->target_frame, false, true, false);
1015 _send_timecode_update = true;
1018 case SessionEvent::LocateRoll:
1019 if (ev->yes_or_no) {
1020 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1021 locate (ev->target_frame, true, true, false);
1023 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1024 start_locate (ev->target_frame, true, true, false);
1026 _send_timecode_update = true;
1029 case SessionEvent::LocateRollLocate:
1030 // locate is handled by ::request_roll_at_and_return()
1031 _requested_return_frame = ev->target_frame;
1032 request_locate (ev->target2_frame, true);
1036 case SessionEvent::SetTransportSpeed:
1037 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1040 case SessionEvent::PunchIn:
1041 // cerr << "PunchIN at " << transport_frame() << endl;
1042 if (config.get_punch_in() && record_status() == Enabled) {
1049 case SessionEvent::PunchOut:
1050 // cerr << "PunchOUT at " << transport_frame() << endl;
1051 if (config.get_punch_out()) {
1052 step_back_from_record ();
1058 case SessionEvent::StopOnce:
1059 if (!non_realtime_work_pending()) {
1060 stop_transport (ev->yes_or_no);
1061 _clear_event_type (SessionEvent::StopOnce);
1067 case SessionEvent::RangeStop:
1068 if (!non_realtime_work_pending()) {
1069 stop_transport (ev->yes_or_no);
1075 case SessionEvent::RangeLocate:
1076 start_locate (ev->target_frame, true, true, false);
1081 case SessionEvent::Overwrite:
1082 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1085 case SessionEvent::SetTrackSpeed:
1086 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1089 case SessionEvent::SetSyncSource:
1090 use_sync_source (ev->slave);
1093 case SessionEvent::Audition:
1094 set_audition (ev->region);
1095 // drop reference to region
1096 ev->region.reset ();
1099 case SessionEvent::InputConfigurationChange:
1100 add_post_transport_work (PostTransportInputChange);
1101 _butler->schedule_transport_work ();
1104 case SessionEvent::SetPlayAudioRange:
1105 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1108 case SessionEvent::RealTimeOperation:
1110 del = false; // other side of RT request needs to clean up
1113 case SessionEvent::AdjustPlaybackBuffering:
1114 schedule_playback_buffering_adjustment ();
1117 case SessionEvent::AdjustCaptureBuffering:
1118 schedule_capture_buffering_adjustment ();
1121 case SessionEvent::SetTimecodeTransmission:
1122 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1126 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1132 del = del && !_remove_event (ev);
1141 Session::compute_stop_limit () const
1143 bool const punching = (config.get_punch_in () && _locations->auto_punch_location());
1145 if (!actively_recording() && !punching && Config->get_stop_at_session_end()) {
1146 return current_end_frame ();
1149 return max_framepos;