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