be3f4f968b9c10a387d823ff7004455a2f421ca5
[ardour.git] / libs / ardour / session_process.cc
1 /*
2     Copyright (C) 1999-2002 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #include <cmath>
21 #include <cerrno>
22 #include <algorithm>
23 #include <unistd.h>
24
25 #include "pbd/error.h"
26 #include "pbd/enumwriter.h"
27
28 #include <glibmm/thread.h>
29
30 #include "ardour/ardour.h"
31 #include "ardour/audioengine.h"
32 #include "ardour/auditioner.h"
33 #include "ardour/butler.h"
34 #include "ardour/debug.h"
35 #include "ardour/process_thread.h"
36 #include "ardour/session.h"
37 #include "ardour/slave.h"
38 #include "ardour/timestamps.h"
39 #include "ardour/graph.h"
40 #include "ardour/audio_port.h"
41 #include "ardour/tempo.h"
42 #include "ardour/ticker.h"
43 #include "ardour/cycle_timer.h"
44
45 #include "midi++/manager.h"
46 #include "midi++/mmc.h"
47
48 #include "i18n.h"
49
50 #include <xmmintrin.h>
51
52 using namespace ARDOUR;
53 using namespace PBD;
54 using namespace std;
55
56 /** Called by the audio engine when there is work to be done with JACK.
57  * @param nframes Number of frames to process.
58  */
59
60 void
61 Session::process (pframes_t nframes)
62 {
63         framepos_t transport_at_start = _transport_frame;
64
65         MIDI::Manager::instance()->cycle_start(nframes);
66
67         _silent = false;
68
69         if (processing_blocked()) {
70                 _silent = true;
71                 return;
72         }
73
74         if (non_realtime_work_pending()) {
75                 if (!_butler->transport_work_requested ()) {
76                         post_transport ();
77                 }
78         }
79
80         _engine.main_thread()->get_buffers ();
81
82         (this->*process_function) (nframes);
83
84         _engine.main_thread()->drop_buffers ();
85
86         /* deliver MIDI clock. Note that we need to use the transport frame
87          * position at the start of process(), not the value at the end of
88          * it. We may already have ticked() because of a transport state
89          * change, for example.
90          */
91
92         try {
93                 if (!_engine.freewheeling() && Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) {
94                         midi_clock->tick (transport_at_start);
95                 }
96         } catch (...) {
97                 /* don't bother with a message */
98         }
99
100         SendFeedback (); /* EMIT SIGNAL */
101
102         MIDI::Manager::instance()->cycle_end();
103 }
104
105 int
106 Session::fail_roll (pframes_t nframes)
107 {
108         return no_roll (nframes);
109 }
110
111 int
112 Session::no_roll (pframes_t nframes)
113 {
114         PT_TIMING_CHECK (4);
115         
116         framepos_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ??
117         int ret = 0;
118         bool declick = get_transport_declick_required();
119         boost::shared_ptr<RouteList> r = routes.reader ();
120
121         if (_click_io) {
122                 _click_io->silence (nframes);
123         }
124
125         if (_process_graph) {
126                 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
127                 _process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
128         } else {
129                 PT_TIMING_CHECK (10);
130                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
131
132                         if ((*i)->is_hidden()) {
133                                 continue;
134                         }
135
136                         (*i)->set_pending_declick (declick);
137
138                         if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending())) {
139                                 error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
140                                 ret = -1;
141                                 break;
142                         }
143                 }
144                 PT_TIMING_CHECK (11);
145         }
146
147         PT_TIMING_CHECK (5);
148         return ret;
149 }
150
151 /** @param need_butler to be set to true by this method if it needs the butler,
152  *  otherwise it must be left alone.
153  */
154 int
155 Session::process_routes (pframes_t nframes, bool& need_butler)
156 {
157         int  declick = get_transport_declick_required();
158         boost::shared_ptr<RouteList> r = routes.reader ();
159
160         if (transport_sub_state & StopPendingCapture) {
161                 /* force a declick out */
162                 declick = -1;
163         }
164
165         const framepos_t start_frame = _transport_frame;
166         const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
167
168         if (_process_graph) {
169                 DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
170                 _process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler);
171         } else {
172
173                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
174
175                         int ret;
176
177                         if ((*i)->is_hidden()) {
178                                 continue;
179                         }
180
181                         (*i)->set_pending_declick (declick);
182
183                         bool b = false;
184
185                         if ((ret = (*i)->roll (nframes, start_frame, end_frame, declick, b)) < 0) {
186                                 stop_transport ();
187                                 return -1;
188                         }
189
190                         if (b) {
191                                 need_butler = true;
192                         }
193                 }
194         }
195
196         return 0;
197 }
198
199 /** @param need_butler to be set to true by this method if it needs the butler,
200  *  otherwise it must be left alone.
201  */
202 int
203 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
204 {
205         boost::shared_ptr<RouteList> r = routes.reader ();
206
207         const framepos_t start_frame = _transport_frame;
208         const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
209
210         if (_process_graph) {
211                 _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
212         } else {
213                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
214
215                         int ret;
216
217                         if ((*i)->is_hidden()) {
218                                 continue;
219                         }
220
221                         bool b = false;
222
223                         if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
224                                 stop_transport ();
225                                 return -1;
226                         }
227
228                         if (b) {
229                                 need_butler = true;
230                         }
231                 }
232         }
233
234         return 0;
235 }
236
237 void
238 Session::get_track_statistics ()
239 {
240         float pworst = 1.0f;
241         float cworst = 1.0f;
242
243         boost::shared_ptr<RouteList> rl = routes.reader();
244         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
245
246                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
247
248                 if (!tr || tr->hidden()) {
249                         continue;
250                 }
251
252                 pworst = min (pworst, tr->playback_buffer_load());
253                 cworst = min (cworst, tr->capture_buffer_load());
254         }
255
256         g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
257         g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
258
259         if (actively_recording()) {
260                 set_dirty();
261         }
262 }
263
264 /** Process callback used when the auditioner is not active */
265 void
266 Session::process_with_events (pframes_t nframes)
267 {
268         PT_TIMING_CHECK (3);
269         
270         SessionEvent*  ev;
271         pframes_t      this_nframes;
272         framepos_t     end_frame;
273         bool           session_needs_butler = false;
274         framecnt_t     frames_moved;
275
276         /* make sure the auditioner is silent */
277
278         if (auditioner) {
279                 auditioner->silence (nframes);
280         }
281
282         /* handle any pending events */
283
284         while (pending_events.read (&ev, 1) == 1) {
285                 merge_event (ev);
286         }
287
288         /* if we are not in the middle of a state change,
289            and there are immediate events queued up,
290            process them.
291         */
292
293         while (!non_realtime_work_pending() && !immediate_events.empty()) {
294                 SessionEvent *ev = immediate_events.front ();
295                 immediate_events.pop_front ();
296                 process_event (ev);
297         }
298
299         /* Decide on what to do with quarter-frame MTC during this cycle */
300
301         bool const was_sending_qf_mtc = _send_qf_mtc;
302         double const tolerance = Config->get_mtc_qf_speed_tolerance() / 100.0;
303
304         if (_transport_speed != 0) {
305                 _send_qf_mtc = (
306                         Config->get_send_mtc () &&
307                         _transport_speed >= (1 - tolerance) &&
308                         _transport_speed <= (1 + tolerance)
309                         );
310
311                 if (_send_qf_mtc && !was_sending_qf_mtc) {
312                         /* we will re-start quarter-frame MTC this cycle, so send a full update to set things up */
313                         _send_timecode_update = true;
314                 }
315
316                 if (Config->get_send_mtc() && !_send_qf_mtc && _pframes_since_last_mtc > (frame_rate () / 4)) {
317                         /* we're sending MTC, but we're not sending QF MTC at the moment, and it's been
318                            a quarter of a second since we sent anything at all, so send a full MTC update
319                            this cycle.
320                         */
321                         _send_timecode_update = true;
322                 }
323
324                 _pframes_since_last_mtc += nframes;
325         }
326
327         /* Events caused a transport change (or we re-started sending
328          * MTC), so send an MTC Full Frame (Timecode) message.  This
329          * is sent whether rolling or not, to give slaves an idea of
330          * ardour time on locates (and allow slow slaves to position
331          * and prepare for rolling)
332          */
333         if (_send_timecode_update) {
334                 send_full_time_code (_transport_frame);
335         }
336
337         if (!process_can_proceed()) {
338                 _silent = true;
339                 return;
340         }
341
342         if (events.empty() || next_event == events.end()) {
343                 process_without_events (nframes);
344                 return;
345         }
346
347         if (_transport_speed == 1.0) {
348                 frames_moved = (framecnt_t) nframes;
349         } else {
350                 interpolation.set_target_speed (fabs(_target_transport_speed));
351                 interpolation.set_speed (fabs(_transport_speed));
352                 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
353         }
354
355         end_frame = _transport_frame + frames_moved;
356
357         {
358                 SessionEvent* this_event;
359                 Events::iterator the_next_one;
360
361                 if (!process_can_proceed()) {
362                         _silent = true;
363                         return;
364                 }
365
366                 if (!_exporting && _slave) {
367                         if (!follow_slave (nframes)) {
368                                 return;
369                         }
370                 }
371
372                 if (_transport_speed == 0) {
373                         no_roll (nframes);
374                         return;
375                 }
376
377                 if (!_exporting && !timecode_transmission_suspended()) {
378                         send_midi_time_code_for_cycle (_transport_frame, end_frame, nframes);
379                 }
380
381                 framepos_t stop_limit = compute_stop_limit ();
382
383                 if (maybe_stop (stop_limit)) {
384                         no_roll (nframes);
385                         return;
386                 }
387
388                 this_event = *next_event;
389                 the_next_one = next_event;
390                 ++the_next_one;
391
392                 /* yes folks, here it is, the actual loop where we really truly
393                    process some audio
394                 */
395
396                 while (nframes) {
397
398                         this_nframes = nframes; /* real (jack) time relative */
399                         frames_moved = (framecnt_t) floor (_transport_speed * nframes); /* transport relative */
400
401                         /* running an event, position transport precisely to its time */
402                         if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
403                                 /* this isn't quite right for reverse play */
404                                 frames_moved = (framecnt_t) (this_event->action_frame - _transport_frame);
405                                 this_nframes = abs (floor(frames_moved / _transport_speed));
406                         }
407
408                         if (this_nframes) {
409
410                                 click (_transport_frame, this_nframes);
411
412                                 if (process_routes (this_nframes, session_needs_butler)) {
413                                         fail_roll (nframes);
414                                         return;
415                                 }
416
417                                 get_track_statistics ();
418
419                                 nframes -= this_nframes;
420
421                                 if (frames_moved < 0) {
422                                         decrement_transport_position (-frames_moved);
423                                 } else {
424                                         increment_transport_position (frames_moved);
425                                 }
426
427                                 maybe_stop (stop_limit);
428                                 check_declick_out ();
429                         }
430
431                         _engine.split_cycle (this_nframes);
432
433                         /* now handle this event and all others scheduled for the same time */
434
435                         while (this_event && this_event->action_frame == _transport_frame) {
436                                 process_event (this_event);
437
438                                 if (the_next_one == events.end()) {
439                                         this_event = 0;
440                                 } else {
441                                         this_event = *the_next_one;
442                                         ++the_next_one;
443                                 }
444                         }
445
446                         /* if an event left our state changing, do the right thing */
447
448                         if (nframes && non_realtime_work_pending()) {
449                                 no_roll (nframes);
450                                 break;
451                         }
452
453                         /* this is necessary to handle the case of seamless looping */
454                         end_frame = _transport_frame + floor (nframes * _transport_speed);
455                 }
456
457                 set_next_event ();
458
459         } /* implicit release of route lock */
460
461         if (session_needs_butler) {
462                 _butler->summon ();
463         }
464 }
465
466 void
467 Session::reset_slave_state ()
468 {
469         average_slave_delta = 1800;
470         delta_accumulator_cnt = 0;
471         have_first_delta_accumulator = false;
472         _slave_state = Stopped;
473 }
474
475 bool
476 Session::transport_locked () const
477 {
478         Slave* sl = _slave;
479
480         if (!locate_pending() && (!config.get_external_sync() || (sl && sl->ok() && sl->locked()))) {
481                 return true;
482         }
483
484         return false;
485 }
486
487 bool
488 Session::follow_slave (pframes_t nframes)
489 {
490         double slave_speed;
491         framepos_t slave_transport_frame;
492         framecnt_t this_delta;
493         int dir;
494
495         if (!_slave->ok()) {
496                 stop_transport ();
497                 config.set_external_sync (false);
498                 goto noroll;
499         }
500
501         _slave->speed_and_position (slave_speed, slave_transport_frame);
502
503         DEBUG_TRACE (DEBUG::Slave, string_compose ("Slave position %1 speed %2\n", slave_transport_frame, slave_speed));
504
505         if (!_slave->locked()) {
506                 DEBUG_TRACE (DEBUG::Slave, "slave not locked\n");
507                 goto noroll;
508         }
509
510         if (slave_transport_frame > _transport_frame) {
511                 this_delta = slave_transport_frame - _transport_frame;
512                 dir = 1;
513         } else {
514                 this_delta = _transport_frame - slave_transport_frame;
515                 dir = -1;
516         }
517
518         if (_slave->starting()) {
519                 slave_speed = 0.0f;
520         }
521
522         if (_slave->is_always_synced() || config.get_timecode_source_is_synced()) {
523
524                 /* if the TC source is synced, then we assume that its
525                    speed is binary: 0.0 or 1.0
526                 */
527
528                 if (slave_speed != 0.0f) {
529                         slave_speed = 1.0f;
530                 }
531
532         } else {
533
534                 /* if we are chasing and the average delta between us and the
535                    master gets too big, we want to switch to silent
536                    motion. so keep track of that here.
537                 */
538
539                 if (_slave_state == Running) {
540                         calculate_moving_average_of_slave_delta(dir, this_delta);
541                 }
542         }
543
544         track_slave_state (slave_speed, slave_transport_frame, this_delta);
545
546         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave state %1 @ %2 speed %3 cur delta %4 avg delta %5\n",
547                                                    _slave_state, slave_transport_frame, slave_speed, this_delta, average_slave_delta));
548
549
550         if (_slave_state == Running && !_slave->is_always_synced() && !config.get_timecode_source_is_synced()) {
551
552                 if (_transport_speed != 0.0f) {
553
554                         /*
555                            note that average_dir is +1 or -1
556                         */
557
558                         float delta;
559
560                         if (average_slave_delta == 0) {
561                                 delta = this_delta;
562                                 delta *= dir;
563                         } else {
564                                 delta = average_slave_delta;
565                                 delta *= average_dir;
566                         }
567
568 #ifndef NDEBUG
569                         if (slave_speed != 0.0) {
570                                 DEBUG_TRACE (DEBUG::Slave, string_compose ("delta = %1 speed = %2 ts = %3 M@%4 S@%5 avgdelta %6\n",
571                                                                            (int) (dir * this_delta),
572                                                                            slave_speed,
573                                                                            _transport_speed,
574                                                                            _transport_frame,
575                                                                            slave_transport_frame,
576                                                                            average_slave_delta));
577                         }
578 #endif
579
580                         if (_slave->give_slave_full_control_over_transport_speed()) {
581                                 set_transport_speed (slave_speed, false, false);
582                                 //std::cout << "set speed = " << slave_speed << "\n";
583                         } else {
584                                 float adjusted_speed = slave_speed + (1.5 * (delta /  float(_current_frame_rate)));
585                                 request_transport_speed (adjusted_speed);
586                                 DEBUG_TRACE (DEBUG::Slave, string_compose ("adjust using %1 towards %2 ratio %3 current %4 slave @ %5\n",
587                                                                            delta, adjusted_speed, adjusted_speed/slave_speed, _transport_speed,
588                                                                            slave_speed));
589                         }
590
591 #if 1
592                         if ((framecnt_t) abs(average_slave_delta) > _slave->resolution()) {
593                                 cerr << "average slave delta greater than slave resolution (" << _slave->resolution() << "), going to silent motion\n";
594                                 goto silent_motion;
595                         }
596 #endif
597                 }
598         }
599
600
601         if (_slave_state == Running && !non_realtime_work_pending()) {
602                 /* speed is set, we're locked, and good to go */
603                 return true;
604         }
605
606   silent_motion:
607         DEBUG_TRACE (DEBUG::Slave, "silent motion\n")
608         follow_slave_silently (nframes, slave_speed);
609
610   noroll:
611         /* don't move at all */
612         DEBUG_TRACE (DEBUG::Slave, "no roll\n")
613         no_roll (nframes);
614         return false;
615 }
616
617 void
618 Session::calculate_moving_average_of_slave_delta (int dir, framecnt_t this_delta)
619 {
620         if (delta_accumulator_cnt >= delta_accumulator_size) {
621                 have_first_delta_accumulator = true;
622                 delta_accumulator_cnt = 0;
623         }
624
625         if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
626                 delta_accumulator[delta_accumulator_cnt++] = (framecnt_t) dir *  (framecnt_t) this_delta;
627         }
628
629         if (have_first_delta_accumulator) {
630                 average_slave_delta = 0L;
631                 for (int i = 0; i < delta_accumulator_size; ++i) {
632                         average_slave_delta += delta_accumulator[i];
633                 }
634                 average_slave_delta /= (int32_t) delta_accumulator_size;
635                 if (average_slave_delta < 0L) {
636                         average_dir = -1;
637                         average_slave_delta = abs(average_slave_delta);
638                 } else {
639                         average_dir = 1;
640                 }
641         }
642 }
643
644 void
645 Session::track_slave_state (float slave_speed, framepos_t slave_transport_frame, framecnt_t /*this_delta*/)
646 {
647         if (slave_speed != 0.0f) {
648
649                 /* slave is running */
650
651                 switch (_slave_state) {
652                 case Stopped:
653                         if (_slave->requires_seekahead()) {
654                                 slave_wait_end = slave_transport_frame + _slave->seekahead_distance ();
655                                 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, but running, requires seekahead to %1\n", slave_wait_end));
656                                 /* we can call locate() here because we are in process context */
657                                 locate (slave_wait_end, false, false);
658                                 _slave_state = Waiting;
659
660                         } else {
661
662                                 _slave_state = Running;
663
664                                 Location* al = _locations->auto_loop_location();
665
666                                 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
667                                         // cancel looping
668                                         request_play_loop(false);
669                                 }
670
671                                 if (slave_transport_frame != _transport_frame) {
672                                         locate (slave_transport_frame, false, false);
673                                 }
674                         }
675                         break;
676
677                 case Waiting:
678                 default:
679                         break;
680                 }
681
682                 if (_slave_state == Waiting) {
683
684                         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave waiting at %1\n", slave_transport_frame));
685
686                         if (slave_transport_frame >= slave_wait_end) {
687
688                                 DEBUG_TRACE (DEBUG::Slave, string_compose ("slave start at %1 vs %2\n", slave_transport_frame, _transport_frame));
689
690                                 _slave_state = Running;
691
692                                 /* now perform a "micro-seek" within the disk buffers to realign ourselves
693                                    precisely with the master.
694                                 */
695
696
697                                 bool ok = true;
698                                 framecnt_t frame_delta = slave_transport_frame - _transport_frame;
699
700                                 boost::shared_ptr<RouteList> rl = routes.reader();
701                                 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
702                                         boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
703                                         if (tr && !tr->can_internal_playback_seek (frame_delta)) {
704                                                 ok = false;
705                                                 break;
706                                         }
707                                 }
708
709                                 if (ok) {
710                                         for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
711                                                 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
712                                                 if (tr) {
713                                                         tr->internal_playback_seek (frame_delta);
714                                                 }
715                                         }
716                                         _transport_frame += frame_delta;
717
718                                 } else {
719                                         cerr << "cannot micro-seek\n";
720                                         /* XXX what? */
721                                 }
722
723                                 memset (delta_accumulator, 0, sizeof (int32_t) * delta_accumulator_size);
724                                 average_slave_delta = 0L;
725                         }
726                 }
727
728                 if (_slave_state == Running && _transport_speed == 0.0f) {
729                         DEBUG_TRACE (DEBUG::Slave, "slave starts transport\n");
730                         start_transport ();
731                 }
732
733         } else { // slave_speed is 0
734
735                 /* slave has stopped */
736
737                 if (_transport_speed != 0.0f) {
738                         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stops transport: %1 frame %2 tf %3\n", slave_speed, slave_transport_frame, _transport_frame));
739                         stop_transport ();
740                 }
741
742                 if (slave_transport_frame != _transport_frame) {
743                         DEBUG_TRACE (DEBUG::Slave, string_compose ("slave stopped, move to %1\n", slave_transport_frame));
744                         force_locate (slave_transport_frame, false);
745                 }
746
747                 _slave_state = Stopped;
748         }
749 }
750
751 void
752 Session::follow_slave_silently (pframes_t nframes, float slave_speed)
753 {
754         if (slave_speed && _transport_speed) {
755
756                 /* something isn't right, but we should move with the master
757                    for now.
758                 */
759
760                 bool need_butler;
761
762                 silent_process_routes (nframes, need_butler);
763
764                 get_track_statistics ();
765
766                 if (need_butler) {
767                         _butler->summon ();
768                 }
769
770                 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
771
772                 if (frames_moved < 0) {
773                         decrement_transport_position (-frames_moved);
774                 } else {
775                         increment_transport_position (frames_moved);
776                 }
777
778                 framepos_t const stop_limit = compute_stop_limit ();
779                 maybe_stop (stop_limit);
780         }
781 }
782
783 void
784 Session::process_without_events (pframes_t nframes)
785 {
786         bool session_needs_butler = false;
787         framecnt_t frames_moved;
788
789         if (!process_can_proceed()) {
790                 _silent = true;
791                 return;
792         }
793
794         if (!_exporting && _slave) {
795                 if (!follow_slave (nframes)) {
796                         return;
797                 }
798         }
799
800         if (_transport_speed == 0) {
801                 fail_roll (nframes);
802                 return;
803         }
804
805         if (_transport_speed == 1.0) {
806                 frames_moved = (framecnt_t) nframes;
807         } else {
808                 interpolation.set_target_speed (fabs(_target_transport_speed));
809                 interpolation.set_speed (fabs(_transport_speed));
810                 frames_moved = (framecnt_t) interpolation.interpolate (0, nframes, 0, 0);
811         }
812
813         if (!_exporting && !timecode_transmission_suspended()) {
814                 send_midi_time_code_for_cycle (_transport_frame, _transport_frame + frames_moved, nframes);
815         }
816
817         framepos_t const stop_limit = compute_stop_limit ();
818
819         if (maybe_stop (stop_limit)) {
820                 fail_roll (nframes);
821                 return;
822         }
823
824         if (maybe_sync_start (nframes)) {
825                 return;
826         }
827
828         click (_transport_frame, nframes);
829
830         if (process_routes (nframes, session_needs_butler)) {
831                 fail_roll (nframes);
832                 return;
833         }
834
835         get_track_statistics ();
836
837         /* XXX: I'm not sure whether this is correct, but at least it
838            matches process_with_events, so that this new frames_moved
839            is -ve when transport speed is -ve.  This means that the
840            transport position is updated correctly when we are in
841            reverse.  It seems a bit wrong that we're not using the
842            interpolator to compute this.
843         */
844
845         frames_moved = (framecnt_t) floor (_transport_speed * nframes);
846
847         if (frames_moved < 0) {
848                 decrement_transport_position (-frames_moved);
849         } else {
850                 increment_transport_position (frames_moved);
851         }
852
853         maybe_stop (stop_limit);
854         check_declick_out ();
855
856         if (session_needs_butler) {
857                 _butler->summon ();
858         }
859 }
860
861 /** Process callback used when the auditioner is active.
862  * @param nframes number of frames to process.
863  */
864 void
865 Session::process_audition (pframes_t nframes)
866 {
867         SessionEvent* ev;
868         boost::shared_ptr<RouteList> r = routes.reader ();
869
870         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
871                 if (!(*i)->is_hidden()) {
872                         (*i)->silence (nframes);
873                 }
874         }
875
876         /* run the auditioner, and if it says we need butler service, ask for it */
877
878         if (auditioner->play_audition (nframes) > 0) {
879                 _butler->summon ();
880         }
881
882         /* if using a monitor section, run it because otherwise we don't hear anything */
883
884         if (auditioner->needs_monitor()) {
885                 _monitor_out->passthru (_transport_frame, _transport_frame + nframes, nframes, false);
886         }
887
888         /* handle pending events */
889
890         while (pending_events.read (&ev, 1) == 1) {
891                 merge_event (ev);
892         }
893
894         /* if we are not in the middle of a state change,
895            and there are immediate events queued up,
896            process them.
897         */
898
899         while (!non_realtime_work_pending() && !immediate_events.empty()) {
900                 SessionEvent *ev = immediate_events.front ();
901                 immediate_events.pop_front ();
902                 process_event (ev);
903         }
904
905         if (!auditioner->auditioning()) {
906                 /* auditioner no longer active, so go back to the normal process callback */
907                 process_function = &Session::process_with_events;
908         }
909 }
910
911 bool
912 Session::maybe_sync_start (pframes_t & nframes)
913 {
914         pframes_t sync_offset;
915
916         if (!waiting_for_sync_offset) {
917                 return false;
918         }
919
920         if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
921
922                 /* generate silence up to the sync point, then
923                    adjust nframes + offset to reflect whatever
924                    is left to do.
925                 */
926
927                 no_roll (sync_offset);
928                 nframes -= sync_offset;
929                 Port::increment_global_port_buffer_offset (sync_offset);
930                 waiting_for_sync_offset = false;
931
932                 if (nframes == 0) {
933                         return true; // done, nothing left to process
934                 }
935
936         } else {
937
938                 /* sync offset point is not within this process()
939                    cycle, so just generate silence. and don't bother
940                    with any fancy stuff here, just the minimal silence.
941                 */
942
943                 _silent = true;
944
945                 if (Config->get_locate_while_waiting_for_sync()) {
946                         if (micro_locate (nframes)) {
947                                 /* XXX ERROR !!! XXX */
948                         }
949                 }
950
951                 return true; // done, nothing left to process
952         }
953
954         return false;
955 }
956
957 void
958 Session::queue_event (SessionEvent* ev)
959 {
960         if (_state_of_the_state & Deletion) {
961                 return;
962         } else if (_state_of_the_state & Loading) {
963                 merge_event (ev);
964         } else {
965                 pending_events.write (&ev, 1);
966         }
967 }
968
969 void
970 Session::set_next_event ()
971 {
972         if (events.empty()) {
973                 next_event = events.end();
974                 return;
975         }
976
977         if (next_event == events.end()) {
978                 next_event = events.begin();
979         }
980
981         if ((*next_event)->action_frame > _transport_frame) {
982                 next_event = events.begin();
983         }
984
985         for (; next_event != events.end(); ++next_event) {
986                 if ((*next_event)->action_frame >= _transport_frame) {
987                         break;
988                 }
989         }
990 }
991
992 void
993 Session::process_event (SessionEvent* ev)
994 {
995         bool remove = true;
996         bool del = true;
997
998         /* if we're in the middle of a state change (i.e. waiting
999            for the butler thread to complete the non-realtime
1000            part of the change), we'll just have to queue this
1001            event for a time when the change is complete.
1002         */
1003
1004         if (non_realtime_work_pending()) {
1005
1006                 /* except locates, which we have the capability to handle */
1007
1008                 if (ev->type != SessionEvent::Locate) {
1009                         immediate_events.insert (immediate_events.end(), ev);
1010                         _remove_event (ev);
1011                         return;
1012                 }
1013         }
1014
1015         DEBUG_TRACE (DEBUG::SessionEvents, string_compose ("Processing event: %1 @ %2\n", enum_2_string (ev->type), _transport_frame));
1016
1017         switch (ev->type) {
1018         case SessionEvent::SetLoop:
1019                 set_play_loop (ev->yes_or_no);
1020                 break;
1021
1022         case SessionEvent::AutoLoop:
1023                 if (play_loop) {
1024                         start_locate (ev->target_frame, true, false, Config->get_seamless_loop());
1025                 }
1026                 remove = false;
1027                 del = false;
1028                 break;
1029
1030         case SessionEvent::Locate:
1031                 if (ev->yes_or_no) {
1032                         // cerr << "forced locate to " << ev->target_frame << endl;
1033                         locate (ev->target_frame, false, true, false);
1034                 } else {
1035                         // cerr << "soft locate to " << ev->target_frame << endl;
1036                         start_locate (ev->target_frame, false, true, false);
1037                 }
1038                 _send_timecode_update = true;
1039                 break;
1040
1041         case SessionEvent::LocateRoll:
1042                 if (ev->yes_or_no) {
1043                         // cerr << "forced locate to+roll " << ev->target_frame << endl;
1044                         locate (ev->target_frame, true, true, false);
1045                 } else {
1046                         // cerr << "soft locate to+roll " << ev->target_frame << endl;
1047                         start_locate (ev->target_frame, true, true, false);
1048                 }
1049                 _send_timecode_update = true;
1050                 break;
1051
1052         case SessionEvent::LocateRollLocate:
1053                 // locate is handled by ::request_roll_at_and_return()
1054                 _requested_return_frame = ev->target_frame;
1055                 request_locate (ev->target2_frame, true);
1056                 break;
1057
1058
1059         case SessionEvent::SetTransportSpeed:
1060                 set_transport_speed (ev->speed, ev->yes_or_no, ev->second_yes_or_no);
1061                 break;
1062
1063         case SessionEvent::PunchIn:
1064                 // cerr << "PunchIN at " << transport_frame() << endl;
1065                 if (config.get_punch_in() && record_status() == Enabled) {
1066                         enable_record ();
1067                 }
1068                 remove = false;
1069                 del = false;
1070                 break;
1071
1072         case SessionEvent::PunchOut:
1073                 // cerr << "PunchOUT at " << transport_frame() << endl;
1074                 if (config.get_punch_out()) {
1075                         step_back_from_record ();
1076                 }
1077                 remove = false;
1078                 del = false;
1079                 break;
1080
1081         case SessionEvent::StopOnce:
1082                 if (!non_realtime_work_pending()) {
1083                         stop_transport (ev->yes_or_no);
1084                         _clear_event_type (SessionEvent::StopOnce);
1085                 }
1086                 remove = false;
1087                 del = false;
1088                 break;
1089
1090         case SessionEvent::RangeStop:
1091                 if (!non_realtime_work_pending()) {
1092                         stop_transport (ev->yes_or_no);
1093                 }
1094                 remove = false;
1095                 del = false;
1096                 break;
1097
1098         case SessionEvent::RangeLocate:
1099                 start_locate (ev->target_frame, true, true, false);
1100                 remove = false;
1101                 del = false;
1102                 break;
1103
1104         case SessionEvent::Overwrite:
1105                 overwrite_some_buffers (static_cast<Track*>(ev->ptr));
1106                 break;
1107
1108         case SessionEvent::SetTrackSpeed:
1109                 set_track_speed (static_cast<Track*> (ev->ptr), ev->speed);
1110                 break;
1111
1112         case SessionEvent::SetSyncSource:
1113                 use_sync_source (ev->slave);
1114                 break;
1115
1116         case SessionEvent::Audition:
1117                 set_audition (ev->region);
1118                 // drop reference to region
1119                 ev->region.reset ();
1120                 break;
1121
1122         case SessionEvent::InputConfigurationChange:
1123                 add_post_transport_work (PostTransportInputChange);
1124                 _butler->schedule_transport_work ();
1125                 break;
1126
1127         case SessionEvent::SetPlayAudioRange:
1128                 set_play_range (ev->audio_range, (ev->speed == 1.0f));
1129                 break;
1130
1131         case SessionEvent::RealTimeOperation:
1132                 process_rtop (ev);
1133                 del = false; // other side of RT request needs to clean up
1134                 break;
1135
1136         case SessionEvent::AdjustPlaybackBuffering:
1137                 schedule_playback_buffering_adjustment ();
1138                 break;
1139
1140         case SessionEvent::AdjustCaptureBuffering:
1141                 schedule_capture_buffering_adjustment ();
1142                 break;
1143
1144         case SessionEvent::SetTimecodeTransmission:
1145                 g_atomic_int_set (&_suspend_timecode_transmission, ev->yes_or_no ? 0 : 1);
1146                 break;
1147
1148         default:
1149           fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg;
1150                 /*NOTREACHED*/
1151                 break;
1152         };
1153
1154         if (remove) {
1155                 del = del && !_remove_event (ev);
1156         }
1157
1158         if (del) {
1159                 delete ev;
1160         }
1161 }
1162
1163 framepos_t
1164 Session::compute_stop_limit () const
1165 {
1166         if (!Config->get_stop_at_session_end ()) {
1167                 return max_framepos;
1168         }
1169         
1170         bool const punching_in = (config.get_punch_in () && _locations->auto_punch_location());
1171         bool const punching_out = (config.get_punch_out () && _locations->auto_punch_location());
1172
1173         if (actively_recording ()) {
1174                 /* permanently recording */
1175                 return max_framepos;
1176         } else if (punching_in && !punching_out) {
1177                 /* punching in but never out */
1178                 return max_framepos;
1179         } else if (punching_in && punching_out && _locations->auto_punch_location()->end() > current_end_frame()) {
1180                 /* punching in and punching out after session end */
1181                 return max_framepos;
1182         }
1183
1184         return current_end_frame ();
1185 }