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/threads.h>
30 #include "ardour/audioengine.h"
31 #include "ardour/auditioner.h"
32 #include "ardour/butler.h"
33 #include "ardour/cycle_timer.h"
34 #include "ardour/debug.h"
35 #include "ardour/graph.h"
36 #include "ardour/port.h"
37 #include "ardour/process_thread.h"
38 #include "ardour/scene_changer.h"
39 #include "ardour/session.h"
40 #include "ardour/slave.h"
41 #include "ardour/ticker.h"
42 #include "ardour/types.h"
44 #include "midi++/mmc.h"
48 using namespace ARDOUR;
52 /** Called by the audio engine when there is work to be done with JACK.
53 * @param nframes Number of frames to process.
57 Session::process (pframes_t nframes)
59 framepos_t transport_at_start = _transport_frame;
63 if (processing_blocked()) {
68 if (non_realtime_work_pending()) {
69 if (!_butler->transport_work_requested ()) {
74 _engine.main_thread()->get_buffers ();
76 (this->*process_function) (nframes);
78 /* realtime-safe meter-position and processor-order changes
80 * ideally this would be done in
81 * Route::process_output_buffers() but various functions
82 * callig it hold a _processor_lock reader-lock
84 boost::shared_ptr<RouteList> r = routes.reader ();
85 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
86 if ((*i)->apply_processor_changes_rt()) {
87 _rt_emit_pending = true;
90 if (_rt_emit_pending) {
91 if (!_rt_thread_active) {
92 emit_route_signals ();
94 if (pthread_mutex_trylock (&_rt_emit_mutex) == 0) {
95 pthread_cond_signal (&_rt_emit_cond);
96 pthread_mutex_unlock (&_rt_emit_mutex);
97 _rt_emit_pending = false;
101 _engine.main_thread()->drop_buffers ();
103 /* deliver MIDI clock. Note that we need to use the transport frame
104 * position at the start of process(), not the value at the end of
105 * it. We may already have ticked() because of a transport state
106 * change, for example.
110 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
111 midi_clock->tick (transport_at_start, nframes);
114 _scene_changer->run (transport_at_start, transport_at_start + nframes);
117 /* don't bother with a message */
120 SendFeedback (); /* EMIT SIGNAL */
124 Session::fail_roll (pframes_t nframes)
126 return no_roll (nframes);
130 Session::no_roll (pframes_t nframes)
134 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
136 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
137 boost::shared_ptr<RouteList> r = routes.reader ();
140 _click_io->silence (nframes);
143 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
145 if (_process_graph) {
146 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
147 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
149 PT_TIMING_CHECK (10);
150 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
152 if ((*i)->is_auditioner()) {
156 (*i)->set_pending_declick (declick);
158 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
159 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
164 PT_TIMING_CHECK (11);
171 /** @param need_butler to be set to true by this method if it needs the butler,
172 * otherwise it must be left alone.
175 Session::process_routes (pframes_t nframes, bool& need_butler)
177 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
178 boost::shared_ptr<RouteList> r = routes.reader ();
180 const framepos_t start_frame = _transport_frame;
181 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
183 if (_process_graph) {
184 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
185 if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
191 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
195 if ((*i)->is_auditioner()) {
199 (*i)->set_pending_declick (declick);
203 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
217 /** @param need_butler to be set to true by this method if it needs the butler,
218 * otherwise it must be left alone.
221 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
223 boost::shared_ptr<RouteList> r = routes.reader ();
225 const framepos_t start_frame = _transport_frame;
226 const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
228 if (_process_graph) {
229 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
231 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
235 if ((*i)->is_auditioner()) {
241 if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
256 Session::get_track_statistics ()
261 boost::shared_ptr<RouteList> rl = routes.reader();
262 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
264 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
266 if (!tr || tr->hidden()) {
270 pworst = min (pworst, tr->playback_buffer_load());
271 cworst = min (cworst, tr->capture_buffer_load());
274 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
275 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
277 if (actively_recording()) {
282 /** Process callback used when the auditioner is not active */
284 Session::process_with_events (pframes_t nframes)
289 pframes_t this_nframes;
290 framepos_t end_frame;
291 bool session_needs_butler = false;
292 framecnt_t frames_moved;
294 /* make sure the auditioner is silent */
297 auditioner->silence (nframes);
300 /* handle any pending events */
302 while (pending_events.read (&ev, 1) == 1) {
306 /* if we are not in the middle of a state change,
307 and there are immediate events queued up,
311 while (!non_realtime_work_pending() && !immediate_events.empty()) {
312 SessionEvent *ev = immediate_events.front ();
313 immediate_events.pop_front ();
318 if (_transport_speed != 1.0 && _count_in_samples > 0) {
319 _count_in_samples = 0;
322 if (_count_in_samples > 0) {
323 framecnt_t ns = std::min ((framecnt_t)nframes, _count_in_samples);
326 run_click (_transport_frame - _count_in_samples, ns);
328 _count_in_samples -= ns;
331 /* process events.. */
332 if (!events.empty() && next_event != events.end()) {
333 SessionEvent* this_event = *next_event;
334 Events::iterator the_next_one = next_event;
337 while (this_event && this_event->action_frame == _transport_frame) {
338 process_event (this_event);
339 if (the_next_one == events.end()) {
342 this_event = *the_next_one;
349 check_declick_out ();
354 _engine.split_cycle (ns);
358 /* Decide on what to do with quarter-frame MTC during this cycle */
360 bool const was_sending_qf_mtc = _send_qf_mtc;
361 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
363 if (_transport_speed != 0) {
365 Config->get_send_mtc () &&
366 _transport_speed >= (1 - tolerance) &&
367 _transport_speed <= (1 + tolerance)
370 if (_send_qf_mtc && !was_sending_qf_mtc) {
371 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
372 _send_timecode_update = true;
375 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
376 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
377 a quarter of a second since we sent anything at all, so send a full MTC update
380 _send_timecode_update = true;
383 _pframes_since_last_mtc += nframes;
386 /* Events caused a transport change (or we re-started sending
387 * MTC), so send an MTC Full Frame (Timecode) message. This
388 * is sent whether rolling or not, to give slaves an idea of
389 * ardour time on locates (and allow slow slaves to position
390 * and prepare for rolling)
392 if (_send_timecode_update) {
393 send_full_time_code (_transport_frame, nframes);
396 if (!process_can_proceed()) {
401 if (events.empty() || next_event == events.end()) {
402 try_run_lua (nframes); // also during export ?? ->move to process_without_events()
403 /* lua scripts may inject events */
404 while (_n_lua_scripts > 0 && pending_events.read (&ev, 1) == 1) {
407 if (events.empty() || next_event == events.end()) {
408 process_without_events (nframes);
413 if (_transport_speed == 1.0) {
414 frames_moved = (framecnt_t) nframes;
416 interpolation.set_target_speed (_target_transport_speed);
417 interpolation.set_speed (_transport_speed);
418 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
421 end_frame = _transport_frame + frames_moved;
424 SessionEvent* this_event;
425 Events::iterator the_next_one;
427 if (!process_can_proceed()) {
432 if (!_exporting && _slave) {
433 if (!follow_slave (nframes)) {
438 if (_transport_speed == 0) {
443 if (!_exporting && !timecode_transmission_suspended()) {
444 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
447 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
449 framepos_t stop_limit = compute_stop_limit ();
451 if (maybe_stop (stop_limit)) {
456 this_event = *next_event;
457 the_next_one = next_event;
460 /* yes folks, here it is, the actual loop where we really truly
466 this_nframes = nframes; /* real (jack) time relative */
467 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
469 /* running an event, position transport precisely to its time */
470 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
471 /* this isn't quite right for reverse play */
472 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
473 this_nframes = abs (floor(frames_moved / _transport_speed));
476 try_run_lua (this_nframes);
480 click (_transport_frame, this_nframes);
482 if (process_routes (this_nframes, session_needs_butler)) {
487 get_track_statistics ();
489 nframes -= this_nframes;
491 if (frames_moved < 0) {
492 decrement_transport_position (-frames_moved);
494 increment_transport_position (frames_moved);
497 maybe_stop (stop_limit);
498 check_declick_out ();
502 _engine.split_cycle (this_nframes);
505 /* now handle this event and all others scheduled for the same time */
507 while (this_event && this_event->action_frame == _transport_frame) {
508 process_event (this_event);
510 if (the_next_one == events.end()) {
513 this_event = *the_next_one;
518 /* if an event left our state changing, do the right thing */
520 if (nframes && non_realtime_work_pending()) {
525 /* this is necessary to handle the case of seamless looping */
526 end_frame = _transport_frame + floor (nframes * _transport_speed);
531 } /* implicit release of route lock */
533 if (session_needs_butler) {
539 Session::reset_slave_state ()
541 average_slave_delta = 1800;
542 delta_accumulator_cnt = 0;
543 have_first_delta_accumulator = false;
544 _slave_state = Stopped;
548 Session::transport_locked () const
552 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
560 Session::follow_slave (pframes_t nframes)
563 framepos_t slave_transport_frame;
564 framecnt_t this_delta;
569 config.set_external_sync (false);
573 _slave->speed_and_position (slave_speed, slave_transport_frame);
575 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
577 if (!_slave->locked()) {
578 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
582 if (slave_transport_frame > _transport_frame) {
583 this_delta = slave_transport_frame - _transport_frame;
586 this_delta = _transport_frame - slave_transport_frame;
590 if (_slave->starting()) {
594 if (_slave->is_always_synced() ||
595 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
598 /* if the TC source is synced, then we assume that its
599 speed is binary: 0.0 or 1.0
602 if (slave_speed != 0.0f) {
608 /* if we are chasing and the average delta between us and the
609 master gets too big, we want to switch to silent
610 motion. so keep track of that here.
613 if (_slave_state == Running) {
614 calculate_moving_average_of_slave_delta(dir, this_delta);
618 track_slave_state (slave_speed, slave_transport_frame, this_delta);
620 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
621 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
624 if (_slave_state == Running && !_slave->is_always_synced() &&
625 !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
628 if (_transport_speed != 0.0f) {
631 note that average_dir is +1 or -1
636 if (average_slave_delta == 0) {
640 delta = average_slave_delta;
641 delta *= average_dir;
645 if (slave_speed != 0.0) {
646 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
647 (int) (dir * this_delta),
651 slave_transport_frame,
652 average_slave_delta));
656 if (_slave->give_slave_full_control_over_transport_speed()) {
657 set_transport_speed (slave_speed, 0, false, false);
658 //std::cout << "set speed = " << slave_speed << "\n";
660 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
661 request_transport_speed (adjusted_speed);
662 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
663 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
668 if (!actively_recording() && (framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
669 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
677 if (_slave_state == Running && 0 == (post_transport_work () & ~PostTransportSpeed)) {
678 /* speed is set, we're locked, and good to go */
683 DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
684 follow_slave_silently (nframes, slave_speed);
687 /* don't move at all */
688 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
694 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
696 if (delta_accumulator_cnt >= delta_accumulator_size) {
697 have_first_delta_accumulator = true;
698 delta_accumulator_cnt = 0;
701 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
702 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
705 if (have_first_delta_accumulator) {
706 average_slave_delta = 0L;
707 for (int i = 0; i < delta_accumulator_size; ++i) {
708 average_slave_delta += delta_accumulator[i];
710 average_slave_delta /= (int32_t) delta_accumulator_size;
711 if (average_slave_delta < 0L) {
713 average_slave_delta = abs(average_slave_delta);
721 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
723 if (slave_speed != 0.0f) {
725 /* slave is running */
727 switch (_slave_state) {
729 if (_slave->requires_seekahead()) {
730 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
731 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
732 /* we can call locate() here because we are in process context */
733 locate (slave_wait_end, false, false);
734 _slave_state = Waiting;
738 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
740 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
741 average_slave_delta = 0L;
743 Location* al = _locations->auto_loop_location();
745 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
747 request_play_loop(false);
750 if (slave_transport_frame != _transport_frame) {
751 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
752 locate (slave_transport_frame, false, false);
754 _slave_state = Running;
763 if (_slave_state == Waiting) {
765 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
767 if (slave_transport_frame >= slave_wait_end) {
769 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
771 _slave_state = Running;
773 /* now perform a "micro-seek" within the disk buffers to realign ourselves
774 precisely with the master.
779 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
781 boost::shared_ptr<RouteList> rl = routes.reader();
782 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
783 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
784 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
791 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
792 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
794 tr->internal_playback_seek (frame_delta);
797 _transport_frame += frame_delta;
800 cerr << "cannot micro-seek\n";
806 if (_slave_state == Running && _transport_speed == 0.0f) {
807 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
811 } else { // slave_speed is 0
813 /* slave has stopped */
815 if (_transport_speed != 0.0f) {
816 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
820 if (slave_transport_frame != _transport_frame) {
821 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
822 force_locate (slave_transport_frame, false);
830 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
832 if (slave_speed && _transport_speed) {
834 /* something isn't right, but we should move with the master
838 bool need_butler = false;
840 silent_process_routes (nframes, need_butler);
842 get_track_statistics ();
848 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
850 if (frames_moved < 0) {
851 decrement_transport_position (-frames_moved);
853 increment_transport_position (frames_moved);
856 framepos_t const stop_limit = compute_stop_limit ();
857 maybe_stop (stop_limit);
862 Session::process_without_events (pframes_t nframes)
864 bool session_needs_butler = false;
865 framecnt_t frames_moved;
867 if (!process_can_proceed()) {
872 if (!_exporting && _slave) {
873 if (!follow_slave (nframes)) {
874 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
879 if (_transport_speed == 0) {
884 if (_transport_speed == 1.0) {
885 frames_moved = (framecnt_t) nframes;
887 interpolation.set_target_speed (_target_transport_speed);
888 interpolation.set_speed (_transport_speed);
889 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
892 if (!_exporting && !timecode_transmission_suspended()) {
893 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
896 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
898 framepos_t const stop_limit = compute_stop_limit ();
900 if (maybe_stop (stop_limit)) {
905 if (maybe_sync_start (nframes)) {
909 click (_transport_frame, nframes);
911 if (process_routes (nframes, session_needs_butler)) {
916 get_track_statistics ();
918 if (frames_moved < 0) {
919 decrement_transport_position (-frames_moved);
921 increment_transport_position (frames_moved);
924 maybe_stop (stop_limit);
925 check_declick_out ();
927 if (session_needs_butler) {
932 /** Process callback used when the auditioner is active.
933 * @param nframes number of frames to process.
936 Session::process_audition (pframes_t nframes)
939 boost::shared_ptr<RouteList> r = routes.reader ();
941 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
942 if (!(*i)->is_auditioner()) {
943 (*i)->silence (nframes);
947 /* run the auditioner, and if it says we need butler service, ask for it */
949 if (auditioner->play_audition (nframes) > 0) {
953 /* if using a monitor section, run it because otherwise we don't hear anything */
955 if (_monitor_out && auditioner->needs_monitor()) {
956 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
959 /* handle pending events */
961 while (pending_events.read (&ev, 1) == 1) {
965 /* if we are not in the middle of a state change,
966 and there are immediate events queued up,
970 while (!non_realtime_work_pending() && !immediate_events.empty()) {
971 SessionEvent *ev = immediate_events.front ();
972 immediate_events.pop_front ();
976 if (!auditioner->auditioning()) {
977 /* auditioner no longer active, so go back to the normal process callback */
978 process_function = &Session::process_with_events;
983 Session::maybe_sync_start (pframes_t & nframes)
985 pframes_t sync_offset;
987 if (!waiting_for_sync_offset) {
991 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
993 /* generate silence up to the sync point, then
994 adjust nframes + offset to reflect whatever
998 no_roll (sync_offset);
999 nframes -= sync_offset;
1000 Port::increment_global_port_buffer_offset (sync_offset);
1001 waiting_for_sync_offset = false;
1004 return true; // done, nothing left to process
1009 /* sync offset point is not within this process()
1010 cycle, so just generate silence. and don't bother
1011 with any fancy stuff here, just the minimal silence.
1016 if (Config->get_locate_while_waiting_for_sync()) {
1017 if (micro_locate (nframes)) {
1018 /* XXX ERROR !!! XXX */
1022 return true; // done, nothing left to process
1029 Session::queue_event (SessionEvent* ev)
1031 if (_state_of_the_state & Deletion) {
1033 } else if (_state_of_the_state & Loading) {
1036 Glib::Threads::Mutex::Lock lm (rb_write_lock);
1037 pending_events.write (&ev, 1);
1042 Session::set_next_event ()
1044 if (events.empty()) {
1045 next_event = events.end();
1049 if (next_event == events.end()) {
1050 next_event = events.begin();
1053 if ((*next_event)->action_frame > _transport_frame) {
1054 next_event = events.begin();
1057 for (; next_event != events.end(); ++next_event) {
1058 if ((*next_event)->action_frame >= _transport_frame) {
1065 Session::process_event (SessionEvent* ev)
1070 /* if we're in the middle of a state change (i.e. waiting
1071 for the butler thread to complete the non-realtime
1072 part of the change), we'll just have to queue this
1073 event for a time when the change is complete.
1076 if (non_realtime_work_pending()) {
1078 /* except locates, which we have the capability to handle */
1080 if (ev->type != SessionEvent::Locate) {
1081 immediate_events.insert (immediate_events.end(), ev);
1087 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1090 case SessionEvent::SetLoop:
1091 set_play_loop (ev->yes_or_no, ev->speed);
1094 case SessionEvent::AutoLoop:
1096 /* roll after locate, do not flush, set "with loop"
1097 true only if we are seamless looping
1099 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1105 case SessionEvent::AutoLoopDeclick:
1107 /* Request a declick fade-out and a fade-in; the fade-out will happen
1108 at the end of the loop, and the fade-in at the start.
1110 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1116 case SessionEvent::Locate:
1117 if (ev->yes_or_no) {
1118 /* args: do not roll after locate, do flush, not with loop */
1119 locate (ev->target_frame, false, true, false);
1121 /* args: do not roll after locate, do flush, not with loop */
1122 start_locate (ev->target_frame, false, true, false);
1124 _send_timecode_update = true;
1127 case SessionEvent::LocateRoll:
1128 if (ev->yes_or_no) {
1129 /* args: roll after locate, do flush, not with loop */
1130 locate (ev->target_frame, true, true, false);
1132 /* args: roll after locate, do flush, not with loop */
1133 start_locate (ev->target_frame, true, true, false);
1135 _send_timecode_update = true;
1138 case SessionEvent::Skip:
1139 if (Config->get_skip_playback()) {
1140 start_locate (ev->target_frame, true, true, false);
1141 _send_timecode_update = true;
1147 case SessionEvent::LocateRollLocate:
1148 // locate is handled by ::request_roll_at_and_return()
1149 _requested_return_frame = ev->target_frame;
1150 request_locate (ev->target2_frame, true);
1154 case SessionEvent::SetTransportSpeed:
1155 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1158 case SessionEvent::PunchIn:
1159 // cerr << "PunchIN at " << transport_frame() << endl;
1160 if (config.get_punch_in() && record_status() == Enabled && !preroll_record_punch_enabled()) {
1167 case SessionEvent::PunchOut:
1168 // cerr << "PunchOUT at " << transport_frame() << endl;
1169 if (config.get_punch_out() && !preroll_record_punch_enabled()) {
1170 step_back_from_record ();
1176 case SessionEvent::RecordStart:
1177 if (preroll_record_punch_enabled() && record_status() == Enabled) {
1184 case SessionEvent::StopOnce:
1185 if (!non_realtime_work_pending()) {
1186 _clear_event_type (SessionEvent::StopOnce);
1187 stop_transport (ev->yes_or_no);
1193 case SessionEvent::RangeStop:
1194 if (!non_realtime_work_pending()) {
1195 stop_transport (ev->yes_or_no);
1201 case SessionEvent::RangeLocate:
1202 /* args: roll after locate, do flush, not with loop */
1203 start_locate (ev->target_frame, true, true, false);
1208 case SessionEvent::Overwrite:
1209 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1212 case SessionEvent::SetTrackSpeed:
1213 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1216 case SessionEvent::SetSyncSource:
1217 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1218 use_sync_source (ev->slave);
1221 case SessionEvent::Audition:
1222 set_audition (ev->region);
1223 // drop reference to region
1224 ev->region.reset ();
1227 case SessionEvent::InputConfigurationChange:
1228 add_post_transport_work (PostTransportInputChange);
1229 _butler->schedule_transport_work ();
1232 case SessionEvent::SetPlayAudioRange:
1233 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1236 case SessionEvent::CancelPlayAudioRange:
1240 case SessionEvent::RealTimeOperation:
1242 del = false; // other side of RT request needs to clean up
1245 case SessionEvent::AdjustPlaybackBuffering:
1246 schedule_playback_buffering_adjustment ();
1249 case SessionEvent::AdjustCaptureBuffering:
1250 schedule_capture_buffering_adjustment ();
1253 case SessionEvent::SetTimecodeTransmission:
1254 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1258 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1259 abort(); /*NOTREACHED*/
1264 del = del && !_remove_event (ev);
1273 Session::compute_stop_limit () const
1275 if (!Config->get_stop_at_session_end ()) {
1276 return max_framepos;
1280 return max_framepos;
1283 if (preroll_record_punch_enabled ()) {
1284 return max_framepos;
1287 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1288 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1290 if (actively_recording ()) {
1291 /* permanently recording */
1292 return max_framepos;
1293 } else if (punching_in && !punching_out) {
1294 /* punching in but never out */
1295 return max_framepos;
1296 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1297 /* punching in and punching out after session end */
1298 return max_framepos;
1301 return current_end_frame ();
1306 /* dedicated thread for signal emission.
1308 * while sending cross-thread signals from the process thread
1309 * is fine in general, PBD::Signal's use of boost::function and
1310 * boost:bind can produce a vast overhead which is not
1311 * acceptable for low latency.
1313 * This works around the issue by moving the boost overhead
1314 * out of the RT thread. The overall load is probably higher but
1315 * the realtime thread remains unaffected.
1319 Session::emit_route_signals ()
1321 // TODO use RAII to allow using these signals in other places
1322 BatchUpdateStart(); /* EMIT SIGNAL */
1323 boost::shared_ptr<RouteList> r = routes.reader ();
1324 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1325 (*ci)->emit_pending_signals ();
1327 BatchUpdateEnd(); /* EMIT SIGNAL */
1331 Session::emit_thread_start ()
1333 if (_rt_thread_active) {
1336 _rt_thread_active = true;
1338 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1339 _rt_thread_active = false;
1344 Session::emit_thread_terminate ()
1346 if (!_rt_thread_active) {
1349 _rt_thread_active = false;
1351 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1352 pthread_cond_signal (&_rt_emit_cond);
1353 pthread_mutex_unlock (&_rt_emit_mutex);
1357 pthread_join (_rt_emit_thread, &status);
1361 Session::emit_thread (void *arg)
1363 Session *s = static_cast<Session *>(arg);
1364 s->emit_thread_run ();
1370 Session::emit_thread_run ()
1372 pthread_mutex_lock (&_rt_emit_mutex);
1373 while (_rt_thread_active) {
1374 emit_route_signals();
1375 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1377 pthread_mutex_unlock (&_rt_emit_mutex);