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 (Config->get_processor_usage() != 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 (Config->get_processor_usage() != 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);
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 (Config->get_processor_usage() != 1) {
194 cerr << "GRAPH PROCESS\n";
195 route_graph->silent_process_routes( nframes, start_frame, end_frame, record_active, rec_monitors, need_butler);
197 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
201 if ((*i)->is_hidden()) {
205 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) {
216 Session::get_track_statistics ()
221 boost::shared_ptr<RouteList> rl = routes.reader();
222 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
224 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
226 if (!tr || tr->hidden()) {
230 pworst = min (pworst, tr->playback_buffer_load());
231 cworst = min (cworst, tr->capture_buffer_load());
234 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
235 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
237 if (actively_recording()) {
242 /** Process callback used when the auditioner is not active */
244 Session::process_with_events (pframes_t nframes)
247 pframes_t this_nframes;
248 framepos_t end_frame;
249 bool session_needs_butler = false;
250 framepos_t stop_limit;
251 framecnt_t frames_moved;
253 /* make sure the auditioner is silent */
256 auditioner->silence (nframes);
259 /* handle any pending events */
261 while (pending_events.read (&ev, 1) == 1) {
265 /* if we are not in the middle of a state change,
266 and there are immediate events queued up,
270 while (!non_realtime_work_pending() && !immediate_events.empty()) {
271 SessionEvent *ev = immediate_events.front ();
272 immediate_events.pop_front ();
276 /* Decide on what to do with quarter-frame MTC during this cycle */
278 bool const was_sending_qf_mtc = _send_qf_mtc;
279 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
281 if (_transport_speed != 0) {
283 Config->get_send_mtc () &&
284 _transport_speed >= (1 - tolerance) &&
285 _transport_speed <= (1 + tolerance)
288 if (_send_qf_mtc && !was_sending_qf_mtc) {
289 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
290 _send_timecode_update = true;
293 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
294 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
295 a quarter of a second since we sent anything at all, so send a full MTC update
298 _send_timecode_update = true;
301 _pframes_since_last_mtc += nframes;
304 /* Events caused a transport change (or we re-started sending
305 * MTC), so send an MTC Full Frame (Timecode) message. This
306 * is sent whether rolling or not, to give slaves an idea of
307 * ardour time on locates (and allow slow slaves to position
308 * and prepare for rolling)
310 if (_send_timecode_update) {
311 send_full_time_code (_transport_frame);
314 if (!process_can_proceed()) {
319 if (events.empty() || next_event == events.end()) {
320 process_without_events (nframes);
324 if (_transport_speed == 1.0) {
325 frames_moved = (framecnt_t) nframes;
327 interpolation.set_target_speed (fabs(_target_transport_speed));
328 interpolation.set_speed (fabs(_transport_speed));
329 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
332 end_frame = _transport_frame + frames_moved;
335 SessionEvent* this_event;
336 Events::iterator the_next_one;
338 if (!process_can_proceed()) {
343 if (!_exporting && _slave) {
344 if (!follow_slave (nframes)) {
349 if (_transport_speed == 0) {
354 if (!_exporting && !timecode_transmission_suspended()) {
355 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
358 if (actively_recording()) {
359 stop_limit = max_framepos;
362 if (Config->get_stop_at_session_end()) {
363 stop_limit = current_end_frame();
365 stop_limit = max_framepos;
369 if (maybe_stop (stop_limit)) {
374 this_event = *next_event;
375 the_next_one = next_event;
378 /* yes folks, here it is, the actual loop where we really truly
384 this_nframes = nframes; /* real (jack) time relative */
385 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
387 /* running an event, position transport precisely to its time */
388 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
389 /* this isn't quite right for reverse play */
390 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
391 this_nframes = abs (floor(frames_moved / _transport_speed));
396 click (_transport_frame, this_nframes);
398 if (process_routes (this_nframes, session_needs_butler)) {
403 get_track_statistics ();
405 nframes -= this_nframes;
407 if (frames_moved < 0) {
408 decrement_transport_position (-frames_moved);
410 increment_transport_position (frames_moved);
413 maybe_stop (stop_limit);
414 check_declick_out ();
417 _engine.split_cycle (this_nframes);
419 /* now handle this event and all others scheduled for the same time */
421 while (this_event && this_event->action_frame == _transport_frame) {
422 process_event (this_event);
424 if (the_next_one == events.end()) {
427 this_event = *the_next_one;
432 /* if an event left our state changing, do the right thing */
434 if (nframes && non_realtime_work_pending()) {
439 /* this is necessary to handle the case of seamless looping */
440 end_frame = _transport_frame + floor (nframes * _transport_speed);
446 } /* implicit release of route lock */
448 if (session_needs_butler) {
454 Session::reset_slave_state ()
456 average_slave_delta = 1800;
457 delta_accumulator_cnt = 0;
458 have_first_delta_accumulator = false;
459 _slave_state = Stopped;
463 Session::transport_locked () const
467 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
475 Session::follow_slave (pframes_t nframes)
478 framepos_t slave_transport_frame;
479 framecnt_t this_delta;
484 config.set_external_sync (false);
488 _slave->speed_and_position (slave_speed, slave_transport_frame);
490 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
492 if (!_slave->locked()) {
493 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
497 if (slave_transport_frame > _transport_frame) {
498 this_delta = slave_transport_frame - _transport_frame;
501 this_delta = _transport_frame - slave_transport_frame;
505 if (_slave->starting()) {
509 if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
511 /* if the TC source is synced, then we assume that its
512 speed is binary: 0.0 or 1.0
515 if (slave_speed != 0.0f) {
521 /* if we are chasing and the average delta between us and the
522 master gets too big, we want to switch to silent
523 motion. so keep track of that here.
526 if (_slave_state == Running) {
527 calculate_moving_average_of_slave_delta(dir, this_delta);
531 track_slave_state (slave_speed, slave_transport_frame, this_delta);
533 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
534 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
537 if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
539 if (_transport_speed != 0.0f) {
542 note that average_dir is +1 or -1
547 if (average_slave_delta == 0) {
551 delta = average_slave_delta;
552 delta *= average_dir;
556 if (slave_speed != 0.0) {
557 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
558 (int) (dir * this_delta),
562 slave_transport_frame,
563 average_slave_delta));
567 if (_slave->give_slave_full_control_over_transport_speed()) {
568 set_transport_speed (slave_speed, false, false);
569 //std::cout << "set speed = " << slave_speed << "\n";
571 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
572 request_transport_speed (adjusted_speed);
573 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
574 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
579 if ((framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
580 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
588 if (_slave_state == Running && !non_realtime_work_pending()) {
589 /* speed is set, we're locked, and good to go */
594 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
595 follow_slave_silently (nframes, slave_speed);
598 /* don't move at all */
599 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
605 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
607 if (delta_accumulator_cnt >= delta_accumulator_size) {
608 have_first_delta_accumulator = true;
609 delta_accumulator_cnt = 0;
612 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
613 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
616 if (have_first_delta_accumulator) {
617 average_slave_delta = 0L;
618 for (int i = 0; i < delta_accumulator_size; ++i) {
619 average_slave_delta += delta_accumulator[i];
621 average_slave_delta /= (int32_t) delta_accumulator_size;
622 if (average_slave_delta < 0L) {
624 average_slave_delta = abs(average_slave_delta);
632 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t this_delta)
634 if (slave_speed != 0.0f) {
636 /* slave is running */
638 switch (_slave_state) {
640 if (_slave->requires_seekahead()) {
641 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
642 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
643 /* we can call locate() here because we are in process context */
644 locate (slave_wait_end, false, false);
645 _slave_state = Waiting;
649 _slave_state = Running;
651 Location* al = _locations->auto_loop_location();
653 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
655 request_play_loop(false);
658 if (slave_transport_frame != _transport_frame) {
659 locate (slave_transport_frame, false, false);
669 if (_slave_state == Waiting) {
671 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
673 if (slave_transport_frame >= slave_wait_end) {
675 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
677 _slave_state = Running;
679 /* now perform a "micro-seek" within the disk buffers to realign ourselves
680 precisely with the master.
685 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
687 boost::shared_ptr<RouteList> rl = routes.reader();
688 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
689 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
690 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
697 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
698 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
700 tr->internal_playback_seek (frame_delta);
703 _transport_frame += frame_delta;
706 cerr << "cannot micro-seek\n";
710 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
711 average_slave_delta = 0L;
716 if (_slave_state == Running && _transport_speed == 0.0f) {
717 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
721 } else { // slave_speed is 0
723 /* slave has stopped */
725 if (_transport_speed != 0.0f) {
726 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
730 if (slave_transport_frame != _transport_frame) {
731 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
732 force_locate (slave_transport_frame, false);
735 _slave_state = Stopped;
740 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
742 if (slave_speed && _transport_speed) {
744 /* something isn't right, but we should move with the master
750 silent_process_routes (nframes, need_butler);
752 get_track_statistics ();
758 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
760 if (frames_moved < 0) {
761 decrement_transport_position (-frames_moved);
763 increment_transport_position (frames_moved);
766 framepos_t stop_limit;
768 if (actively_recording()) {
769 stop_limit = max_framepos;
771 if (Config->get_stop_at_session_end()) {
772 stop_limit = current_end_frame();
774 stop_limit = max_framepos;
778 maybe_stop (stop_limit);
783 Session::process_without_events (pframes_t nframes)
785 bool session_needs_butler = false;
786 framepos_t stop_limit;
787 framecnt_t frames_moved;
789 if (!process_can_proceed()) {
794 if (!_exporting && _slave) {
795 if (!follow_slave (nframes)) {
800 if (_transport_speed == 0) {
805 if (_transport_speed == 1.0) {
806 frames_moved = (framecnt_t) nframes;
808 interpolation.set_target_speed (fabs(_target_transport_speed));
809 interpolation.set_speed (fabs(_transport_speed));
810 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
813 if (!_exporting && !timecode_transmission_suspended()) {
814 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
817 if (actively_recording()) {
818 stop_limit = max_framepos;
820 if (Config->get_stop_at_session_end()) {
821 stop_limit = current_end_frame();
823 stop_limit = max_framepos;
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 /* XXX: I'm not sure whether this is correct, but at least it
846 matches process_with_events, so that this new frames_moved
847 is -ve when transport speed is -ve. This means that the
848 transport position is updated correctly when we are in
849 reverse. It seems a bit wrong that we're not using the
850 interpolator to compute this.
853 frames_moved = (framecnt_t) floor (_transport_speed * nframes);
855 if (frames_moved < 0) {
856 decrement_transport_position (-frames_moved);
858 increment_transport_position (frames_moved);
861 maybe_stop (stop_limit);
862 check_declick_out ();
864 if (session_needs_butler) {
869 /** Process callback used when the auditioner is active.
870 * @param nframes number of frames to process.
873 Session::process_audition (pframes_t nframes)
876 boost::shared_ptr<RouteList> r = routes.reader ();
878 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
879 if (!(*i)->is_hidden()) {
880 (*i)->silence (nframes);
884 /* run the auditioner, and if it says we need butler service, ask for it */
886 if (auditioner->play_audition (nframes) > 0) {
890 /* if using a monitor section, run it because otherwise we don't hear anything */
892 if (auditioner->needs_monitor()) {
893 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
896 /* handle pending events */
898 while (pending_events.read (&ev, 1) == 1) {
902 /* if we are not in the middle of a state change,
903 and there are immediate events queued up,
907 while (!non_realtime_work_pending() && !immediate_events.empty()) {
908 SessionEvent *ev = immediate_events.front ();
909 immediate_events.pop_front ();
913 if (!auditioner->auditioning()) {
914 /* auditioner no longer active, so go back to the normal process callback */
915 process_function = &Session::process_with_events;
920 Session::maybe_sync_start (pframes_t & nframes)
922 pframes_t sync_offset;
924 if (!waiting_for_sync_offset) {
928 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
930 /* generate silence up to the sync point, then
931 adjust nframes + offset to reflect whatever
935 no_roll (sync_offset);
936 nframes -= sync_offset;
937 AudioPort::increment_port_offset (sync_offset);
938 waiting_for_sync_offset = false;
941 return true; // done, nothing left to process
946 /* sync offset point is not within this process()
947 cycle, so just generate silence. and don't bother
948 with any fancy stuff here, just the minimal silence.
953 if (Config->get_locate_while_waiting_for_sync()) {
954 if (micro_locate (nframes)) {
955 /* XXX ERROR !!! XXX */
959 return true; // done, nothing left to process
966 Session::queue_event (SessionEvent* ev)
968 if (_state_of_the_state & Deletion) {
970 } else if (_state_of_the_state & Loading) {
973 pending_events.write (&ev, 1);
978 Session::set_next_event ()
980 if (events.empty()) {
981 next_event = events.end();
985 if (next_event == events.end()) {
986 next_event = events.begin();
989 if ((*next_event)->action_frame > _transport_frame) {
990 next_event = events.begin();
993 for (; next_event != events.end(); ++next_event) {
994 if ((*next_event)->action_frame >= _transport_frame) {
1001 Session::process_event (SessionEvent* ev)
1006 /* if we're in the middle of a state change (i.e. waiting
1007 for the butler thread to complete the non-realtime
1008 part of the change), we'll just have to queue this
1009 event for a time when the change is complete.
1012 if (non_realtime_work_pending()) {
1014 /* except locates, which we have the capability to handle */
1016 if (ev->type != SessionEvent::Locate) {
1017 immediate_events.insert (immediate_events.end(), ev);
1023 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1026 case SessionEvent::SetLoop:
1027 set_play_loop (ev->yes_or_no);
1030 case SessionEvent::AutoLoop:
1032 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1038 case SessionEvent::Locate:
1039 if (ev->yes_or_no) {
1040 // cerr << "forced locate to " << ev->target_frame << endl;
1041 locate (ev->target_frame, false, true, false);
1043 // cerr << "soft locate to " << ev->target_frame << endl;
1044 start_locate (ev->target_frame, false, true, false);
1046 _send_timecode_update = true;
1049 case SessionEvent::LocateRoll:
1050 if (ev->yes_or_no) {
1051 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1052 locate (ev->target_frame, true, true, false);
1054 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1055 start_locate (ev->target_frame, true, true, false);
1057 _send_timecode_update = true;
1060 case SessionEvent::LocateRollLocate:
1061 // locate is handled by ::request_roll_at_and_return()
1062 _requested_return_frame = ev->target_frame;
1063 request_locate (ev->target2_frame, true);
1067 case SessionEvent::SetTransportSpeed:
1068 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1071 case SessionEvent::PunchIn:
1072 // cerr << "PunchIN at " << transport_frame() << endl;
1073 if (config.get_punch_in() && record_status() == Enabled) {
1080 case SessionEvent::PunchOut:
1081 // cerr << "PunchOUT at " << transport_frame() << endl;
1082 if (config.get_punch_out()) {
1083 step_back_from_record ();
1089 case SessionEvent::StopOnce:
1090 if (!non_realtime_work_pending()) {
1091 stop_transport (ev->yes_or_no);
1092 _clear_event_type (SessionEvent::StopOnce);
1098 case SessionEvent::RangeStop:
1099 if (!non_realtime_work_pending()) {
1100 stop_transport (ev->yes_or_no);
1106 case SessionEvent::RangeLocate:
1107 start_locate (ev->target_frame, true, true, false);
1112 case SessionEvent::Overwrite:
1113 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1116 case SessionEvent::SetTrackSpeed:
1117 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1120 case SessionEvent::SetSyncSource:
1121 use_sync_source (ev->slave);
1124 case SessionEvent::Audition:
1125 set_audition (ev->region);
1126 // drop reference to region
1127 ev->region.reset ();
1130 case SessionEvent::InputConfigurationChange:
1131 add_post_transport_work (PostTransportInputChange);
1132 _butler->schedule_transport_work ();
1135 case SessionEvent::SetPlayAudioRange:
1136 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1139 case SessionEvent::RealTimeOperation:
1141 del = false; // other side of RT request needs to clean up
1144 case SessionEvent::AdjustPlaybackBuffering:
1145 schedule_playback_buffering_adjustment ();
1148 case SessionEvent::AdjustCaptureBuffering:
1149 schedule_capture_buffering_adjustment ();
1152 case SessionEvent::SetTimecodeTransmission:
1153 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1157 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1163 del = del && !_remove_event (ev);