2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "pbd/error.h"
26 #include "pbd/enumwriter.h"
28 #include <glibmm/threads.h>
30 #include "ardour/audioengine.h"
31 #include "ardour/auditioner.h"
32 #include "ardour/butler.h"
33 #include "ardour/cycle_timer.h"
34 #include "ardour/debug.h"
35 #include "ardour/graph.h"
36 #include "ardour/port.h"
37 #include "ardour/process_thread.h"
38 #include "ardour/scene_changer.h"
39 #include "ardour/session.h"
40 #include "ardour/slave.h"
41 #include "ardour/ticker.h"
42 #include "ardour/types.h"
44 #include "midi++/mmc.h"
48 using namespace ARDOUR;
52 /** Called by the audio engine when there is work to be done with JACK.
53 * @param nframes Number of frames to process.
57 Session::process (pframes_t nframes)
59 framepos_t transport_at_start = _transport_frame;
63 if (processing_blocked()) {
68 if (non_realtime_work_pending()) {
69 if (!_butler->transport_work_requested ()) {
74 _engine.main_thread()->get_buffers ();
76 (this->*process_function) (nframes);
78 _engine.main_thread()->drop_buffers ();
80 /* deliver MIDI clock. Note that we need to use the transport frame
81 * position at the start of process(), not the value at the end of
82 * it. We may already have ticked() because of a transport state
83 * change, for example.
87 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
88 midi_clock->tick (transport_at_start, nframes);
91 _scene_changer->run (transport_at_start, transport_at_start + nframes);
94 /* don't bother with a message */
97 SendFeedback (); /* EMIT SIGNAL */
101 Session::fail_roll (pframes_t nframes)
103 return no_roll (nframes);
107 Session::no_roll (pframes_t nframes)
111 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
113 int declick = get_transport_declick_required();
114 boost::shared_ptr<RouteList> r = routes.reader ();
117 _click_io->silence (nframes);
120 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
122 if (_process_graph) {
123 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
124 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
126 PT_TIMING_CHECK (10);
127 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
129 if ((*i)->is_auditioner()) {
133 (*i)->set_pending_declick (declick);
135 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
136 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
141 PT_TIMING_CHECK (11);
148 /** @param need_butler to be set to true by this method if it needs the butler,
149 * otherwise it must be left alone.
152 Session::process_routes (pframes_t nframes, bool& need_butler)
154 int declick = get_transport_declick_required();
155 boost::shared_ptr<RouteList> r = routes.reader ();
157 const framepos_t start_frame = _transport_frame;
158 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
160 if (_process_graph) {
161 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
162 if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
168 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
172 if ((*i)->is_auditioner()) {
176 (*i)->set_pending_declick (declick);
180 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
194 /** @param need_butler to be set to true by this method if it needs the butler,
195 * otherwise it must be left alone.
198 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
200 boost::shared_ptr<RouteList> r = routes.reader ();
202 const framepos_t start_frame = _transport_frame;
203 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
205 if (_process_graph) {
206 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
208 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
212 if ((*i)->is_auditioner()) {
218 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
233 Session::get_track_statistics ()
238 boost::shared_ptr<RouteList> rl = routes.reader();
239 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
241 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
243 if (!tr || tr->hidden()) {
247 pworst = min (pworst, tr->playback_buffer_load());
248 cworst = min (cworst, tr->capture_buffer_load());
251 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
252 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
254 if (actively_recording()) {
259 /** Process callback used when the auditioner is not active */
261 Session::process_with_events (pframes_t nframes)
266 pframes_t this_nframes;
267 framepos_t end_frame;
268 bool session_needs_butler = false;
269 framecnt_t frames_moved;
271 /* make sure the auditioner is silent */
274 auditioner->silence (nframes);
277 /* handle any pending events */
279 while (pending_events.read (&ev, 1) == 1) {
283 /* if we are not in the middle of a state change,
284 and there are immediate events queued up,
288 while (!non_realtime_work_pending() && !immediate_events.empty()) {
289 SessionEvent *ev = immediate_events.front ();
290 immediate_events.pop_front ();
294 /* Decide on what to do with quarter-frame MTC during this cycle */
296 bool const was_sending_qf_mtc = _send_qf_mtc;
297 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
299 if (_transport_speed != 0) {
301 Config->get_send_mtc () &&
302 _transport_speed >= (1 - tolerance) &&
303 _transport_speed <= (1 + tolerance)
306 if (_send_qf_mtc && !was_sending_qf_mtc) {
307 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
308 _send_timecode_update = true;
311 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
312 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
313 a quarter of a second since we sent anything at all, so send a full MTC update
316 _send_timecode_update = true;
319 _pframes_since_last_mtc += nframes;
322 /* Events caused a transport change (or we re-started sending
323 * MTC), so send an MTC Full Frame (Timecode) message. This
324 * is sent whether rolling or not, to give slaves an idea of
325 * ardour time on locates (and allow slow slaves to position
326 * and prepare for rolling)
328 if (_send_timecode_update) {
329 send_full_time_code (_transport_frame, nframes);
332 if (!process_can_proceed()) {
337 if (events.empty() || next_event == events.end()) {
338 process_without_events (nframes);
342 if (_transport_speed == 1.0) {
343 frames_moved = (framecnt_t) nframes;
345 interpolation.set_target_speed (_target_transport_speed);
346 interpolation.set_speed (_transport_speed);
347 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
350 end_frame = _transport_frame + frames_moved;
353 SessionEvent* this_event;
354 Events::iterator the_next_one;
356 if (!process_can_proceed()) {
361 if (!_exporting && _slave) {
362 if (!follow_slave (nframes)) {
367 if (_transport_speed == 0) {
372 if (!_exporting && !timecode_transmission_suspended()) {
373 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
376 framepos_t stop_limit = compute_stop_limit ();
378 if (maybe_stop (stop_limit)) {
383 this_event = *next_event;
384 the_next_one = next_event;
387 /* yes folks, here it is, the actual loop where we really truly
393 this_nframes = nframes; /* real (jack) time relative */
394 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
396 /* running an event, position transport precisely to its time */
397 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
398 /* this isn't quite right for reverse play */
399 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
400 this_nframes = abs (floor(frames_moved / _transport_speed));
405 click (_transport_frame, this_nframes);
407 if (process_routes (this_nframes, session_needs_butler)) {
412 get_track_statistics ();
414 nframes -= this_nframes;
416 if (frames_moved < 0) {
417 decrement_transport_position (-frames_moved);
419 increment_transport_position (frames_moved);
422 maybe_stop (stop_limit);
423 check_declick_out ();
427 _engine.split_cycle (this_nframes);
430 /* now handle this event and all others scheduled for the same time */
432 while (this_event && this_event->action_frame == _transport_frame) {
433 process_event (this_event);
435 if (the_next_one == events.end()) {
438 this_event = *the_next_one;
443 /* if an event left our state changing, do the right thing */
445 if (nframes && non_realtime_work_pending()) {
450 /* this is necessary to handle the case of seamless looping */
451 end_frame = _transport_frame + floor (nframes * _transport_speed);
456 } /* implicit release of route lock */
458 if (session_needs_butler) {
464 Session::reset_slave_state ()
466 average_slave_delta = 1800;
467 delta_accumulator_cnt = 0;
468 have_first_delta_accumulator = false;
469 _slave_state = Stopped;
473 Session::transport_locked () const
477 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
485 Session::follow_slave (pframes_t nframes)
488 framepos_t slave_transport_frame;
489 framecnt_t this_delta;
494 config.set_external_sync (false);
498 _slave->speed_and_position (slave_speed, slave_transport_frame);
500 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
502 if (!_slave->locked()) {
503 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
507 if (slave_transport_frame > _transport_frame) {
508 this_delta = slave_transport_frame - _transport_frame;
511 this_delta = _transport_frame - slave_transport_frame;
515 if (_slave->starting()) {
519 if (_slave->is_always_synced() ||
520 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
523 /* if the TC source is synced, then we assume that its
524 speed is binary: 0.0 or 1.0
527 if (slave_speed != 0.0f) {
533 /* if we are chasing and the average delta between us and the
534 master gets too big, we want to switch to silent
535 motion. so keep track of that here.
538 if (_slave_state == Running) {
539 calculate_moving_average_of_slave_delta(dir, this_delta);
543 track_slave_state (slave_speed, slave_transport_frame, this_delta);
545 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
546 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
549 if (_slave_state == Running && !_slave->is_always_synced() &&
550 !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
553 if (_transport_speed != 0.0f) {
556 note that average_dir is +1 or -1
561 if (average_slave_delta == 0) {
565 delta = average_slave_delta;
566 delta *= average_dir;
570 if (slave_speed != 0.0) {
571 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
572 (int) (dir * this_delta),
576 slave_transport_frame,
577 average_slave_delta));
581 if (_slave->give_slave_full_control_over_transport_speed()) {
582 set_transport_speed (slave_speed, 0, false, false);
583 //std::cout << "set speed = " << slave_speed << "\n";
585 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
586 request_transport_speed (adjusted_speed);
587 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
588 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
593 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
594 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
602 if (_slave_state == Running && !non_realtime_work_pending()) {
603 /* speed is set, we're locked, and good to go */
608 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
609 follow_slave_silently (nframes, slave_speed);
612 /* don't move at all */
613 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
619 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
621 if (delta_accumulator_cnt >= delta_accumulator_size) {
622 have_first_delta_accumulator = true;
623 delta_accumulator_cnt = 0;
626 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
627 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
630 if (have_first_delta_accumulator) {
631 average_slave_delta = 0L;
632 for (int i = 0; i < delta_accumulator_size; ++i) {
633 average_slave_delta += delta_accumulator[i];
635 average_slave_delta /= (int32_t) delta_accumulator_size;
636 if (average_slave_delta < 0L) {
638 average_slave_delta = abs(average_slave_delta);
646 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
648 if (slave_speed != 0.0f) {
650 /* slave is running */
652 switch (_slave_state) {
654 if (_slave->requires_seekahead()) {
655 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
656 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
657 /* we can call locate() here because we are in process context */
658 locate (slave_wait_end, false, false);
659 _slave_state = Waiting;
663 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
665 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
666 average_slave_delta = 0L;
668 Location* al = _locations->auto_loop_location();
670 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
672 request_play_loop(false);
675 if (slave_transport_frame != _transport_frame) {
676 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
677 locate (slave_transport_frame, false, false);
679 _slave_state = Running;
688 if (_slave_state == Waiting) {
690 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
692 if (slave_transport_frame >= slave_wait_end) {
694 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
696 _slave_state = Running;
698 /* now perform a "micro-seek" within the disk buffers to realign ourselves
699 precisely with the master.
704 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
706 boost::shared_ptr<RouteList> rl = routes.reader();
707 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
708 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
709 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
716 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
717 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
719 tr->internal_playback_seek (frame_delta);
722 _transport_frame += frame_delta;
725 cerr << "cannot micro-seek\n";
731 if (_slave_state == Running && _transport_speed == 0.0f) {
732 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
736 } else { // slave_speed is 0
738 /* slave has stopped */
740 if (_transport_speed != 0.0f) {
741 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
745 if (slave_transport_frame != _transport_frame) {
746 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
747 force_locate (slave_transport_frame, false);
755 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
757 if (slave_speed && _transport_speed) {
759 /* something isn't right, but we should move with the master
763 bool need_butler = false;
765 silent_process_routes (nframes, need_butler);
767 get_track_statistics ();
773 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
775 if (frames_moved < 0) {
776 decrement_transport_position (-frames_moved);
778 increment_transport_position (frames_moved);
781 framepos_t const stop_limit = compute_stop_limit ();
782 maybe_stop (stop_limit);
787 Session::process_without_events (pframes_t nframes)
789 bool session_needs_butler = false;
790 framecnt_t frames_moved;
792 if (!process_can_proceed()) {
797 if (!_exporting && _slave) {
798 if (!follow_slave (nframes)) {
799 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
804 if (_transport_speed == 0) {
809 if (_transport_speed == 1.0) {
810 frames_moved = (framecnt_t) nframes;
812 interpolation.set_target_speed (_target_transport_speed);
813 interpolation.set_speed (_transport_speed);
814 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
817 if (!_exporting && !timecode_transmission_suspended()) {
818 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
821 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
823 framepos_t const stop_limit = compute_stop_limit ();
825 if (maybe_stop (stop_limit)) {
830 if (maybe_sync_start (nframes)) {
834 click (_transport_frame, nframes);
836 if (process_routes (nframes, session_needs_butler)) {
841 get_track_statistics ();
843 if (frames_moved < 0) {
844 decrement_transport_position (-frames_moved);
846 increment_transport_position (frames_moved);
849 maybe_stop (stop_limit);
850 check_declick_out ();
852 if (session_needs_butler) {
857 /** Process callback used when the auditioner is active.
858 * @param nframes number of frames to process.
861 Session::process_audition (pframes_t nframes)
864 boost::shared_ptr<RouteList> r = routes.reader ();
866 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
867 if (!(*i)->is_auditioner()) {
868 (*i)->silence (nframes);
872 /* run the auditioner, and if it says we need butler service, ask for it */
874 if (auditioner->play_audition (nframes) > 0) {
878 /* if using a monitor section, run it because otherwise we don't hear anything */
880 if (_monitor_out && auditioner->needs_monitor()) {
881 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
884 /* handle pending events */
886 while (pending_events.read (&ev, 1) == 1) {
890 /* if we are not in the middle of a state change,
891 and there are immediate events queued up,
895 while (!non_realtime_work_pending() && !immediate_events.empty()) {
896 SessionEvent *ev = immediate_events.front ();
897 immediate_events.pop_front ();
901 if (!auditioner->auditioning()) {
902 /* auditioner no longer active, so go back to the normal process callback */
903 process_function = &Session::process_with_events;
908 Session::maybe_sync_start (pframes_t & nframes)
910 pframes_t sync_offset;
912 if (!waiting_for_sync_offset) {
916 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
918 /* generate silence up to the sync point, then
919 adjust nframes + offset to reflect whatever
923 no_roll (sync_offset);
924 nframes -= sync_offset;
925 Port::increment_global_port_buffer_offset (sync_offset);
926 waiting_for_sync_offset = false;
929 return true; // done, nothing left to process
934 /* sync offset point is not within this process()
935 cycle, so just generate silence. and don't bother
936 with any fancy stuff here, just the minimal silence.
941 if (Config->get_locate_while_waiting_for_sync()) {
942 if (micro_locate (nframes)) {
943 /* XXX ERROR !!! XXX */
947 return true; // done, nothing left to process
954 Session::queue_event (SessionEvent* ev)
956 if (_state_of_the_state & Deletion) {
958 } else if (_state_of_the_state & Loading) {
961 pending_events.write (&ev, 1);
966 Session::set_next_event ()
968 if (events.empty()) {
969 next_event = events.end();
973 if (next_event == events.end()) {
974 next_event = events.begin();
977 if ((*next_event)->action_frame > _transport_frame) {
978 next_event = events.begin();
981 for (; next_event != events.end(); ++next_event) {
982 if ((*next_event)->action_frame >= _transport_frame) {
989 Session::process_event (SessionEvent* ev)
994 /* if we're in the middle of a state change (i.e. waiting
995 for the butler thread to complete the non-realtime
996 part of the change), we'll just have to queue this
997 event for a time when the change is complete.
1000 if (non_realtime_work_pending()) {
1002 /* except locates, which we have the capability to handle */
1004 if (ev->type != SessionEvent::Locate) {
1005 immediate_events.insert (immediate_events.end(), ev);
1011 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1014 case SessionEvent::SetLoop:
1015 set_play_loop (ev->yes_or_no, ev->speed);
1018 case SessionEvent::AutoLoop:
1020 /* roll after locate, do not flush, set "with loop"
1021 true only if we are seamless looping
1023 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1029 case SessionEvent::AutoLoopDeclick:
1031 /* Request a declick fade-out and a fade-in; the fade-out will happen
1032 at the end of the loop, and the fade-in at the start.
1034 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1040 case SessionEvent::Locate:
1041 if (ev->yes_or_no) {
1042 /* args: do not roll after locate, do flush, not with loop */
1043 locate (ev->target_frame, false, true, false);
1045 /* args: do not roll after locate, do flush, not with loop */
1046 start_locate (ev->target_frame, false, true, false);
1048 _send_timecode_update = true;
1051 case SessionEvent::LocateRoll:
1052 if (ev->yes_or_no) {
1053 /* args: roll after locate, do flush, not with loop */
1054 locate (ev->target_frame, true, true, false);
1056 /* args: roll after locate, do flush, not with loop */
1057 start_locate (ev->target_frame, true, true, false);
1059 _send_timecode_update = true;
1062 case SessionEvent::Skip:
1063 if (Config->get_skip_playback()) {
1064 start_locate (ev->target_frame, true, true, false);
1065 _send_timecode_update = true;
1071 case SessionEvent::LocateRollLocate:
1072 // locate is handled by ::request_roll_at_and_return()
1073 _requested_return_frame = ev->target_frame;
1074 request_locate (ev->target2_frame, true);
1078 case SessionEvent::SetTransportSpeed:
1079 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1082 case SessionEvent::PunchIn:
1083 // cerr << "PunchIN at " << transport_frame() << endl;
1084 if (config.get_punch_in() && record_status() == Enabled) {
1091 case SessionEvent::PunchOut:
1092 // cerr << "PunchOUT at " << transport_frame() << endl;
1093 if (config.get_punch_out()) {
1094 step_back_from_record ();
1100 case SessionEvent::StopOnce:
1101 if (!non_realtime_work_pending()) {
1102 _clear_event_type (SessionEvent::StopOnce);
1103 stop_transport (ev->yes_or_no);
1109 case SessionEvent::RangeStop:
1110 if (!non_realtime_work_pending()) {
1111 stop_transport (ev->yes_or_no);
1117 case SessionEvent::RangeLocate:
1118 /* args: roll after locate, do flush, not with loop */
1119 start_locate (ev->target_frame, true, true, false);
1124 case SessionEvent::Overwrite:
1125 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1128 case SessionEvent::SetTrackSpeed:
1129 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1132 case SessionEvent::SetSyncSource:
1133 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1134 use_sync_source (ev->slave);
1137 case SessionEvent::Audition:
1138 set_audition (ev->region);
1139 // drop reference to region
1140 ev->region.reset ();
1143 case SessionEvent::InputConfigurationChange:
1144 add_post_transport_work (PostTransportInputChange);
1145 _butler->schedule_transport_work ();
1148 case SessionEvent::SetPlayAudioRange:
1149 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1152 case SessionEvent::CancelPlayAudioRange:
1156 case SessionEvent::RealTimeOperation:
1158 del = false; // other side of RT request needs to clean up
1161 case SessionEvent::AdjustPlaybackBuffering:
1162 schedule_playback_buffering_adjustment ();
1165 case SessionEvent::AdjustCaptureBuffering:
1166 schedule_capture_buffering_adjustment ();
1169 case SessionEvent::SetTimecodeTransmission:
1170 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1174 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1175 abort(); /*NOTREACHED*/
1180 del = del && !_remove_event (ev);
1189 Session::compute_stop_limit () const
1191 if (!Config->get_stop_at_session_end ()) {
1192 return max_framepos;
1196 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 ();