055cbcf82d40680067fa5cff61cddcb479925776
[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         if (synced_to_jack() && waiting_to_start) {
49                 if ( _engine.transport_state() == AudioEngine::TransportRolling) {
50                         actually_start_transport ();
51                 }
52         }
53
54         if (non_realtime_work_pending()) {
55                 if (!transport_work_requested ()) {
56                         post_transport ();
57                 } 
58         } 
59         
60         (this->*process_function) (nframes);
61
62         SendFeedback (); /* EMIT SIGNAL */
63 }
64
65 void
66 Session::prepare_diskstreams ()
67 {
68         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
69         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
70                 (*i)->prepare ();
71         }
72 }
73
74 int
75 Session::no_roll (nframes_t nframes, nframes_t offset)
76 {
77         nframes_t end_frame = _transport_frame + nframes;
78         int ret = 0;
79         bool declick = get_transport_declick_required();
80         boost::shared_ptr<RouteList> r = routes.reader ();
81
82         if (_click_io) {
83                 _click_io->silence (nframes, offset);
84         }
85
86         if (g_atomic_int_get (&processing_prohibited)) {
87                 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
88                         (*i)->silence (nframes, offset);
89                 }
90                 return 0;
91         }
92
93         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
94                 
95                 if ((*i)->hidden()) {
96                         continue;
97                 }
98                 
99                 (*i)->set_pending_declick (declick);
100                 
101                 if ((*i)->no_roll (nframes, _transport_frame, end_frame, offset, non_realtime_work_pending(), 
102                                    actively_recording(), declick)) {
103                         error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
104                         ret = -1;
105                         break;
106                 }
107         }
108
109         return ret;
110 }
111
112 int
113 Session::process_routes (nframes_t nframes, nframes_t offset)
114 {
115         bool record_active;
116         int  declick = get_transport_declick_required();
117         bool rec_monitors = get_rec_monitors_input();
118         boost::shared_ptr<RouteList> r = routes.reader ();
119
120         if (transport_sub_state & StopPendingCapture) {
121                 /* force a declick out */
122                 declick = -1;
123         }
124
125         record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
126
127         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
128
129                 int ret;
130
131                 if ((*i)->hidden()) {
132                         continue;
133                 }
134
135                 (*i)->set_pending_declick (declick);
136
137                 if ((ret = (*i)->roll (nframes, _transport_frame, _transport_frame + nframes, offset, declick, record_active, rec_monitors)) < 0) {
138
139                         /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
140                            and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
141                            call path, so make sure we release any outstanding locks here before we return failure.
142                         */
143
144                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
145                         for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
146                                 (*ids)->recover ();
147                         }
148
149                         stop_transport ();
150                         return -1;
151                 } 
152         }
153
154         return 0;
155 }
156
157 int
158 Session::silent_process_routes (nframes_t nframes, nframes_t offset)
159 {
160         bool record_active = actively_recording();
161         int  declick = get_transport_declick_required();
162         bool rec_monitors = get_rec_monitors_input();
163         boost::shared_ptr<RouteList> r = routes.reader ();
164
165         if (transport_sub_state & StopPendingCapture) {
166                 /* force a declick out */
167                 declick = -1;
168         }
169
170         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
171
172                 int ret;
173
174                 if ((*i)->hidden()) {
175                         continue;
176                 }
177
178                 if ((ret = (*i)->silent_roll (nframes, _transport_frame, _transport_frame + nframes, offset, record_active, rec_monitors)) < 0) {
179                         
180                         /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
181                            and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
182                            call path, so make sure we release any outstanding locks here before we return failure.
183                         */
184
185                         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
186                         for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) {
187                                 (*ids)->recover ();
188                         }
189
190                         stop_transport ();
191                         return -1;
192                 } 
193         }
194
195         return 0;
196 }
197
198 void
199 Session::commit_diskstreams (nframes_t nframes, bool &needs_butler)
200 {
201         int dret;
202         float pworst = 1.0f;
203         float cworst = 1.0f;
204
205         boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
206         for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
207
208                 if ((*i)->hidden()) {
209                         continue;
210                 }
211                 
212                 /* force all diskstreams not handled by a Route to call do their stuff.
213                    Note: the diskstreams that were handled by a route will just return zero
214                    from this call, because they know they were processed. So in fact, this
215                    also runs commit() for every diskstream.
216                  */
217
218                 if ((dret = (*i)->process (_transport_frame, nframes, 0, actively_recording(), get_rec_monitors_input())) == 0) {
219                         if ((*i)->commit (nframes)) {
220                                 needs_butler = true;
221                         }
222
223                 } else if (dret < 0) {
224                         (*i)->recover();
225                 }
226                 
227                 pworst = min (pworst, (*i)->playback_buffer_load());
228                 cworst = min (cworst, (*i)->capture_buffer_load());
229         }
230
231         uint32_t pmin = g_atomic_int_get (&_playback_load);
232         uint32_t pminold = g_atomic_int_get (&_playback_load_min);
233         uint32_t cmin = g_atomic_int_get (&_capture_load);
234         uint32_t cminold = g_atomic_int_get (&_capture_load_min);
235
236         g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f));
237         g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f));
238         g_atomic_int_set (&_playback_load_min, min (pmin, pminold));
239         g_atomic_int_set (&_capture_load_min, min (cmin, cminold));
240
241         if (actively_recording()) {
242                 set_dirty();
243         }
244 }
245
246 void
247 Session::process_with_events (nframes_t nframes)
248 {
249         Event* ev;
250         nframes_t this_nframes;
251         nframes_t end_frame;
252         nframes_t offset;
253         bool session_needs_butler = false;
254         nframes_t stop_limit;
255         long           frames_moved;
256
257         /* make sure the auditioner is silent */
258
259         if (auditioner) {
260                 auditioner->silence (nframes, 0);
261         }
262
263         /* handle any pending events */
264
265         while (pending_events.read (&ev, 1) == 1) {
266                 merge_event (ev);
267         }
268
269         /* if we are not in the middle of a state change,
270            and there are immediate events queued up,
271            process them. 
272         */
273
274         while (!non_realtime_work_pending() && !immediate_events.empty()) {
275                 Event *ev = immediate_events.front ();
276                 immediate_events.pop_front ();
277                 process_event (ev);
278         }
279
280         if (!process_can_proceed()) {
281                 no_roll (nframes, 0);
282                 return;
283         }
284                 
285         if (events.empty() || next_event == events.end()) {
286                 process_without_events (nframes);
287                 return;
288         }
289
290         end_frame = _transport_frame + (nframes_t)abs(floor(nframes * _transport_speed));
291
292         {
293                 Event* this_event;
294                 Events::iterator the_next_one;
295                 
296                 if (post_transport_work & (PostTransportLocate|PostTransportStop)) {
297                         no_roll (nframes, 0);
298                         return;
299                 }
300                 
301                 if (!_exporting && _slave) {
302                         if (!follow_slave (nframes, 0)) {
303                                 return;
304                         }
305                 } 
306
307                 if (_transport_speed == 0) {
308                         no_roll (nframes, 0);
309                         return;
310                 }
311
312                 if (actively_recording()) {
313                         stop_limit = max_frames;
314                 } else {
315
316                         if (Config->get_stop_at_session_end()) {
317                                 stop_limit = current_end_frame();
318                         } else {
319                                 stop_limit = max_frames;
320                         }
321                 }
322
323                 if (maybe_stop (stop_limit)) {
324                         no_roll (nframes, 0);
325                         return;
326                 } 
327
328                 this_event = *next_event;
329                 the_next_one = next_event;
330                 ++the_next_one;
331
332                 offset = 0;
333
334                 while (nframes) {
335
336                         this_nframes = nframes; /* real (jack) time relative */
337                         frames_moved = (long) floor (_transport_speed * nframes); /* transport relative */
338
339                         /* running an event, position transport precisely to its time */
340                         if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) {
341                                 /* this isn't quite right for reverse play */
342                                 frames_moved = (long) (this_event->action_frame - _transport_frame);
343                                 this_nframes = (nframes_t) abs( floor(frames_moved / _transport_speed) );
344                         } 
345
346                         if (this_nframes) {
347                                 
348                                 click (_transport_frame, nframes, offset);
349                                 
350                                 /* now process frames between now and the first event in this block */
351                                 prepare_diskstreams ();
352
353                                 if (process_routes (this_nframes, offset)) {
354                                         no_roll (nframes, 0);
355                                         return;
356                                 }
357                                 
358                                 commit_diskstreams (this_nframes, session_needs_butler);
359
360                                 nframes -= this_nframes;
361                                 offset += this_nframes;
362                                 
363                                 if (frames_moved < 0) {
364                                         decrement_transport_position (-frames_moved);
365                                 } else {
366                                         increment_transport_position (frames_moved);
367                                 }
368
369                                 maybe_stop (stop_limit);
370                                 check_declick_out ();
371                         }
372
373                         /* now handle this event and all others scheduled for the same time */
374                         
375                         while (this_event && this_event->action_frame == _transport_frame) {
376                                 process_event (this_event);
377
378                                 if (the_next_one == events.end()) {
379                                         this_event = 0;
380                                 } else {
381                                         this_event = *the_next_one;
382                                         ++the_next_one;
383                                 }
384                         } 
385
386                         /* if an event left our state changing, do the right thing */
387
388                         if (non_realtime_work_pending()) {
389                                 no_roll (nframes, offset);
390                                 break;
391                         }
392
393                         /* this is necessary to handle the case of seamless looping */
394                         end_frame = _transport_frame + (nframes_t) floor (nframes * _transport_speed);
395                         
396                 }
397
398                 set_next_event ();
399
400         } /* implicit release of route lock */
401
402
403         if (session_needs_butler) {
404                 summon_butler ();
405         } 
406         
407         if (!_engine.freewheeling() && session_send_mtc) {
408                 send_midi_time_code_in_another_thread ();
409         }
410
411         return;
412 }               
413
414 void
415 Session::reset_slave_state ()
416 {
417         average_slave_delta = 1800;
418         delta_accumulator_cnt = 0;
419         have_first_delta_accumulator = false;
420         slave_state = Stopped;
421 }
422
423 bool
424 Session::transport_locked () const
425 {
426         Slave* sl = _slave;
427
428         if (!locate_pending() && ((Config->get_slave_source() == None) || (sl && sl->ok() && sl->locked()))) {
429                 return true;
430         }
431
432         return false;
433 }
434
435 bool
436 Session::follow_slave (nframes_t nframes, nframes_t offset)
437 {
438         float slave_speed;
439         nframes_t slave_transport_frame;
440         nframes_t this_delta;
441         int dir;
442         bool starting;
443
444         if (!_slave->ok()) {
445                 stop_transport ();
446                 Config->set_slave_source (None);
447                 goto noroll;
448         }
449         
450         _slave->speed_and_position (slave_speed, slave_transport_frame);
451
452         if (!_slave->locked()) {
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 (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 && !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                         // cerr << "adjust using " << delta
650                         // << " towards " << adjusted_speed
651                         // << " ratio = " << adjusted_speed / slave_speed
652                         // << " current = " << _transport_speed
653                         // << " slave @ " << slave_speed
654                         // << endl;
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         {
728                 if (post_transport_work & (PostTransportLocate|PostTransportStop)) {
729                         no_roll (nframes, 0);
730                         return;
731                 }
732
733                 if (!_exporting && _slave) {
734                         if (!follow_slave (nframes, 0)) {
735                                 return;
736                         }
737                 } 
738
739                 if (_transport_speed == 0) {
740                         no_roll (nframes, 0);
741                         return;
742                 }
743                 
744                 if (actively_recording()) {
745                         stop_limit = max_frames;
746                 } else {
747                         if (Config->get_stop_at_session_end()) {
748                                 stop_limit = current_end_frame();
749                         } else {
750                                 stop_limit = max_frames;
751                         }
752                 }
753                 
754                 if (maybe_stop (stop_limit)) {
755                         no_roll (nframes, 0);
756                         return;
757                 } 
758
759                 if (maybe_sync_start (nframes, offset)) {
760                         return;
761                 }
762
763                 click (_transport_frame, nframes, offset);
764
765                 prepare_diskstreams ();
766         
767                 frames_moved = (long) floor (_transport_speed * nframes);
768
769                 if (process_routes (nframes, offset)) {
770                         no_roll (nframes, offset);
771                         return;
772                 }
773
774                 commit_diskstreams (nframes, session_needs_butler);
775
776                 if (frames_moved < 0) {
777                         decrement_transport_position (-frames_moved);
778                 } else {
779                         increment_transport_position (frames_moved);
780                 }
781
782                 maybe_stop (stop_limit);
783                 check_declick_out ();
784
785         } /* implicit release of route lock */
786
787         if (session_needs_butler) {
788                 summon_butler ();
789         } 
790         
791         if (!_engine.freewheeling() && session_send_mtc) {
792                 send_midi_time_code_in_another_thread ();
793         }
794
795         return;
796 }               
797
798 void
799 Session::process_audition (nframes_t nframes)
800 {
801         Event* ev;
802         boost::shared_ptr<RouteList> r = routes.reader ();
803
804         for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
805                 if (!(*i)->hidden()) {
806                         (*i)->silence (nframes, 0);
807                 }
808         }
809
810         /* run the auditioner, and if it says we need butler service, ask for it */
811         
812         if (auditioner->play_audition (nframes) > 0) {
813                 summon_butler ();
814         } 
815
816         /* handle pending events */
817
818         while (pending_events.read (&ev, 1) == 1) {
819                 merge_event (ev);
820         }
821
822         /* if we are not in the middle of a state change,
823            and there are immediate events queued up,
824            process them. 
825         */
826
827         while (!non_realtime_work_pending() && !immediate_events.empty()) {
828                 Event *ev = immediate_events.front ();
829                 immediate_events.pop_front ();
830                 process_event (ev);
831         }
832
833         if (!auditioner->active()) {
834                 process_function = &Session::process_with_events;
835         }
836 }
837
838 bool
839 Session::maybe_sync_start (nframes_t& nframes, nframes_t& offset)
840 {
841         nframes_t sync_offset;
842         
843         if (!waiting_for_sync_offset) {
844                 return false;
845         }
846
847         if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) {
848
849                 no_roll (sync_offset, 0);
850                 nframes -= sync_offset;
851                 offset += sync_offset;
852                 waiting_for_sync_offset = false;
853                 
854                 if (nframes == 0) {
855                         return true; // done
856                 }
857                 
858         } else {
859                 no_roll (nframes, 0);
860                 return true; // done
861         }
862
863         return false;
864 }
865