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/audio_diskstream.h"
32 #include "ardour/audioengine.h"
33 #include "ardour/auditioner.h"
34 #include "ardour/butler.h"
35 #include "ardour/debug.h"
36 #include "ardour/session.h"
37 #include "ardour/slave.h"
38 #include "ardour/timestamps.h"
40 #include "midi++/manager.h"
44 using namespace ARDOUR;
48 /** Called by the audio engine when there is work to be done with JACK.
49 * @param nframes Number of frames to process.
52 Session::process (nframes_t nframes)
54 MIDI::Manager::instance()->cycle_start(nframes);
58 if (processing_blocked()) {
63 if (non_realtime_work_pending()) {
64 if (!_butler->transport_work_requested ()) {
69 (this->*process_function) (nframes);
71 // the ticker is for sending time information like MidiClock
72 nframes_t transport_frames = transport_frame();
73 BBT_Time transport_bbt;
74 bbt_time(transport_frames, transport_bbt);
75 Timecode::Time transport_timecode;
76 timecode_time(transport_frames, transport_timecode);
77 tick (transport_frames, transport_bbt, transport_timecode); /* EMIT SIGNAL */
79 SendFeedback (); /* EMIT SIGNAL */
81 MIDI::Manager::instance()->cycle_end();
85 Session::prepare_diskstreams ()
87 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
88 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
94 Session::fail_roll (nframes_t nframes)
96 return no_roll (nframes);
100 Session::no_roll (nframes_t nframes)
102 nframes_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
104 bool declick = get_transport_declick_required();
105 boost::shared_ptr<RouteList> r = routes.reader ();
108 _click_io->silence (nframes);
111 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
113 if ((*i)->is_hidden()) {
117 (*i)->set_pending_declick (declick);
119 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(),
120 actively_recording(), declick)) {
121 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
131 Session::process_routes (nframes_t nframes)
134 int declick = get_transport_declick_required();
135 bool rec_monitors = get_rec_monitors_input();
136 boost::shared_ptr<RouteList> r = routes.reader ();
138 if (transport_sub_state & StopPendingCapture) {
139 /* force a declick out */
143 record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
145 const nframes_t start_frame = _transport_frame;
146 const nframes_t end_frame = _transport_frame + (nframes_t)floor(nframes * _transport_speed);
148 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
152 if ((*i)->is_hidden()) {
156 (*i)->set_pending_declick (declick);
158 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors)) < 0) {
160 /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
161 and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
162 call path, so make sure we release any outstanding locks here before we return failure.
165 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
166 for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
179 Session::silent_process_routes (nframes_t nframes)
181 bool record_active = actively_recording();
182 int declick = get_transport_declick_required();
183 bool rec_monitors = get_rec_monitors_input();
184 boost::shared_ptr<RouteList> r = routes.reader ();
186 if (transport_sub_state & StopPendingCapture) {
187 /* force a declick out */
191 const nframes_t start_frame = _transport_frame;
192 const nframes_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
194 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
198 if ((*i)->is_hidden()) {
202 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors)) < 0) {
204 /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
205 and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
206 call path, so make sure we release any outstanding locks here before we return failure.
209 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
210 for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
223 Session::commit_diskstreams (nframes_t nframes, bool &needs_butler)
229 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
230 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
232 if ((*i)->hidden()) {
236 /* force all diskstreams not handled by a Route to call do their stuff.
237 Note: the diskstreams that were handled by a route will just return zero
238 from this call, because they know they were processed. So in fact, this
239 also runs commit() for every diskstream.
242 if ((dret = (*i)->process (_transport_frame, nframes, actively_recording(), get_rec_monitors_input())) == 0) {
243 if ((*i)->commit (nframes)) {
247 } else if (dret < 0) {
251 pworst = min (pworst, (*i)->playback_buffer_load());
252 cworst = min (cworst, (*i)->capture_buffer_load());
255 uint32_t pmin = g_atomic_int_get (&_playback_load);
256 uint32_t pminold = g_atomic_int_get (&_playback_load_min);
257 uint32_t cmin = g_atomic_int_get (&_capture_load);
258 uint32_t cminold = g_atomic_int_get (&_capture_load_min);
260 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
261 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
262 g_atomic_int_set (&_playback_load_min, min (pmin, pminold));
263 g_atomic_int_set (&_capture_load_min, min (cmin, cminold));
265 if (actively_recording()) {
270 /** Process callback used when the auditioner is not active */
272 Session::process_with_events (nframes_t nframes)
275 nframes_t this_nframes;
277 bool session_needs_butler = false;
278 nframes_t stop_limit;
281 /* make sure the auditioner is silent */
284 auditioner->silence (nframes);
287 /* handle any pending events */
289 while (pending_events.read (&ev, 1) == 1) {
293 /* if we are not in the middle of a state change,
294 and there are immediate events queued up,
298 while (!non_realtime_work_pending() && !immediate_events.empty()) {
299 SessionEvent *ev = immediate_events.front ();
300 immediate_events.pop_front ();
304 /* Events caused a transport change, send an MTC Full Frame (Timecode) message.
305 * This is sent whether rolling or not, to give slaves an idea of ardour time
306 * on locates (and allow slow slaves to position and prepare for rolling)
308 if (_send_timecode_update) {
309 send_full_time_code(nframes);
310 deliver_mmc (MIDI::MachineControl::cmdLocate, _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 = (long) nframes;
326 interpolation.set_target_speed (fabs(_target_transport_speed));
327 interpolation.set_speed (fabs(_transport_speed));
328 frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
331 end_frame = _transport_frame + (nframes_t)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) {
354 send_midi_time_code_for_cycle (nframes);
357 if (actively_recording()) {
358 stop_limit = max_frames;
361 if (Config->get_stop_at_session_end()) {
362 stop_limit = current_end_frame();
364 stop_limit = max_frames;
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 = (long) 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 = (long) (this_event->action_frame - _transport_frame);
390 this_nframes = (nframes_t) abs( floor(frames_moved / _transport_speed) );
395 click (_transport_frame, this_nframes);
397 /* now process frames between now and the first event in this block */
398 prepare_diskstreams ();
400 if (process_routes (this_nframes)) {
405 commit_diskstreams (this_nframes, session_needs_butler);
407 nframes -= this_nframes;
409 if (frames_moved < 0) {
410 decrement_transport_position (-frames_moved);
412 increment_transport_position (frames_moved);
415 maybe_stop (stop_limit);
416 check_declick_out ();
419 _engine.split_cycle (this_nframes);
421 /* now handle this event and all others scheduled for the same time */
423 while (this_event && this_event->action_frame == _transport_frame) {
424 process_event (this_event);
426 if (the_next_one == events.end()) {
429 this_event = *the_next_one;
434 /* if an event left our state changing, do the right thing */
436 if (nframes && non_realtime_work_pending()) {
441 /* this is necessary to handle the case of seamless looping */
442 end_frame = _transport_frame + (nframes_t) floor (nframes * _transport_speed);
448 } /* implicit release of route lock */
450 if (session_needs_butler) {
456 Session::reset_slave_state ()
458 average_slave_delta = 1800;
459 delta_accumulator_cnt = 0;
460 have_first_delta_accumulator = false;
461 _slave_state = Stopped;
465 Session::transport_locked () const
469 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
477 Session::follow_slave (nframes_t nframes)
480 nframes64_t slave_transport_frame;
481 nframes_t this_delta;
486 config.set_external_sync (false);
490 _slave->speed_and_position (slave_speed, slave_transport_frame);
492 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
494 if (!_slave->locked()) {
495 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
499 if (slave_transport_frame > _transport_frame) {
500 this_delta = slave_transport_frame - _transport_frame;
503 this_delta = _transport_frame - slave_transport_frame;
507 if (_slave->starting()) {
511 if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
513 /* if the TC source is synced, then we assume that its
514 speed is binary: 0.0 or 1.0
517 if (slave_speed != 0.0f) {
523 /* if we are chasing and the average delta between us and the
524 master gets too big, we want to switch to silent
525 motion. so keep track of that here.
528 if (_slave_state == Running) {
529 calculate_moving_average_of_slave_delta(dir, this_delta);
533 track_slave_state (slave_speed, slave_transport_frame, this_delta);
535 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
536 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
539 if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
541 if (_transport_speed != 0.0f) {
544 note that average_dir is +1 or -1
549 if (average_slave_delta == 0) {
553 delta = average_slave_delta;
554 delta *= average_dir;
558 if (slave_speed != 0.0) {
559 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
560 (int) (dir * this_delta),
564 slave_transport_frame,
565 average_slave_delta));
569 if (_slave->give_slave_full_control_over_transport_speed()) {
570 set_transport_speed (slave_speed, false, false);
572 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
573 request_transport_speed (adjusted_speed);
574 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
575 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
579 if (abs(average_slave_delta) > _slave->resolution()) {
580 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
587 if (_slave_state == Running && !non_realtime_work_pending()) {
588 /* speed is set, we're locked, and good to go */
593 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
594 follow_slave_silently (nframes, slave_speed);
597 /* don't move at all */
598 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
604 Session::calculate_moving_average_of_slave_delta(int dir, nframes_t this_delta)
606 if (delta_accumulator_cnt >= delta_accumulator_size) {
607 have_first_delta_accumulator = true;
608 delta_accumulator_cnt = 0;
611 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
612 delta_accumulator[delta_accumulator_cnt++] = long(dir) * long(this_delta);
615 if (have_first_delta_accumulator) {
616 average_slave_delta = 0L;
617 for (int i = 0; i < delta_accumulator_size; ++i) {
618 average_slave_delta += delta_accumulator[i];
620 average_slave_delta /= long(delta_accumulator_size);
621 if (average_slave_delta < 0L) {
623 average_slave_delta = abs(average_slave_delta);
631 Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame, nframes_t this_delta)
633 if (slave_speed != 0.0f) {
635 /* slave is running */
637 switch (_slave_state) {
639 if (_slave->requires_seekahead()) {
640 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
641 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
642 /* we can call locate() here because we are in process context */
643 locate (slave_wait_end, false, false);
644 _slave_state = Waiting;
648 _slave_state = Running;
650 Location* al = _locations.auto_loop_location();
652 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
654 request_play_loop(false);
657 if (slave_transport_frame != _transport_frame) {
658 locate (slave_transport_frame, false, false);
668 if (_slave_state == Waiting) {
670 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
672 if (slave_transport_frame >= slave_wait_end) {
674 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
676 _slave_state = Running;
678 /* now perform a "micro-seek" within the disk buffers to realign ourselves
679 precisely with the master.
684 nframes_t frame_delta = slave_transport_frame - _transport_frame;
686 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
688 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
689 if (!(*i)->can_internal_playback_seek (frame_delta)) {
696 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
697 (*i)->internal_playback_seek (frame_delta);
699 _transport_frame += frame_delta;
702 cerr << "cannot micro-seek\n";
706 memset (delta_accumulator, 0, sizeof (long) * delta_accumulator_size);
707 average_slave_delta = 0L;
712 if (_slave_state == Running && _transport_speed == 0.0f) {
713 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
717 } else { // slave_speed is 0
719 /* slave has stopped */
721 if (_transport_speed != 0.0f) {
722 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
726 if (slave_transport_frame != _transport_frame) {
727 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
728 force_locate (slave_transport_frame, false);
731 _slave_state = Stopped;
736 Session::follow_slave_silently (nframes_t nframes, float slave_speed)
738 if (slave_speed && _transport_speed) {
740 /* something isn't right, but we should move with the master
746 prepare_diskstreams ();
747 silent_process_routes (nframes);
748 commit_diskstreams (nframes, need_butler);
754 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
756 if (frames_moved < 0) {
757 decrement_transport_position (-frames_moved);
759 increment_transport_position (frames_moved);
762 nframes_t stop_limit;
764 if (actively_recording()) {
765 stop_limit = max_frames;
767 if (Config->get_stop_at_session_end()) {
768 stop_limit = current_end_frame();
770 stop_limit = max_frames;
774 maybe_stop (stop_limit);
779 Session::process_without_events (nframes_t nframes)
781 bool session_needs_butler = false;
782 nframes_t stop_limit;
785 if (!process_can_proceed()) {
790 if (!_exporting && _slave) {
791 if (!follow_slave (nframes)) {
796 if (_transport_speed == 0) {
802 send_midi_time_code_for_cycle (nframes);
805 if (actively_recording()) {
806 stop_limit = max_frames;
808 if (Config->get_stop_at_session_end()) {
809 stop_limit = current_end_frame();
811 stop_limit = max_frames;
815 if (maybe_stop (stop_limit)) {
820 if (maybe_sync_start (nframes)) {
824 click (_transport_frame, nframes);
826 prepare_diskstreams ();
828 if (_transport_speed == 1.0) {
829 frames_moved = (long) nframes;
831 interpolation.set_target_speed (fabs(_target_transport_speed));
832 interpolation.set_speed (fabs(_transport_speed));
833 frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
836 if (process_routes (nframes)) {
841 commit_diskstreams (nframes, session_needs_butler);
843 if (frames_moved < 0) {
844 decrement_transport_position (-frames_moved);
846 increment_transport_position (frames_moved);
849 maybe_stop (stop_limit);
850 check_declick_out ();
852 if (session_needs_butler) {
857 /** Process callback used when the auditioner is active.
858 * @param nframes number of frames to process.
861 Session::process_audition (nframes_t nframes)
864 boost::shared_ptr<RouteList> r = routes.reader ();
866 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
867 if (!(*i)->is_hidden()) {
868 (*i)->silence (nframes);
872 /* run the auditioner, and if it says we need butler service, ask for it */
874 if (auditioner->play_audition (nframes) > 0) {
878 /* handle pending events */
880 while (pending_events.read (&ev, 1) == 1) {
884 /* if we are not in the middle of a state change,
885 and there are immediate events queued up,
889 while (!non_realtime_work_pending() && !immediate_events.empty()) {
890 SessionEvent *ev = immediate_events.front ();
891 immediate_events.pop_front ();
895 if (!auditioner->active()) {
896 /* auditioner no longer active, so go back to the normal process callback */
897 process_function = &Session::process_with_events;
902 Session::maybe_sync_start (nframes_t& nframes)
904 nframes_t sync_offset;
906 if (!waiting_for_sync_offset) {
910 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
912 /* generate silence up to the sync point, then
913 adjust nframes + offset to reflect whatever
917 no_roll (sync_offset);
918 nframes -= sync_offset;
919 Port::increment_port_offset (sync_offset);
920 waiting_for_sync_offset = false;
923 return true; // done, nothing left to process
928 /* sync offset point is not within this process()
929 cycle, so just generate silence. and don't bother
930 with any fancy stuff here, just the minimal silence.
935 if (Config->get_locate_while_waiting_for_sync()) {
936 if (micro_locate (nframes)) {
937 /* XXX ERROR !!! XXX */
941 return true; // done, nothing left to process
948 Session::queue_event (SessionEvent* ev)
950 if (_state_of_the_state & Deletion) {
952 } else if (_state_of_the_state & Loading) {
955 pending_events.write (&ev, 1);
960 Session::set_next_event ()
962 if (events.empty()) {
963 next_event = events.end();
967 if (next_event == events.end()) {
968 next_event = events.begin();
971 if ((*next_event)->action_frame > _transport_frame) {
972 next_event = events.begin();
975 for (; next_event != events.end(); ++next_event) {
976 if ((*next_event)->action_frame >= _transport_frame) {
983 Session::process_event (SessionEvent* ev)
988 /* if we're in the middle of a state change (i.e. waiting
989 for the butler thread to complete the non-realtime
990 part of the change), we'll just have to queue this
991 event for a time when the change is complete.
994 if (non_realtime_work_pending()) {
996 /* except locates, which we have the capability to handle */
998 if (ev->type != SessionEvent::Locate) {
999 immediate_events.insert (immediate_events.end(), ev);
1005 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1008 case SessionEvent::SetLoop:
1009 set_play_loop (ev->yes_or_no);
1012 case SessionEvent::AutoLoop:
1014 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1020 case SessionEvent::Locate:
1021 if (ev->yes_or_no) {
1022 // cerr << "forced locate to " << ev->target_frame << endl;
1023 locate (ev->target_frame, false, true, false);
1025 // cerr << "soft locate to " << ev->target_frame << endl;
1026 start_locate (ev->target_frame, false, true, false);
1028 _send_timecode_update = true;
1031 case SessionEvent::LocateRoll:
1032 if (ev->yes_or_no) {
1033 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1034 locate (ev->target_frame, true, true, false);
1036 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1037 start_locate (ev->target_frame, true, true, false);
1039 _send_timecode_update = true;
1042 case SessionEvent::LocateRollLocate:
1043 // locate is handled by ::request_roll_at_and_return()
1044 _requested_return_frame = ev->target_frame;
1045 request_locate (ev->target2_frame, true);
1049 case SessionEvent::SetTransportSpeed:
1050 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1053 case SessionEvent::PunchIn:
1054 // cerr << "PunchIN at " << transport_frame() << endl;
1055 if (config.get_punch_in() && record_status() == Enabled) {
1062 case SessionEvent::PunchOut:
1063 // cerr << "PunchOUT at " << transport_frame() << endl;
1064 if (config.get_punch_out()) {
1065 step_back_from_record ();
1071 case SessionEvent::StopOnce:
1072 if (!non_realtime_work_pending()) {
1073 stop_transport (ev->yes_or_no);
1074 _clear_event_type (SessionEvent::StopOnce);
1080 case SessionEvent::RangeStop:
1081 if (!non_realtime_work_pending()) {
1082 stop_transport (ev->yes_or_no);
1088 case SessionEvent::RangeLocate:
1089 start_locate (ev->target_frame, true, true, false);
1094 case SessionEvent::Overwrite:
1095 overwrite_some_buffers (static_cast<Diskstream*>(ev->ptr));
1098 case SessionEvent::SetDiskstreamSpeed:
1099 set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed);
1102 case SessionEvent::SetSyncSource:
1103 use_sync_source (ev->slave);
1106 case SessionEvent::Audition:
1107 set_audition (ev->region);
1108 // drop reference to region
1109 ev->region.reset ();
1112 case SessionEvent::InputConfigurationChange:
1113 add_post_transport_work (PostTransportInputChange);
1114 _butler->schedule_transport_work ();
1117 case SessionEvent::SetPlayAudioRange:
1118 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1121 case SessionEvent::RealTimeOperation:
1123 del = false; // other side of RT request needs to clean up
1127 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1133 del = del && !_remove_event (ev);
1142 Session::process_rtop (SessionEvent* ev)