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