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