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::Graph,"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 if (route_graph->threads_in_use() > 0) {
153 DEBUG_TRACE(DEBUG::Graph,"calling graph/process-routes\n");
154 route_graph->process_routes( nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler);
157 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
161 if ((*i)->is_hidden()) {
165 (*i)->set_pending_declick (declick);
167 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler)) < 0) {
178 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
180 bool record_active = actively_recording();
181 int declick = get_transport_declick_required();
182 bool rec_monitors = get_rec_monitors_input();
183 boost::shared_ptr<RouteList> r = routes.reader ();
185 if (transport_sub_state & StopPendingCapture) {
186 /* force a declick out */
190 const framepos_t start_frame = _transport_frame;
191 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
193 if (route_graph->threads_in_use() > 0) {
194 route_graph->silent_process_routes( nframes, start_frame, end_frame, record_active, rec_monitors, need_butler);
196 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
200 if ((*i)->is_hidden()) {
204 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) {
215 Session::get_track_statistics ()
220 boost::shared_ptr<RouteList> rl = routes.reader();
221 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
223 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
225 if (!tr || tr->hidden()) {
229 pworst = min (pworst, tr->playback_buffer_load());
230 cworst = min (cworst, tr->capture_buffer_load());
233 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
234 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
236 if (actively_recording()) {
241 /** Process callback used when the auditioner is not active */
243 Session::process_with_events (pframes_t nframes)
246 pframes_t this_nframes;
247 framepos_t end_frame;
248 bool session_needs_butler = false;
249 framepos_t stop_limit;
250 framecnt_t frames_moved;
252 /* make sure the auditioner is silent */
255 auditioner->silence (nframes);
258 /* handle any pending events */
260 while (pending_events.read (&ev, 1) == 1) {
264 /* if we are not in the middle of a state change,
265 and there are immediate events queued up,
269 while (!non_realtime_work_pending() && !immediate_events.empty()) {
270 SessionEvent *ev = immediate_events.front ();
271 immediate_events.pop_front ();
275 /* Decide on what to do with quarter-frame MTC during this cycle */
277 bool const was_sending_qf_mtc = _send_qf_mtc;
278 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
280 if (_transport_speed != 0) {
282 Config->get_send_mtc () &&
283 _transport_speed >= (1 - tolerance) &&
284 _transport_speed <= (1 + tolerance)
287 if (_send_qf_mtc && !was_sending_qf_mtc) {
288 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
289 _send_timecode_update = true;
292 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
293 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
294 a quarter of a second since we sent anything at all, so send a full MTC update
297 _send_timecode_update = true;
300 _pframes_since_last_mtc += nframes;
303 /* Events caused a transport change (or we re-started sending
304 * MTC), so send an MTC Full Frame (Timecode) message. This
305 * is sent whether rolling or not, to give slaves an idea of
306 * ardour time on locates (and allow slow slaves to position
307 * and prepare for rolling)
309 if (_send_timecode_update) {
310 send_full_time_code (_transport_frame);
313 if (!process_can_proceed()) {
318 if (events.empty() || next_event == events.end()) {
319 process_without_events (nframes);
323 if (_transport_speed == 1.0) {
324 frames_moved = (framecnt_t) nframes;
326 interpolation.set_target_speed (fabs(_target_transport_speed));
327 interpolation.set_speed (fabs(_transport_speed));
328 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
331 end_frame = _transport_frame + frames_moved;
334 SessionEvent* this_event;
335 Events::iterator the_next_one;
337 if (!process_can_proceed()) {
342 if (!_exporting && _slave) {
343 if (!follow_slave (nframes)) {
348 if (_transport_speed == 0) {
353 if (!_exporting && !timecode_transmission_suspended()) {
354 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
357 if (actively_recording()) {
358 stop_limit = max_framepos;
361 if (Config->get_stop_at_session_end()) {
362 stop_limit = current_end_frame();
364 stop_limit = max_framepos;
368 if (maybe_stop (stop_limit)) {
373 this_event = *next_event;
374 the_next_one = next_event;
377 /* yes folks, here it is, the actual loop where we really truly
383 this_nframes = nframes; /* real (jack) time relative */
384 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
386 /* running an event, position transport precisely to its time */
387 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
388 /* this isn't quite right for reverse play */
389 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
390 this_nframes = abs (floor(frames_moved / _transport_speed));
395 click (_transport_frame, this_nframes);
397 if (process_routes (this_nframes, session_needs_butler)) {
402 get_track_statistics ();
404 nframes -= this_nframes;
406 if (frames_moved < 0) {
407 decrement_transport_position (-frames_moved);
409 increment_transport_position (frames_moved);
412 maybe_stop (stop_limit);
413 check_declick_out ();
416 _engine.split_cycle (this_nframes);
418 /* now handle this event and all others scheduled for the same time */
420 while (this_event && this_event->action_frame == _transport_frame) {
421 process_event (this_event);
423 if (the_next_one == events.end()) {
426 this_event = *the_next_one;
431 /* if an event left our state changing, do the right thing */
433 if (nframes && non_realtime_work_pending()) {
438 /* this is necessary to handle the case of seamless looping */
439 end_frame = _transport_frame + floor (nframes * _transport_speed);
444 } /* implicit release of route lock */
446 if (session_needs_butler) {
452 Session::reset_slave_state ()
454 average_slave_delta = 1800;
455 delta_accumulator_cnt = 0;
456 have_first_delta_accumulator = false;
457 _slave_state = Stopped;
461 Session::transport_locked () const
465 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
473 Session::follow_slave (pframes_t nframes)
476 framepos_t slave_transport_frame;
477 framecnt_t this_delta;
482 config.set_external_sync (false);
486 _slave->speed_and_position (slave_speed, slave_transport_frame);
488 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
490 if (!_slave->locked()) {
491 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
495 if (slave_transport_frame > _transport_frame) {
496 this_delta = slave_transport_frame - _transport_frame;
499 this_delta = _transport_frame - slave_transport_frame;
503 if (_slave->starting()) {
507 if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
509 /* if the TC source is synced, then we assume that its
510 speed is binary: 0.0 or 1.0
513 if (slave_speed != 0.0f) {
519 /* if we are chasing and the average delta between us and the
520 master gets too big, we want to switch to silent
521 motion. so keep track of that here.
524 if (_slave_state == Running) {
525 calculate_moving_average_of_slave_delta(dir, this_delta);
529 track_slave_state (slave_speed, slave_transport_frame, this_delta);
531 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
532 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
535 if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
537 if (_transport_speed != 0.0f) {
540 note that average_dir is +1 or -1
545 if (average_slave_delta == 0) {
549 delta = average_slave_delta;
550 delta *= average_dir;
554 if (slave_speed != 0.0) {
555 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
556 (int) (dir * this_delta),
560 slave_transport_frame,
561 average_slave_delta));
565 if (_slave->give_slave_full_control_over_transport_speed()) {
566 set_transport_speed (slave_speed, false, false);
567 //std::cout << "set speed = " << slave_speed << "\n";
569 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
570 request_transport_speed (adjusted_speed);
571 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
572 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
577 if ((framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
578 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
586 if (_slave_state == Running && !non_realtime_work_pending()) {
587 /* speed is set, we're locked, and good to go */
592 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
593 follow_slave_silently (nframes, slave_speed);
596 /* don't move at all */
597 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
603 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
605 if (delta_accumulator_cnt >= delta_accumulator_size) {
606 have_first_delta_accumulator = true;
607 delta_accumulator_cnt = 0;
610 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
611 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
614 if (have_first_delta_accumulator) {
615 average_slave_delta = 0L;
616 for (int i = 0; i < delta_accumulator_size; ++i) {
617 average_slave_delta += delta_accumulator[i];
619 average_slave_delta /= (int32_t) delta_accumulator_size;
620 if (average_slave_delta < 0L) {
622 average_slave_delta = abs(average_slave_delta);
630 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t this_delta)
632 if (slave_speed != 0.0f) {
634 /* slave is running */
636 switch (_slave_state) {
638 if (_slave->requires_seekahead()) {
639 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
640 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
641 /* we can call locate() here because we are in process context */
642 locate (slave_wait_end, false, false);
643 _slave_state = Waiting;
647 _slave_state = Running;
649 Location* al = _locations->auto_loop_location();
651 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
653 request_play_loop(false);
656 if (slave_transport_frame != _transport_frame) {
657 locate (slave_transport_frame, false, false);
667 if (_slave_state == Waiting) {
669 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
671 if (slave_transport_frame >= slave_wait_end) {
673 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
675 _slave_state = Running;
677 /* now perform a "micro-seek" within the disk buffers to realign ourselves
678 precisely with the master.
683 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
685 boost::shared_ptr<RouteList> rl = routes.reader();
686 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
687 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
688 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
695 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
696 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
698 tr->internal_playback_seek (frame_delta);
701 _transport_frame += frame_delta;
704 cerr << "cannot micro-seek\n";
708 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
709 average_slave_delta = 0L;
714 if (_slave_state == Running && _transport_speed == 0.0f) {
715 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
719 } else { // slave_speed is 0
721 /* slave has stopped */
723 if (_transport_speed != 0.0f) {
724 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
728 if (slave_transport_frame != _transport_frame) {
729 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
730 force_locate (slave_transport_frame, false);
733 _slave_state = Stopped;
738 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
740 if (slave_speed && _transport_speed) {
742 /* something isn't right, but we should move with the master
748 silent_process_routes (nframes, need_butler);
750 get_track_statistics ();
756 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
758 if (frames_moved < 0) {
759 decrement_transport_position (-frames_moved);
761 increment_transport_position (frames_moved);
764 framepos_t stop_limit;
766 if (actively_recording()) {
767 stop_limit = max_framepos;
769 if (Config->get_stop_at_session_end()) {
770 stop_limit = current_end_frame();
772 stop_limit = max_framepos;
776 maybe_stop (stop_limit);
781 Session::process_without_events (pframes_t nframes)
783 bool session_needs_butler = false;
784 framepos_t stop_limit;
785 framecnt_t frames_moved;
787 if (!process_can_proceed()) {
792 if (!_exporting && _slave) {
793 if (!follow_slave (nframes)) {
798 if (_transport_speed == 0) {
803 if (_transport_speed == 1.0) {
804 frames_moved = (framecnt_t) nframes;
806 interpolation.set_target_speed (fabs(_target_transport_speed));
807 interpolation.set_speed (fabs(_transport_speed));
808 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
811 if (!_exporting && !timecode_transmission_suspended()) {
812 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
815 if (actively_recording()) {
816 stop_limit = max_framepos;
818 if (Config->get_stop_at_session_end()) {
819 stop_limit = current_end_frame();
821 stop_limit = max_framepos;
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 /* XXX: I'm not sure whether this is correct, but at least it
844 matches process_with_events, so that this new frames_moved
845 is -ve when transport speed is -ve. This means that the
846 transport position is updated correctly when we are in
847 reverse. It seems a bit wrong that we're not using the
848 interpolator to compute this.
851 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
853 if (frames_moved < 0) {
854 decrement_transport_position (-frames_moved);
856 increment_transport_position (frames_moved);
859 maybe_stop (stop_limit);
860 check_declick_out ();
862 if (session_needs_butler) {
867 /** Process callback used when the auditioner is active.
868 * @param nframes number of frames to process.
871 Session::process_audition (pframes_t nframes)
874 boost::shared_ptr<RouteList> r = routes.reader ();
876 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
877 if (!(*i)->is_hidden()) {
878 (*i)->silence (nframes);
882 /* run the auditioner, and if it says we need butler service, ask for it */
884 if (auditioner->play_audition (nframes) > 0) {
888 /* if using a monitor section, run it because otherwise we don't hear anything */
890 if (auditioner->needs_monitor()) {
891 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
894 /* handle pending events */
896 while (pending_events.read (&ev, 1) == 1) {
900 /* if we are not in the middle of a state change,
901 and there are immediate events queued up,
905 while (!non_realtime_work_pending() && !immediate_events.empty()) {
906 SessionEvent *ev = immediate_events.front ();
907 immediate_events.pop_front ();
911 if (!auditioner->auditioning()) {
912 /* auditioner no longer active, so go back to the normal process callback */
913 process_function = &Session::process_with_events;
918 Session::maybe_sync_start (pframes_t & nframes)
920 pframes_t sync_offset;
922 if (!waiting_for_sync_offset) {
926 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
928 /* generate silence up to the sync point, then
929 adjust nframes + offset to reflect whatever
933 no_roll (sync_offset);
934 nframes -= sync_offset;
935 Port::increment_global_port_buffer_offset (sync_offset);
936 waiting_for_sync_offset = false;
939 return true; // done, nothing left to process
944 /* sync offset point is not within this process()
945 cycle, so just generate silence. and don't bother
946 with any fancy stuff here, just the minimal silence.
951 if (Config->get_locate_while_waiting_for_sync()) {
952 if (micro_locate (nframes)) {
953 /* XXX ERROR !!! XXX */
957 return true; // done, nothing left to process
964 Session::queue_event (SessionEvent* ev)
966 if (_state_of_the_state & Deletion) {
968 } else if (_state_of_the_state & Loading) {
971 pending_events.write (&ev, 1);
976 Session::set_next_event ()
978 if (events.empty()) {
979 next_event = events.end();
983 if (next_event == events.end()) {
984 next_event = events.begin();
987 if ((*next_event)->action_frame > _transport_frame) {
988 next_event = events.begin();
991 for (; next_event != events.end(); ++next_event) {
992 if ((*next_event)->action_frame >= _transport_frame) {
999 Session::process_event (SessionEvent* ev)
1004 /* if we're in the middle of a state change (i.e. waiting
1005 for the butler thread to complete the non-realtime
1006 part of the change), we'll just have to queue this
1007 event for a time when the change is complete.
1010 if (non_realtime_work_pending()) {
1012 /* except locates, which we have the capability to handle */
1014 if (ev->type != SessionEvent::Locate) {
1015 immediate_events.insert (immediate_events.end(), ev);
1021 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1024 case SessionEvent::SetLoop:
1025 set_play_loop (ev->yes_or_no);
1028 case SessionEvent::AutoLoop:
1030 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1036 case SessionEvent::Locate:
1037 if (ev->yes_or_no) {
1038 // cerr << "forced locate to " << ev->target_frame << endl;
1039 locate (ev->target_frame, false, true, false);
1041 // cerr << "soft locate to " << ev->target_frame << endl;
1042 start_locate (ev->target_frame, false, true, false);
1044 _send_timecode_update = true;
1047 case SessionEvent::LocateRoll:
1048 if (ev->yes_or_no) {
1049 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1050 locate (ev->target_frame, true, true, false);
1052 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1053 start_locate (ev->target_frame, true, true, false);
1055 _send_timecode_update = true;
1058 case SessionEvent::LocateRollLocate:
1059 // locate is handled by ::request_roll_at_and_return()
1060 _requested_return_frame = ev->target_frame;
1061 request_locate (ev->target2_frame, true);
1065 case SessionEvent::SetTransportSpeed:
1066 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1069 case SessionEvent::PunchIn:
1070 // cerr << "PunchIN at " << transport_frame() << endl;
1071 if (config.get_punch_in() && record_status() == Enabled) {
1078 case SessionEvent::PunchOut:
1079 // cerr << "PunchOUT at " << transport_frame() << endl;
1080 if (config.get_punch_out()) {
1081 step_back_from_record ();
1087 case SessionEvent::StopOnce:
1088 if (!non_realtime_work_pending()) {
1089 stop_transport (ev->yes_or_no);
1090 _clear_event_type (SessionEvent::StopOnce);
1096 case SessionEvent::RangeStop:
1097 if (!non_realtime_work_pending()) {
1098 stop_transport (ev->yes_or_no);
1104 case SessionEvent::RangeLocate:
1105 start_locate (ev->target_frame, true, true, false);
1110 case SessionEvent::Overwrite:
1111 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1114 case SessionEvent::SetTrackSpeed:
1115 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1118 case SessionEvent::SetSyncSource:
1119 use_sync_source (ev->slave);
1122 case SessionEvent::Audition:
1123 set_audition (ev->region);
1124 // drop reference to region
1125 ev->region.reset ();
1128 case SessionEvent::InputConfigurationChange:
1129 add_post_transport_work (PostTransportInputChange);
1130 _butler->schedule_transport_work ();
1133 case SessionEvent::SetPlayAudioRange:
1134 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1137 case SessionEvent::RealTimeOperation:
1139 del = false; // other side of RT request needs to clean up
1142 case SessionEvent::AdjustPlaybackBuffering:
1143 schedule_playback_buffering_adjustment ();
1146 case SessionEvent::AdjustCaptureBuffering:
1147 schedule_capture_buffering_adjustment ();
1150 case SessionEvent::SetTimecodeTransmission:
1151 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1155 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1161 del = del && !_remove_event (ev);