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