4f82de1c0ed1917b23462d2bc1ec3ef8bb46140a
[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 nframes_t start_frame = _transport_frame;
134         const nframes_t end_frame = _transport_frame + (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 nframes_t start_frame = _transport_frame;
180         const 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                    Note: the diskstreams that were handled by a route will just return zero
226                    from this call, because they know they were processed. So in fact, this
227                    also runs commit() for every diskstream.
228                  */
229
230                 if ((dret = (*i)->process (_transport_frame, nframes, 0, actively_recording(), get_rec_monitors_input())) == 0) {
231                         if ((*i)->commit (nframes)) {
232                                 needs_butler = true;
233                         }
234
235                 } else if (dret < 0) {
236                         (*i)->recover();
237                 }
238                 
239                 pworst = min (pworst, (*i)->playback_buffer_load());
240                 cworst = min (cworst, (*i)->capture_buffer_load());
241         }
242
243         uint32_t pmin = g_atomic_int_get (&_playback_load);
244         uint32_t pminold = g_atomic_int_get (&_playback_load_min);
245         uint32_t cmin = g_atomic_int_get (&_capture_load);
246         uint32_t cminold = g_atomic_int_get (&_capture_load_min);
247
248         g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
249         g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
250         g_atomic_int_set (&_playback_load_min, min (pmin, pminold));
251         g_atomic_int_set (&_capture_load_min, min (cmin, cminold));
252
253         if (actively_recording()) {
254                 set_dirty();
255         }
256 }
257
258
259 void
260 Session::process_with_events (nframes_t nframes)
261 {
262         Event*         ev;
263         nframes_t this_nframes;
264         nframes_t end_frame;
265         nframes_t offset;
266         nframes_t stop_limit;
267         long           frames_moved;
268         bool           session_needs_butler = false;
269
270         /* make sure the auditioner is silent */
271
272         if (auditioner) {
273                 auditioner->silence (nframes, 0);
274         }
275
276         /* handle any pending events */
277
278         while (pending_events.read (&ev, 1) == 1) {
279                 merge_event (ev);
280         }
281
282         /* if we are not in the middle of a state change,
283            and there are immediate events queued up,
284            process them. 
285         */
286
287         while (!non_realtime_work_pending() && !immediate_events.empty()) {
288                 Event *ev = immediate_events.front ();
289                 immediate_events.pop_front ();
290                 process_event (ev);
291         }
292
293         /* Events caused a transport change, send an MTC Full Frame (SMPTE) message.
294          * This is sent whether rolling or not, to give slaves an idea of ardour time
295          * on locates (and allow slow slaves to position and prepare for rolling)
296          */
297         if (_send_smpte_update) {
298                 send_full_time_code(nframes);
299         }
300
301         if (!process_can_proceed()) {
302                 no_roll (nframes, 0);
303                 return;
304         }
305
306         if (events.empty() || next_event == events.end()) {
307                 process_without_events (nframes);
308                 return;
309         }
310
311         end_frame = _transport_frame + (nframes_t)abs(floor(nframes * _transport_speed));
312
313         {
314                 Event* this_event;
315                 Events::iterator the_next_one;
316                 
317                 if (post_transport_work & (PostTransportLocate|PostTransportStop)) {
318                         no_roll (nframes, 0);
319                         return;
320                 }
321                 
322                 if (!_exporting && _slave) {
323                         if (!follow_slave (nframes, 0)) {
324                                 return;
325                         }
326                 } 
327
328                 if (_transport_speed == 0) {
329                         no_roll (nframes, 0);
330                         return;
331                 }
332         
333                 send_midi_time_code_for_cycle(nframes);
334
335                 if (actively_recording()) {
336                         stop_limit = max_frames;
337                 } else {
338
339                         if (Config->get_stop_at_session_end()) {
340                                 stop_limit = current_end_frame();
341                         } else {
342                                 stop_limit = max_frames;
343                         }
344                 }
345
346                 if (maybe_stop (stop_limit)) {
347                         no_roll (nframes, 0);
348                         return;
349                 } 
350
351                 this_event = *next_event;
352                 the_next_one = next_event;
353                 ++the_next_one;
354
355                 offset = 0;
356
357                 while (nframes) {
358
359                         this_nframes = nframes; /* real (jack) time relative */
360                         frames_moved = (long) floor (_transport_speed * nframes); /* transport relative */
361
362                         /* running an event, position transport precisely to its time */
363                         if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
364                                 /* this isn't quite right for reverse play */
365                                 frames_moved = (long) (this_event->action_frame - _transport_frame);
366                                 this_nframes = (nframes_t) abs( floor(frames_moved / _transport_speed) );
367                         } 
368
369                         if (this_nframes) {
370                                 
371                                 click (_transport_frame, nframes, offset);
372                                 
373                                 /* now process frames between now and the first event in this block */
374                                 prepare_diskstreams ();
375
376                                 if (process_routes (this_nframes, offset)) {
377                                         no_roll (nframes, 0);
378                                         return;
379                                 }
380                                 
381                                 commit_diskstreams (this_nframes, session_needs_butler);
382
383                                 nframes -= this_nframes;
384                                 offset += this_nframes;
385                                 
386                                 if (frames_moved < 0) {
387                                         decrement_transport_position (-frames_moved);
388                                 } else {
389                                         increment_transport_position (frames_moved);
390                                 }
391
392                                 maybe_stop (stop_limit);
393                                 check_declick_out ();
394                         }
395
396                         /* now handle this event and all others scheduled for the same time */
397                         
398                         while (this_event && this_event->action_frame == _transport_frame) {
399                                 process_event (this_event);
400
401                                 if (the_next_one == events.end()) {
402                                         this_event = 0;
403                                 } else {
404                                         this_event = *the_next_one;
405                                         ++the_next_one;
406                                 }
407                         } 
408
409                         /* if an event left our state changing, do the right thing */
410
411                         if (non_realtime_work_pending()) {
412                                 no_roll (nframes, offset);
413                                 break;
414                         }
415
416                         /* this is necessary to handle the case of seamless looping */
417                         end_frame = _transport_frame + (nframes_t) floor (nframes * _transport_speed);
418                         
419                 }
420
421                 set_next_event ();
422
423         } /* implicit release of route lock */
424
425         if (session_needs_butler)
426                 summon_butler ();
427 }
428
429 void
430 Session::reset_slave_state ()
431 {
432         average_slave_delta = 1800;
433         delta_accumulator_cnt = 0;
434         have_first_delta_accumulator = false;
435         slave_state = Stopped;
436 }
437
438 bool
439 Session::transport_locked () const
440 {
441         Slave* sl = _slave;
442
443         if (!locate_pending() && ((Config->get_slave_source() == None) || (sl && sl->ok() && sl->locked()))) {
444                 return true;
445         }
446
447         return false;
448 }
449
450 bool
451 Session::follow_slave (nframes_t nframes, nframes_t offset)
452 {
453         float slave_speed;
454         nframes_t slave_transport_frame;
455         nframes_t this_delta;
456         int dir;
457         bool starting;
458
459         if (!_slave->ok()) {
460                 stop_transport ();
461                 Config->set_slave_source (None);
462                 goto noroll;
463         }
464         
465         _slave->speed_and_position (slave_speed, slave_transport_frame);
466
467         if (!_slave->locked()) {
468                 goto noroll;
469         }
470
471         if (slave_transport_frame > _transport_frame) {
472                 this_delta = slave_transport_frame - _transport_frame;
473                 dir = 1;
474         } else {
475                 this_delta = _transport_frame - slave_transport_frame;
476                 dir = -1;
477         }
478
479         if ((starting = _slave->starting())) {
480                 slave_speed = 0.0f;
481         }
482
483 #if 0
484         cerr << "delta = " << (int) (dir * this_delta)
485              << " speed = " << slave_speed 
486              << " ts = " << _transport_speed 
487              << " M@"<< slave_transport_frame << " S@" << _transport_frame 
488              << " avgdelta = " << average_slave_delta 
489              << endl;
490 #endif  
491
492         if (Config->get_timecode_source_is_synced()) {
493
494                 /* if the TC source is synced, then we assume that its 
495                    speed is binary: 0.0 or 1.0
496                 */
497
498                 if (slave_speed != 0.0f) {
499                         slave_speed = 1.0f;
500                 } 
501
502         } else {
503
504                 /* TC source is able to drift relative to us (slave)
505                    so we need to keep track of the drift and adjust
506                    our speed to remain locked.
507                 */
508
509                 if (delta_accumulator_cnt >= delta_accumulator_size) {
510                         have_first_delta_accumulator = true;
511                         delta_accumulator_cnt = 0;
512                 }
513
514                 if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) {
515                         delta_accumulator[delta_accumulator_cnt++] = dir*this_delta;
516                 }
517                 
518                 if (have_first_delta_accumulator) {
519                         average_slave_delta = 0;
520                         for (int i = 0; i < delta_accumulator_size; ++i) {
521                                 average_slave_delta += delta_accumulator[i];
522                         }
523                         average_slave_delta /= delta_accumulator_size;
524                         if (average_slave_delta < 0) {
525                                 average_dir = -1;
526                                 average_slave_delta = -average_slave_delta;
527                         } else {
528                                 average_dir = 1;
529                         }
530                         // cerr << "avgdelta = " << average_slave_delta*average_dir << endl;
531                 }
532         }
533
534         if (slave_speed != 0.0f) {
535
536                 /* slave is running */
537
538                 switch (slave_state) {
539                 case Stopped:
540                         if (_slave->requires_seekahead()) {
541                                 slave_wait_end = slave_transport_frame + _current_frame_rate;
542                                 locate (slave_wait_end, false, false);
543                                 slave_state = Waiting;
544                                 starting = true;
545
546                         } else {
547
548                                 slave_state = Running;
549
550                                 Location* al = _locations.auto_loop_location();
551
552                                 if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
553                                         // cancel looping
554                                         request_play_loop(false);
555                                 }
556
557                                 if (slave_transport_frame != _transport_frame) {
558                                         locate (slave_transport_frame, false, false);
559                                 }
560                         }
561                         break;
562
563                 case Waiting:
564                         break;
565
566                 default:
567                         break;
568
569                 }
570
571                 if (slave_state == Waiting) {
572
573                         // cerr << "waiting at " << slave_transport_frame << endl;
574                         if (slave_transport_frame >= slave_wait_end) {
575                                 // cerr << "\tstart at " << _transport_frame << endl;
576
577                                 slave_state = Running;
578
579                                 bool ok = true;
580                                 nframes_t frame_delta = slave_transport_frame - _transport_frame;
581
582                                 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
583                                 
584                                 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
585                                         if (!(*i)->can_internal_playback_seek (frame_delta)) {
586                                                 ok = false;
587                                                 break;
588                                         }
589                                 }
590
591                                 if (ok) {
592                                         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
593                                                 (*i)->internal_playback_seek (frame_delta);
594                                         }
595                                         _transport_frame += frame_delta;
596                                        
597                                 } else {
598                                         // cerr << "cannot micro-seek\n";
599                                         /* XXX what? */
600                                 }
601
602                                 memset (delta_accumulator, 0, sizeof (nframes_t) * delta_accumulator_size);
603                                 average_slave_delta = 0;
604                                 this_delta = 0;
605                         }
606                 }
607                 
608                 if (slave_state == Running && _transport_speed == 0.0f) {
609                         
610                         // cerr << "slave starts transport\n";
611                         
612                         start_transport ();
613                 } 
614
615         } else {
616
617                 /* slave has stopped */
618
619                 if (_transport_speed != 0.0f) {
620
621                         // cerr << "slave stops transport: " << slave_speed << " frame: " << slave_transport_frame 
622                         // << " tf = " << _transport_frame
623                         // << endl;
624                         
625                         if (Config->get_slave_source() == JACK) {
626                                 last_stop_frame = _transport_frame;
627                         }
628
629                         stop_transport();
630                 }
631
632                 if (slave_transport_frame != _transport_frame) {
633                         // cerr << "slave stopped, move to " << slave_transport_frame << endl;
634                         force_locate (slave_transport_frame, false);
635                 }
636
637                 slave_state = Stopped;
638         }
639
640         if (slave_state == Running && !Config->get_timecode_source_is_synced()) {
641
642
643                 if (_transport_speed != 0.0f) {
644                         
645                         /* 
646                            note that average_dir is +1 or -1 
647                         */
648                         
649                         const float adjust_seconds = 1.0f;
650                         float delta;
651
652                         //if (average_slave_delta == 0) {
653                                 delta = this_delta;
654                                 delta *= dir;
655 //                      } else {
656 //                              delta = average_slave_delta;
657 //                              delta *= average_dir;
658 //                      }
659
660                         float adjusted_speed = slave_speed +
661                                 (delta / (adjust_seconds * _current_frame_rate));
662                         
663                         // cerr << "adjust using " << delta
664                         // << " towards " << adjusted_speed
665                         // << " ratio = " << adjusted_speed / slave_speed
666                         // << " current = " << _transport_speed
667                         // << " slave @ " << slave_speed
668                         // << endl;
669                         
670                         request_transport_speed (adjusted_speed);
671                         
672 #if 1
673                         if ((nframes_t) average_slave_delta > _slave->resolution()) {
674                                 // cerr << "not locked\n";
675                                 goto silent_motion;
676                         }
677 #endif
678                 }
679         } 
680
681         if (!starting && !non_realtime_work_pending()) {
682                 /* speed is set, we're locked, and good to go */
683                 return true;
684         }
685
686   silent_motion:
687
688         if (slave_speed && _transport_speed) {
689
690                 /* something isn't right, but we should move with the master
691                    for now.
692                 */
693
694                 bool need_butler;
695                 
696                 prepare_diskstreams ();
697                 silent_process_routes (nframes, offset);
698                 commit_diskstreams (nframes, need_butler);
699
700                 if (need_butler) {
701                         summon_butler ();
702                 }
703                 
704                 int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
705                 
706                 if (frames_moved < 0) {
707                         decrement_transport_position (-frames_moved);
708                 } else {
709                         increment_transport_position (frames_moved);
710                 }
711                 
712                 nframes_t stop_limit;
713                 
714                 if (actively_recording()) {
715                         stop_limit = max_frames;
716                 } else {
717                         if (Config->get_stop_at_session_end()) {
718                                 stop_limit = current_end_frame();
719                         } else {
720                                 stop_limit = max_frames;
721                         }
722                 }
723
724                 maybe_stop (stop_limit);
725         }
726
727   noroll:
728         /* don't move at all */
729         no_roll (nframes, 0);
730         return false;
731 }
732
733 void
734 Session::process_without_events (nframes_t nframes)
735 {
736         bool session_needs_butler = false;
737         nframes_t stop_limit;
738         long frames_moved;
739         nframes_t offset = 0;
740
741         {
742                 if (post_transport_work & (PostTransportLocate|PostTransportStop)) {
743                         no_roll (nframes, 0);
744                         return;
745                 }
746
747                 if (!_exporting && _slave) {
748                         if (!follow_slave (nframes, 0)) {
749                                 return;
750                         }
751                 } 
752
753                 if (_transport_speed == 0) {
754                         no_roll (nframes, 0);
755                         return;
756                 }
757         
758                 send_midi_time_code_for_cycle(nframes);
759                 
760                 if (actively_recording()) {
761                         stop_limit = max_frames;
762                 } else {
763                         if (Config->get_stop_at_session_end()) {
764                                 stop_limit = current_end_frame();
765                         } else {
766                                 stop_limit = max_frames;
767                         }
768                 }
769                 
770                 if (maybe_stop (stop_limit)) {
771                         no_roll (nframes, 0);
772                         return;
773                 } 
774
775                 if (maybe_sync_start (nframes, offset)) {
776                         return;
777                 }
778
779                 click (_transport_frame, nframes, offset);
780
781                 prepare_diskstreams ();
782         
783                 frames_moved = (long) floor (_transport_speed * nframes);
784
785                 if (process_routes (nframes, offset)) {
786                         no_roll (nframes, offset);
787                         return;
788                 }
789
790                 commit_diskstreams (nframes, session_needs_butler);
791
792                 if (frames_moved < 0) {
793                         decrement_transport_position (-frames_moved);
794                 } else {
795                         increment_transport_position (frames_moved);
796                 }
797
798                 maybe_stop (stop_limit);
799                 check_declick_out ();
800
801         } /* implicit release of route lock */
802
803         if (session_needs_butler)
804                 summon_butler ();
805 }
806
807 void
808 Session::process_audition (nframes_t nframes)
809 {
810         Event* ev;
811         boost::shared_ptr<RouteList> r = routes.reader ();
812
813         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
814                 if (!(*i)->hidden()) {
815                         (*i)->silence (nframes, 0);
816                 }
817         }
818
819         /* run the auditioner, and if it says we need butler service, ask for it */
820         
821         if (auditioner->play_audition (nframes) > 0) {
822                 summon_butler ();
823         } 
824
825         /* handle pending events */
826
827         while (pending_events.read (&ev, 1) == 1) {
828                 merge_event (ev);
829         }
830
831         /* if we are not in the middle of a state change,
832            and there are immediate events queued up,
833            process them. 
834         */
835
836         while (!non_realtime_work_pending() && !immediate_events.empty()) {
837                 Event *ev = immediate_events.front ();
838                 immediate_events.pop_front ();
839                 process_event (ev);
840         }
841
842         if (!auditioner->active()) {
843                 process_function = &Session::process_with_events;
844         }
845 }
846
847 bool
848 Session::maybe_sync_start (nframes_t& nframes, nframes_t& offset)
849 {
850         nframes_t sync_offset;
851         
852         if (!waiting_for_sync_offset) {
853                 return false;
854         }
855
856         if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
857
858                 no_roll (sync_offset, 0);
859                 nframes -= sync_offset;
860                 offset += sync_offset;
861                 waiting_for_sync_offset = false;
862                 
863                 if (nframes == 0) {
864                         return true; // done
865                 }
866                 
867         } else {
868                 no_roll (nframes, 0);
869                 return true; // done
870         }
871
872         return false;
873 }
874