added RCU handling of Session route list, and major use of shared_ptr<T> everywhere...
[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     $Id$
19 */
20
21 #include <cmath>
22 #include <cerrno>
23 #include <algorithm>
24 #include <unistd.h>
25
26 #include <pbd/error.h>
27  
28 #include <glibmm/thread.h>
29
30 #include <ardour/ardour.h>
31 #include <ardour/session.h>
32 #include <ardour/timestamps.h>
33 #include <ardour/audio_diskstream.h>
34 #include <ardour/audioengine.h>
35 #include <ardour/slave.h>
36 #include <ardour/auditioner.h>
37 #include <ardour/cycles.h>
38 #include <ardour/cycle_timer.h>
39
40 #include "i18n.h"
41
42 using namespace ARDOUR;
43 using namespace PBD;
44 using namespace std;
45
46 void
47 Session::process (jack_nframes_t nframes)
48 {
49         if (synced_to_jack() && waiting_to_start) {
50                 if ( _engine.transport_state() == AudioEngine::TransportRolling) {
51                         actually_start_transport ();
52                 }
53         }
54
55         if (non_realtime_work_pending()) {
56                 if (g_atomic_int_get (&butler_should_do_transport_work) == 0) {
57                         post_transport ();
58                 } 
59         } 
60         
61         (this->*process_function) (nframes);
62
63         SendFeedback (); /* EMIT SIGNAL */
64 }
65
66 void
67 Session::prepare_diskstreams ()
68 {
69         for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
70                 (*i)->prepare ();
71         }
72 }
73
74 int
75 Session::no_roll (jack_nframes_t nframes, jack_nframes_t offset)
76 {
77         jack_nframes_t end_frame = _transport_frame + nframes;
78         int ret = 0;
79         bool declick = get_transport_declick_required();
80         boost::shared_ptr<RouteList> r = routes.reader ();
81
82         if (_click_io) {
83                 _click_io->silence (nframes, offset);
84         }
85
86         if (g_atomic_int_get (&processing_prohibited)) {
87                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
88                         (*i)->silence (nframes, offset);
89                 }
90                 return 0;
91         }
92
93         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
94                 
95                 if ((*i)->hidden()) {
96                         continue;
97                 }
98                 
99                 (*i)->set_pending_declick (declick);
100                 
101                 if ((*i)->no_roll (nframes, _transport_frame, end_frame, offset, non_realtime_work_pending(), 
102                                    actively_recording(), declick)) {
103                         error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
104                         ret = -1;
105                         break;
106                 }
107         }
108
109         return ret;
110 }
111
112 int
113 Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset)
114 {
115         bool record_active;
116         int  declick = get_transport_declick_required();
117         bool rec_monitors = get_rec_monitors_input();
118         boost::shared_ptr<RouteList> r = routes.reader ();
119
120         if (transport_sub_state & StopPendingCapture) {
121                 /* force a declick out */
122                 declick = -1;
123         }
124
125         record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
126
127         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
128
129                 int ret;
130
131                 if ((*i)->hidden()) {
132                         continue;
133                 }
134
135                 (*i)->set_pending_declick (declick);
136
137                 if ((ret = (*i)->roll (nframes, _transport_frame, _transport_frame + nframes, offset, declick, record_active, rec_monitors)) < 0) {
138
139                         /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
140                            and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
141                            call path, so make sure we release any outstanding locks here before we return failure.
142                         */
143
144                         for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) {
145                                 (*ids)->recover ();
146                         }
147
148                         stop_transport ();
149                         return -1;
150                 } 
151         }
152
153         return 0;
154 }
155
156 int
157 Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset)
158 {
159         bool record_active = actively_recording();
160         int  declick = get_transport_declick_required();
161         bool rec_monitors = get_rec_monitors_input();
162         boost::shared_ptr<RouteList> r = routes.reader ();
163
164         if (transport_sub_state & StopPendingCapture) {
165                 /* force a declick out */
166                 declick = -1;
167         }
168
169         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
170
171                 int ret;
172
173                 if ((*i)->hidden()) {
174                         continue;
175                 }
176
177                 if ((ret = (*i)->silent_roll (nframes, _transport_frame, _transport_frame + nframes, offset, record_active, rec_monitors)) < 0) {
178                         
179                         /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
180                            and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
181                            call path, so make sure we release any outstanding locks here before we return failure.
182                         */
183
184                         for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) {
185                                 (*ids)->recover ();
186                         }
187
188                         stop_transport ();
189                         return -1;
190                 } 
191         }
192
193         return 0;
194 }
195
196 void
197 Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler)
198 {
199         int dret;
200         float pworst = 1.0f;
201         float cworst = 1.0f;
202
203         for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
204
205                 if ((*i)->hidden()) {
206                         continue;
207                 }
208                 
209                 /* force all diskstreams not handled by a Route to call do their stuff.
210                  */
211
212                 if ((dret = (*i)->process (_transport_frame, nframes, 0, actively_recording(), get_rec_monitors_input())) == 0) {
213                         if ((*i)->commit (nframes)) {
214                                 needs_butler = true;
215                         }
216
217                 } else if (dret < 0) {
218                         (*i)->recover();
219                 }
220                 
221                 pworst = min (pworst, (*i)->playback_buffer_load());
222                 cworst = min (cworst, (*i)->capture_buffer_load());
223         }
224
225         uint32_t pmin = g_atomic_int_get (&_playback_load);
226         uint32_t pminold = g_atomic_int_get (&_playback_load_min);
227         uint32_t cmin = g_atomic_int_get (&_capture_load);
228         uint32_t cminold = g_atomic_int_get (&_capture_load_min);
229
230         g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
231         g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
232         g_atomic_int_set (&_playback_load_min, min (pmin, pminold));
233         g_atomic_int_set (&_capture_load_min, min (cmin, cminold));
234
235         if (actively_recording()) {
236                 set_dirty();
237         }
238 }
239
240 void
241 Session::process_with_events (jack_nframes_t nframes)
242 {
243         Event* ev;
244         jack_nframes_t this_nframes;
245         jack_nframes_t end_frame;
246         jack_nframes_t offset;
247         bool session_needs_butler = false;
248         jack_nframes_t stop_limit;
249         long           frames_moved;
250
251         /* make sure the auditioner is silent */
252
253         if (auditioner) {
254                 auditioner->silence (nframes, 0);
255         }
256
257         /* handle any pending events */
258
259         while (pending_events.read (&ev, 1) == 1) {
260                 merge_event (ev);
261         }
262
263         /* if we are not in the middle of a state change,
264            and there are immediate events queued up,
265            process them. 
266         */
267
268         while (!non_realtime_work_pending() && !immediate_events.empty()) {
269                 Event *ev = immediate_events.front ();
270                 immediate_events.pop_front ();
271                 process_event (ev);
272         }
273
274         if (!process_can_proceed()) {
275                 no_roll (nframes, 0);
276                 return;
277         }
278                 
279         if (events.empty() || next_event == events.end()) {
280                 process_without_events (nframes);
281                 return;
282         }
283
284         end_frame = _transport_frame + nframes;
285
286         {
287                 Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
288         
289                 Event* this_event;
290                 Events::iterator the_next_one;
291                 
292                 if (!dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) {
293                         no_roll (nframes, 0);
294                         return;
295                 }
296                 
297                 if (!_exporting && _slave) {
298                         if (!follow_slave (nframes, 0)) {
299                                 return;
300                         }
301                 } 
302
303                 if (_transport_speed == 0) {
304                         no_roll (nframes, 0);
305                         return;
306                 }
307
308                 if (actively_recording()) {
309                         stop_limit = max_frames;
310                 } else {
311
312                         if (Config->get_stop_at_session_end()) {
313                                 stop_limit = current_end_frame();
314                         } else {
315                                 stop_limit = max_frames;
316                         }
317                 }
318
319                 if (maybe_stop (stop_limit)) {
320                         no_roll (nframes, 0);
321                         return;
322                 } 
323
324                 this_event = *next_event;
325                 the_next_one = next_event;
326                 ++the_next_one;
327
328                 offset = 0;
329
330                 while (nframes) {
331
332                         if (this_event == 0 || this_event->action_frame > end_frame || this_event->action_frame < _transport_frame) {
333
334                                 this_nframes = nframes;
335                                 
336                         } else {
337                                 
338                                 /* compute nframes to next event */
339
340                                 if (this_event->action_frame < end_frame) {
341                                         this_nframes = nframes - (end_frame - this_event->action_frame);
342                                 } else {
343                                         this_nframes = nframes;
344                                 }
345                         }
346
347                         if (this_nframes) {
348                                 
349                                 click (_transport_frame, nframes, offset);
350                                 
351                                 /* now process frames between now and the first event in this block */
352                                 prepare_diskstreams ();
353
354                                 if (process_routes (this_nframes, offset)) {
355                                         no_roll (nframes, 0);
356                                         return;
357                                 }
358                                 
359                                 commit_diskstreams (this_nframes, session_needs_butler);
360
361                                 nframes -= this_nframes;
362                                 offset += this_nframes;
363                                 
364                                 frames_moved = (jack_nframes_t) floor (_transport_speed * this_nframes);
365                         
366                                 if (frames_moved < 0) {
367                                         decrement_transport_position (-frames_moved);
368                                 } else {
369                                         increment_transport_position (frames_moved);
370                                 }
371
372                                 maybe_stop (stop_limit);
373                                 check_declick_out ();
374                         }
375
376                         /* now handle this event and all others scheduled for the same time */
377                         
378                         while (this_event && this_event->action_frame == _transport_frame) {
379                                 process_event (this_event);
380
381                                 if (the_next_one == events.end()) {
382                                         this_event = 0;
383                                 } else {
384                                         this_event = *the_next_one;
385                                         ++the_next_one;
386                                 }
387                         } 
388
389                         /* if an event left our state changing, do the right thing */
390
391                         if (non_realtime_work_pending()) {
392                                 no_roll (nframes, offset);
393                                 break;
394                         }
395
396                         /* this is necessary to handle the case of seamless looping */
397                         /* not sure if it will work in conjuction with varispeed */
398                         end_frame = _transport_frame + nframes;
399                         
400                 }
401
402                 set_next_event ();
403
404         } /* implicit release of route lock */
405
406
407         if (session_needs_butler) {
408                 summon_butler ();
409         } 
410         
411         if (!_engine.freewheeling() && send_mtc) {
412                 send_midi_time_code_in_another_thread ();
413         }
414
415         return;
416 }               
417
418 void
419 Session::reset_slave_state ()
420 {
421         average_slave_delta = 1800;
422         delta_accumulator_cnt = 0;
423         have_first_delta_accumulator = false;
424         slave_state = Stopped;
425 }
426
427 bool
428 Session::transport_locked () const
429 {
430         Slave* sl = _slave;
431
432         if (!locate_pending() && ((_slave_type == None) || (sl && sl->ok() && sl->locked()))) {
433                 return true;
434         }
435
436         return false;
437 }
438
439 bool
440 Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
441 {
442         float slave_speed;
443         jack_nframes_t slave_transport_frame;
444         jack_nframes_t this_delta;
445         int dir;
446         bool starting;
447
448         if (!_slave->ok()) {
449                 stop_transport ();
450                 set_slave_source (None, 0);
451                 goto noroll;
452         }
453         
454         _slave->speed_and_position (slave_speed, slave_transport_frame);
455
456         if (!_slave->locked()) {
457                 goto noroll;
458         }
459
460         if (slave_transport_frame > _transport_frame) {
461                 this_delta = slave_transport_frame - _transport_frame;
462                 dir = 1;
463         } else {
464                 this_delta = _transport_frame - slave_transport_frame;
465                 dir = -1;
466         }
467
468         if ((starting = _slave->starting())) {
469                 slave_speed = 0.0f;
470         }
471
472 #if 0
473         cerr << "delta = " << (int) (dir * this_delta)
474              << " speed = " << slave_speed 
475              << " ts = " << _transport_speed 
476              << " M@"<< slave_transport_frame << " S@" << _transport_frame 
477              << " avgdelta = " << average_slave_delta 
478              << endl;
479 #endif  
480
481         if (Config->get_timecode_source_is_synced()) {
482
483                 /* if the TC source is synced, then we assume that its 
484                    speed is binary: 0.0 or 1.0
485                 */
486
487                 if (slave_speed != 0.0f) {
488                         slave_speed = 1.0f;
489                 } 
490
491         } else {
492
493                 /* TC source is able to drift relative to us (slave)
494                    so we need to keep track of the drift and adjust
495                    our speed to remain locked.
496                 */
497
498                 if (delta_accumulator_cnt >= delta_accumulator_size) {
499                         have_first_delta_accumulator = true;
500                         delta_accumulator_cnt = 0;
501                 }
502
503                 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
504                         delta_accumulator[delta_accumulator_cnt++] = dir*this_delta;
505                 }
506                 
507                 if (have_first_delta_accumulator) {
508                         average_slave_delta = 0;
509                         for (int i = 0; i < delta_accumulator_size; ++i) {
510                                 average_slave_delta += delta_accumulator[i];
511                         }
512                         average_slave_delta /= delta_accumulator_size;
513                         if (average_slave_delta < 0) {
514                                 average_dir = -1;
515                                 average_slave_delta = -average_slave_delta;
516                         } else {
517                                 average_dir = 1;
518                         }
519                         // cerr << "avgdelta = " << average_slave_delta*average_dir << endl;
520                 }
521         }
522
523         if (slave_speed != 0.0f) {
524
525                 /* slave is running */
526
527                 switch (slave_state) {
528                 case Stopped:
529                         if (_slave->requires_seekahead()) {
530                                 slave_wait_end = slave_transport_frame + _current_frame_rate;
531                                 locate (slave_wait_end, false, false);
532                                 slave_state = Waiting;
533                                 starting = true;
534
535                         } else {
536
537                                 slave_state = Running;
538
539                                 Location* al = _locations.auto_loop_location();
540
541                                 if (al && auto_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
542                                         // cancel looping
543                                         request_auto_loop(false);
544                                 }
545
546                                 if (slave_transport_frame != _transport_frame) {
547                                         locate (slave_transport_frame, false, false);
548                                 }
549                         }
550                         break;
551
552                 case Waiting:
553                         break;
554
555                 default:
556                         break;
557
558                 }
559
560                 if (slave_state == Waiting) {
561
562                         // cerr << "waiting at " << slave_transport_frame << endl;
563                         Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
564                                 
565                         if (dsm.locked() && slave_transport_frame >= slave_wait_end) {
566                                 // cerr << "\tstart at " << _transport_frame << endl;
567
568                                 slave_state = Running;
569
570                                 bool ok = true;
571                                 jack_nframes_t frame_delta = slave_transport_frame - _transport_frame;
572                                 
573                                 for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
574                                         if (!(*i)->can_internal_playback_seek (frame_delta)) {
575                                                 ok = false;
576                                                 break;
577                                         }
578                                 }
579
580                                 if (ok) {
581                                         for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
582                                                 (*i)->internal_playback_seek (frame_delta);
583                                         }
584                                         _transport_frame += frame_delta;
585                                        
586                                 } else {
587                                         // cerr << "cannot micro-seek\n";
588                                         /* XXX what? */
589                                 }
590
591                                 memset (delta_accumulator, 0, sizeof (jack_nframes_t) * delta_accumulator_size);
592                                 average_slave_delta = 0;
593                                 this_delta = 0;
594                         }
595                 }
596                 
597                 if (slave_state == Running && _transport_speed == 0.0f) {
598                         
599                         // cerr << "slave starts transport\n";
600                         
601                         start_transport ();
602                 } 
603
604         } else {
605
606                 /* slave has stopped */
607
608                 if (_transport_speed != 0.0f) {
609
610                         // cerr << "slave stops transport: " << slave_speed << " frame: " << slave_transport_frame 
611                         // << " tf = " << _transport_frame
612                         // << endl;
613                         
614                         if (_slave_type == JACK) {
615                                 last_stop_frame = _transport_frame;
616                         }
617
618                         stop_transport();
619                 }
620
621                 if (slave_transport_frame != _transport_frame) {
622                         // cerr << "slave stopped, move to " << slave_transport_frame << endl;
623                         force_locate (slave_transport_frame, false);
624                 }
625
626                 slave_state = Stopped;
627         }
628
629         if (slave_state == Running && !Config->get_timecode_source_is_synced()) {
630
631
632                 if (_transport_speed != 0.0f) {
633                         
634                         /* 
635                            note that average_dir is +1 or -1 
636                         */
637                         
638                         const float adjust_seconds = 1.0f;
639                         float delta;
640
641                         //if (average_slave_delta == 0) {
642                                 delta = this_delta;
643                                 delta *= dir;
644 //                      } else {
645 //                              delta = average_slave_delta;
646 //                              delta *= average_dir;
647 //                      }
648
649                         float adjusted_speed = slave_speed +
650                                 (delta / (adjust_seconds * _current_frame_rate));
651                         
652                         // cerr << "adjust using " << delta
653                         // << " towards " << adjusted_speed
654                         // << " ratio = " << adjusted_speed / slave_speed
655                         // << " current = " << _transport_speed
656                         // << " slave @ " << slave_speed
657                         // << endl;
658                         
659                         request_transport_speed (adjusted_speed);
660                         
661 #if 1
662                         if ((jack_nframes_t) average_slave_delta > _slave->resolution()) {
663                                 // cerr << "not locked\n";
664                                 goto silent_motion;
665                         }
666 #endif
667                 }
668         } 
669
670         if (!starting && !non_realtime_work_pending()) {
671                 /* speed is set, we're locked, and good to go */
672                 return true;
673         }
674
675   silent_motion:
676
677         if (slave_speed && _transport_speed) {
678
679                 /* something isn't right, but we should move with the master
680                    for now.
681                 */
682
683                 bool need_butler;
684                 
685                 Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
686                 if (!dsm.locked()) {
687                         goto noroll;
688                 }
689
690                 
691                 prepare_diskstreams ();
692                 silent_process_routes (nframes, offset);
693                 commit_diskstreams (nframes, need_butler);
694
695                 if (need_butler) {
696                         summon_butler ();
697                 }
698                 
699                 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
700                 
701                 if (frames_moved < 0) {
702                         decrement_transport_position (-frames_moved);
703                 } else {
704                         increment_transport_position (frames_moved);
705                 }
706                 
707                 jack_nframes_t stop_limit;
708                 
709                 if (actively_recording()) {
710                         stop_limit = max_frames;
711                 } else {
712                         if (Config->get_stop_at_session_end()) {
713                                 stop_limit = current_end_frame();
714                         } else {
715                                 stop_limit = max_frames;
716                         }
717                 }
718
719                 maybe_stop (stop_limit);
720         }
721
722   noroll:
723         /* don't move at all */
724         no_roll (nframes, 0);
725         return false;
726 }
727
728 void
729 Session::process_without_events (jack_nframes_t nframes)
730 {
731         bool session_needs_butler = false;
732         jack_nframes_t stop_limit;
733         long frames_moved;
734         
735         {
736                 Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
737
738                 if (!dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) {
739                         no_roll (nframes, 0);
740                         return;
741                 }
742
743                 if (!_exporting && _slave) {
744                         if (!follow_slave (nframes, 0)) {
745                                 return;
746                         }
747                 } 
748
749                 if (_transport_speed == 0) {
750                         no_roll (nframes, 0);
751                         return;
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                         no_roll (nframes, 0);
766                         return;
767                 } 
768
769                 click (_transport_frame, nframes, 0);
770
771                 prepare_diskstreams ();
772         
773                 frames_moved = (long) floor (_transport_speed * nframes);
774
775                 if (process_routes (nframes, 0)) {
776                         no_roll (nframes, 0);
777                         return;
778                 }
779
780                 commit_diskstreams (nframes, session_needs_butler);
781
782                 if (frames_moved < 0) {
783                         decrement_transport_position (-frames_moved);
784                 } else {
785                         increment_transport_position (frames_moved);
786                 }
787                 
788                 maybe_stop (stop_limit);
789                 check_declick_out ();
790
791         } /* implicit release of route lock */
792
793         if (session_needs_butler) {
794                 summon_butler ();
795         } 
796         
797         if (!_engine.freewheeling() && send_mtc) {
798                 send_midi_time_code_in_another_thread ();
799         }
800
801         return;
802 }               
803
804 void
805 Session::process_audition (jack_nframes_t nframes)
806 {
807         Event* ev;
808         boost::shared_ptr<RouteList> r = routes.reader ();
809
810         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
811                 if (!(*i)->hidden()) {
812                         (*i)->silence (nframes, 0);
813                 }
814         }
815
816         /* run the auditioner, and if it says we need butler service, ask for it */
817         
818         if (auditioner->play_audition (nframes) > 0) {
819                 summon_butler ();
820         } 
821
822         /* handle pending events */
823
824         while (pending_events.read (&ev, 1) == 1) {
825                 merge_event (ev);
826         }
827
828         /* if we are not in the middle of a state change,
829            and there are immediate events queued up,
830            process them. 
831         */
832
833         while (!non_realtime_work_pending() && !immediate_events.empty()) {
834                 Event *ev = immediate_events.front ();
835                 immediate_events.pop_front ();
836                 process_event (ev);
837         }
838
839         if (!auditioner->active()) {
840                 process_function = &Session::process_with_events;
841         }
842 }
843