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 /* handle pending events */
883 while (pending_events
.read (&ev
, 1) == 1) {
887 /* if we are not in the middle of a state change,
888 and there are immediate events queued up,
892 while (!non_realtime_work_pending() && !immediate_events
.empty()) {
893 SessionEvent
*ev
= immediate_events
.front ();
894 immediate_events
.pop_front ();
898 if (!auditioner
->active()) {
899 /* auditioner no longer active, so go back to the normal process callback */
900 process_function
= &Session::process_with_events
;
905 Session::maybe_sync_start (nframes_t
& nframes
)
907 nframes_t sync_offset
;
909 if (!waiting_for_sync_offset
) {
913 if (_engine
.get_sync_offset (sync_offset
) && sync_offset
< nframes
) {
915 /* generate silence up to the sync point, then
916 adjust nframes + offset to reflect whatever
920 no_roll (sync_offset
);
921 nframes
-= sync_offset
;
922 Port::increment_port_offset (sync_offset
);
923 waiting_for_sync_offset
= false;
926 return true; // done, nothing left to process
931 /* sync offset point is not within this process()
932 cycle, so just generate silence. and don't bother
933 with any fancy stuff here, just the minimal silence.
938 if (Config
->get_locate_while_waiting_for_sync()) {
939 if (micro_locate (nframes
)) {
940 /* XXX ERROR !!! XXX */
944 return true; // done, nothing left to process
951 Session::queue_event (SessionEvent
* ev
)
953 if (_state_of_the_state
& Deletion
) {
955 } else if (_state_of_the_state
& Loading
) {
958 pending_events
.write (&ev
, 1);
963 Session::set_next_event ()
965 if (events
.empty()) {
966 next_event
= events
.end();
970 if (next_event
== events
.end()) {
971 next_event
= events
.begin();
974 if ((*next_event
)->action_frame
> _transport_frame
) {
975 next_event
= events
.begin();
978 for (; next_event
!= events
.end(); ++next_event
) {
979 if ((*next_event
)->action_frame
>= _transport_frame
) {
986 Session::process_event (SessionEvent
* ev
)
991 /* if we're in the middle of a state change (i.e. waiting
992 for the butler thread to complete the non-realtime
993 part of the change), we'll just have to queue this
994 event for a time when the change is complete.
997 if (non_realtime_work_pending()) {
999 /* except locates, which we have the capability to handle */
1001 if (ev
->type
!= SessionEvent::Locate
) {
1002 immediate_events
.insert (immediate_events
.end(), ev
);
1008 DEBUG_TRACE (DEBUG::SessionEvents
, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev
->type
), _transport_frame
));
1011 case SessionEvent::SetLoop
:
1012 set_play_loop (ev
->yes_or_no
);
1015 case SessionEvent::AutoLoop
:
1017 start_locate (ev
->target_frame
, true, false, Config
->get_seamless_loop());
1023 case SessionEvent::Locate
:
1024 if (ev
->yes_or_no
) {
1025 // cerr << "forced locate to " << ev->target_frame << endl;
1026 locate (ev
->target_frame
, false, true, false);
1028 // cerr << "soft locate to " << ev->target_frame << endl;
1029 start_locate (ev
->target_frame
, false, true, false);
1031 _send_timecode_update
= true;
1034 case SessionEvent::LocateRoll
:
1035 if (ev
->yes_or_no
) {
1036 // cerr << "forced locate to+roll " << ev->target_frame << endl;
1037 locate (ev
->target_frame
, true, true, false);
1039 // cerr << "soft locate to+roll " << ev->target_frame << endl;
1040 start_locate (ev
->target_frame
, true, true, false);
1042 _send_timecode_update
= true;
1045 case SessionEvent::LocateRollLocate
:
1046 // locate is handled by ::request_roll_at_and_return()
1047 _requested_return_frame
= ev
->target_frame
;
1048 request_locate (ev
->target2_frame
, true);
1052 case SessionEvent::SetTransportSpeed
:
1053 set_transport_speed (ev
->speed
, ev
->yes_or_no
, ev
->second_yes_or_no
);
1056 case SessionEvent::PunchIn
:
1057 // cerr << "PunchIN at " << transport_frame() << endl;
1058 if (config
.get_punch_in() && record_status() == Enabled
) {
1065 case SessionEvent::PunchOut
:
1066 // cerr << "PunchOUT at " << transport_frame() << endl;
1067 if (config
.get_punch_out()) {
1068 step_back_from_record ();
1074 case SessionEvent::StopOnce
:
1075 if (!non_realtime_work_pending()) {
1076 stop_transport (ev
->yes_or_no
);
1077 _clear_event_type (SessionEvent::StopOnce
);
1083 case SessionEvent::RangeStop
:
1084 if (!non_realtime_work_pending()) {
1085 stop_transport (ev
->yes_or_no
);
1091 case SessionEvent::RangeLocate
:
1092 start_locate (ev
->target_frame
, true, true, false);
1097 case SessionEvent::Overwrite
:
1098 overwrite_some_buffers (static_cast<Diskstream
*>(ev
->ptr
));
1101 case SessionEvent::SetDiskstreamSpeed
:
1102 set_diskstream_speed (static_cast<Diskstream
*> (ev
->ptr
), ev
->speed
);
1105 case SessionEvent::SetSyncSource
:
1106 use_sync_source (ev
->slave
);
1109 case SessionEvent::Audition
:
1110 set_audition (ev
->region
);
1111 // drop reference to region
1112 ev
->region
.reset ();
1115 case SessionEvent::InputConfigurationChange
:
1116 add_post_transport_work (PostTransportInputChange
);
1117 _butler
->schedule_transport_work ();
1120 case SessionEvent::SetPlayAudioRange
:
1121 set_play_range (ev
->audio_range
, (ev
->speed
== 1.0f
));
1124 case SessionEvent::RealTimeOperation
:
1126 del
= false; // other side of RT request needs to clean up
1130 fatal
<< string_compose(_("Programming error: illegal event type in process_event (%1)"), ev
->type
) << endmsg
;
1136 del
= del
&& !_remove_event (ev
);