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