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/port.h"
41 #include "midi++/manager.h"
45 using namespace ARDOUR
;
49 /** Called by the audio engine when there is work to be done with JACK.
50 * @param nframes Number of frames to process.
53 Session::process (nframes_t nframes
)
55 MIDI::Manager::instance()->cycle_start(nframes
);
59 if (processing_blocked()) {
64 if (non_realtime_work_pending()) {
65 if (!_butler
->transport_work_requested ()) {
70 _engine
.main_thread()->get_buffers ();
72 (this->*process_function
) (nframes
);
74 _engine
.main_thread()->drop_buffers ();
76 // the ticker is for sending time information like MidiClock
77 nframes_t transport_frames
= transport_frame();
78 BBT_Time transport_bbt
;
79 bbt_time(transport_frames
, transport_bbt
);
80 Timecode::Time transport_timecode
;
81 timecode_time(transport_frames
, transport_timecode
);
82 tick (transport_frames
, transport_bbt
, transport_timecode
); /* EMIT SIGNAL */
84 SendFeedback (); /* EMIT SIGNAL */
86 MIDI::Manager::instance()->cycle_end();
90 Session::fail_roll (nframes_t nframes
)
92 return no_roll (nframes
);
96 Session::no_roll (nframes_t nframes
)
98 nframes_t end_frame
= _transport_frame
+ nframes
; // FIXME: varispeed + no_roll ??
100 bool declick
= get_transport_declick_required();
101 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
104 _click_io
->silence (nframes
);
107 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
109 if ((*i
)->is_hidden()) {
113 (*i
)->set_pending_declick (declick
);
115 if ((*i
)->no_roll (nframes
, _transport_frame
, end_frame
, non_realtime_work_pending(),
116 actively_recording(), declick
)) {
117 error
<< string_compose(_("Session: error in no roll for %1"), (*i
)->name()) << endmsg
;
127 Session::process_routes (nframes_t nframes
, bool& need_butler
)
130 int declick
= get_transport_declick_required();
131 bool rec_monitors
= get_rec_monitors_input();
132 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
134 if (transport_sub_state
& StopPendingCapture
) {
135 /* force a declick out */
139 record_active
= actively_recording(); // || (get_record_enabled() && get_punch_in());
141 const nframes_t start_frame
= _transport_frame
;
142 const nframes_t end_frame
= _transport_frame
+ (nframes_t
)floor(nframes
* _transport_speed
);
144 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
148 if ((*i
)->is_hidden()) {
152 (*i
)->set_pending_declick (declick
);
154 if ((ret
= (*i
)->roll (nframes
, start_frame
, end_frame
, declick
, record_active
, rec_monitors
, need_butler
)) < 0) {
164 Session::silent_process_routes (nframes_t nframes
, bool& need_butler
)
166 bool record_active
= actively_recording();
167 int declick
= get_transport_declick_required();
168 bool rec_monitors
= get_rec_monitors_input();
169 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
171 if (transport_sub_state
& StopPendingCapture
) {
172 /* force a declick out */
176 const nframes_t start_frame
= _transport_frame
;
177 const nframes_t end_frame
= _transport_frame
+ lrintf(nframes
* _transport_speed
);
179 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
183 if ((*i
)->is_hidden()) {
187 if ((ret
= (*i
)->silent_roll (nframes
, start_frame
, end_frame
, record_active
, rec_monitors
, need_butler
)) < 0) {
197 Session::get_track_statistics ()
202 boost::shared_ptr
<RouteList
> rl
= routes
.reader();
203 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
205 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
207 if (!tr
|| tr
->hidden()) {
211 pworst
= min (pworst
, tr
->playback_buffer_load());
212 cworst
= min (cworst
, tr
->capture_buffer_load());
215 g_atomic_int_set (&_playback_load
, (uint32_t) floor (pworst
* 100.0f
));
216 g_atomic_int_set (&_capture_load
, (uint32_t) floor (cworst
* 100.0f
));
218 if (actively_recording()) {
223 /** Process callback used when the auditioner is not active */
225 Session::process_with_events (nframes_t nframes
)
228 nframes_t this_nframes
;
230 bool session_needs_butler
= false;
231 nframes_t stop_limit
;
234 /* make sure the auditioner is silent */
237 auditioner
->silence (nframes
);
240 /* handle any pending events */
242 while (pending_events
.read (&ev
, 1) == 1) {
246 /* if we are not in the middle of a state change,
247 and there are immediate events queued up,
251 while (!non_realtime_work_pending() && !immediate_events
.empty()) {
252 SessionEvent
*ev
= immediate_events
.front ();
253 immediate_events
.pop_front ();
257 /* Events caused a transport change, send an MTC Full Frame (Timecode) message.
258 * This is sent whether rolling or not, to give slaves an idea of ardour time
259 * on locates (and allow slow slaves to position and prepare for rolling)
261 if (_send_timecode_update
) {
262 send_full_time_code(nframes
);
263 deliver_mmc (MIDI::MachineControl::cmdLocate
, _transport_frame
);
266 if (!process_can_proceed()) {
271 if (events
.empty() || next_event
== events
.end()) {
272 process_without_events (nframes
);
276 if (_transport_speed
== 1.0) {
277 frames_moved
= (long) nframes
;
279 interpolation
.set_target_speed (fabs(_target_transport_speed
));
280 interpolation
.set_speed (fabs(_transport_speed
));
281 frames_moved
= (long) interpolation
.interpolate (0, nframes
, 0, 0);
284 end_frame
= _transport_frame
+ (nframes_t
)frames_moved
;
287 SessionEvent
* this_event
;
288 Events::iterator the_next_one
;
290 if (!process_can_proceed()) {
295 if (!_exporting
&& _slave
) {
296 if (!follow_slave (nframes
)) {
301 if (_transport_speed
== 0) {
307 send_midi_time_code_for_cycle (nframes
);
310 if (actively_recording()) {
311 stop_limit
= max_frames
;
314 if (Config
->get_stop_at_session_end()) {
315 stop_limit
= current_end_frame();
317 stop_limit
= max_frames
;
321 if (maybe_stop (stop_limit
)) {
326 this_event
= *next_event
;
327 the_next_one
= next_event
;
330 /* yes folks, here it is, the actual loop where we really truly
336 this_nframes
= nframes
; /* real (jack) time relative */
337 frames_moved
= (long) floor (_transport_speed
* nframes
); /* transport relative */
339 /* running an event, position transport precisely to its time */
340 if (this_event
&& this_event
->action_frame
<= end_frame
&& this_event
->action_frame
>= _transport_frame
) {
341 /* this isn't quite right for reverse play */
342 frames_moved
= (long) (this_event
->action_frame
- _transport_frame
);
343 this_nframes
= (nframes_t
) abs( floor(frames_moved
/ _transport_speed
) );
348 click (_transport_frame
, this_nframes
);
350 if (process_routes (this_nframes
, session_needs_butler
)) {
355 get_track_statistics ();
357 nframes
-= this_nframes
;
359 if (frames_moved
< 0) {
360 decrement_transport_position (-frames_moved
);
362 increment_transport_position (frames_moved
);
365 maybe_stop (stop_limit
);
366 check_declick_out ();
369 _engine
.split_cycle (this_nframes
);
371 /* now handle this event and all others scheduled for the same time */
373 while (this_event
&& this_event
->action_frame
== _transport_frame
) {
374 process_event (this_event
);
376 if (the_next_one
== events
.end()) {
379 this_event
= *the_next_one
;
384 /* if an event left our state changing, do the right thing */
386 if (nframes
&& non_realtime_work_pending()) {
391 /* this is necessary to handle the case of seamless looping */
392 end_frame
= _transport_frame
+ (nframes_t
) floor (nframes
* _transport_speed
);
398 } /* implicit release of route lock */
400 if (session_needs_butler
) {
406 Session::reset_slave_state ()
408 average_slave_delta
= 1800;
409 delta_accumulator_cnt
= 0;
410 have_first_delta_accumulator
= false;
411 _slave_state
= Stopped
;
415 Session::transport_locked () const
419 if (!locate_pending() && (!config
.get_external_sync() || (sl
&& sl
->ok() && sl
->locked()))) {
427 Session::follow_slave (nframes_t nframes
)
430 nframes64_t slave_transport_frame
;
431 nframes_t this_delta
;
436 config
.set_external_sync (false);
440 _slave
->speed_and_position (slave_speed
, slave_transport_frame
);
442 DEBUG_TRACE (DEBUG::Slave
, string_compose ("Slave position %1 speed %2\n", slave_transport_frame
, slave_speed
));
444 if (!_slave
->locked()) {
445 DEBUG_TRACE (DEBUG::Slave
, "slave not locked\n");
449 if (slave_transport_frame
> _transport_frame
) {
450 this_delta
= slave_transport_frame
- _transport_frame
;
453 this_delta
= _transport_frame
- slave_transport_frame
;
457 if (_slave
->starting()) {
461 if (_slave
->is_always_synced() || config
.get_timecode_source_is_synced()) {
463 /* if the TC source is synced, then we assume that its
464 speed is binary: 0.0 or 1.0
467 if (slave_speed
!= 0.0f
) {
473 /* if we are chasing and the average delta between us and the
474 master gets too big, we want to switch to silent
475 motion. so keep track of that here.
478 if (_slave_state
== Running
) {
479 calculate_moving_average_of_slave_delta(dir
, this_delta
);
483 track_slave_state (slave_speed
, slave_transport_frame
, this_delta
);
485 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
486 _slave_state
, slave_transport_frame
, slave_speed
, this_delta
, average_slave_delta
));
489 if (_slave_state
== Running
&& !_slave
->is_always_synced() && !config
.get_timecode_source_is_synced()) {
491 if (_transport_speed
!= 0.0f
) {
494 note that average_dir is +1 or -1
499 if (average_slave_delta
== 0) {
503 delta
= average_slave_delta
;
504 delta
*= average_dir
;
508 if (slave_speed
!= 0.0) {
509 DEBUG_TRACE (DEBUG::Slave
, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
510 (int) (dir
* this_delta
),
514 slave_transport_frame
,
515 average_slave_delta
));
519 if (_slave
->give_slave_full_control_over_transport_speed()) {
520 set_transport_speed (slave_speed
, false, false);
521 //std::cout << "set speed = " << slave_speed << "\n";
523 float adjusted_speed
= slave_speed
+ (1.5 * (delta
/ float(_current_frame_rate
)));
524 request_transport_speed (adjusted_speed
);
525 DEBUG_TRACE (DEBUG::Slave
, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
526 delta
, adjusted_speed
, adjusted_speed
/slave_speed
, _transport_speed
,
531 if ((nframes_t
) abs(average_slave_delta
) > _slave
->resolution()) {
532 cerr
<< "average slave delta greater than slave resolution (" << _slave
->resolution() << "), going to silent motion\n";
540 if (_slave_state
== Running
&& !non_realtime_work_pending()) {
541 /* speed is set, we're locked, and good to go */
546 DEBUG_TRACE (DEBUG::Slave
, "silent motion\n")
547 follow_slave_silently (nframes
, slave_speed
);
550 /* don't move at all */
551 DEBUG_TRACE (DEBUG::Slave
, "no roll\n")
557 Session::calculate_moving_average_of_slave_delta(int dir
, nframes_t this_delta
)
559 if (delta_accumulator_cnt
>= delta_accumulator_size
) {
560 have_first_delta_accumulator
= true;
561 delta_accumulator_cnt
= 0;
564 if (delta_accumulator_cnt
!= 0 || this_delta
< _current_frame_rate
) {
565 delta_accumulator
[delta_accumulator_cnt
++] = long(dir
) * long(this_delta
);
568 if (have_first_delta_accumulator
) {
569 average_slave_delta
= 0L;
570 for (int i
= 0; i
< delta_accumulator_size
; ++i
) {
571 average_slave_delta
+= delta_accumulator
[i
];
573 average_slave_delta
/= long(delta_accumulator_size
);
574 if (average_slave_delta
< 0L) {
576 average_slave_delta
= abs(average_slave_delta
);
584 Session::track_slave_state (float slave_speed
, nframes_t slave_transport_frame
, nframes_t this_delta
)
586 if (slave_speed
!= 0.0f
) {
588 /* slave is running */
590 switch (_slave_state
) {
592 if (_slave
->requires_seekahead()) {
593 slave_wait_end
= slave_transport_frame
+ _slave
->seekahead_distance ();
594 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end
));
595 /* we can call locate() here because we are in process context */
596 locate (slave_wait_end
, false, false);
597 _slave_state
= Waiting
;
601 _slave_state
= Running
;
603 Location
* al
= _locations
.auto_loop_location();
605 if (al
&& play_loop
&& (slave_transport_frame
< al
->start() || slave_transport_frame
> al
->end())) {
607 request_play_loop(false);
610 if (slave_transport_frame
!= _transport_frame
) {
611 locate (slave_transport_frame
, false, false);
621 if (_slave_state
== Waiting
) {
623 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave waiting at %1\n", slave_transport_frame
));
625 if (slave_transport_frame
>= slave_wait_end
) {
627 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave start at %1 vs %2\n", slave_transport_frame
, _transport_frame
));
629 _slave_state
= Running
;
631 /* now perform a "micro-seek" within the disk buffers to realign ourselves
632 precisely with the master.
637 nframes_t frame_delta
= slave_transport_frame
- _transport_frame
;
639 boost::shared_ptr
<RouteList
> rl
= routes
.reader();
640 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
641 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
642 if (tr
&& !tr
->can_internal_playback_seek (frame_delta
)) {
649 for (RouteList::iterator i
= rl
->begin(); i
!= rl
->end(); ++i
) {
650 boost::shared_ptr
<Track
> tr
= boost::dynamic_pointer_cast
<Track
> (*i
);
652 tr
->internal_playback_seek (frame_delta
);
655 _transport_frame
+= frame_delta
;
658 cerr
<< "cannot micro-seek\n";
662 memset (delta_accumulator
, 0, sizeof (long) * delta_accumulator_size
);
663 average_slave_delta
= 0L;
668 if (_slave_state
== Running
&& _transport_speed
== 0.0f
) {
669 DEBUG_TRACE (DEBUG::Slave
, "slave starts transport\n");
673 } else { // slave_speed is 0
675 /* slave has stopped */
677 if (_transport_speed
!= 0.0f
) {
678 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed
, slave_transport_frame
, _transport_frame
));
682 if (slave_transport_frame
!= _transport_frame
) {
683 DEBUG_TRACE (DEBUG::Slave
, string_compose ("slave stopped, move to %1\n", slave_transport_frame
));
684 force_locate (slave_transport_frame
, false);
687 _slave_state
= Stopped
;
692 Session::follow_slave_silently (nframes_t nframes
, float slave_speed
)
694 if (slave_speed
&& _transport_speed
) {
696 /* something isn't right, but we should move with the master
702 silent_process_routes (nframes
, need_butler
);
704 get_track_statistics ();
710 int32_t frames_moved
= (int32_t) floor (_transport_speed
* nframes
);
712 if (frames_moved
< 0) {
713 decrement_transport_position (-frames_moved
);
715 increment_transport_position (frames_moved
);
718 nframes_t stop_limit
;
720 if (actively_recording()) {
721 stop_limit
= max_frames
;
723 if (Config
->get_stop_at_session_end()) {
724 stop_limit
= current_end_frame();
726 stop_limit
= max_frames
;
730 maybe_stop (stop_limit
);
735 Session::process_without_events (nframes_t nframes
)
737 bool session_needs_butler
= false;
738 nframes_t stop_limit
;
741 if (!process_can_proceed()) {
746 if (!_exporting
&& _slave
) {
747 if (!follow_slave (nframes
)) {
752 if (_transport_speed
== 0) {
758 send_midi_time_code_for_cycle (nframes
);
761 if (actively_recording()) {
762 stop_limit
= max_frames
;
764 if (Config
->get_stop_at_session_end()) {
765 stop_limit
= current_end_frame();
767 stop_limit
= max_frames
;
771 if (maybe_stop (stop_limit
)) {
776 if (maybe_sync_start (nframes
)) {
780 click (_transport_frame
, nframes
);
782 if (_transport_speed
== 1.0) {
783 frames_moved
= (long) nframes
;
785 interpolation
.set_target_speed (fabs(_target_transport_speed
));
786 interpolation
.set_speed (fabs(_transport_speed
));
787 frames_moved
= (long) interpolation
.interpolate (0, nframes
, 0, 0);
790 if (process_routes (nframes
, session_needs_butler
)) {
795 get_track_statistics ();
797 if (frames_moved
< 0) {
798 decrement_transport_position (-frames_moved
);
800 increment_transport_position (frames_moved
);
803 maybe_stop (stop_limit
);
804 check_declick_out ();
806 if (session_needs_butler
) {
811 /** Process callback used when the auditioner is active.
812 * @param nframes number of frames to process.
815 Session::process_audition (nframes_t nframes
)
818 boost::shared_ptr
<RouteList
> r
= routes
.reader ();
820 for (RouteList::iterator i
= r
->begin(); i
!= r
->end(); ++i
) {
821 if (!(*i
)->is_hidden()) {
822 (*i
)->silence (nframes
);
826 /* run the auditioner, and if it says we need butler service, ask for it */
828 if (auditioner
->play_audition (nframes
) > 0) {
832 /* if using a monitor section, run it because otherwise we don't hear anything */
834 if (auditioner
->needs_monitor()) {
835 _monitor_out
->passthru (_transport_frame
, _transport_frame
+ nframes
, nframes
, false);
838 /* handle pending events */
840 while (pending_events
.read (&ev
, 1) == 1) {
844 /* if we are not in the middle of a state change,
845 and there are immediate events queued up,
849 while (!non_realtime_work_pending() && !immediate_events
.empty()) {
850 SessionEvent
*ev
= immediate_events
.front ();
851 immediate_events
.pop_front ();
855 if (!auditioner
->auditioning()) {
856 /* auditioner no longer active, so go back to the normal process callback */
857 process_function
= &Session::process_with_events
;
862 Session::maybe_sync_start (nframes_t
& nframes
)
864 nframes_t sync_offset
;
866 if (!waiting_for_sync_offset
) {
870 if (_engine
.get_sync_offset (sync_offset
) && sync_offset
< nframes
) {
872 /* generate silence up to the sync point, then
873 adjust nframes + offset to reflect whatever
877 no_roll (sync_offset
);
878 nframes
-= sync_offset
;
879 Port::increment_port_offset (sync_offset
);
880 waiting_for_sync_offset
= false;
883 return true; // done, nothing left to process
888 /* sync offset point is not within this process()
889 cycle, so just generate silence. and don't bother
890 with any fancy stuff here, just the minimal silence.
895 if (Config
->get_locate_while_waiting_for_sync()) {
896 if (micro_locate (nframes
)) {
897 /* XXX ERROR !!! XXX */
901 return true; // done, nothing left to process
908 Session::queue_event (SessionEvent
* ev
)
910 if (_state_of_the_state
& Deletion
) {
912 } else if (_state_of_the_state
& Loading
) {
915 pending_events
.write (&ev
, 1);
920 Session::set_next_event ()
922 if (events
.empty()) {
923 next_event
= events
.end();
927 if (next_event
== events
.end()) {
928 next_event
= events
.begin();
931 if ((*next_event
)->action_frame
> _transport_frame
) {
932 next_event
= events
.begin();
935 for (; next_event
!= events
.end(); ++next_event
) {
936 if ((*next_event
)->action_frame
>= _transport_frame
) {
943 Session::process_event (SessionEvent
* ev
)
948 /* if we're in the middle of a state change (i.e. waiting
949 for the butler thread to complete the non-realtime
950 part of the change), we'll just have to queue this
951 event for a time when the change is complete.
954 if (non_realtime_work_pending()) {
956 /* except locates, which we have the capability to handle */
958 if (ev
->type
!= SessionEvent::Locate
) {
959 immediate_events
.insert (immediate_events
.end(), ev
);
965 DEBUG_TRACE (DEBUG::SessionEvents
, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev
->type
), _transport_frame
));
968 case SessionEvent::SetLoop
:
969 set_play_loop (ev
->yes_or_no
);
972 case SessionEvent::AutoLoop
:
974 start_locate (ev
->target_frame
, true, false, Config
->get_seamless_loop());
980 case SessionEvent::Locate
:
982 // cerr << "forced locate to " << ev->target_frame << endl;
983 locate (ev
->target_frame
, false, true, false);
985 // cerr << "soft locate to " << ev->target_frame << endl;
986 start_locate (ev
->target_frame
, false, true, false);
988 _send_timecode_update
= true;
991 case SessionEvent::LocateRoll
:
993 // cerr << "forced locate to+roll " << ev->target_frame << endl;
994 locate (ev
->target_frame
, true, true, false);
996 // cerr << "soft locate to+roll " << ev->target_frame << endl;
997 start_locate (ev
->target_frame
, true, true, false);
999 _send_timecode_update
= true;
1002 case SessionEvent::LocateRollLocate
:
1003 // locate is handled by ::request_roll_at_and_return()
1004 _requested_return_frame
= ev
->target_frame
;
1005 request_locate (ev
->target2_frame
, true);
1009 case SessionEvent::SetTransportSpeed
:
1010 set_transport_speed (ev
->speed
, ev
->yes_or_no
, ev
->second_yes_or_no
);
1013 case SessionEvent::PunchIn
:
1014 // cerr << "PunchIN at " << transport_frame() << endl;
1015 if (config
.get_punch_in() && record_status() == Enabled
) {
1022 case SessionEvent::PunchOut
:
1023 // cerr << "PunchOUT at " << transport_frame() << endl;
1024 if (config
.get_punch_out()) {
1025 step_back_from_record ();
1031 case SessionEvent::StopOnce
:
1032 if (!non_realtime_work_pending()) {
1033 stop_transport (ev
->yes_or_no
);
1034 _clear_event_type (SessionEvent::StopOnce
);
1040 case SessionEvent::RangeStop
:
1041 if (!non_realtime_work_pending()) {
1042 stop_transport (ev
->yes_or_no
);
1048 case SessionEvent::RangeLocate
:
1049 start_locate (ev
->target_frame
, true, true, false);
1054 case SessionEvent::Overwrite
:
1055 overwrite_some_buffers (static_cast<Track
*>(ev
->ptr
));
1058 case SessionEvent::SetTrackSpeed
:
1059 set_track_speed (static_cast<Track
*> (ev
->ptr
), ev
->speed
);
1062 case SessionEvent::SetSyncSource
:
1063 use_sync_source (ev
->slave
);
1066 case SessionEvent::Audition
:
1067 set_audition (ev
->region
);
1068 // drop reference to region
1069 ev
->region
.reset ();
1072 case SessionEvent::InputConfigurationChange
:
1073 add_post_transport_work (PostTransportInputChange
);
1074 _butler
->schedule_transport_work ();
1077 case SessionEvent::SetPlayAudioRange
:
1078 set_play_range (ev
->audio_range
, (ev
->speed
== 1.0f
));
1081 case SessionEvent::RealTimeOperation
:
1083 del
= false; // other side of RT request needs to clean up
1087 fatal
<< string_compose(_("Programming error: illegal event type in process_event (%1)"), ev
->type
) << endmsg
;
1093 del
= del
&& !_remove_event (ev
);