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