- /* track the frame number... This is for convenience, but also
- making sure our last packet doesn't end with added padding. If
- the last packet is partial, the number of samples we'll have to
- return will be past the vb->frameno.
-
- This is not foolproof! It will be confused if we begin
- decoding at the last page after a seek or hole. In that case,
- we don't have a starting point to judge where the last frame
- is. For this reason, vorbisfile will always try to make sure
- it reads the last two marked pages in proper sequence */
-
- if(v->frameno==-1)
- v->frameno=vb->frameno;
- else{
- v->frameno+=(centerW-v->centerW);
- if(vb->frameno!=-1 && v->frameno!=vb->frameno){
- if(v->frameno>vb->frameno && vb->eofflag){
- /* partial last frame. Strip the padding off */
- centerW-=(v->frameno-vb->frameno);
- }/* else{ Shouldn't happen *unless* the bitstream is out of
- spec. Either way, believe the bitstream } */
- v->frameno=vb->frameno;
+ if(v->centerW)
+ v->centerW=0;
+ else
+ v->centerW=n1;
+
+ /* deal with initial packet state; we do this using the explicit
+ pcm_returned==-1 flag otherwise we're sensitive to first block
+ being short or long */
+
+ if(v->pcm_returned==-1){
+ v->pcm_returned=thisCenter;
+ v->pcm_current=thisCenter;
+ }else{
+ v->pcm_returned=prevCenter;
+ v->pcm_current=prevCenter+
+ ((ci->blocksizes[v->lW]/4+
+ ci->blocksizes[v->W]/4)>>hs);
+ }
+
+ }
+
+ /* track the frame number... This is for convenience, but also
+ making sure our last packet doesn't end with added padding. If
+ the last packet is partial, the number of samples we'll have to
+ return will be past the vb->granulepos.
+
+ This is not foolproof! It will be confused if we begin
+ decoding at the last page after a seek or hole. In that case,
+ we don't have a starting point to judge where the last frame
+ is. For this reason, vorbisfile will always try to make sure
+ it reads the last two marked pages in proper sequence */
+
+ if(b->sample_count==-1){
+ b->sample_count=0;
+ }else{
+ b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
+ }
+
+ if(v->granulepos==-1){
+ if(vb->granulepos!=-1){ /* only set if we have a position to set to */
+
+ v->granulepos=vb->granulepos;
+
+ /* is this a short page? */
+ if(b->sample_count>v->granulepos){
+ /* corner case; if this is both the first and last audio page,
+ then spec says the end is cut, not beginning */
+ long extra=b->sample_count-vb->granulepos;
+
+ /* we use ogg_int64_t for granule positions because a
+ uint64 isn't universally available. Unfortunately,
+ that means granposes can be 'negative' and result in
+ extra being negative */
+ if(extra<0)
+ extra=0;
+
+ if(vb->eofflag){
+ /* trim the end */
+ /* no preceding granulepos; assume we started at zero (we'd
+ have to in a short single-page stream) */
+ /* granulepos could be -1 due to a seek, but that would result
+ in a long count, not short count */
+
+ /* Guard against corrupt/malicious frames that set EOP and
+ a backdated granpos; don't rewind more samples than we
+ actually have */
+ if(extra > (v->pcm_current - v->pcm_returned)<<hs)
+ extra = (v->pcm_current - v->pcm_returned)<<hs;
+
+ v->pcm_current-=extra>>hs;
+ }else{
+ /* trim the beginning */
+ v->pcm_returned+=extra>>hs;
+ if(v->pcm_returned>v->pcm_current)
+ v->pcm_returned=v->pcm_current;
+ }
+