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.
55 Session::process (pframes_t nframes)
57 MIDI::Manager::instance()->cycle_start(nframes);
61 if (processing_blocked()) {
66 if (non_realtime_work_pending()) {
67 if (!_butler->transport_work_requested ()) {
72 _engine.main_thread()->get_buffers ();
74 (this->*process_function) (nframes);
76 _engine.main_thread()->drop_buffers ();
78 // the ticker is for sending time information like MidiClock
79 framepos_t transport_frames = transport_frame();
80 Timecode::BBT_Time transport_bbt;
81 bbt_time(transport_frames, transport_bbt);
82 Timecode::Time transport_timecode;
83 timecode_time(transport_frames, transport_timecode);
84 tick (transport_frames, transport_bbt, transport_timecode); /* EMIT SIGNAL */
86 SendFeedback (); /* EMIT SIGNAL */
88 MIDI::Manager::instance()->cycle_end();
92 Session::fail_roll (pframes_t nframes)
94 return no_roll (nframes);
98 Session::no_roll (pframes_t nframes)
100 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
102 bool declick = get_transport_declick_required();
103 boost::shared_ptr<RouteList> r = routes.reader ();
106 _click_io->silence (nframes);
109 if (route_graph->threads_in_use() > 1) {
110 DEBUG_TRACE(DEBUG::Graph,"calling graph/no-roll\n");
111 route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), actively_recording(), declick);
113 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
115 if ((*i)->is_hidden()) {
119 (*i)->set_pending_declick (declick);
121 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(),
122 actively_recording(), declick)) {
123 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
134 Session::process_routes (pframes_t nframes, bool& need_butler)
137 int declick = get_transport_declick_required();
138 bool rec_monitors = get_rec_monitors_input();
139 boost::shared_ptr<RouteList> r = routes.reader ();
141 if (transport_sub_state & StopPendingCapture) {
142 /* force a declick out */
146 record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
148 const framepos_t start_frame = _transport_frame;
149 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
151 if (route_graph->threads_in_use() > 1) {
152 DEBUG_TRACE(DEBUG::Graph,"calling graph/process-routes\n");
153 route_graph->process_routes( nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler);
156 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
160 if ((*i)->is_hidden()) {
164 (*i)->set_pending_declick (declick);
166 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler)) < 0) {
177 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
179 bool record_active = actively_recording();
180 int declick = get_transport_declick_required();
181 bool rec_monitors = get_rec_monitors_input();
182 boost::shared_ptr<RouteList> r = routes.reader ();
184 if (transport_sub_state & StopPendingCapture) {
185 /* force a declick out */
189 const framepos_t start_frame = _transport_frame;
190 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
192 if (route_graph->threads_in_use() > 1) {
193 route_graph->silent_process_routes( nframes, start_frame, end_frame, record_active, rec_monitors, need_butler);
195 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
199 if ((*i)->is_hidden()) {
203 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) {
214 Session::get_track_statistics ()
219 boost::shared_ptr<RouteList> rl = routes.reader();
220 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
222 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
224 if (!tr || tr->hidden()) {
228 pworst = min (pworst, tr->playback_buffer_load());
229 cworst = min (cworst, tr->capture_buffer_load());
232 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
233 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
235 if (actively_recording()) {
240 /** Process callback used when the auditioner is not active */
242 Session::process_with_events (pframes_t nframes)
245 pframes_t this_nframes;
246 framepos_t end_frame;
247 bool session_needs_butler = false;
248 framepos_t stop_limit;
249 framecnt_t frames_moved;
251 /* make sure the auditioner is silent */
254 auditioner->silence (nframes);
257 /* handle any pending events */
259 while (pending_events.read (&ev, 1) == 1) {
263 /* if we are not in the middle of a state change,
264 and there are immediate events queued up,
268 while (!non_realtime_work_pending() && !immediate_events.empty()) {
269 SessionEvent *ev = immediate_events.front ();
270 immediate_events.pop_front ();
274 /* Decide on what to do with quarter-frame MTC during this cycle */
276 bool const was_sending_qf_mtc = _send_qf_mtc;
277 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
279 if (_transport_speed != 0) {
281 Config->get_send_mtc () &&
282 _transport_speed >= (1 - tolerance) &&
283 _transport_speed <= (1 + tolerance)
286 if (_send_qf_mtc && !was_sending_qf_mtc) {
287 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
288 _send_timecode_update = true;
291 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
292 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
293 a quarter of a second since we sent anything at all, so send a full MTC update
296 _send_timecode_update = true;
299 _pframes_since_last_mtc += nframes;
302 /* Events caused a transport change (or we re-started sending
303 * MTC), so send an MTC Full Frame (Timecode) message. This
304 * is sent whether rolling or not, to give slaves an idea of
305 * ardour time on locates (and allow slow slaves to position
306 * and prepare for rolling)
308 if (_send_timecode_update) {
309 send_full_time_code (_transport_frame);
312 if (!process_can_proceed()) {
317 if (events.empty() || next_event == events.end()) {
318 process_without_events (nframes);
322 if (_transport_speed == 1.0) {
323 frames_moved = (framecnt_t) nframes;
325 interpolation.set_target_speed (fabs(_target_transport_speed));
326 interpolation.set_speed (fabs(_transport_speed));
327 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
330 end_frame = _transport_frame + frames_moved;
333 SessionEvent* this_event;
334 Events::iterator the_next_one;
336 if (!process_can_proceed()) {
341 if (!_exporting && _slave) {
342 if (!follow_slave (nframes)) {
347 if (_transport_speed == 0) {
352 if (!_exporting && !timecode_transmission_suspended()) {
353 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
356 if (actively_recording()) {
357 stop_limit = max_framepos;
360 if (Config->get_stop_at_session_end()) {
361 stop_limit = current_end_frame();
363 stop_limit = max_framepos;
367 if (maybe_stop (stop_limit)) {
372 this_event = *next_event;
373 the_next_one = next_event;
376 /* yes folks, here it is, the actual loop where we really truly
382 this_nframes = nframes; /* real (jack) time relative */
383 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
385 /* running an event, position transport precisely to its time */
386 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
387 /* this isn't quite right for reverse play */
388 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
389 this_nframes = abs (floor(frames_moved / _transport_speed));
394 click (_transport_frame, this_nframes);
396 if (process_routes (this_nframes, session_needs_butler)) {
401 get_track_statistics ();
403 nframes -= this_nframes;
405 if (frames_moved < 0) {
406 decrement_transport_position (-frames_moved);
408 increment_transport_position (frames_moved);
411 maybe_stop (stop_limit);
412 check_declick_out ();
415 _engine.split_cycle (this_nframes);
417 /* now handle this event and all others scheduled for the same time */
419 while (this_event && this_event->action_frame == _transport_frame) {
420 process_event (this_event);
422 if (the_next_one == events.end()) {
425 this_event = *the_next_one;
430 /* if an event left our state changing, do the right thing */
432 if (nframes && non_realtime_work_pending()) {
437 /* this is necessary to handle the case of seamless looping */
438 end_frame = _transport_frame + floor (nframes * _transport_speed);
443 } /* implicit release of route lock */
445 if (session_needs_butler) {
451 Session::reset_slave_state ()
453 average_slave_delta = 1800;
454 delta_accumulator_cnt = 0;
455 have_first_delta_accumulator = false;
456 _slave_state = Stopped;
460 Session::transport_locked () const
464 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
472 Session::follow_slave (pframes_t nframes)
475 framepos_t slave_transport_frame;
476 framecnt_t this_delta;
481 config.set_external_sync (false);
485 _slave->speed_and_position (slave_speed, slave_transport_frame);
487 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
489 if (!_slave->locked()) {
490 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
494 if (slave_transport_frame > _transport_frame) {
495 this_delta = slave_transport_frame - _transport_frame;
498 this_delta = _transport_frame - slave_transport_frame;
502 if (_slave->starting()) {
506 if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
508 /* if the TC source is synced, then we assume that its
509 speed is binary: 0.0 or 1.0
512 if (slave_speed != 0.0f) {
518 /* if we are chasing and the average delta between us and the
519 master gets too big, we want to switch to silent
520 motion. so keep track of that here.
523 if (_slave_state == Running) {
524 calculate_moving_average_of_slave_delta(dir, this_delta);
528 track_slave_state (slave_speed, slave_transport_frame, this_delta);
530 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
531 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
534 if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
536 if (_transport_speed != 0.0f) {
539 note that average_dir is +1 or -1
544 if (average_slave_delta == 0) {
548 delta = average_slave_delta;
549 delta *= average_dir;
553 if (slave_speed != 0.0) {
554 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
555 (int) (dir * this_delta),
559 slave_transport_frame,
560 average_slave_delta));
564 if (_slave->give_slave_full_control_over_transport_speed()) {
565 set_transport_speed (slave_speed, false, false);
566 //std::cout << "set speed = " << slave_speed << "\n";
568 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
569 request_transport_speed (adjusted_speed);
570 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
571 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
576 if ((framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
577 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
585 if (_slave_state == Running && !non_realtime_work_pending()) {
586 /* speed is set, we're locked, and good to go */
591 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
592 follow_slave_silently (nframes, slave_speed);
595 /* don't move at all */
596 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
602 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
604 if (delta_accumulator_cnt >= delta_accumulator_size) {
605 have_first_delta_accumulator = true;
606 delta_accumulator_cnt = 0;
609 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
610 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
613 if (have_first_delta_accumulator) {
614 average_slave_delta = 0L;
615 for (int i = 0; i < delta_accumulator_size; ++i) {
616 average_slave_delta += delta_accumulator[i];
618 average_slave_delta /= (int32_t) delta_accumulator_size;
619 if (average_slave_delta < 0L) {
621 average_slave_delta = abs(average_slave_delta);
629 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t this_delta)
631 if (slave_speed != 0.0f) {
633 /* slave is running */
635 switch (_slave_state) {
637 if (_slave->requires_seekahead()) {
638 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
639 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
640 /* we can call locate() here because we are in process context */
641 locate (slave_wait_end, false, false);
642 _slave_state = Waiting;
646 _slave_state = Running;
648 Location* al = _locations->auto_loop_location();
650 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
652 request_play_loop(false);
655 if (slave_transport_frame != _transport_frame) {
656 locate (slave_transport_frame, false, false);
666 if (_slave_state == Waiting) {
668 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
670 if (slave_transport_frame >= slave_wait_end) {
672 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
674 _slave_state = Running;
676 /* now perform a "micro-seek" within the disk buffers to realign ourselves
677 precisely with the master.
682 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
684 boost::shared_ptr<RouteList> rl = routes.reader();
685 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
686 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
687 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
694 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
695 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
697 tr->internal_playback_seek (frame_delta);
700 _transport_frame += frame_delta;
703 cerr << "cannot micro-seek\n";
707 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
708 average_slave_delta = 0L;
713 if (_slave_state == Running && _transport_speed == 0.0f) {
714 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
718 } else { // slave_speed is 0
720 /* slave has stopped */
722 if (_transport_speed != 0.0f) {
723 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
727 if (slave_transport_frame != _transport_frame) {
728 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
729 force_locate (slave_transport_frame, false);
732 _slave_state = Stopped;
737 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
739 if (slave_speed && _transport_speed) {
741 /* something isn't right, but we should move with the master
747 silent_process_routes (nframes, need_butler);
749 get_track_statistics ();
755 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
757 if (frames_moved < 0) {
758 decrement_transport_position (-frames_moved);
760 increment_transport_position (frames_moved);
763 framepos_t stop_limit;
765 if (actively_recording()) {
766 stop_limit = max_framepos;
768 if (Config->get_stop_at_session_end()) {
769 stop_limit = current_end_frame();
771 stop_limit = max_framepos;
775 maybe_stop (stop_limit);
780 Session::process_without_events (pframes_t nframes)
782 bool session_needs_butler = false;
783 framepos_t stop_limit;
784 framecnt_t frames_moved;
786 if (!process_can_proceed()) {
791 if (!_exporting && _slave) {
792 if (!follow_slave (nframes)) {
797 if (_transport_speed == 0) {
802 if (_transport_speed == 1.0) {
803 frames_moved = (framecnt_t) nframes;
805 interpolation.set_target_speed (fabs(_target_transport_speed));
806 interpolation.set_speed (fabs(_transport_speed));
807 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
810 if (!_exporting && !timecode_transmission_suspended()) {
811 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
814 if (actively_recording()) {
815 stop_limit = max_framepos;
817 if (Config->get_stop_at_session_end()) {
818 stop_limit = current_end_frame();
820 stop_limit = max_framepos;
824 if (maybe_stop (stop_limit)) {
829 if (maybe_sync_start (nframes)) {
833 click (_transport_frame, nframes);
835 if (process_routes (nframes, session_needs_butler)) {
840 get_track_statistics ();
842 /* XXX: I'm not sure whether this is correct, but at least it
843 matches process_with_events, so that this new frames_moved
844 is -ve when transport speed is -ve. This means that the
845 transport position is updated correctly when we are in
846 reverse. It seems a bit wrong that we're not using the
847 interpolator to compute this.
850 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
852 if (frames_moved < 0) {
853 decrement_transport_position (-frames_moved);
855 increment_transport_position (frames_moved);
858 maybe_stop (stop_limit);
859 check_declick_out ();
861 if (session_needs_butler) {
866 /** Process callback used when the auditioner is active.
867 * @param nframes number of frames to process.
870 Session::process_audition (pframes_t nframes)
873 boost::shared_ptr<RouteList> r = routes.reader ();
875 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
876 if (!(*i)->is_hidden()) {
877 (*i)->silence (nframes);
881 /* run the auditioner, and if it says we need butler service, ask for it */
883 if (auditioner->play_audition (nframes) > 0) {
887 /* if using a monitor section, run it because otherwise we don't hear anything */
889 if (auditioner->needs_monitor()) {
890 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
893 /* handle pending events */
895 while (pending_events.read (&ev, 1) == 1) {
899 /* if we are not in the middle of a state change,
900 and there are immediate events queued up,
904 while (!non_realtime_work_pending() && !immediate_events.empty()) {
905 SessionEvent *ev = immediate_events.front ();
906 immediate_events.pop_front ();
910 if (!auditioner->auditioning()) {
911 /* auditioner no longer active, so go back to the normal process callback */
912 process_function = &Session::process_with_events;
917 Session::maybe_sync_start (pframes_t & nframes)
919 pframes_t sync_offset;
921 if (!waiting_for_sync_offset) {
925 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
927 /* generate silence up to the sync point, then
928 adjust nframes + offset to reflect whatever
932 no_roll (sync_offset);
933 nframes -= sync_offset;
934 AudioPort::increment_port_offset (sync_offset);
935 waiting_for_sync_offset = false;
938 return true; // done, nothing left to process
943 /* sync offset point is not within this process()
944 cycle, so just generate silence. and don't bother
945 with any fancy stuff here, just the minimal silence.
950 if (Config->get_locate_while_waiting_for_sync()) {
951 if (micro_locate (nframes)) {
952 /* XXX ERROR !!! XXX */
956 return true; // done, nothing left to process
963 Session::queue_event (SessionEvent* ev)
965 if (_state_of_the_state & Deletion) {
967 } else if (_state_of_the_state & Loading) {
970 pending_events.write (&ev, 1);
975 Session::set_next_event ()
977 if (events.empty()) {
978 next_event = events.end();
982 if (next_event == events.end()) {
983 next_event = events.begin();
986 if ((*next_event)->action_frame > _transport_frame) {
987 next_event = events.begin();
990 for (; next_event != events.end(); ++next_event) {
991 if ((*next_event)->action_frame >= _transport_frame) {
998 Session::process_event (SessionEvent* ev)
1003 /* if we're in the middle of a state change (i.e. waiting
1004 for the butler thread to complete the non-realtime
1005 part of the change), we'll just have to queue this
1006 event for a time when the change is complete.
1009 if (non_realtime_work_pending()) {
1011 /* except locates, which we have the capability to handle */
1013 if (ev->type != SessionEvent::Locate) {
1014 immediate_events.insert (immediate_events.end(), ev);
1020 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1023 case SessionEvent::SetLoop:
1024 set_play_loop (ev->yes_or_no);
1027 case SessionEvent::AutoLoop:
1029 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1035 case SessionEvent::Locate:
1036 if (ev->yes_or_no) {
1037 // cerr << "forced locate to " << ev->target_frame << endl;
1038 locate (ev->target_frame, false, true, false);
1040 // cerr << "soft locate to " << ev->target_frame << endl;
1041 start_locate (ev->target_frame, false, true, false);
1043 _send_timecode_update = true;
1046 case SessionEvent::LocateRoll:
1047 if (ev->yes_or_no) {
1048 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1049 locate (ev->target_frame, true, true, false);
1051 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1052 start_locate (ev->target_frame, true, true, false);
1054 _send_timecode_update = true;
1057 case SessionEvent::LocateRollLocate:
1058 // locate is handled by ::request_roll_at_and_return()
1059 _requested_return_frame = ev->target_frame;
1060 request_locate (ev->target2_frame, true);
1064 case SessionEvent::SetTransportSpeed:
1065 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1068 case SessionEvent::PunchIn:
1069 // cerr << "PunchIN at " << transport_frame() << endl;
1070 if (config.get_punch_in() && record_status() == Enabled) {
1077 case SessionEvent::PunchOut:
1078 // cerr << "PunchOUT at " << transport_frame() << endl;
1079 if (config.get_punch_out()) {
1080 step_back_from_record ();
1086 case SessionEvent::StopOnce:
1087 if (!non_realtime_work_pending()) {
1088 stop_transport (ev->yes_or_no);
1089 _clear_event_type (SessionEvent::StopOnce);
1095 case SessionEvent::RangeStop:
1096 if (!non_realtime_work_pending()) {
1097 stop_transport (ev->yes_or_no);
1103 case SessionEvent::RangeLocate:
1104 start_locate (ev->target_frame, true, true, false);
1109 case SessionEvent::Overwrite:
1110 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1113 case SessionEvent::SetTrackSpeed:
1114 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1117 case SessionEvent::SetSyncSource:
1118 use_sync_source (ev->slave);
1121 case SessionEvent::Audition:
1122 set_audition (ev->region);
1123 // drop reference to region
1124 ev->region.reset ();
1127 case SessionEvent::InputConfigurationChange:
1128 add_post_transport_work (PostTransportInputChange);
1129 _butler->schedule_transport_work ();
1132 case SessionEvent::SetPlayAudioRange:
1133 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1136 case SessionEvent::RealTimeOperation:
1138 del = false; // other side of RT request needs to clean up
1141 case SessionEvent::AdjustPlaybackBuffering:
1142 schedule_playback_buffering_adjustment ();
1145 case SessionEvent::AdjustCaptureBuffering:
1146 schedule_capture_buffering_adjustment ();
1149 case SessionEvent::SetTimecodeTransmission:
1150 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1154 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1160 del = del && !_remove_event (ev);