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/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 (nframes_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 ()) {
73 _mmc
->flush_pending ();
76 _engine
.main_thread()->get_buffers ();
78 (this->*process_function
) (nframes
);
80 _engine
.main_thread()->drop_buffers ();
82 // the ticker is for sending time information like MidiClock
83 nframes_t transport_frames
= transport_frame();
84 BBT_Time transport_bbt
;
85 bbt_time(transport_frames
, transport_bbt
);
86 Timecode::Time transport_timecode
;
87 timecode_time(transport_frames
, transport_timecode
);
88 tick (transport_frames
, transport_bbt
, transport_timecode
); /* EMIT SIGNAL */
90 SendFeedback (); /* EMIT SIGNAL */
92 MIDI::Manager::instance()->cycle_end();
96 Session::fail_roll (nframes_t nframes
)
98 return no_roll (nframes
);
102 Session::no_roll (nframes_t nframes
)
104 nframes_t end_frame
= _transport_frame
+ nframes
; // FIXME: varispeed + no_roll ??
106 bool declick
= get_transport_declick_required();
107 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
110 _click_io
->silence (nframes
);
113 route_graph
->routes_no_roll( nframes
, _transport_frame
, end_frame
, non_realtime_work_pending(), actively_recording(), declick
);
115 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
117 if ((*i)->is_hidden()) {
121 (*i)->set_pending_declick (declick);
123 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(),
124 actively_recording(), declick)) {
125 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
136 Session::process_routes (nframes_t nframes
, bool& need_butler
)
139 int declick
= get_transport_declick_required();
140 bool rec_monitors
= get_rec_monitors_input();
141 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
143 if (transport_sub_state
& StopPendingCapture
) {
144 /* force a declick out */
148 record_active
= actively_recording(); // || (get_record_enabled() && get_punch_in());
150 const nframes_t start_frame
= _transport_frame
;
151 const nframes_t end_frame
= _transport_frame
+ (nframes_t
)floor(nframes
* _transport_speed
);
153 route_graph
->process_routes( nframes
, start_frame
, end_frame
, declick
, record_active
, rec_monitors
, need_butler
);
155 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
159 if ((*i)->is_hidden()) {
163 (*i)->set_pending_declick (declick);
165 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, record_active, rec_monitors, need_butler)) < 0) {
175 Session::silent_process_routes (nframes_t nframes
, bool& need_butler
)
177 bool record_active
= actively_recording();
178 int declick
= get_transport_declick_required();
179 bool rec_monitors
= get_rec_monitors_input();
180 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
182 if (transport_sub_state
& StopPendingCapture
) {
183 /* force a declick out */
187 const nframes_t start_frame
= _transport_frame
;
188 const nframes_t end_frame
= _transport_frame
+ lrintf(nframes
* _transport_speed
);
190 route_graph
->silent_process_routes( nframes
, start_frame
, end_frame
, record_active
, rec_monitors
, need_butler
);
192 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
196 if ((*i)->is_hidden()) {
200 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, record_active, rec_monitors, need_butler)) < 0) {
210 Session::get_track_statistics ()
215 boost::shared_ptr
<RouteList
> rl
= routes
.reader();
216 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
218 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
220 if (!tr
|| tr
->hidden()) {
224 pworst
= min (pworst
, tr
->playback_buffer_load());
225 cworst
= min (cworst
, tr
->capture_buffer_load());
228 g_atomic_int_set (&_playback_load
, (uint32_t) floor (pworst
* 100.0f
));
229 g_atomic_int_set (&_capture_load
, (uint32_t) floor (cworst
* 100.0f
));
231 if (actively_recording()) {
236 /** Process callback used when the auditioner is not active */
238 Session::process_with_events (nframes_t nframes
)
241 nframes_t this_nframes
;
243 bool session_needs_butler
= false;
244 nframes_t stop_limit
;
247 /* make sure the auditioner is silent */
250 auditioner
->silence (nframes
);
253 /* handle any pending events */
255 while (pending_events
.read (&ev
, 1) == 1) {
259 /* if we are not in the middle of a state change,
260 and there are immediate events queued up,
264 while (!non_realtime_work_pending() && !immediate_events
.empty()) {
265 SessionEvent
*ev
= immediate_events
.front ();
266 immediate_events
.pop_front ();
270 /* Events caused a transport change, send an MTC Full Frame (Timecode) message.
271 * This is sent whether rolling or not, to give slaves an idea of ardour time
272 * on locates (and allow slow slaves to position and prepare for rolling)
274 if (_send_timecode_update
) {
275 send_full_time_code(nframes
);
278 if (!process_can_proceed()) {
283 if (events
.empty() || next_event
== events
.end()) {
284 process_without_events (nframes
);
288 if (_transport_speed
== 1.0) {
289 frames_moved
= (long) nframes
;
291 interpolation
.set_target_speed (fabs(_target_transport_speed
));
292 interpolation
.set_speed (fabs(_transport_speed
));
293 frames_moved
= (long) interpolation
.interpolate (0, nframes
, 0, 0);
296 end_frame
= _transport_frame
+ (nframes_t
)frames_moved
;
299 SessionEvent
* this_event
;
300 Events::iterator the_next_one
;
302 if (!process_can_proceed()) {
307 if (!_exporting
&& _slave
) {
308 if (!follow_slave (nframes
)) {
313 if (_transport_speed
== 0) {
319 send_midi_time_code_for_cycle (nframes
);
322 if (actively_recording()) {
323 stop_limit
= max_frames
;
326 if (Config
->get_stop_at_session_end()) {
327 stop_limit
= current_end_frame();
329 stop_limit
= max_frames
;
333 if (maybe_stop (stop_limit
)) {
338 this_event
= *next_event
;
339 the_next_one
= next_event
;
342 /* yes folks, here it is, the actual loop where we really truly
348 this_nframes
= nframes
; /* real (jack) time relative */
349 frames_moved
= (long) floor (_transport_speed
* nframes
); /* transport relative */
351 /* running an event, position transport precisely to its time */
352 if (this_event
&& this_event
->action_frame
<= end_frame
&& this_event
->action_frame
>= _transport_frame
) {
353 /* this isn't quite right for reverse play */
354 frames_moved
= (long) (this_event
->action_frame
- _transport_frame
);
355 this_nframes
= (nframes_t
) abs( floor(frames_moved
/ _transport_speed
) );
360 click (_transport_frame
, this_nframes
);
362 if (process_routes (this_nframes
, session_needs_butler
)) {
367 get_track_statistics ();
369 nframes
-= this_nframes
;
371 if (frames_moved
< 0) {
372 decrement_transport_position (-frames_moved
);
374 increment_transport_position (frames_moved
);
377 maybe_stop (stop_limit
);
378 check_declick_out ();
381 _engine
.split_cycle (this_nframes
);
383 /* now handle this event and all others scheduled for the same time */
385 while (this_event
&& this_event
->action_frame
== _transport_frame
) {
386 process_event (this_event
);
388 if (the_next_one
== events
.end()) {
391 this_event
= *the_next_one
;
396 /* if an event left our state changing, do the right thing */
398 if (nframes
&& non_realtime_work_pending()) {
403 /* this is necessary to handle the case of seamless looping */
404 end_frame
= _transport_frame
+ (nframes_t
) floor (nframes
* _transport_speed
);
410 } /* implicit release of route lock */
412 if (session_needs_butler
) {
418 Session::reset_slave_state ()
420 average_slave_delta
= 1800;
421 delta_accumulator_cnt
= 0;
422 have_first_delta_accumulator
= false;
423 _slave_state
= Stopped
;
427 Session::transport_locked () const
431 if (!locate_pending() && (!config
.get_external_sync() || (sl
&& sl
->ok() && sl
->locked()))) {
439 Session::follow_slave (nframes_t nframes
)
442 nframes64_t slave_transport_frame
;
443 nframes_t this_delta
;
448 config
.set_external_sync (false);
452 _slave
->speed_and_position (slave_speed
, slave_transport_frame
);
454 DEBUG_TRACE (DEBUG::Slave
, string_compose ("Slave position %1 speed %2\n", slave_transport_frame
, slave_speed
));
456 if (!_slave
->locked()) {
457 DEBUG_TRACE (DEBUG::Slave
, "slave not locked\n");
461 if (slave_transport_frame
> _transport_frame
) {
462 this_delta
= slave_transport_frame
- _transport_frame
;
465 this_delta
= _transport_frame
- slave_transport_frame
;
469 if (_slave
->starting()) {
473 if (_slave
->is_always_synced() || config
.get_timecode_source_is_synced()) {
475 /* if the TC source is synced, then we assume that its
476 speed is binary: 0.0 or 1.0
479 if (slave_speed
!= 0.0f
) {
485 /* if we are chasing and the average delta between us and the
486 master gets too big, we want to switch to silent
487 motion. so keep track of that here.
490 if (_slave_state
== Running
) {
491 calculate_moving_average_of_slave_delta(dir
, this_delta
);
495 track_slave_state (slave_speed
, slave_transport_frame
, this_delta
);
497 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
498 _slave_state
, slave_transport_frame
, slave_speed
, this_delta
, average_slave_delta
));
501 if (_slave_state
== Running
&& !_slave
->is_always_synced() && !config
.get_timecode_source_is_synced()) {
503 if (_transport_speed
!= 0.0f
) {
506 note that average_dir is +1 or -1
511 if (average_slave_delta
== 0) {
515 delta
= average_slave_delta
;
516 delta
*= average_dir
;
520 if (slave_speed
!= 0.0) {
521 DEBUG_TRACE (DEBUG::Slave
, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
522 (int) (dir
* this_delta
),
526 slave_transport_frame
,
527 average_slave_delta
));
531 if (_slave
->give_slave_full_control_over_transport_speed()) {
532 set_transport_speed (slave_speed
, false, false);
533 //std::cout << "set speed = " << slave_speed << "\n";
535 float adjusted_speed
= slave_speed
+ (1.5 * (delta
/ float(_current_frame_rate
)));
536 request_transport_speed (adjusted_speed
);
537 DEBUG_TRACE (DEBUG::Slave
, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
538 delta
, adjusted_speed
, adjusted_speed
/slave_speed
, _transport_speed
,
543 if ((nframes_t
) abs(average_slave_delta
) > _slave
->resolution()) {
544 cerr
<< "average slave delta greater than slave resolution (" << _slave
->resolution() << "), going to silent motion\n";
552 if (_slave_state
== Running
&& !non_realtime_work_pending()) {
553 /* speed is set, we're locked, and good to go */
558 DEBUG_TRACE (DEBUG::Slave
, "silent motion\n")
559 follow_slave_silently (nframes
, slave_speed
);
562 /* don't move at all */
563 DEBUG_TRACE (DEBUG::Slave
, "no roll\n")
569 Session::calculate_moving_average_of_slave_delta(int dir
, nframes_t this_delta
)
571 if (delta_accumulator_cnt
>= delta_accumulator_size
) {
572 have_first_delta_accumulator
= true;
573 delta_accumulator_cnt
= 0;
576 if (delta_accumulator_cnt
!= 0 || this_delta
< _current_frame_rate
) {
577 delta_accumulator
[delta_accumulator_cnt
++] = long(dir
) * long(this_delta
);
580 if (have_first_delta_accumulator
) {
581 average_slave_delta
= 0L;
582 for (int i
= 0; i
< delta_accumulator_size
; ++i
) {
583 average_slave_delta
+= delta_accumulator
[i
];
585 average_slave_delta
/= long(delta_accumulator_size
);
586 if (average_slave_delta
< 0L) {
588 average_slave_delta
= abs(average_slave_delta
);
596 Session::track_slave_state (float slave_speed
, nframes_t slave_transport_frame
, nframes_t this_delta
)
598 if (slave_speed
!= 0.0f
) {
600 /* slave is running */
602 switch (_slave_state
) {
604 if (_slave
->requires_seekahead()) {
605 slave_wait_end
= slave_transport_frame
+ _slave
->seekahead_distance ();
606 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end
));
607 /* we can call locate() here because we are in process context */
608 locate (slave_wait_end
, false, false);
609 _slave_state
= Waiting
;
613 _slave_state
= Running
;
615 Location
* al
= _locations
.auto_loop_location();
617 if (al
&& play_loop
&& (slave_transport_frame
< al
->start() || slave_transport_frame
> al
->end())) {
619 request_play_loop(false);
622 if (slave_transport_frame
!= _transport_frame
) {
623 locate (slave_transport_frame
, false, false);
633 if (_slave_state
== Waiting
) {
635 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave waiting at %1\n", slave_transport_frame
));
637 if (slave_transport_frame
>= slave_wait_end
) {
639 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave start at %1 vs %2\n", slave_transport_frame
, _transport_frame
));
641 _slave_state
= Running
;
643 /* now perform a "micro-seek" within the disk buffers to realign ourselves
644 precisely with the master.
649 nframes_t frame_delta
= slave_transport_frame
- _transport_frame
;
651 boost::shared_ptr
<RouteList
> rl
= routes
.reader();
652 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
653 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
654 if (tr
&& !tr
->can_internal_playback_seek (frame_delta
)) {
661 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
662 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
664 tr
->internal_playback_seek (frame_delta
);
667 _transport_frame
+= frame_delta
;
670 cerr
<< "cannot micro-seek\n";
674 memset (delta_accumulator
, 0, sizeof (long) * delta_accumulator_size
);
675 average_slave_delta
= 0L;
680 if (_slave_state
== Running
&& _transport_speed
== 0.0f
) {
681 DEBUG_TRACE (DEBUG::Slave
, "slave starts transport\n");
685 } else { // slave_speed is 0
687 /* slave has stopped */
689 if (_transport_speed
!= 0.0f
) {
690 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed
, slave_transport_frame
, _transport_frame
));
694 if (slave_transport_frame
!= _transport_frame
) {
695 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave stopped, move to %1\n", slave_transport_frame
));
696 force_locate (slave_transport_frame
, false);
699 _slave_state
= Stopped
;
704 Session::follow_slave_silently (nframes_t nframes
, float slave_speed
)
706 if (slave_speed
&& _transport_speed
) {
708 /* something isn't right, but we should move with the master
714 silent_process_routes (nframes
, need_butler
);
716 get_track_statistics ();
722 int32_t frames_moved
= (int32_t) floor (_transport_speed
* nframes
);
724 if (frames_moved
< 0) {
725 decrement_transport_position (-frames_moved
);
727 increment_transport_position (frames_moved
);
730 nframes_t stop_limit
;
732 if (actively_recording()) {
733 stop_limit
= max_frames
;
735 if (Config
->get_stop_at_session_end()) {
736 stop_limit
= current_end_frame();
738 stop_limit
= max_frames
;
742 maybe_stop (stop_limit
);
747 Session::process_without_events (nframes_t nframes
)
749 bool session_needs_butler
= false;
750 nframes_t stop_limit
;
753 if (!process_can_proceed()) {
758 if (!_exporting
&& _slave
) {
759 if (!follow_slave (nframes
)) {
764 if (_transport_speed
== 0) {
770 send_midi_time_code_for_cycle (nframes
);
773 if (actively_recording()) {
774 stop_limit
= max_frames
;
776 if (Config
->get_stop_at_session_end()) {
777 stop_limit
= current_end_frame();
779 stop_limit
= max_frames
;
783 if (maybe_stop (stop_limit
)) {
788 if (maybe_sync_start (nframes
)) {
792 click (_transport_frame
, nframes
);
794 if (_transport_speed
== 1.0) {
795 frames_moved
= (long) nframes
;
797 interpolation
.set_target_speed (fabs(_target_transport_speed
));
798 interpolation
.set_speed (fabs(_transport_speed
));
799 frames_moved
= (long) interpolation
.interpolate (0, nframes
, 0, 0);
802 if (process_routes (nframes
, session_needs_butler
)) {
807 get_track_statistics ();
809 if (frames_moved
< 0) {
810 decrement_transport_position (-frames_moved
);
812 increment_transport_position (frames_moved
);
815 maybe_stop (stop_limit
);
816 check_declick_out ();
818 if (session_needs_butler
) {
823 /** Process callback used when the auditioner is active.
824 * @param nframes number of frames to process.
827 Session::process_audition (nframes_t nframes
)
830 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
832 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
833 if (!(*i
)->is_hidden()) {
834 (*i
)->silence (nframes
);
838 /* run the auditioner, and if it says we need butler service, ask for it */
840 if (auditioner
->play_audition (nframes
) > 0) {
844 /* if using a monitor section, run it because otherwise we don't hear anything */
846 if (auditioner
->needs_monitor()) {
847 _monitor_out
->passthru (_transport_frame
, _transport_frame
+ nframes
, nframes
, false);
850 /* handle pending events */
852 while (pending_events
.read (&ev
, 1) == 1) {
856 /* if we are not in the middle of a state change,
857 and there are immediate events queued up,
861 while (!non_realtime_work_pending() && !immediate_events
.empty()) {
862 SessionEvent
*ev
= immediate_events
.front ();
863 immediate_events
.pop_front ();
867 if (!auditioner
->auditioning()) {
868 /* auditioner no longer active, so go back to the normal process callback */
869 process_function
= &Session::process_with_events
;
874 Session::maybe_sync_start (nframes_t
& nframes
)
876 nframes_t sync_offset
;
878 if (!waiting_for_sync_offset
) {
882 if (_engine
.get_sync_offset (sync_offset
) && sync_offset
< nframes
) {
884 /* generate silence up to the sync point, then
885 adjust nframes + offset to reflect whatever
889 no_roll (sync_offset
);
890 nframes
-= sync_offset
;
891 Port::increment_port_offset (sync_offset
);
892 waiting_for_sync_offset
= false;
895 return true; // done, nothing left to process
900 /* sync offset point is not within this process()
901 cycle, so just generate silence. and don't bother
902 with any fancy stuff here, just the minimal silence.
907 if (Config
->get_locate_while_waiting_for_sync()) {
908 if (micro_locate (nframes
)) {
909 /* XXX ERROR !!! XXX */
913 return true; // done, nothing left to process
920 Session::queue_event (SessionEvent
* ev
)
922 if (_state_of_the_state
& Deletion
) {
924 } else if (_state_of_the_state
& Loading
) {
927 pending_events
.write (&ev
, 1);
932 Session::set_next_event ()
934 if (events
.empty()) {
935 next_event
= events
.end();
939 if (next_event
== events
.end()) {
940 next_event
= events
.begin();
943 if ((*next_event
)->action_frame
> _transport_frame
) {
944 next_event
= events
.begin();
947 for (; next_event
!= events
.end(); ++next_event
) {
948 if ((*next_event
)->action_frame
>= _transport_frame
) {
955 Session::process_event (SessionEvent
* ev
)
960 /* if we're in the middle of a state change (i.e. waiting
961 for the butler thread to complete the non-realtime
962 part of the change), we'll just have to queue this
963 event for a time when the change is complete.
966 if (non_realtime_work_pending()) {
968 /* except locates, which we have the capability to handle */
970 if (ev
->type
!= SessionEvent::Locate
) {
971 immediate_events
.insert (immediate_events
.end(), ev
);
977 DEBUG_TRACE (DEBUG::SessionEvents
, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev
->type
), _transport_frame
));
980 case SessionEvent::SetLoop
:
981 set_play_loop (ev
->yes_or_no
);
984 case SessionEvent::AutoLoop
:
986 start_locate (ev
->target_frame
, true, false, Config
->get_seamless_loop());
992 case SessionEvent::Locate
:
994 // cerr << "forced locate to " << ev->target_frame << endl;
995 locate (ev
->target_frame
, false, true, false);
997 // cerr << "soft locate to " << ev->target_frame << endl;
998 start_locate (ev
->target_frame
, false, true, false);
1000 _send_timecode_update
= true;
1003 case SessionEvent::LocateRoll
:
1004 if (ev
->yes_or_no
) {
1005 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1006 locate (ev
->target_frame
, true, true, false);
1008 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1009 start_locate (ev
->target_frame
, true, true, false);
1011 _send_timecode_update
= true;
1014 case SessionEvent::LocateRollLocate
:
1015 // locate is handled by ::request_roll_at_and_return()
1016 _requested_return_frame
= ev
->target_frame
;
1017 request_locate (ev
->target2_frame
, true);
1021 case SessionEvent::SetTransportSpeed
:
1022 set_transport_speed (ev
->speed
, ev
->yes_or_no
, ev
->second_yes_or_no
);
1025 case SessionEvent::PunchIn
:
1026 // cerr << "PunchIN at " << transport_frame() << endl;
1027 if (config
.get_punch_in() && record_status() == Enabled
) {
1034 case SessionEvent::PunchOut
:
1035 // cerr << "PunchOUT at " << transport_frame() << endl;
1036 if (config
.get_punch_out()) {
1037 step_back_from_record ();
1043 case SessionEvent::StopOnce
:
1044 if (!non_realtime_work_pending()) {
1045 stop_transport (ev
->yes_or_no
);
1046 _clear_event_type (SessionEvent::StopOnce
);
1052 case SessionEvent::RangeStop
:
1053 if (!non_realtime_work_pending()) {
1054 stop_transport (ev
->yes_or_no
);
1060 case SessionEvent::RangeLocate
:
1061 start_locate (ev
->target_frame
, true, true, false);
1066 case SessionEvent::Overwrite
:
1067 overwrite_some_buffers (static_cast<Track
*>(ev
->ptr
));
1070 case SessionEvent::SetTrackSpeed
:
1071 set_track_speed (static_cast<Track
*> (ev
->ptr
), ev
->speed
);
1074 case SessionEvent::SetSyncSource
:
1075 use_sync_source (ev
->slave
);
1078 case SessionEvent::Audition
:
1079 set_audition (ev
->region
);
1080 // drop reference to region
1081 ev
->region
.reset ();
1084 case SessionEvent::InputConfigurationChange
:
1085 add_post_transport_work (PostTransportInputChange
);
1086 _butler
->schedule_transport_work ();
1089 case SessionEvent::SetPlayAudioRange
:
1090 set_play_range (ev
->audio_range
, (ev
->speed
== 1.0f
));
1093 case SessionEvent::RealTimeOperation
:
1095 del
= false; // other side of RT request needs to clean up
1098 case SessionEvent::AdjustPlaybackBuffering
:
1099 schedule_playback_buffering_adjustment ();
1102 case SessionEvent::AdjustCaptureBuffering
:
1103 schedule_capture_buffering_adjustment ();
1107 fatal
<< string_compose(_("Programming error: illegal event type in process_event (%1)"), ev
->type
) << endmsg
;
1113 del
= del
&& !_remove_event (ev
);