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);
571 //std::cout << "set speed = " << slave_speed << "\n";
573 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
574 request_transport_speed (adjusted_speed);
575 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
576 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
581 if ((nframes_t) abs(average_slave_delta) > _slave->resolution()) {
582 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
590 if (_slave_state == Running && !non_realtime_work_pending()) {
591 /* speed is set, we're locked, and good to go */
596 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
597 follow_slave_silently (nframes, slave_speed);
600 /* don't move at all */
601 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
607 Session::calculate_moving_average_of_slave_delta(int dir, nframes_t this_delta)
609 if (delta_accumulator_cnt >= delta_accumulator_size) {
610 have_first_delta_accumulator = true;
611 delta_accumulator_cnt = 0;
614 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
615 delta_accumulator[delta_accumulator_cnt++] = long(dir) * long(this_delta);
618 if (have_first_delta_accumulator) {
619 average_slave_delta = 0L;
620 for (int i = 0; i < delta_accumulator_size; ++i) {
621 average_slave_delta += delta_accumulator[i];
623 average_slave_delta /= long(delta_accumulator_size);
624 if (average_slave_delta < 0L) {
626 average_slave_delta = abs(average_slave_delta);
634 Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame, nframes_t this_delta)
636 if (slave_speed != 0.0f) {
638 /* slave is running */
640 switch (_slave_state) {
642 if (_slave->requires_seekahead()) {
643 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
644 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
645 /* we can call locate() here because we are in process context */
646 locate (slave_wait_end, false, false);
647 _slave_state = Waiting;
651 _slave_state = Running;
653 Location* al = _locations.auto_loop_location();
655 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
657 request_play_loop(false);
660 if (slave_transport_frame != _transport_frame) {
661 locate (slave_transport_frame, false, false);
671 if (_slave_state == Waiting) {
673 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
675 if (slave_transport_frame >= slave_wait_end) {
677 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
679 _slave_state = Running;
681 /* now perform a "micro-seek" within the disk buffers to realign ourselves
682 precisely with the master.
687 nframes_t frame_delta = slave_transport_frame - _transport_frame;
689 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
691 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
692 if (!(*i)->can_internal_playback_seek (frame_delta)) {
699 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
700 (*i)->internal_playback_seek (frame_delta);
702 _transport_frame += frame_delta;
705 cerr << "cannot micro-seek\n";
709 memset (delta_accumulator, 0, sizeof (long) * delta_accumulator_size);
710 average_slave_delta = 0L;
715 if (_slave_state == Running && _transport_speed == 0.0f) {
716 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
720 } else { // slave_speed is 0
722 /* slave has stopped */
724 if (_transport_speed != 0.0f) {
725 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
729 if (slave_transport_frame != _transport_frame) {
730 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
731 force_locate (slave_transport_frame, false);
734 _slave_state = Stopped;
739 Session::follow_slave_silently (nframes_t nframes, float slave_speed)
741 if (slave_speed && _transport_speed) {
743 /* something isn't right, but we should move with the master
749 prepare_diskstreams ();
750 silent_process_routes (nframes);
751 commit_diskstreams (nframes, need_butler);
757 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
759 if (frames_moved < 0) {
760 decrement_transport_position (-frames_moved);
762 increment_transport_position (frames_moved);
765 nframes_t stop_limit;
767 if (actively_recording()) {
768 stop_limit = max_frames;
770 if (Config->get_stop_at_session_end()) {
771 stop_limit = current_end_frame();
773 stop_limit = max_frames;
777 maybe_stop (stop_limit);
782 Session::process_without_events (nframes_t nframes)
784 bool session_needs_butler = false;
785 nframes_t stop_limit;
788 if (!process_can_proceed()) {
793 if (!_exporting && _slave) {
794 if (!follow_slave (nframes)) {
799 if (_transport_speed == 0) {
805 send_midi_time_code_for_cycle (nframes);
808 if (actively_recording()) {
809 stop_limit = max_frames;
811 if (Config->get_stop_at_session_end()) {
812 stop_limit = current_end_frame();
814 stop_limit = max_frames;
818 if (maybe_stop (stop_limit)) {
823 if (maybe_sync_start (nframes)) {
827 click (_transport_frame, nframes);
829 prepare_diskstreams ();
831 if (_transport_speed == 1.0) {
832 frames_moved = (long) nframes;
834 interpolation.set_target_speed (fabs(_target_transport_speed));
835 interpolation.set_speed (fabs(_transport_speed));
836 frames_moved = (long) interpolation.interpolate (0, nframes, 0, 0);
839 if (process_routes (nframes)) {
844 commit_diskstreams (nframes, session_needs_butler);
846 if (frames_moved < 0) {
847 decrement_transport_position (-frames_moved);
849 increment_transport_position (frames_moved);
852 maybe_stop (stop_limit);
853 check_declick_out ();
855 if (session_needs_butler) {
860 /** Process callback used when the auditioner is active.
861 * @param nframes number of frames to process.
864 Session::process_audition (nframes_t nframes)
867 boost::shared_ptr<RouteList> r = routes.reader ();
869 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
870 if (!(*i)->is_hidden()) {
871 (*i)->silence (nframes);
875 /* run the auditioner, and if it says we need butler service, ask for it */
877 if (auditioner->play_audition (nframes) > 0) {
881 /* if using a monitor section, run it because otherwise we don't hear anything */
883 if (auditioner->needs_monitor()) {
884 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
887 /* handle pending events */
889 while (pending_events.read (&ev, 1) == 1) {
893 /* if we are not in the middle of a state change,
894 and there are immediate events queued up,
898 while (!non_realtime_work_pending() && !immediate_events.empty()) {
899 SessionEvent *ev = immediate_events.front ();
900 immediate_events.pop_front ();
904 if (!auditioner->auditioning()) {
905 /* auditioner no longer active, so go back to the normal process callback */
906 process_function = &Session::process_with_events;
911 Session::maybe_sync_start (nframes_t& nframes)
913 nframes_t sync_offset;
915 if (!waiting_for_sync_offset) {
919 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
921 /* generate silence up to the sync point, then
922 adjust nframes + offset to reflect whatever
926 no_roll (sync_offset);
927 nframes -= sync_offset;
928 Port::increment_port_offset (sync_offset);
929 waiting_for_sync_offset = false;
932 return true; // done, nothing left to process
937 /* sync offset point is not within this process()
938 cycle, so just generate silence. and don't bother
939 with any fancy stuff here, just the minimal silence.
944 if (Config->get_locate_while_waiting_for_sync()) {
945 if (micro_locate (nframes)) {
946 /* XXX ERROR !!! XXX */
950 return true; // done, nothing left to process
957 Session::queue_event (SessionEvent* ev)
959 if (_state_of_the_state & Deletion) {
961 } else if (_state_of_the_state & Loading) {
964 pending_events.write (&ev, 1);
969 Session::set_next_event ()
971 if (events.empty()) {
972 next_event = events.end();
976 if (next_event == events.end()) {
977 next_event = events.begin();
980 if ((*next_event)->action_frame > _transport_frame) {
981 next_event = events.begin();
984 for (; next_event != events.end(); ++next_event) {
985 if ((*next_event)->action_frame >= _transport_frame) {
992 Session::process_event (SessionEvent* ev)
997 /* if we're in the middle of a state change (i.e. waiting
998 for the butler thread to complete the non-realtime
999 part of the change), we'll just have to queue this
1000 event for a time when the change is complete.
1003 if (non_realtime_work_pending()) {
1005 /* except locates, which we have the capability to handle */
1007 if (ev->type != SessionEvent::Locate) {
1008 immediate_events.insert (immediate_events.end(), ev);
1014 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1017 case SessionEvent::SetLoop:
1018 set_play_loop (ev->yes_or_no);
1021 case SessionEvent::AutoLoop:
1023 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1029 case SessionEvent::Locate:
1030 if (ev->yes_or_no) {
1031 // cerr << "forced locate to " << ev->target_frame << endl;
1032 locate (ev->target_frame, false, true, false);
1034 // cerr << "soft locate to " << ev->target_frame << endl;
1035 start_locate (ev->target_frame, false, true, false);
1037 _send_timecode_update = true;
1040 case SessionEvent::LocateRoll:
1041 if (ev->yes_or_no) {
1042 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1043 locate (ev->target_frame, true, true, false);
1045 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1046 start_locate (ev->target_frame, true, true, false);
1048 _send_timecode_update = true;
1051 case SessionEvent::LocateRollLocate:
1052 // locate is handled by ::request_roll_at_and_return()
1053 _requested_return_frame = ev->target_frame;
1054 request_locate (ev->target2_frame, true);
1058 case SessionEvent::SetTransportSpeed:
1059 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1062 case SessionEvent::PunchIn:
1063 // cerr << "PunchIN at " << transport_frame() << endl;
1064 if (config.get_punch_in() && record_status() == Enabled) {
1071 case SessionEvent::PunchOut:
1072 // cerr << "PunchOUT at " << transport_frame() << endl;
1073 if (config.get_punch_out()) {
1074 step_back_from_record ();
1080 case SessionEvent::StopOnce:
1081 if (!non_realtime_work_pending()) {
1082 stop_transport (ev->yes_or_no);
1083 _clear_event_type (SessionEvent::StopOnce);
1089 case SessionEvent::RangeStop:
1090 if (!non_realtime_work_pending()) {
1091 stop_transport (ev->yes_or_no);
1097 case SessionEvent::RangeLocate:
1098 start_locate (ev->target_frame, true, true, false);
1103 case SessionEvent::Overwrite:
1104 overwrite_some_buffers (static_cast<Diskstream*>(ev->ptr));
1107 case SessionEvent::SetDiskstreamSpeed:
1108 set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed);
1111 case SessionEvent::SetSyncSource:
1112 use_sync_source (ev->slave);
1115 case SessionEvent::Audition:
1116 set_audition (ev->region);
1117 // drop reference to region
1118 ev->region.reset ();
1121 case SessionEvent::InputConfigurationChange:
1122 add_post_transport_work (PostTransportInputChange);
1123 _butler->schedule_transport_work ();
1126 case SessionEvent::SetPlayAudioRange:
1127 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1130 case SessionEvent::RealTimeOperation:
1132 del = false; // other side of RT request needs to clean up
1136 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1142 del = del && !_remove_event (ev);