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)) {
416 cerr << "P-w-E: FS fail\n";
421 if (_transport_speed == 0) {
422 cerr << "P-w-E: ts = 0\n";
427 if (!_exporting && !timecode_transmission_suspended()) {
428 send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
431 ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
433 framepos_t stop_limit = compute_stop_limit ();
435 if (maybe_stop (stop_limit)) {
436 cerr << "P-w-E: mebbe stop\n";
441 this_event = *next_event;
442 the_next_one = next_event;
445 /* yes folks, here it is, the actual loop where we really truly
451 this_nframes = nframes; /* real (jack) time relative */
452 if (locate_pending()) {
455 frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
458 /* running an event, position transport precisely to its time */
459 if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
460 /* this isn't quite right for reverse play */
461 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
462 this_nframes = abs (floor(frames_moved / _transport_speed));
465 try_run_lua (this_nframes);
469 click (_transport_frame, this_nframes);
471 if (process_routes (this_nframes, session_needs_butler)) {
472 cerr << "P-w-E: PR fail\n";
477 get_track_statistics ();
479 nframes -= this_nframes;
481 if (frames_moved < 0) {
482 decrement_transport_position (-frames_moved);
483 } else if (frames_moved) {
484 increment_transport_position (frames_moved);
487 cerr << "P-w-E: ts now = " << _transport_frame << endl;
489 maybe_stop (stop_limit);
490 check_declick_out ();
494 _engine.split_cycle (this_nframes);
497 /* now handle this event and all others scheduled for the same time */
499 while (this_event && this_event->action_frame == _transport_frame) {
500 process_event (this_event);
502 if (the_next_one == events.end()) {
505 this_event = *the_next_one;
510 /* if an event left our state changing, do the right thing */
512 if (nframes && non_realtime_work_pending()) {
513 cerr << "P-w-E: nrtwp no roll\n";
518 /* this is necessary to handle the case of seamless looping */
519 end_frame = _transport_frame + floor (nframes * _transport_speed);
524 } /* implicit release of route lock */
526 cerr << "P-w-E: final ts = " << _transport_frame << endl;
528 if (session_needs_butler) {
529 DEBUG_TRACE (DEBUG::Butler, "p-with-events: session needs butler, call it\n");
535 Session::reset_slave_state ()
537 average_slave_delta = 1800;
538 delta_accumulator_cnt = 0;
539 have_first_delta_accumulator = false;
540 _slave_state = Stopped;
541 DiskReader::set_no_disk_output (false);
545 Session::transport_locked () const
549 if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
557 Session::follow_slave (pframes_t nframes)
560 framepos_t slave_transport_frame;
561 framecnt_t this_delta;
566 config.set_external_sync (false);
570 _slave->speed_and_position (slave_speed, slave_transport_frame);
572 DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
574 if (!_slave->locked()) {
575 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
579 if (slave_transport_frame > _transport_frame) {
580 this_delta = slave_transport_frame - _transport_frame;
583 this_delta = _transport_frame - slave_transport_frame;
587 if (_slave->starting()) {
591 if (_slave->is_always_synced() ||
592 (Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)
595 /* if the TC source is synced, then we assume that its
596 speed is binary: 0.0 or 1.0
599 if (slave_speed != 0.0f) {
605 /* if we are chasing and the average delta between us and the
606 master gets too big, we want to switch to silent
607 motion. so keep track of that here.
610 if (_slave_state == Running) {
611 calculate_moving_average_of_slave_delta(dir, abs(this_delta));
615 track_slave_state (slave_speed, slave_transport_frame, this_delta);
617 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
618 _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
621 if (_slave_state == Running && !_slave->is_always_synced() && !(Config->get_timecode_source_is_synced() && (dynamic_cast<TimecodeSlave*>(_slave)) != 0)) {
623 /* may need to varispeed to sync with slave */
625 if (_transport_speed != 0.0f) {
628 note that average_dir is +1 or -1
633 if (average_slave_delta == 0) {
637 delta = average_slave_delta;
638 delta *= average_dir;
642 if (slave_speed != 0.0) {
643 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
644 (int) (dir * this_delta),
648 slave_transport_frame,
649 average_slave_delta));
653 if (_slave->give_slave_full_control_over_transport_speed()) {
654 set_transport_speed (slave_speed, 0, false, false);
655 //std::cout << "set speed = " << slave_speed << "\n";
657 float adjusted_speed = slave_speed + (1.5 * (delta / float(_current_frame_rate)));
658 request_transport_speed (adjusted_speed);
659 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
660 delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
664 if (!actively_recording() && (framecnt_t) average_slave_delta > _slave->resolution()) {
665 DEBUG_TRACE (DEBUG::Slave, string_compose ("average slave delta %1 greater than slave resolution %2 => no disk output\n", average_slave_delta, _slave->resolution()));
666 /* run routes as normal, but no disk output */
667 DiskReader::set_no_disk_output (true);
671 if (!have_first_delta_accumulator) {
672 DEBUG_TRACE (DEBUG::Slave, "waiting for first slave delta accumulator to be ready, no disk output\n");
673 /* run routes as normal, but no disk output */
674 DiskReader::set_no_disk_output (true);
681 if (!have_first_delta_accumulator) {
682 DEBUG_TRACE (DEBUG::Slave, "still waiting to compute slave delta, no disk output\n");
683 DiskReader::set_no_disk_output (true);
685 DiskReader::set_no_disk_output (false);
688 if ((_slave_state == Running) && (0 == (post_transport_work () & ~PostTransportSpeed))) {
689 /* speed is set, we're locked, and good to go */
694 /* don't move at all */
695 DEBUG_TRACE (DEBUG::Slave, "no roll\n")
701 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
703 if (delta_accumulator_cnt >= delta_accumulator_size) {
704 have_first_delta_accumulator = true;
705 delta_accumulator_cnt = 0;
708 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
709 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir * (framecnt_t) this_delta;
712 if (have_first_delta_accumulator) {
713 average_slave_delta = 0L;
714 for (int i = 0; i < delta_accumulator_size; ++i) {
715 average_slave_delta += delta_accumulator[i];
717 average_slave_delta /= (int32_t) delta_accumulator_size;
718 if (average_slave_delta < 0L) {
720 average_slave_delta = average_slave_delta;
728 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
730 if (slave_speed != 0.0f) {
732 /* slave is running */
734 switch (_slave_state) {
736 if (_slave->requires_seekahead()) {
737 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
738 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
739 /* we can call locate() here because we are in process context */
740 locate (slave_wait_end, false, false);
741 _slave_state = Waiting;
745 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped -> running at %1\n", slave_transport_frame));
747 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
748 average_slave_delta = 0L;
750 Location* al = _locations->auto_loop_location();
752 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
754 request_play_loop(false);
757 if (slave_transport_frame != _transport_frame) {
758 DEBUG_TRACE (DEBUG::Slave, string_compose ("require locate to run. eng: %1 -> sl: %2\n", _transport_frame, slave_transport_frame));
759 locate (slave_transport_frame, false, false);
761 _slave_state = Running;
770 if (_slave_state == Waiting) {
772 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
774 if (slave_transport_frame >= slave_wait_end) {
776 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
778 _slave_state = Running;
780 /* now perform a "micro-seek" within the disk buffers to realign ourselves
781 precisely with the master.
786 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
788 boost::shared_ptr<RouteList> rl = routes.reader();
789 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
790 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
791 if (tr && !tr->can_internal_playback_seek (frame_delta)) {
798 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
799 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
801 tr->internal_playback_seek (frame_delta);
804 _transport_frame += frame_delta;
807 cerr << "cannot micro-seek\n";
813 if (_slave_state == Running && _transport_speed == 0.0f) {
814 DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
818 } else { // slave_speed is 0
820 /* slave has stopped */
822 if (_transport_speed != 0.0f) {
823 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
827 if (slave_transport_frame != _transport_frame) {
828 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
829 force_locate (slave_transport_frame, false);
837 Session::process_without_events (pframes_t nframes)
839 bool session_needs_butler = false;
840 framecnt_t frames_moved;
842 if (!process_can_proceed()) {
847 if (!_exporting && _slave) {
848 if (!follow_slave (nframes)) {
849 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame, 0, 0 , nframes);
850 cerr << "p-WO-E: FS fail\n";
855 if (_transport_speed == 0) {
856 cerr << "p-WO-E: ts = 0\n";
861 if (locate_pending()) {
862 cerr << "p-WO-E: locate still pending\n";
865 if (_transport_speed == 1.0) {
866 frames_moved = (framecnt_t) nframes;
868 interpolation.set_target_speed (_target_transport_speed);
869 interpolation.set_speed (_transport_speed);
870 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
871 cerr << "p-WO-E: current speed : " << _transport_speed << " interpolate says " << frames_moved << endl;
875 cerr << "p-WO-E: will move " << frames_moved << endl;
877 if (!_exporting && !timecode_transmission_suspended()) {
878 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
881 ltc_tx_send_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, _target_transport_speed, _transport_speed, nframes);
883 framepos_t const stop_limit = compute_stop_limit ();
885 if (maybe_stop (stop_limit)) {
886 cerr << "p-WO-E: mebbe stop\n";
891 if (maybe_sync_start (nframes)) {
892 cerr << "p-WO-E: sync start said no\n";
896 click (_transport_frame, nframes);
898 if (process_routes (nframes, session_needs_butler)) {
899 cerr << "p-WO-E: pr failed\n";
904 get_track_statistics ();
906 if (frames_moved < 0) {
907 decrement_transport_position (-frames_moved);
908 } else if (frames_moved) {
909 increment_transport_position (frames_moved);
912 cerr << "p-WO-E: ts now " << _transport_frame << endl;
914 maybe_stop (stop_limit);
915 check_declick_out ();
917 if (session_needs_butler) {
918 DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
923 /** Process callback used when the auditioner is active.
924 * @param nframes number of frames to process.
927 Session::process_audition (pframes_t nframes)
930 boost::shared_ptr<RouteList> r = routes.reader ();
932 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
933 if (!(*i)->is_auditioner()) {
934 (*i)->silence (nframes);
938 /* run the auditioner, and if it says we need butler service, ask for it */
940 if (auditioner->play_audition (nframes) > 0) {
941 DEBUG_TRACE (DEBUG::Butler, "auditioner needs butler, call it\n");
945 /* if using a monitor section, run it because otherwise we don't hear anything */
947 if (_monitor_out && auditioner->needs_monitor()) {
948 _monitor_out->monitor_run (_transport_frame, _transport_frame + nframes, nframes, false);
951 /* handle pending events */
953 while (pending_events.read (&ev, 1) == 1) {
957 /* if we are not in the middle of a state change,
958 and there are immediate events queued up,
962 while (!non_realtime_work_pending() && !immediate_events.empty()) {
963 SessionEvent *ev = immediate_events.front ();
964 immediate_events.pop_front ();
968 if (!auditioner->auditioning()) {
969 /* auditioner no longer active, so go back to the normal process callback */
970 process_function = &Session::process_with_events;
975 Session::maybe_sync_start (pframes_t & nframes)
977 pframes_t sync_offset;
979 if (!waiting_for_sync_offset) {
983 if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
985 /* generate silence up to the sync point, then
986 adjust nframes + offset to reflect whatever
990 no_roll (sync_offset);
991 nframes -= sync_offset;
992 Port::increment_global_port_buffer_offset (sync_offset);
993 waiting_for_sync_offset = false;
996 return true; // done, nothing left to process
1001 /* sync offset point is not within this process()
1002 cycle, so just generate silence. and don't bother
1003 with any fancy stuff here, just the minimal silence.
1008 if (Config->get_locate_while_waiting_for_sync()) {
1009 if (micro_locate (nframes)) {
1010 /* XXX ERROR !!! XXX */
1014 return true; // done, nothing left to process
1021 Session::queue_event (SessionEvent* ev)
1023 if (_state_of_the_state & Deletion) {
1025 } else if (_state_of_the_state & Loading) {
1028 Glib::Threads::Mutex::Lock lm (rb_write_lock);
1029 pending_events.write (&ev, 1);
1034 Session::set_next_event ()
1036 if (events.empty()) {
1037 next_event = events.end();
1041 if (next_event == events.end()) {
1042 next_event = events.begin();
1045 if ((*next_event)->action_frame > _transport_frame) {
1046 next_event = events.begin();
1049 for (; next_event != events.end(); ++next_event) {
1050 if ((*next_event)->action_frame >= _transport_frame) {
1057 Session::process_event (SessionEvent* ev)
1062 /* if we're in the middle of a state change (i.e. waiting
1063 for the butler thread to complete the non-realtime
1064 part of the change), we'll just have to queue this
1065 event for a time when the change is complete.
1068 if (non_realtime_work_pending()) {
1070 /* except locates, which we have the capability to handle */
1072 if (ev->type != SessionEvent::Locate) {
1073 immediate_events.insert (immediate_events.end(), ev);
1079 DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1082 case SessionEvent::SetLoop:
1083 set_play_loop (ev->yes_or_no, ev->speed);
1086 case SessionEvent::AutoLoop:
1088 /* roll after locate, do not flush, set "with loop"
1089 true only if we are seamless looping
1091 start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1097 case SessionEvent::AutoLoopDeclick:
1099 /* Request a declick fade-out and a fade-in; the fade-out will happen
1100 at the end of the loop, and the fade-in at the start.
1102 transport_sub_state |= (PendingLoopDeclickOut | PendingLoopDeclickIn);
1108 case SessionEvent::Locate:
1109 if (ev->yes_or_no) {
1110 /* args: do not roll after locate, do flush, not with loop */
1111 locate (ev->target_frame, false, true, false);
1113 /* args: do not roll after locate, do flush, not with loop */
1114 start_locate (ev->target_frame, false, true, false);
1116 _send_timecode_update = true;
1119 case SessionEvent::LocateRoll:
1120 if (ev->yes_or_no) {
1121 /* args: roll after locate, do flush, not with loop */
1122 locate (ev->target_frame, true, true, false);
1124 /* args: roll after locate, do flush, not with loop */
1125 start_locate (ev->target_frame, true, true, false);
1127 _send_timecode_update = true;
1130 case SessionEvent::Skip:
1131 if (Config->get_skip_playback()) {
1132 start_locate (ev->target_frame, true, true, false);
1133 _send_timecode_update = true;
1139 case SessionEvent::LocateRollLocate:
1140 // locate is handled by ::request_roll_at_and_return()
1141 _requested_return_frame = ev->target_frame;
1142 request_locate (ev->target2_frame, true);
1146 case SessionEvent::SetTransportSpeed:
1147 set_transport_speed (ev->speed, ev->target_frame, ev->yes_or_no, ev->second_yes_or_no, ev->third_yes_or_no);
1150 case SessionEvent::PunchIn:
1151 // cerr << "PunchIN at " << transport_frame() << endl;
1152 if (config.get_punch_in() && record_status() == Enabled && !preroll_record_punch_enabled()) {
1159 case SessionEvent::PunchOut:
1160 // cerr << "PunchOUT at " << transport_frame() << endl;
1161 if (config.get_punch_out() && !preroll_record_punch_enabled()) {
1162 step_back_from_record ();
1168 case SessionEvent::RecordStart:
1169 if (preroll_record_punch_enabled() && record_status() == Enabled) {
1176 case SessionEvent::StopOnce:
1177 if (!non_realtime_work_pending()) {
1178 _clear_event_type (SessionEvent::StopOnce);
1179 stop_transport (ev->yes_or_no);
1185 case SessionEvent::RangeStop:
1186 if (!non_realtime_work_pending()) {
1187 stop_transport (ev->yes_or_no);
1193 case SessionEvent::RangeLocate:
1194 /* args: roll after locate, do flush, not with loop */
1195 start_locate (ev->target_frame, true, true, false);
1200 case SessionEvent::Overwrite:
1201 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1204 case SessionEvent::SetSyncSource:
1205 DEBUG_TRACE (DEBUG::Slave, "seen request for new slave\n");
1206 use_sync_source (ev->slave);
1209 case SessionEvent::Audition:
1210 set_audition (ev->region);
1211 // drop reference to region
1212 ev->region.reset ();
1215 case SessionEvent::SetPlayAudioRange:
1216 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1219 case SessionEvent::CancelPlayAudioRange:
1223 case SessionEvent::RealTimeOperation:
1225 del = false; // other side of RT request needs to clean up
1228 case SessionEvent::AdjustPlaybackBuffering:
1229 schedule_playback_buffering_adjustment ();
1232 case SessionEvent::AdjustCaptureBuffering:
1233 schedule_capture_buffering_adjustment ();
1236 case SessionEvent::SetTimecodeTransmission:
1237 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1241 fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1242 abort(); /*NOTREACHED*/
1247 del = del && !_remove_event (ev);
1256 Session::compute_stop_limit () const
1258 if (!Config->get_stop_at_session_end ()) {
1259 return max_framepos;
1263 return max_framepos;
1266 if (preroll_record_punch_enabled ()) {
1267 return max_framepos;
1270 bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1271 bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1273 if (actively_recording ()) {
1274 /* permanently recording */
1275 return max_framepos;
1276 } else if (punching_in && !punching_out) {
1277 /* punching in but never out */
1278 return max_framepos;
1279 } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1280 /* punching in and punching out after session end */
1281 return max_framepos;
1284 return current_end_frame ();
1289 /* dedicated thread for signal emission.
1291 * while sending cross-thread signals from the process thread
1292 * is fine in general, PBD::Signal's use of boost::function and
1293 * boost:bind can produce a vast overhead which is not
1294 * acceptable for low latency.
1296 * This works around the issue by moving the boost overhead
1297 * out of the RT thread. The overall load is probably higher but
1298 * the realtime thread remains unaffected.
1302 Session::emit_route_signals ()
1304 // TODO use RAII to allow using these signals in other places
1305 BatchUpdateStart(); /* EMIT SIGNAL */
1306 boost::shared_ptr<RouteList> r = routes.reader ();
1307 for (RouteList::const_iterator ci = r->begin(); ci != r->end(); ++ci) {
1308 (*ci)->emit_pending_signals ();
1310 BatchUpdateEnd(); /* EMIT SIGNAL */
1314 Session::emit_thread_start ()
1316 if (_rt_thread_active) {
1319 _rt_thread_active = true;
1321 if (pthread_create (&_rt_emit_thread, NULL, emit_thread, this)) {
1322 _rt_thread_active = false;
1327 Session::emit_thread_terminate ()
1329 if (!_rt_thread_active) {
1332 _rt_thread_active = false;
1334 if (pthread_mutex_lock (&_rt_emit_mutex) == 0) {
1335 pthread_cond_signal (&_rt_emit_cond);
1336 pthread_mutex_unlock (&_rt_emit_mutex);
1340 pthread_join (_rt_emit_thread, &status);
1344 Session::emit_thread (void *arg)
1346 Session *s = static_cast<Session *>(arg);
1347 s->emit_thread_run ();
1353 Session::emit_thread_run ()
1355 pthread_mutex_lock (&_rt_emit_mutex);
1356 while (_rt_thread_active) {
1357 emit_route_signals();
1358 pthread_cond_wait (&_rt_emit_cond, &_rt_emit_mutex);
1360 pthread_mutex_unlock (&_rt_emit_mutex);