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