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