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 if (transport_sub_state & StopPendingCapture) {
158 /* force a declick out */
162 const framepos_t start_frame = _transport_frame;
163 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
165 if (_process_graph) {
166 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
167 _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
170 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
174 if ((*i)->is_auditioner()) {
178 (*i)->set_pending_declick (declick);
182 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
196 /** @param need_butler to be set to true by this method if it needs the butler,
197 * otherwise it must be left alone.
200 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
202 boost::shared_ptr<RouteList> r = routes.reader ();
204 const framepos_t start_frame = _transport_frame;
205 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
207 if (_process_graph) {
208 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
210 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
214 if ((*i)->is_auditioner()) {
220 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
235 Session::get_track_statistics ()
240 boost::shared_ptr<RouteList> rl = routes.reader();
241 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
243 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
245 if (!tr || tr->hidden()) {
249 pworst = min (pworst, tr->playback_buffer_load());
250 cworst = min (cworst, tr->capture_buffer_load());
253 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
254 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
256 if (actively_recording()) {
261 /** Process callback used when the auditioner is not active */
263 Session::process_with_events (pframes_t nframes)
268 pframes_t this_nframes;
269 framepos_t end_frame;
270 bool session_needs_butler = false;
271 framecnt_t frames_moved;
273 /* make sure the auditioner is silent */
276 auditioner->silence (nframes);
279 /* handle any pending events */
281 while (pending_events.read (&ev, 1) == 1) {
285 /* if we are not in the middle of a state change,
286 and there are immediate events queued up,
290 while (!non_realtime_work_pending() && !immediate_events.empty()) {
291 SessionEvent *ev = immediate_events.front ();
292 immediate_events.pop_front ();
296 /* Decide on what to do with quarter-frame MTC during this cycle */
298 bool const was_sending_qf_mtc = _send_qf_mtc;
299 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
301 if (_transport_speed != 0) {
303 Config->get_send_mtc () &&
304 _transport_speed >= (1 - tolerance) &&
305 _transport_speed <= (1 + tolerance)
308 if (_send_qf_mtc && !was_sending_qf_mtc) {
309 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
310 _send_timecode_update = true;
313 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
314 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
315 a quarter of a second since we sent anything at all, so send a full MTC update
318 _send_timecode_update = true;
321 _pframes_since_last_mtc += nframes;
324 /* Events caused a transport change (or we re-started sending
325 * MTC), so send an MTC Full Frame (Timecode) message. This
326 * is sent whether rolling or not, to give slaves an idea of
327 * ardour time on locates (and allow slow slaves to position
328 * and prepare for rolling)
330 if (_send_timecode_update) {
331 send_full_time_code (_transport_frame, nframes);
334 if (!process_can_proceed()) {
339 if (events.empty() || next_event == events.end()) {
340 process_without_events (nframes);
344 if (_transport_speed == 1.0) {
345 frames_moved = (framecnt_t) nframes;
347 interpolation.set_target_speed (_target_transport_speed);
348 interpolation.set_speed (_transport_speed);
349 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
352 end_frame = _transport_frame + frames_moved;
355 SessionEvent* this_event;
356 Events::iterator the_next_one;
358 if (!process_can_proceed()) {
363 if (!_exporting && _slave) {
364 if (!follow_slave (nframes)) {
369 if (_transport_speed == 0) {
374 if (!_exporting && !timecode_transmission_suspended()) {
375 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
378 framepos_t stop_limit = compute_stop_limit ();
380 if (maybe_stop (stop_limit)) {
385 this_event = *next_event;
386 the_next_one = next_event;
389 /* yes folks, here it is, the actual loop where we really truly
395 this_nframes = nframes; /* real (jack) time relative */
396 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
398 /* running an event, position transport precisely to its time */
399 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
400 /* this isn't quite right for reverse play */
401 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
402 this_nframes = abs (floor(frames_moved / _transport_speed));
407 click (_transport_frame, this_nframes);
409 if (process_routes (this_nframes, session_needs_butler)) {
414 get_track_statistics ();
416 nframes -= this_nframes;
418 if (frames_moved < 0) {
419 decrement_transport_position (-frames_moved);
421 increment_transport_position (frames_moved);
424 maybe_stop (stop_limit);
425 check_declick_out ();
429 _engine.split_cycle (this_nframes);
432 /* now handle this event and all others scheduled for the same time */
434 while (this_event && this_event->action_frame == _transport_frame) {
435 process_event (this_event);
437 if (the_next_one == events.end()) {
440 this_event = *the_next_one;
445 /* if an event left our state changing, do the right thing */
447 if (nframes && non_realtime_work_pending()) {
452 /* this is necessary to handle the case of seamless looping */
453 end_frame = _transport_frame + floor (nframes * _transport_speed);
458 } /* implicit release of route lock */
460 if (session_needs_butler) {
466 Session::reset_slave_state ()
468 average_slave_delta = 1800;
469 delta_accumulator_cnt = 0;
470 have_first_delta_accumulator = false;
471 _slave_state = Stopped;
475 Session::transport_locked () const
479 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
487 Session::follow_slave (pframes_t nframes)
490 framepos_t slave_transport_frame;
491 framecnt_t this_delta;
496 config.set_external_sync (false);
500 _slave->speed_and_position (slave_speed, slave_transport_frame);
502 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
504 if (!_slave->locked()) {
505 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
509 if (slave_transport_frame > _transport_frame) {
510 this_delta = slave_transport_frame - _transport_frame;
513 this_delta = _transport_frame - slave_transport_frame;
517 if (_slave->starting()) {
521 if (_slave->is_always_synced() ||
522 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
525 /* if the TC source is synced, then we assume that its
526 speed is binary: 0.0 or 1.0
529 if (slave_speed != 0.0f) {
535 /* if we are chasing and the average delta between us and the
536 master gets too big, we want to switch to silent
537 motion. so keep track of that here.
540 if (_slave_state == Running) {
541 calculate_moving_average_of_slave_delta(dir, this_delta);
545 track_slave_state (slave_speed, slave_transport_frame, this_delta);
547 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
548 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
551 if (_slave_state == Running && !_slave->is_always_synced() &&
552 !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
555 if (_transport_speed != 0.0f) {
558 note that average_dir is +1 or -1
563 if (average_slave_delta == 0) {
567 delta = average_slave_delta;
568 delta *= average_dir;
572 if (slave_speed != 0.0) {
573 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
574 (int) (dir * this_delta),
578 slave_transport_frame,
579 average_slave_delta));
583 if (_slave->give_slave_full_control_over_transport_speed()) {
584 set_transport_speed (slave_speed, false, false);
585 //std::cout << "set speed = " << slave_speed << "\n";
587 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
588 request_transport_speed (adjusted_speed);
589 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
590 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
595 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
596 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
604 if (_slave_state == Running && !non_realtime_work_pending()) {
605 /* speed is set, we're locked, and good to go */
610 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
611 follow_slave_silently (nframes, slave_speed);
614 /* don't move at all */
615 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
621 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
623 if (delta_accumulator_cnt >= delta_accumulator_size) {
624 have_first_delta_accumulator = true;
625 delta_accumulator_cnt = 0;
628 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
629 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
632 if (have_first_delta_accumulator) {
633 average_slave_delta = 0L;
634 for (int i = 0; i < delta_accumulator_size; ++i) {
635 average_slave_delta += delta_accumulator[i];
637 average_slave_delta /= (int32_t) delta_accumulator_size;
638 if (average_slave_delta < 0L) {
640 average_slave_delta = abs(average_slave_delta);
648 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
650 if (slave_speed != 0.0f) {
652 /* slave is running */
654 switch (_slave_state) {
656 if (_slave->requires_seekahead()) {
657 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
658 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
659 /* we can call locate() here because we are in process context */
660 locate (slave_wait_end, false, false);
661 _slave_state = Waiting;
665 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
667 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
668 average_slave_delta = 0L;
670 Location* al = _locations->auto_loop_location();
672 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
674 request_play_loop(false);
677 if (slave_transport_frame != _transport_frame) {
678 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
679 locate (slave_transport_frame, false, false);
681 _slave_state = Running;
690 if (_slave_state == Waiting) {
692 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
694 if (slave_transport_frame >= slave_wait_end) {
696 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
698 _slave_state = Running;
700 /* now perform a "micro-seek" within the disk buffers to realign ourselves
701 precisely with the master.
706 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
708 boost::shared_ptr<RouteList> rl = routes.reader();
709 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
710 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
711 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
718 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
719 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
721 tr->internal_playback_seek (frame_delta);
724 _transport_frame += frame_delta;
727 cerr << "cannot micro-seek\n";
733 if (_slave_state == Running && _transport_speed == 0.0f) {
734 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
738 } else { // slave_speed is 0
740 /* slave has stopped */
742 if (_transport_speed != 0.0f) {
743 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
747 if (slave_transport_frame != _transport_frame) {
748 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
749 force_locate (slave_transport_frame, false);
757 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
759 if (slave_speed && _transport_speed) {
761 /* something isn't right, but we should move with the master
767 silent_process_routes (nframes, need_butler);
769 get_track_statistics ();
775 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
777 if (frames_moved < 0) {
778 decrement_transport_position (-frames_moved);
780 increment_transport_position (frames_moved);
783 framepos_t const stop_limit = compute_stop_limit ();
784 maybe_stop (stop_limit);
789 Session::process_without_events (pframes_t nframes)
791 bool session_needs_butler = false;
792 framecnt_t frames_moved;
794 if (!process_can_proceed()) {
799 if (!_exporting && _slave) {
800 if (!follow_slave (nframes)) {
801 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
806 if (_transport_speed == 0) {
811 if (_transport_speed == 1.0) {
812 frames_moved = (framecnt_t) nframes;
814 interpolation.set_target_speed (_target_transport_speed);
815 interpolation.set_speed (_transport_speed);
816 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
819 if (!_exporting && !timecode_transmission_suspended()) {
820 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
823 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
825 framepos_t const stop_limit = compute_stop_limit ();
827 if (maybe_stop (stop_limit)) {
832 if (maybe_sync_start (nframes)) {
836 click (_transport_frame, nframes);
838 if (process_routes (nframes, session_needs_butler)) {
843 get_track_statistics ();
845 if (frames_moved < 0) {
846 decrement_transport_position (-frames_moved);
848 increment_transport_position (frames_moved);
851 maybe_stop (stop_limit);
852 check_declick_out ();
854 if (session_needs_butler) {
859 /** Process callback used when the auditioner is active.
860 * @param nframes number of frames to process.
863 Session::process_audition (pframes_t nframes)
866 boost::shared_ptr<RouteList> r = routes.reader ();
868 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
869 if (!(*i)->is_auditioner()) {
870 (*i)->silence (nframes);
874 /* run the auditioner, and if it says we need butler service, ask for it */
876 if (auditioner->play_audition (nframes) > 0) {
880 /* if using a monitor section, run it because otherwise we don't hear anything */
882 if (_monitor_out && auditioner->needs_monitor()) {
883 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
886 /* handle pending events */
888 while (pending_events.read (&ev, 1) == 1) {
892 /* if we are not in the middle of a state change,
893 and there are immediate events queued up,
897 while (!non_realtime_work_pending() && !immediate_events.empty()) {
898 SessionEvent *ev = immediate_events.front ();
899 immediate_events.pop_front ();
903 if (!auditioner->auditioning()) {
904 /* auditioner no longer active, so go back to the normal process callback */
905 process_function = &Session::process_with_events;
910 Session::maybe_sync_start (pframes_t & nframes)
912 pframes_t sync_offset;
914 if (!waiting_for_sync_offset) {
918 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
920 /* generate silence up to the sync point, then
921 adjust nframes + offset to reflect whatever
925 no_roll (sync_offset);
926 nframes -= sync_offset;
927 Port::increment_global_port_buffer_offset (sync_offset);
928 waiting_for_sync_offset = false;
931 return true; // done, nothing left to process
936 /* sync offset point is not within this process()
937 cycle, so just generate silence. and don't bother
938 with any fancy stuff here, just the minimal silence.
943 if (Config->get_locate_while_waiting_for_sync()) {
944 if (micro_locate (nframes)) {
945 /* XXX ERROR !!! XXX */
949 return true; // done, nothing left to process
956 Session::queue_event (SessionEvent* ev)
958 if (_state_of_the_state & Deletion) {
960 } else if (_state_of_the_state & Loading) {
963 pending_events.write (&ev, 1);
968 Session::set_next_event ()
970 if (events.empty()) {
971 next_event = events.end();
975 if (next_event == events.end()) {
976 next_event = events.begin();
979 if ((*next_event)->action_frame > _transport_frame) {
980 next_event = events.begin();
983 for (; next_event != events.end(); ++next_event) {
984 if ((*next_event)->action_frame >= _transport_frame) {
991 Session::process_event (SessionEvent* ev)
996 /* if we're in the middle of a state change (i.e. waiting
997 for the butler thread to complete the non-realtime
998 part of the change), we'll just have to queue this
999 event for a time when the change is complete.
1002 if (non_realtime_work_pending()) {
1004 /* except locates, which we have the capability to handle */
1006 if (ev->type != SessionEvent::Locate) {
1007 immediate_events.insert (immediate_events.end(), ev);
1013 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1016 case SessionEvent::SetLoop:
1017 set_play_loop (ev->yes_or_no, ev->speed);
1020 case SessionEvent::AutoLoop:
1022 /* roll after locate, do not flush, set "with loop"
1023 true only if we are seamless looping
1025 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1031 case SessionEvent::AutoLoopDeclick:
1033 /* Request a declick fade-out and a fade-in; the fade-out will happen
1034 at the end of the loop, and the fade-in at the start.
1036 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1042 case SessionEvent::Locate:
1043 if (ev->yes_or_no) {
1044 /* args: do not roll after locate, do flush, not with loop */
1045 locate (ev->target_frame, false, true, false);
1047 /* args: do not roll after locate, do flush, not with loop */
1048 start_locate (ev->target_frame, false, true, false);
1050 _send_timecode_update = true;
1053 case SessionEvent::LocateRoll:
1054 if (ev->yes_or_no) {
1055 /* args: roll after locate, do flush, not with loop */
1056 locate (ev->target_frame, true, true, false);
1058 /* args: roll after locate, do flush, not with loop */
1059 start_locate (ev->target_frame, true, true, false);
1061 _send_timecode_update = true;
1064 case SessionEvent::LocateRollLocate:
1065 // locate is handled by ::request_roll_at_and_return()
1066 _requested_return_frame = ev->target_frame;
1067 request_locate (ev->target2_frame, true);
1071 case SessionEvent::SetTransportSpeed:
1072 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1075 case SessionEvent::PunchIn:
1076 // cerr << "PunchIN at " << transport_frame() << endl;
1077 if (config.get_punch_in() && record_status() == Enabled) {
1084 case SessionEvent::PunchOut:
1085 // cerr << "PunchOUT at " << transport_frame() << endl;
1086 if (config.get_punch_out()) {
1087 step_back_from_record ();
1093 case SessionEvent::StopOnce:
1094 if (!non_realtime_work_pending()) {
1095 stop_transport (ev->yes_or_no);
1096 _clear_event_type (SessionEvent::StopOnce);
1102 case SessionEvent::RangeStop:
1103 if (!non_realtime_work_pending()) {
1104 stop_transport (ev->yes_or_no);
1110 case SessionEvent::RangeLocate:
1111 /* args: roll after locate, do flush, not with loop */
1112 start_locate (ev->target_frame, true, true, false);
1117 case SessionEvent::Overwrite:
1118 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1121 case SessionEvent::SetTrackSpeed:
1122 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1125 case SessionEvent::SetSyncSource:
1126 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1127 use_sync_source (ev->slave);
1130 case SessionEvent::Audition:
1131 set_audition (ev->region);
1132 // drop reference to region
1133 ev->region.reset ();
1136 case SessionEvent::InputConfigurationChange:
1137 add_post_transport_work (PostTransportInputChange);
1138 _butler->schedule_transport_work ();
1141 case SessionEvent::SetPlayAudioRange:
1142 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1145 case SessionEvent::RealTimeOperation:
1147 del = false; // other side of RT request needs to clean up
1150 case SessionEvent::AdjustPlaybackBuffering:
1151 schedule_playback_buffering_adjustment ();
1154 case SessionEvent::AdjustCaptureBuffering:
1155 schedule_capture_buffering_adjustment ();
1158 case SessionEvent::SetTimecodeTransmission:
1159 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1163 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1169 del = del && !_remove_event (ev);
1178 Session::compute_stop_limit () const
1180 if (!Config->get_stop_at_session_end ()) {
1181 return max_framepos;
1185 return max_framepos;
1189 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1190 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1192 if (actively_recording ()) {
1193 /* permanently recording */
1194 return max_framepos;
1195 } else if (punching_in && !punching_out) {
1196 /* punching in but never out */
1197 return max_framepos;
1198 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1199 /* punching in and punching out after session end */
1200 return max_framepos;
1203 return current_end_frame ();