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 DEBUG_TRACE(DEBUG::Graph,"calling graph/no-roll\n");
110 route_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), actively_recording(), declick);
112 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
114 if ((*i)->is_hidden()) {
118 (*i)->set_pending_declick (declick);
120 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(),
121 actively_recording(), declick)) {
122 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
133 Session::process_routes (pframes_t nframes, bool& need_butler)
136 int declick = get_transport_declick_required();
137 bool rec_monitors = get_rec_monitors_input();
138 boost::shared_ptr<RouteList> r = routes.reader ();
140 if (transport_sub_state & StopPendingCapture) {
141 /* force a declick out */
145 record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
147 const framepos_t start_frame = _transport_frame;
148 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
150 DEBUG_TRACE(DEBUG::Graph,"calling graph/process-routes\n");
151 route_graph->process_routes( nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler);
153 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
157 if ((*i)->is_hidden()) {
161 (*i)->set_pending_declick (declick);
163 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler)) < 0) {
173 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
175 bool record_active = actively_recording();
176 int declick = get_transport_declick_required();
177 bool rec_monitors = get_rec_monitors_input();
178 boost::shared_ptr<RouteList> r = routes.reader ();
180 if (transport_sub_state & StopPendingCapture) {
181 /* force a declick out */
185 const framepos_t start_frame = _transport_frame;
186 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
188 route_graph->silent_process_routes( nframes, start_frame, end_frame, record_active, rec_monitors, need_butler);
190 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
194 if ((*i)->is_hidden()) {
198 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) {
208 Session::get_track_statistics ()
213 boost::shared_ptr<RouteList> rl = routes.reader();
214 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
216 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
218 if (!tr || tr->hidden()) {
222 pworst = min (pworst, tr->playback_buffer_load());
223 cworst = min (cworst, tr->capture_buffer_load());
226 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
227 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
229 if (actively_recording()) {
234 /** Process callback used when the auditioner is not active */
236 Session::process_with_events (pframes_t nframes)
239 pframes_t this_nframes;
240 framepos_t end_frame;
241 bool session_needs_butler = false;
242 framepos_t stop_limit;
243 framecnt_t frames_moved;
245 /* make sure the auditioner is silent */
248 auditioner->silence (nframes);
251 /* handle any pending events */
253 while (pending_events.read (&ev, 1) == 1) {
257 /* if we are not in the middle of a state change,
258 and there are immediate events queued up,
262 while (!non_realtime_work_pending() && !immediate_events.empty()) {
263 SessionEvent *ev = immediate_events.front ();
264 immediate_events.pop_front ();
268 /* Decide on what to do with quarter-frame MTC during this cycle */
270 bool const was_sending_qf_mtc = _send_qf_mtc;
271 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
274 Config->get_send_mtc () &&
275 _transport_speed >= (1 - tolerance) &&
276 _transport_speed <= (1 + tolerance)
279 if (_send_qf_mtc && !was_sending_qf_mtc) {
280 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
281 _send_timecode_update = true;
284 /* Events caused a transport change (or we re-started sending
285 * MTC), so send an MTC Full Frame (Timecode) message. This
286 * is sent whether rolling or not, to give slaves an idea of
287 * ardour time on locates (and allow slow slaves to position
288 * and prepare for rolling)
290 if (_send_timecode_update) {
291 send_full_time_code (_transport_frame);
294 if (!process_can_proceed()) {
299 if (events.empty() || next_event == events.end()) {
300 process_without_events (nframes);
304 if (_transport_speed == 1.0) {
305 frames_moved = (framecnt_t) nframes;
307 interpolation.set_target_speed (fabs(_target_transport_speed));
308 interpolation.set_speed (fabs(_transport_speed));
309 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
312 end_frame = _transport_frame + frames_moved;
315 SessionEvent* this_event;
316 Events::iterator the_next_one;
318 if (!process_can_proceed()) {
323 if (!_exporting && _slave) {
324 if (!follow_slave (nframes)) {
329 if (_transport_speed == 0) {
334 if (!_exporting && !timecode_transmission_suspended()) {
335 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
338 if (actively_recording()) {
339 stop_limit = max_framepos;
342 if (Config->get_stop_at_session_end()) {
343 stop_limit = current_end_frame();
345 stop_limit = max_framepos;
349 if (maybe_stop (stop_limit)) {
354 this_event = *next_event;
355 the_next_one = next_event;
358 /* yes folks, here it is, the actual loop where we really truly
364 this_nframes = nframes; /* real (jack) time relative */
365 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
367 /* running an event, position transport precisely to its time */
368 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
369 /* this isn't quite right for reverse play */
370 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
371 this_nframes = abs (floor(frames_moved / _transport_speed));
376 click (_transport_frame, this_nframes);
378 if (process_routes (this_nframes, session_needs_butler)) {
383 get_track_statistics ();
385 nframes -= this_nframes;
387 if (frames_moved < 0) {
388 decrement_transport_position (-frames_moved);
390 increment_transport_position (frames_moved);
393 maybe_stop (stop_limit);
394 check_declick_out ();
397 _engine.split_cycle (this_nframes);
399 /* now handle this event and all others scheduled for the same time */
401 while (this_event && this_event->action_frame == _transport_frame) {
402 process_event (this_event);
404 if (the_next_one == events.end()) {
407 this_event = *the_next_one;
412 /* if an event left our state changing, do the right thing */
414 if (nframes && non_realtime_work_pending()) {
419 /* this is necessary to handle the case of seamless looping */
420 end_frame = _transport_frame + floor (nframes * _transport_speed);
426 } /* implicit release of route lock */
428 if (session_needs_butler) {
434 Session::reset_slave_state ()
436 average_slave_delta = 1800;
437 delta_accumulator_cnt = 0;
438 have_first_delta_accumulator = false;
439 _slave_state = Stopped;
443 Session::transport_locked () const
447 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
455 Session::follow_slave (pframes_t nframes)
458 framepos_t slave_transport_frame;
459 framecnt_t this_delta;
464 config.set_external_sync (false);
468 _slave->speed_and_position (slave_speed, slave_transport_frame);
470 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
472 if (!_slave->locked()) {
473 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
477 if (slave_transport_frame > _transport_frame) {
478 this_delta = slave_transport_frame - _transport_frame;
481 this_delta = _transport_frame - slave_transport_frame;
485 if (_slave->starting()) {
489 if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
491 /* if the TC source is synced, then we assume that its
492 speed is binary: 0.0 or 1.0
495 if (slave_speed != 0.0f) {
501 /* if we are chasing and the average delta between us and the
502 master gets too big, we want to switch to silent
503 motion. so keep track of that here.
506 if (_slave_state == Running) {
507 calculate_moving_average_of_slave_delta(dir, this_delta);
511 track_slave_state (slave_speed, slave_transport_frame, this_delta);
513 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
514 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
517 if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
519 if (_transport_speed != 0.0f) {
522 note that average_dir is +1 or -1
527 if (average_slave_delta == 0) {
531 delta = average_slave_delta;
532 delta *= average_dir;
536 if (slave_speed != 0.0) {
537 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
538 (int) (dir * this_delta),
542 slave_transport_frame,
543 average_slave_delta));
547 if (_slave->give_slave_full_control_over_transport_speed()) {
548 set_transport_speed (slave_speed, false, false);
549 //std::cout << "set speed = " << slave_speed << "\n";
551 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
552 request_transport_speed (adjusted_speed);
553 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
554 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
559 if ((framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
560 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
568 if (_slave_state == Running && !non_realtime_work_pending()) {
569 /* speed is set, we're locked, and good to go */
574 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
575 follow_slave_silently (nframes, slave_speed);
578 /* don't move at all */
579 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
585 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
587 if (delta_accumulator_cnt >= delta_accumulator_size) {
588 have_first_delta_accumulator = true;
589 delta_accumulator_cnt = 0;
592 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
593 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
596 if (have_first_delta_accumulator) {
597 average_slave_delta = 0L;
598 for (int i = 0; i < delta_accumulator_size; ++i) {
599 average_slave_delta += delta_accumulator[i];
601 average_slave_delta /= (int32_t) delta_accumulator_size;
602 if (average_slave_delta < 0L) {
604 average_slave_delta = abs(average_slave_delta);
612 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t this_delta)
614 if (slave_speed != 0.0f) {
616 /* slave is running */
618 switch (_slave_state) {
620 if (_slave->requires_seekahead()) {
621 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
622 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
623 /* we can call locate() here because we are in process context */
624 locate (slave_wait_end, false, false);
625 _slave_state = Waiting;
629 _slave_state = Running;
631 Location* al = _locations->auto_loop_location();
633 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
635 request_play_loop(false);
638 if (slave_transport_frame != _transport_frame) {
639 locate (slave_transport_frame, false, false);
649 if (_slave_state == Waiting) {
651 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
653 if (slave_transport_frame >= slave_wait_end) {
655 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
657 _slave_state = Running;
659 /* now perform a "micro-seek" within the disk buffers to realign ourselves
660 precisely with the master.
665 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
667 boost::shared_ptr<RouteList> rl = routes.reader();
668 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
669 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
670 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
677 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
678 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
680 tr->internal_playback_seek (frame_delta);
683 _transport_frame += frame_delta;
686 cerr << "cannot micro-seek\n";
690 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
691 average_slave_delta = 0L;
696 if (_slave_state == Running && _transport_speed == 0.0f) {
697 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
701 } else { // slave_speed is 0
703 /* slave has stopped */
705 if (_transport_speed != 0.0f) {
706 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
710 if (slave_transport_frame != _transport_frame) {
711 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
712 force_locate (slave_transport_frame, false);
715 _slave_state = Stopped;
720 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
722 if (slave_speed && _transport_speed) {
724 /* something isn't right, but we should move with the master
730 silent_process_routes (nframes, need_butler);
732 get_track_statistics ();
738 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
740 if (frames_moved < 0) {
741 decrement_transport_position (-frames_moved);
743 increment_transport_position (frames_moved);
746 framepos_t stop_limit;
748 if (actively_recording()) {
749 stop_limit = max_framepos;
751 if (Config->get_stop_at_session_end()) {
752 stop_limit = current_end_frame();
754 stop_limit = max_framepos;
758 maybe_stop (stop_limit);
763 Session::process_without_events (pframes_t nframes)
765 bool session_needs_butler = false;
766 framepos_t stop_limit;
767 framecnt_t frames_moved;
769 if (!process_can_proceed()) {
774 if (!_exporting && _slave) {
775 if (!follow_slave (nframes)) {
780 if (_transport_speed == 0) {
785 if (_transport_speed == 1.0) {
786 frames_moved = (framecnt_t) nframes;
788 interpolation.set_target_speed (fabs(_target_transport_speed));
789 interpolation.set_speed (fabs(_transport_speed));
790 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
793 if (!_exporting && !timecode_transmission_suspended()) {
794 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
797 if (actively_recording()) {
798 stop_limit = max_framepos;
800 if (Config->get_stop_at_session_end()) {
801 stop_limit = current_end_frame();
803 stop_limit = max_framepos;
807 if (maybe_stop (stop_limit)) {
812 if (maybe_sync_start (nframes)) {
816 click (_transport_frame, nframes);
818 if (process_routes (nframes, session_needs_butler)) {
823 get_track_statistics ();
825 if (frames_moved < 0) {
826 decrement_transport_position (-frames_moved);
828 increment_transport_position (frames_moved);
831 maybe_stop (stop_limit);
832 check_declick_out ();
834 if (session_needs_butler) {
839 /** Process callback used when the auditioner is active.
840 * @param nframes number of frames to process.
843 Session::process_audition (pframes_t nframes)
846 boost::shared_ptr<RouteList> r = routes.reader ();
848 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
849 if (!(*i)->is_hidden()) {
850 (*i)->silence (nframes);
854 /* run the auditioner, and if it says we need butler service, ask for it */
856 if (auditioner->play_audition (nframes) > 0) {
860 /* if using a monitor section, run it because otherwise we don't hear anything */
862 if (auditioner->needs_monitor()) {
863 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
866 /* handle pending events */
868 while (pending_events.read (&ev, 1) == 1) {
872 /* if we are not in the middle of a state change,
873 and there are immediate events queued up,
877 while (!non_realtime_work_pending() && !immediate_events.empty()) {
878 SessionEvent *ev = immediate_events.front ();
879 immediate_events.pop_front ();
883 if (!auditioner->auditioning()) {
884 /* auditioner no longer active, so go back to the normal process callback */
885 process_function = &Session::process_with_events;
890 Session::maybe_sync_start (pframes_t & nframes)
892 pframes_t sync_offset;
894 if (!waiting_for_sync_offset) {
898 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
900 /* generate silence up to the sync point, then
901 adjust nframes + offset to reflect whatever
905 no_roll (sync_offset);
906 nframes -= sync_offset;
907 AudioPort::increment_port_offset (sync_offset);
908 waiting_for_sync_offset = false;
911 return true; // done, nothing left to process
916 /* sync offset point is not within this process()
917 cycle, so just generate silence. and don't bother
918 with any fancy stuff here, just the minimal silence.
923 if (Config->get_locate_while_waiting_for_sync()) {
924 if (micro_locate (nframes)) {
925 /* XXX ERROR !!! XXX */
929 return true; // done, nothing left to process
936 Session::queue_event (SessionEvent* ev)
938 if (_state_of_the_state & Deletion) {
940 } else if (_state_of_the_state & Loading) {
943 pending_events.write (&ev, 1);
948 Session::set_next_event ()
950 if (events.empty()) {
951 next_event = events.end();
955 if (next_event == events.end()) {
956 next_event = events.begin();
959 if ((*next_event)->action_frame > _transport_frame) {
960 next_event = events.begin();
963 for (; next_event != events.end(); ++next_event) {
964 if ((*next_event)->action_frame >= _transport_frame) {
971 Session::process_event (SessionEvent* ev)
976 /* if we're in the middle of a state change (i.e. waiting
977 for the butler thread to complete the non-realtime
978 part of the change), we'll just have to queue this
979 event for a time when the change is complete.
982 if (non_realtime_work_pending()) {
984 /* except locates, which we have the capability to handle */
986 if (ev->type != SessionEvent::Locate) {
987 immediate_events.insert (immediate_events.end(), ev);
993 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
996 case SessionEvent::SetLoop:
997 set_play_loop (ev->yes_or_no);
1000 case SessionEvent::AutoLoop:
1002 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1008 case SessionEvent::Locate:
1009 if (ev->yes_or_no) {
1010 // cerr << "forced locate to " << ev->target_frame << endl;
1011 locate (ev->target_frame, false, true, false);
1013 // cerr << "soft locate to " << ev->target_frame << endl;
1014 start_locate (ev->target_frame, false, true, false);
1016 _send_timecode_update = true;
1019 case SessionEvent::LocateRoll:
1020 if (ev->yes_or_no) {
1021 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1022 locate (ev->target_frame, true, true, false);
1024 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1025 start_locate (ev->target_frame, true, true, false);
1027 _send_timecode_update = true;
1030 case SessionEvent::LocateRollLocate:
1031 // locate is handled by ::request_roll_at_and_return()
1032 _requested_return_frame = ev->target_frame;
1033 request_locate (ev->target2_frame, true);
1037 case SessionEvent::SetTransportSpeed:
1038 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1041 case SessionEvent::PunchIn:
1042 // cerr << "PunchIN at " << transport_frame() << endl;
1043 if (config.get_punch_in() && record_status() == Enabled) {
1050 case SessionEvent::PunchOut:
1051 // cerr << "PunchOUT at " << transport_frame() << endl;
1052 if (config.get_punch_out()) {
1053 step_back_from_record ();
1059 case SessionEvent::StopOnce:
1060 if (!non_realtime_work_pending()) {
1061 stop_transport (ev->yes_or_no);
1062 _clear_event_type (SessionEvent::StopOnce);
1068 case SessionEvent::RangeStop:
1069 if (!non_realtime_work_pending()) {
1070 stop_transport (ev->yes_or_no);
1076 case SessionEvent::RangeLocate:
1077 start_locate (ev->target_frame, true, true, false);
1082 case SessionEvent::Overwrite:
1083 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1086 case SessionEvent::SetTrackSpeed:
1087 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1090 case SessionEvent::SetSyncSource:
1091 use_sync_source (ev->slave);
1094 case SessionEvent::Audition:
1095 set_audition (ev->region);
1096 // drop reference to region
1097 ev->region.reset ();
1100 case SessionEvent::InputConfigurationChange:
1101 add_post_transport_work (PostTransportInputChange);
1102 _butler->schedule_transport_work ();
1105 case SessionEvent::SetPlayAudioRange:
1106 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1109 case SessionEvent::RealTimeOperation:
1111 del = false; // other side of RT request needs to clean up
1114 case SessionEvent::AdjustPlaybackBuffering:
1115 schedule_playback_buffering_adjustment ();
1118 case SessionEvent::AdjustCaptureBuffering:
1119 schedule_capture_buffering_adjustment ();
1122 case SessionEvent::SetTimecodeTransmission:
1123 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1127 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1133 del = del && !_remove_event (ev);