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/disk_reader.h"
36 #include "ardour/graph.h"
37 #include "ardour/port.h"
38 #include "ardour/process_thread.h"
39 #include "ardour/scene_changer.h"
40 #include "ardour/session.h"
41 #include "ardour/slave.h"
42 #include "ardour/ticker.h"
43 #include "ardour/types.h"
44 #include "ardour/vca.h"
45 #include "ardour/vca_manager.h"
47 #include "midi++/mmc.h"
51 using namespace ARDOUR;
55 /** Called by the audio engine when there is work to be done with JACK.
56 * @param nframes Number of frames to process.
60 Session::process (pframes_t nframes)
62 framepos_t transport_at_start = _transport_frame;
66 if (processing_blocked()) {
71 if (non_realtime_work_pending()) {
72 if (!_butler->transport_work_requested ()) {
77 _engine.main_thread()->get_buffers ();
79 (this->*process_function) (nframes);
81 /* realtime-safe meter-position and processor-order changes
83 * ideally this would be done in
84 * Route::process_output_buffers() but various functions
85 * callig it hold a _processor_lock reader-lock
87 boost::shared_ptr<RouteList> r = routes.reader ();
88 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
89 if ((*i)->apply_processor_changes_rt()) {
90 _rt_emit_pending = true;
93 if (_rt_emit_pending) {
94 if (!_rt_thread_active) {
95 emit_route_signals ();
97 if (pthread_mutex_trylock (&_rt_emit_mutex) == 0) {
98 pthread_cond_signal (&_rt_emit_cond);
99 pthread_mutex_unlock (&_rt_emit_mutex);
100 _rt_emit_pending = false;
104 _engine.main_thread()->drop_buffers ();
106 /* deliver MIDI clock. Note that we need to use the transport frame
107 * position at the start of process(), not the value at the end of
108 * it. We may already have ticked() because of a transport state
109 * change, for example.
113 if (!_silent && !_engine.freewheeling() && Config->get_send_midi_clock() && (transport_speed() == 1.0f || transport_speed() == 0.0f) && midi_clock->has_midi_port()) {
114 midi_clock->tick (transport_at_start, nframes);
117 _scene_changer->run (transport_at_start, transport_at_start + nframes);
120 /* don't bother with a message */
123 SendFeedback (); /* EMIT SIGNAL */
127 Session::fail_roll (pframes_t nframes)
129 return no_roll (nframes);
133 Session::no_roll (pframes_t nframes)
137 framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
139 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
140 boost::shared_ptr<RouteList> r = routes.reader ();
143 _click_io->silence (nframes);
146 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
148 VCAList v = _vca_manager->vcas ();
149 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
150 (*i)->automation_run (_transport_frame, nframes);
153 if (_process_graph) {
154 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
155 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
157 PT_TIMING_CHECK (10);
158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
160 if ((*i)->is_auditioner()) {
164 (*i)->set_pending_declick (declick);
166 if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
167 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
172 PT_TIMING_CHECK (11);
179 /** @param need_butler to be set to true by this method if it needs the butler,
180 * otherwise it must be left alone.
183 Session::process_routes (pframes_t nframes, bool& need_butler)
185 int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
186 boost::shared_ptr<RouteList> r = routes.reader ();
188 const framepos_t start_frame = _transport_frame;
189 const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
191 VCAList v = _vca_manager->vcas ();
192 for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
193 (*i)->automation_run (start_frame, nframes);
196 _global_locate_pending = locate_pending ();
198 if (_process_graph) {
199 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
200 if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
206 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
210 if ((*i)->is_auditioner()) {
214 (*i)->set_pending_declick (declick);
218 if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
224 DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 rolled and needs butler\n", (*i)->name()));
234 Session::get_track_statistics ()
239 boost::shared_ptr<RouteList> rl = routes.reader();
240 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
242 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
244 if (!tr || tr->is_private_route()) {
248 pworst = min (pworst, tr->playback_buffer_load());
249 cworst = min (cworst, tr->capture_buffer_load());
252 g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
253 g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
255 if (actively_recording()) {
260 /** Process callback used when the auditioner is not active */
262 Session::process_with_events (pframes_t nframes)
267 pframes_t this_nframes;
268 framepos_t end_frame;
269 bool session_needs_butler = false;
270 framecnt_t frames_moved;
272 /* make sure the auditioner is silent */
275 auditioner->silence (nframes);
278 /* handle any pending events */
280 while (pending_events.read (&ev, 1) == 1) {
284 /* if we are not in the middle of a state change,
285 and there are immediate events queued up,
289 while (!non_realtime_work_pending() && !immediate_events.empty()) {
290 SessionEvent *ev = immediate_events.front ();
291 immediate_events.pop_front ();
296 if (_transport_speed != 1.0 && _count_in_samples > 0) {
297 _count_in_samples = 0;
300 if (_count_in_samples > 0) {
301 framecnt_t ns = std::min ((framecnt_t)nframes, _count_in_samples);
304 run_click (_transport_frame - _count_in_samples, ns);
306 _count_in_samples -= ns;
309 /* process events.. */
310 if (!events.empty() && next_event != events.end()) {
311 SessionEvent* this_event = *next_event;
312 Events::iterator the_next_one = next_event;
315 while (this_event && this_event->action_frame == _transport_frame) {
316 process_event (this_event);
317 if (the_next_one == events.end()) {
320 this_event = *the_next_one;
327 check_declick_out ();
332 _engine.split_cycle (ns);
336 /* Decide on what to do with quarter-frame MTC during this cycle */
338 bool const was_sending_qf_mtc = _send_qf_mtc;
339 double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
341 if (_transport_speed != 0) {
343 Config->get_send_mtc () &&
344 _transport_speed >= (1 - tolerance) &&
345 _transport_speed <= (1 + tolerance)
348 if (_send_qf_mtc && !was_sending_qf_mtc) {
349 /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
350 _send_timecode_update = true;
353 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
354 /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
355 a quarter of a second since we sent anything at all, so send a full MTC update
358 _send_timecode_update = true;
361 _pframes_since_last_mtc += nframes;
364 /* Events caused a transport change (or we re-started sending
365 * MTC), so send an MTC Full Frame (Timecode) message. This
366 * is sent whether rolling or not, to give slaves an idea of
367 * ardour time on locates (and allow slow slaves to position
368 * and prepare for rolling)
370 if (_send_timecode_update) {
371 send_full_time_code (_transport_frame, nframes);
374 if (!process_can_proceed()) {
379 if (events.empty() || next_event == events.end()) {
380 try_run_lua (nframes); // also during export ?? ->move to process_without_events()
381 /* lua scripts may inject events */
382 while (_n_lua_scripts > 0 && pending_events.read (&ev, 1) == 1) {
385 if (events.empty() || next_event == events.end()) {
386 process_without_events (nframes);
391 if (locate_pending()) {
394 if (_transport_speed == 1.0) {
395 frames_moved = (framecnt_t) nframes;
397 interpolation.set_target_speed (_target_transport_speed);
398 interpolation.set_speed (_transport_speed);
399 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
403 end_frame = _transport_frame + frames_moved;
406 SessionEvent* this_event;
407 Events::iterator the_next_one;
409 if (!process_can_proceed()) {
414 if (!_exporting && _slave) {
415 if (!follow_slave (nframes)) {
420 if (_transport_speed == 0) {
425 if (!_exporting && !timecode_transmission_suspended()) {
426 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
429 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
431 framepos_t stop_limit = compute_stop_limit ();
433 if (maybe_stop (stop_limit)) {
438 this_event = *next_event;
439 the_next_one = next_event;
442 /* yes folks, here it is, the actual loop where we really truly
448 this_nframes = nframes; /* real (jack) time relative */
449 if (locate_pending()) {
452 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
455 /* running an event, position transport precisely to its time */
456 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
457 /* this isn't quite right for reverse play */
458 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
459 this_nframes = abs (floor(frames_moved / _transport_speed));
462 try_run_lua (this_nframes);
466 click (_transport_frame, this_nframes);
468 if (process_routes (this_nframes, session_needs_butler)) {
473 get_track_statistics ();
475 nframes -= this_nframes;
477 if (frames_moved < 0) {
478 decrement_transport_position (-frames_moved);
479 } else if (frames_moved) {
480 increment_transport_position (frames_moved);
483 maybe_stop (stop_limit);
484 check_declick_out ();
488 _engine.split_cycle (this_nframes);
491 /* now handle this event and all others scheduled for the same time */
493 while (this_event && this_event->action_frame == _transport_frame) {
494 process_event (this_event);
496 if (the_next_one == events.end()) {
499 this_event = *the_next_one;
504 /* if an event left our state changing, do the right thing */
506 if (nframes && non_realtime_work_pending()) {
511 /* this is necessary to handle the case of seamless looping */
512 end_frame = _transport_frame + floor (nframes * _transport_speed);
517 } /* implicit release of route lock */
519 if (session_needs_butler) {
520 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
526 Session::reset_slave_state ()
528 average_slave_delta = 1800;
529 delta_accumulator_cnt = 0;
530 have_first_delta_accumulator = false;
531 _slave_state = Stopped;
535 Session::transport_locked () const
539 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
547 Session::follow_slave (pframes_t nframes)
550 framepos_t slave_transport_frame;
551 framecnt_t this_delta;
556 config.set_external_sync (false);
560 _slave->speed_and_position (slave_speed, slave_transport_frame);
562 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
564 if (!_slave->locked()) {
565 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
569 if (slave_transport_frame > _transport_frame) {
570 this_delta = slave_transport_frame - _transport_frame;
573 this_delta = _transport_frame - slave_transport_frame;
577 if (_slave->starting()) {
581 if (_slave->is_always_synced() ||
582 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
585 /* if the TC source is synced, then we assume that its
586 speed is binary: 0.0 or 1.0
589 if (slave_speed != 0.0f) {
595 /* if we are chasing and the average delta between us and the
596 master gets too big, we want to switch to silent
597 motion. so keep track of that here.
600 if (_slave_state == Running) {
601 calculate_moving_average_of_slave_delta(dir, abs(this_delta));
605 track_slave_state (slave_speed, slave_transport_frame, this_delta);
607 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
608 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
611 if (_slave_state == Running && !_slave->is_always_synced() && !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)) {
613 /* may need to varispeed to sync with slave */
615 if (_transport_speed != 0.0f) {
618 note that average_dir is +1 or -1
623 if (average_slave_delta == 0) {
627 delta = average_slave_delta;
628 delta *= average_dir;
632 if (slave_speed != 0.0) {
633 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
634 (int) (dir * this_delta),
638 slave_transport_frame,
639 average_slave_delta));
643 if (_slave->give_slave_full_control_over_transport_speed()) {
644 set_transport_speed (slave_speed, 0, false, false);
645 //std::cout << "set speed = " << slave_speed << "\n";
647 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
648 request_transport_speed (adjusted_speed);
649 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
650 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
654 if (!actively_recording() && (framecnt_t) average_slave_delta > _slave->resolution()) {
655 DEBUG_TRACE (DEBUG::Slave, string_compose ("average slave delta %1 greater than slave resolution %2 => silent motion\n", average_slave_delta, _slave->resolution()));
656 /* run routes as normal, but no disk output */
657 cerr << "sync too far apart " << average_slave_delta << ", NO disk audio for now\n";
658 DiskReader::set_no_disk_output (true);
662 if (!have_first_delta_accumulator) {
663 DEBUG_TRACE (DEBUG::Slave, "waiting for first slave delta accumulator to be ready\n");
664 /* run routes as normal, but no disk output */
665 cerr << "can't measure sync yet, NO disk audio for now\n";
666 DiskReader::set_no_disk_output (true);
673 if (!have_first_delta_accumulator) {
674 DiskReader::set_no_disk_output (true);
676 DiskReader::set_no_disk_output (false);
679 if ((_slave_state == Running) && (0 == (post_transport_work () & ~PostTransportSpeed))) {
680 /* speed is set, we're locked, and good to go */
681 cerr << "slave is locked, play disk audio ? " << !DiskReader::no_disk_output() << " delta = " << average_slave_delta << endl;
686 /* don't move at all */
687 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
693 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
695 if (delta_accumulator_cnt >= delta_accumulator_size) {
696 have_first_delta_accumulator = true;
697 delta_accumulator_cnt = 0;
700 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
701 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
704 if (have_first_delta_accumulator) {
705 average_slave_delta = 0L;
706 for (int i = 0; i < delta_accumulator_size; ++i) {
707 average_slave_delta += delta_accumulator[i];
709 average_slave_delta /= (int32_t) delta_accumulator_size;
710 if (average_slave_delta < 0L) {
712 average_slave_delta = average_slave_delta;
720 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
722 if (slave_speed != 0.0f) {
724 /* slave is running */
726 switch (_slave_state) {
728 if (_slave->requires_seekahead()) {
729 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
730 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
731 /* we can call locate() here because we are in process context */
732 locate (slave_wait_end, false, false);
733 _slave_state = Waiting;
737 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
739 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
740 average_slave_delta = 0L;
742 Location* al = _locations->auto_loop_location();
744 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
746 request_play_loop(false);
749 if (slave_transport_frame != _transport_frame) {
750 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
751 locate (slave_transport_frame, false, false);
753 _slave_state = Running;
762 if (_slave_state == Waiting) {
764 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
766 if (slave_transport_frame >= slave_wait_end) {
768 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
770 _slave_state = Running;
772 /* now perform a "micro-seek" within the disk buffers to realign ourselves
773 precisely with the master.
778 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
780 boost::shared_ptr<RouteList> rl = routes.reader();
781 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
782 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
783 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
790 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
791 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
793 tr->internal_playback_seek (frame_delta);
796 _transport_frame += frame_delta;
799 cerr << "cannot micro-seek\n";
805 if (_slave_state == Running && _transport_speed == 0.0f) {
806 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
810 } else { // slave_speed is 0
812 /* slave has stopped */
814 if (_transport_speed != 0.0f) {
815 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
819 if (slave_transport_frame != _transport_frame) {
820 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
821 force_locate (slave_transport_frame, false);
829 Session::process_without_events (pframes_t nframes)
831 bool session_needs_butler = false;
832 framecnt_t frames_moved;
834 if (!process_can_proceed()) {
839 if (!_exporting && _slave) {
840 if (!follow_slave (nframes)) {
841 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
846 if (_transport_speed == 0) {
851 if (locate_pending()) {
854 if (_transport_speed == 1.0) {
855 frames_moved = (framecnt_t) nframes;
857 interpolation.set_target_speed (_target_transport_speed);
858 interpolation.set_speed (_transport_speed);
859 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
863 if (!_exporting && !timecode_transmission_suspended()) {
864 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
867 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
869 framepos_t const stop_limit = compute_stop_limit ();
871 if (maybe_stop (stop_limit)) {
876 if (maybe_sync_start (nframes)) {
880 click (_transport_frame, nframes);
882 if (process_routes (nframes, session_needs_butler)) {
887 get_track_statistics ();
889 if (frames_moved < 0) {
890 decrement_transport_position (-frames_moved);
891 } else if (frames_moved) {
892 increment_transport_position (frames_moved);
895 maybe_stop (stop_limit);
896 check_declick_out ();
898 if (session_needs_butler) {
899 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
904 /** Process callback used when the auditioner is active.
905 * @param nframes number of frames to process.
908 Session::process_audition (pframes_t nframes)
911 boost::shared_ptr<RouteList> r = routes.reader ();
913 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
914 if (!(*i)->is_auditioner()) {
915 (*i)->silence (nframes);
919 /* run the auditioner, and if it says we need butler service, ask for it */
921 if (auditioner->play_audition (nframes) > 0) {
922 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
926 /* if using a monitor section, run it because otherwise we don't hear anything */
928 if (_monitor_out && auditioner->needs_monitor()) {
929 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
932 /* handle pending events */
934 while (pending_events.read (&ev, 1) == 1) {
938 /* if we are not in the middle of a state change,
939 and there are immediate events queued up,
943 while (!non_realtime_work_pending() && !immediate_events.empty()) {
944 SessionEvent *ev = immediate_events.front ();
945 immediate_events.pop_front ();
949 if (!auditioner->auditioning()) {
950 /* auditioner no longer active, so go back to the normal process callback */
951 process_function = &Session::process_with_events;
956 Session::maybe_sync_start (pframes_t & nframes)
958 pframes_t sync_offset;
960 if (!waiting_for_sync_offset) {
964 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
966 /* generate silence up to the sync point, then
967 adjust nframes + offset to reflect whatever
971 no_roll (sync_offset);
972 nframes -= sync_offset;
973 Port::increment_global_port_buffer_offset (sync_offset);
974 waiting_for_sync_offset = false;
977 return true; // done, nothing left to process
982 /* sync offset point is not within this process()
983 cycle, so just generate silence. and don't bother
984 with any fancy stuff here, just the minimal silence.
989 if (Config->get_locate_while_waiting_for_sync()) {
990 if (micro_locate (nframes)) {
991 /* XXX ERROR !!! XXX */
995 return true; // done, nothing left to process
1002 Session::queue_event (SessionEvent* ev)
1004 if (_state_of_the_state & Deletion) {
1006 } else if (_state_of_the_state & Loading) {
1009 Glib::Threads::Mutex::Lock lm (rb_write_lock);
1010 pending_events.write (&ev, 1);
1015 Session::set_next_event ()
1017 if (events.empty()) {
1018 next_event = events.end();
1022 if (next_event == events.end()) {
1023 next_event = events.begin();
1026 if ((*next_event)->action_frame > _transport_frame) {
1027 next_event = events.begin();
1030 for (; next_event != events.end(); ++next_event) {
1031 if ((*next_event)->action_frame >= _transport_frame) {
1038 Session::process_event (SessionEvent* ev)
1043 /* if we're in the middle of a state change (i.e. waiting
1044 for the butler thread to complete the non-realtime
1045 part of the change), we'll just have to queue this
1046 event for a time when the change is complete.
1049 if (non_realtime_work_pending()) {
1051 /* except locates, which we have the capability to handle */
1053 if (ev->type != SessionEvent::Locate) {
1054 immediate_events.insert (immediate_events.end(), ev);
1060 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1063 case SessionEvent::SetLoop:
1064 set_play_loop (ev->yes_or_no, ev->speed);
1067 case SessionEvent::AutoLoop:
1069 /* roll after locate, do not flush, set "with loop"
1070 true only if we are seamless looping
1072 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1078 case SessionEvent::AutoLoopDeclick:
1080 /* Request a declick fade-out and a fade-in; the fade-out will happen
1081 at the end of the loop, and the fade-in at the start.
1083 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1089 case SessionEvent::Locate:
1090 if (ev->yes_or_no) {
1091 /* args: do not roll after locate, do flush, not with loop */
1092 locate (ev->target_frame, false, true, false);
1094 /* args: do not roll after locate, do flush, not with loop */
1095 start_locate (ev->target_frame, false, true, false);
1097 _send_timecode_update = true;
1100 case SessionEvent::LocateRoll:
1101 if (ev->yes_or_no) {
1102 /* args: roll after locate, do flush, not with loop */
1103 locate (ev->target_frame, true, true, false);
1105 /* args: roll after locate, do flush, not with loop */
1106 start_locate (ev->target_frame, true, true, false);
1108 _send_timecode_update = true;
1111 case SessionEvent::Skip:
1112 if (Config->get_skip_playback()) {
1113 start_locate (ev->target_frame, true, true, false);
1114 _send_timecode_update = true;
1120 case SessionEvent::LocateRollLocate:
1121 // locate is handled by ::request_roll_at_and_return()
1122 _requested_return_frame = ev->target_frame;
1123 request_locate (ev->target2_frame, true);
1127 case SessionEvent::SetTransportSpeed:
1128 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1131 case SessionEvent::PunchIn:
1132 // cerr << "PunchIN at " << transport_frame() << endl;
1133 if (config.get_punch_in() && record_status() == Enabled && !preroll_record_punch_enabled()) {
1140 case SessionEvent::PunchOut:
1141 // cerr << "PunchOUT at " << transport_frame() << endl;
1142 if (config.get_punch_out() && !preroll_record_punch_enabled()) {
1143 step_back_from_record ();
1149 case SessionEvent::RecordStart:
1150 if (preroll_record_punch_enabled() && record_status() == Enabled) {
1157 case SessionEvent::StopOnce:
1158 if (!non_realtime_work_pending()) {
1159 _clear_event_type (SessionEvent::StopOnce);
1160 stop_transport (ev->yes_or_no);
1166 case SessionEvent::RangeStop:
1167 if (!non_realtime_work_pending()) {
1168 stop_transport (ev->yes_or_no);
1174 case SessionEvent::RangeLocate:
1175 /* args: roll after locate, do flush, not with loop */
1176 start_locate (ev->target_frame, true, true, false);
1181 case SessionEvent::Overwrite:
1182 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1185 case SessionEvent::SetSyncSource:
1186 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1187 use_sync_source (ev->slave);
1190 case SessionEvent::Audition:
1191 set_audition (ev->region);
1192 // drop reference to region
1193 ev->region.reset ();
1196 case SessionEvent::SetPlayAudioRange:
1197 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1200 case SessionEvent::CancelPlayAudioRange:
1204 case SessionEvent::RealTimeOperation:
1206 del = false; // other side of RT request needs to clean up
1209 case SessionEvent::AdjustPlaybackBuffering:
1210 schedule_playback_buffering_adjustment ();
1213 case SessionEvent::AdjustCaptureBuffering:
1214 schedule_capture_buffering_adjustment ();
1217 case SessionEvent::SetTimecodeTransmission:
1218 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1222 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1223 abort(); /*NOTREACHED*/
1228 del = del && !_remove_event (ev);
1237 Session::compute_stop_limit () const
1239 if (!Config->get_stop_at_session_end ()) {
1240 return max_framepos;
1244 return max_framepos;
1247 if (preroll_record_punch_enabled ()) {
1248 return max_framepos;
1251 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1252 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1254 if (actively_recording ()) {
1255 /* permanently recording */
1256 return max_framepos;
1257 } else if (punching_in && !punching_out) {
1258 /* punching in but never out */
1259 return max_framepos;
1260 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1261 /* punching in and punching out after session end */
1262 return max_framepos;
1265 return current_end_frame ();
1270 /* dedicated thread for signal emission.
1272 * while sending cross-thread signals from the process thread
1273 * is fine in general, PBD::Signal's use of boost::function and
1274 * boost:bind can produce a vast overhead which is not
1275 * acceptable for low latency.
1277 * This works around the issue by moving the boost overhead
1278 * out of the RT thread. The overall load is probably higher but
1279 * the realtime thread remains unaffected.
1283 Session::emit_route_signals ()
1285 // TODO use RAII to allow using these signals in other places
1286 BatchUpdateStart(); /* EMIT SIGNAL */
1287 boost::shared_ptr<RouteList> r = routes.reader ();
1288 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1289 (*ci)->emit_pending_signals ();
1291 BatchUpdateEnd(); /* EMIT SIGNAL */
1295 Session::emit_thread_start ()
1297 if (_rt_thread_active) {
1300 _rt_thread_active = true;
1302 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1303 _rt_thread_active = false;
1308 Session::emit_thread_terminate ()
1310 if (!_rt_thread_active) {
1313 _rt_thread_active = false;
1315 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1316 pthread_cond_signal (&_rt_emit_cond);
1317 pthread_mutex_unlock (&_rt_emit_mutex);
1321 pthread_join (_rt_emit_thread, &status);
1325 Session::emit_thread (void *arg)
1327 Session *s = static_cast<Session *>(arg);
1328 s->emit_thread_run ();
1334 Session::emit_thread_run ()
1336 pthread_mutex_lock (&_rt_emit_mutex);
1337 while (_rt_thread_active) {
1338 emit_route_signals();
1339 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1341 pthread_mutex_unlock (&_rt_emit_mutex);