546793b025aee7fcfbf0d72546056db7f5fadf94
[platform/upstream/libvorbis.git] / lib / block.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE.  *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5  * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
6  * PLEASE READ THESE TERMS DISTRIBUTING.                            *
7  *                                                                  *
8  * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000             *
9  * by Monty <monty@xiph.org> and The XIPHOPHORUS Company            *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: PCM data vector blocking, windowing and dis/reassembly
15  last mod: $Id: block.c,v 1.31 2000/06/14 10:13:35 xiphmont Exp $
16
17  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
18  more amusing by Vorbis' current two allowed block sizes.
19  
20  Vorbis manipulates the dynamic range of the incoming PCM data
21  envelope to minimise time-domain energy leakage from percussive and
22  plosive waveforms being quantized in the MDCT domain.
23
24  ********************************************************************/
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include "vorbis/codec.h"
30
31 #include "window.h"
32 #include "envelope.h"
33 #include "mdct.h"
34 #include "lpc.h"
35 #include "bitwise.h"
36 #include "registry.h"
37 #include "sharedbook.h"
38 #include "bookinternal.h"
39 #include "misc.h"
40
41 static int ilog2(unsigned int v){
42   int ret=0;
43   while(v>1){
44     ret++;
45     v>>=1;
46   }
47   return(ret);
48 }
49
50 /* pcm accumulator examples (not exhaustive):
51
52  <-------------- lW ---------------->
53                    <--------------- W ---------------->
54 :            .....|.....       _______________         |
55 :        .'''     |     '''_---      |       |\        |
56 :.....'''         |_____--- '''......|       | \_______|
57 :.................|__________________|_______|__|______|
58                   |<------ Sl ------>|      > Sr <     |endW
59                   |beginSl           |endSl  |  |endSr   
60                   |beginW            |endlW  |beginSr
61
62
63                       |< lW >|       
64                    <--------------- W ---------------->
65                   |   |  ..  ______________            |
66                   |   | '  `/        |     ---_        |
67                   |___.'___/`.       |         ---_____| 
68                   |_______|__|_______|_________________|
69                   |      >|Sl|<      |<------ Sr ----->|endW
70                   |       |  |endSl  |beginSr          |endSr
71                   |beginW |  |endlW                     
72                   mult[0] |beginSl                     mult[n]
73
74  <-------------- lW ----------------->
75                           |<--W-->|                               
76 :            ..............  ___  |   |                    
77 :        .'''             |`/   \ |   |                       
78 :.....'''                 |/`....\|...|                    
79 :.........................|___|___|___|                  
80                           |Sl |Sr |endW    
81                           |   |   |endSr
82                           |   |beginSr
83                           |   |endSl
84                           |beginSl
85                           |beginW
86 */
87
88 /* block abstraction setup *********************************************/
89
90 #ifndef WORD_ALIGN
91 #define WORD_ALIGN 8
92 #endif
93
94 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
95   memset(vb,0,sizeof(vorbis_block));
96   vb->vd=v;
97   vb->localalloc=0;
98   vb->localstore=NULL;
99   if(v->analysisp)
100     _oggpack_writeinit(&vb->opb);
101
102   return(0);
103 }
104
105 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
106   bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
107   if(bytes+vb->localtop>vb->localalloc){
108     /* can't just realloc... there are outstanding pointers */
109     if(vb->localstore){
110       struct alloc_chain *link=malloc(sizeof(struct alloc_chain));
111       vb->totaluse+=vb->localtop;
112       link->next=vb->reap;
113       link->ptr=vb->localstore;
114       vb->reap=link;
115     }
116     /* highly conservative */
117     vb->localalloc=bytes;
118     vb->localstore=malloc(vb->localalloc);
119     vb->localtop=0;
120   }
121   {
122     void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
123     vb->localtop+=bytes;
124     return ret;
125   }
126 }
127
128 /* reap the chain, pull the ripcord */
129 void _vorbis_block_ripcord(vorbis_block *vb){
130   /* reap the chain */
131   struct alloc_chain *reap=vb->reap;
132   while(reap){
133     struct alloc_chain *next=reap->next;
134     free(reap->ptr);
135     memset(reap,0,sizeof(struct alloc_chain));
136     free(reap);
137     reap=next;
138   }
139   /* consolidate storage */
140   if(vb->totaluse){
141     vb->localstore=realloc(vb->localstore,vb->totaluse+vb->localalloc);
142     vb->localalloc+=vb->totaluse;
143     vb->totaluse=0;
144   }
145
146   /* pull the ripcord */
147   vb->localtop=0;
148   vb->reap=NULL;
149 }
150
151 int vorbis_block_clear(vorbis_block *vb){
152   if(vb->vd)
153     if(vb->vd->analysisp)
154       _oggpack_writeclear(&vb->opb);
155   _vorbis_block_ripcord(vb);
156   if(vb->localstore)free(vb->localstore);
157
158   memset(vb,0,sizeof(vorbis_block));
159   return(0);
160 }
161
162 /* Analysis side code, but directly related to blocking.  Thus it's
163    here and not in analysis.c (which is for analysis transforms only).
164    The init is here because some of it is shared */
165
166 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
167   int i;
168   memset(v,0,sizeof(vorbis_dsp_state));
169
170   v->vi=vi;
171   v->modebits=ilog2(vi->modes);
172
173   v->transform[0]=calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
174   v->transform[1]=calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
175
176   /* MDCT is tranform 0 */
177
178   v->transform[0][0]=calloc(1,sizeof(mdct_lookup));
179   v->transform[1][0]=calloc(1,sizeof(mdct_lookup));
180   mdct_init(v->transform[0][0],vi->blocksizes[0]);
181   mdct_init(v->transform[1][0],vi->blocksizes[1]);
182
183   v->window[0][0][0]=calloc(VI_WINDOWB,sizeof(double *));
184   v->window[0][0][1]=v->window[0][0][0];
185   v->window[0][1][0]=v->window[0][0][0];
186   v->window[0][1][1]=v->window[0][0][0];
187   v->window[1][0][0]=calloc(VI_WINDOWB,sizeof(double *));
188   v->window[1][0][1]=calloc(VI_WINDOWB,sizeof(double *));
189   v->window[1][1][0]=calloc(VI_WINDOWB,sizeof(double *));
190   v->window[1][1][1]=calloc(VI_WINDOWB,sizeof(double *));
191
192   for(i=0;i<VI_WINDOWB;i++){
193     v->window[0][0][0][i]=
194       _vorbis_window(i,vi->blocksizes[0],vi->blocksizes[0]/2,vi->blocksizes[0]/2);
195     v->window[1][0][0][i]=
196       _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[0]/2,vi->blocksizes[0]/2);
197     v->window[1][0][1][i]=
198       _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[0]/2,vi->blocksizes[1]/2);
199     v->window[1][1][0][i]=
200       _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[1]/2,vi->blocksizes[0]/2);
201     v->window[1][1][1][i]=
202       _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[1]/2,vi->blocksizes[1]/2);
203   }
204
205   if(encp){ /* encode/decode differ here */
206     /* finish the codebooks */
207     v->fullbooks=calloc(vi->books,sizeof(codebook));
208     for(i=0;i<vi->books;i++)
209       vorbis_book_init_encode(v->fullbooks+i,vi->book_param[i]);
210     v->analysisp=1;
211   }else{
212     /* finish the codebooks */
213     v->fullbooks=calloc(vi->books,sizeof(codebook));
214     for(i=0;i<vi->books;i++)
215       vorbis_book_init_decode(v->fullbooks+i,vi->book_param[i]);
216   }
217
218   /* initialize the storage vectors to a decent size greater than the
219      minimum */
220   
221   v->pcm_storage=8192; /* we'll assume later that we have
222                           a minimum of twice the blocksize of
223                           accumulated samples in analysis */
224   v->pcm=malloc(vi->channels*sizeof(double *));
225   v->pcmret=malloc(vi->channels*sizeof(double *));
226   {
227     int i;
228     for(i=0;i<vi->channels;i++)
229       v->pcm[i]=calloc(v->pcm_storage,sizeof(double));
230   }
231
232   /* all 1 (large block) or 0 (small block) */
233   /* explicitly set for the sake of clarity */
234   v->lW=0; /* previous window size */
235   v->W=0;  /* current window size */
236
237   /* all vector indexes; multiples of samples_per_envelope_step */
238   v->centerW=vi->blocksizes[1]/2;
239
240   v->pcm_current=v->centerW;
241
242   /* initialize all the mapping/backend lookups */
243   v->mode=calloc(vi->modes,sizeof(vorbis_look_mapping *));
244   for(i=0;i<vi->modes;i++){
245     int mapnum=vi->mode_param[i]->mapping;
246     int maptype=vi->map_type[mapnum];
247     v->mode[i]=_mapping_P[maptype]->look(v,vi->mode_param[i],
248                                          vi->map_param[mapnum]);
249   }
250
251   return(0);
252 }
253
254 /* arbitrary settings and spec-mandated numbers get filled in here */
255 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
256   _vds_shared_init(v,vi,1);
257
258   /* Initialize the envelope multiplier storage */
259
260   v->envelope_storage=v->pcm_storage/vi->envelopesa;
261   v->multipliers=calloc(v->envelope_storage,sizeof(double));
262   _ve_envelope_init(&v->ve,vi->envelopesa);
263
264   v->envelope_current=v->centerW/vi->envelopesa;
265   return(0);
266 }
267
268 void vorbis_dsp_clear(vorbis_dsp_state *v){
269   int i,j,k;
270   if(v){
271     vorbis_info *vi=v->vi;
272
273     if(v->window[0][0][0]){
274       for(i=0;i<VI_WINDOWB;i++)
275         if(v->window[0][0][0][i])free(v->window[0][0][0][i]);
276       free(v->window[0][0][0]);
277
278       for(j=0;j<2;j++)
279         for(k=0;k<2;k++){
280           for(i=0;i<VI_WINDOWB;i++)
281             if(v->window[1][j][k][i])free(v->window[1][j][k][i]);
282           free(v->window[1][j][k]);
283         }
284     }
285     
286     if(v->pcm){
287       for(i=0;i<vi->channels;i++)
288         if(v->pcm[i])free(v->pcm[i]);
289       free(v->pcm);
290       if(v->pcmret)free(v->pcmret);
291     }
292     if(v->multipliers)free(v->multipliers);
293
294     _ve_envelope_clear(&v->ve);
295     if(v->transform[0]){
296       mdct_clear(v->transform[0][0]);
297       free(v->transform[0][0]);
298       free(v->transform[0]);
299     }
300     if(v->transform[1]){
301       mdct_clear(v->transform[1][0]);
302       free(v->transform[1][0]);
303       free(v->transform[1]);
304     }
305
306     /* free mode lookups; these are actually vorbis_look_mapping structs */
307     if(vi){
308       for(i=0;i<vi->modes;i++){
309         int mapnum=vi->mode_param[i]->mapping;
310         int maptype=vi->map_type[mapnum];
311         _mapping_P[maptype]->free_look(v->mode[i]);
312       }
313       /* free codebooks */
314       for(i=0;i<vi->books;i++)
315         vorbis_book_clear(v->fullbooks+i);
316     }
317
318     if(v->mode)free(v->mode);    
319     if(v->fullbooks)free(v->fullbooks);
320
321     /* free header, header1, header2 */
322     if(v->header)free(v->header);
323     if(v->header1)free(v->header1);
324     if(v->header2)free(v->header2);
325
326     memset(v,0,sizeof(vorbis_dsp_state));
327   }
328 }
329
330 double **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
331   int i;
332   vorbis_info *vi=v->vi;
333
334   /* free header, header1, header2 */
335   if(v->header)free(v->header);v->header=NULL;
336   if(v->header1)free(v->header1);v->header1=NULL;
337   if(v->header2)free(v->header2);v->header2=NULL;
338
339   /* Do we have enough storage space for the requested buffer? If not,
340      expand the PCM (and envelope) storage */
341     
342   if(v->pcm_current+vals>=v->pcm_storage){
343     v->pcm_storage=v->pcm_current+vals*2;
344     v->envelope_storage=v->pcm_storage/v->vi->envelopesa;
345    
346     for(i=0;i<vi->channels;i++){
347       v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
348     }
349     v->multipliers=realloc(v->multipliers,v->envelope_storage*sizeof(double));
350   }
351
352   for(i=0;i<vi->channels;i++)
353     v->pcmret[i]=v->pcm[i]+v->pcm_current;
354     
355   return(v->pcmret);
356 }
357
358 /* call with val<=0 to set eof */
359
360 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
361   vorbis_info *vi=v->vi;
362   if(vals<=0){
363     /* We're encoding the end of the stream.  Just make sure we have
364        [at least] a full block of zeroes at the end. */
365
366     int i;
367     vorbis_analysis_buffer(v,v->vi->blocksizes[1]*2);
368     v->eofflag=v->pcm_current;
369     v->pcm_current+=v->vi->blocksizes[1]*2;
370     for(i=0;i<vi->channels;i++)
371       memset(v->pcm[i]+v->eofflag,0,
372              (v->pcm_current-v->eofflag)*sizeof(double));
373   }else{
374     
375     if(v->pcm_current+vals>v->pcm_storage)
376       return(-1);
377
378     v->pcm_current+=vals;
379   }
380   return(0);
381 }
382
383 /* do the deltas, envelope shaping, pre-echo and determine the size of
384    the next block on which to continue analysis */
385 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
386   int i;
387   vorbis_info *vi=v->vi;
388   long beginW=v->centerW-vi->blocksizes[v->W]/2,centerNext;
389
390   /* check to see if we're done... */
391   if(v->eofflag==-1)return(0);
392
393   /* if we have any unfilled envelope blocks for which we have PCM
394      data, fill them up in before proceeding. */
395
396   if(v->pcm_current/vi->envelopesa>v->envelope_current){
397     /* This generates the multipliers, but does not sparsify the vector.
398        That's done by block before coding */
399     _ve_envelope_deltas(v);
400   }
401
402   /* By our invariant, we have lW, W and centerW set.  Search for
403      the next boundary so we can determine nW (the next window size)
404      which lets us compute the shape of the current block's window */
405   
406   if(vi->blocksizes[0]<vi->blocksizes[1]){
407     
408     if(v->W)
409       /* this is a long window; we start the search forward of centerW
410          because that's the fastest we could react anyway */
411       i=v->centerW+vi->blocksizes[1]/4-vi->blocksizes[0]/4;
412     else
413       /* short window.  Search from centerW */
414       i=v->centerW;
415     i/=vi->envelopesa;
416     
417     for(;i<v->envelope_current-1;i++){
418       /* Compare last with current; do we have an abrupt energy change? */
419       
420       if(v->multipliers[i-1]*vi->preecho_thresh<  
421          v->multipliers[i])break;
422       
423       /* because the overlapping nature of the delta finding
424          'smears' the energy cliffs, also compare completely
425          unoverlapped areas just in case the plosive happened in an
426          unlucky place */
427       
428       if(v->multipliers[i-1]*vi->preecho_thresh<  
429          v->multipliers[i+1])break;
430         
431     }
432     
433     if(i<v->envelope_current-1){
434       /* Ooo, we hit a multiplier. Is it beyond the boundary to make the
435          upcoming block large ? */
436       long largebound;
437       if(v->W)
438         /* min boundary; nW large, next small */
439         largebound=v->centerW+vi->blocksizes[1]*3/4+vi->blocksizes[0]/4;
440       else
441         /* min boundary; nW large, next small */
442         largebound=v->centerW+vi->blocksizes[0]/2+vi->blocksizes[1]/2;
443       largebound/=vi->envelopesa;
444       
445       if(i>=largebound)
446         v->nW=1;
447       else
448         v->nW=0;
449       
450     }else{
451       /* Assume maximum; if the block is incomplete given current
452          buffered data, this will be detected below */
453       v->nW=1;
454     }
455   }else
456     v->nW=0;
457
458   /* Do we actually have enough data *now* for the next block? The
459      reason to check is that if we had no multipliers, that could
460      simply been due to running out of data.  In that case, we don't
461      know the size of the next block for sure and we need that now to
462      figure out the window shape of this block */
463   
464   centerNext=v->centerW+vi->blocksizes[v->W]/4+vi->blocksizes[v->nW]/4;
465
466   {
467     /* center of next block + next block maximum right side.  Note
468        that the next block needs an additional vi->envelopesa samples 
469        to actually be written (for the last multiplier), but we didn't
470        need that to determine its size */
471
472     long blockbound=centerNext+vi->blocksizes[v->nW]/2;
473     if(v->pcm_current<blockbound)return(0); /* not enough data yet */    
474   }
475   
476   /* fill in the block.  Note that for a short window, lW and nW are *short*
477      regardless of actual settings in the stream */
478
479   _vorbis_block_ripcord(vb);
480   if(v->W){
481     vb->lW=v->lW;
482     vb->W=v->W;
483     vb->nW=v->nW;
484   }else{
485     vb->lW=0;
486     vb->W=v->W;
487     vb->nW=0;
488   }
489   vb->vd=v;
490   vb->sequence=v->sequence;
491   vb->frameno=v->frameno;
492   vb->pcmend=vi->blocksizes[v->W];
493   
494   /* copy the vectors; this uses the local storage in vb */
495   {
496     vb->pcm=_vorbis_block_alloc(vb,sizeof(double *)*vi->channels);
497     for(i=0;i<vi->channels;i++){
498       vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(double));
499       memcpy(vb->pcm[i],v->pcm[i]+beginW,vi->blocksizes[v->W]*sizeof(double));
500     }
501   }
502   
503   /* handle eof detection: eof==0 means that we've not yet received EOF
504                            eof>0  marks the last 'real' sample in pcm[]
505                            eof<0  'no more to do'; doesn't get here */
506
507   if(v->eofflag){
508     if(v->centerW>=v->eofflag){
509       v->eofflag=-1;
510       vb->eofflag=1;
511       return(1);
512     }
513   }
514
515   /* advance storage vectors and clean up */
516   {
517     int new_centerNext=vi->blocksizes[1]/2;
518     int movementW=centerNext-new_centerNext;
519     int movementM=movementW/vi->envelopesa;
520
521
522
523     /* the multipliers and pcm stay synced up because the blocksize
524        must be multiples of samples_per_envelope_step (minimum
525        multiple is 2) */
526
527     v->pcm_current-=movementW;
528     v->envelope_current-=movementM;
529
530     for(i=0;i<vi->channels;i++)
531       memmove(v->pcm[i],v->pcm[i]+movementW,
532               v->pcm_current*sizeof(double));
533     
534     memmove(v->multipliers,v->multipliers+movementM,
535             v->envelope_current*sizeof(double));
536
537     v->lW=v->W;
538     v->W=v->nW;
539     v->centerW=new_centerNext;
540
541     v->sequence++;
542
543     if(v->eofflag){
544       v->eofflag-=movementW;
545       /* do not add padding to end of stream! */
546       if(v->centerW>=v->eofflag){
547         v->frameno+=v->eofflag;
548       }else{
549         v->frameno+=movementW;
550       }
551     }else
552       v->frameno+=movementW;
553   }
554
555   /* done */
556   return(1);
557 }
558
559 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
560   _vds_shared_init(v,vi,0);
561
562   /* Adjust centerW to allow an easier mechanism for determining output */
563   v->pcm_returned=v->centerW;
564   v->centerW-= vi->blocksizes[v->W]/4+vi->blocksizes[v->lW]/4;
565   v->frameno=-1;
566   v->sequence=-1;
567
568   return(0);
569 }
570
571 /* Unike in analysis, the window is only partially applied for each
572    block.  The time domain envelope is not yet handled at the point of
573    calling (as it relies on the previous block). */
574
575 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
576   vorbis_info *vi=v->vi;
577
578   /* Shift out any PCM/multipliers that we returned previously */
579   /* centerW is currently the center of the last block added */
580   if(v->pcm_returned  && v->centerW>vi->blocksizes[1]/2){
581
582     /* don't shift too much; we need to have a minimum PCM buffer of
583        1/2 long block */
584
585     int shiftPCM=v->centerW-vi->blocksizes[1]/2;
586     shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
587
588     v->pcm_current-=shiftPCM;
589     v->centerW-=shiftPCM;
590     v->pcm_returned-=shiftPCM;
591     
592     if(shiftPCM){
593       int i;
594       for(i=0;i<vi->channels;i++)
595         memmove(v->pcm[i],v->pcm[i]+shiftPCM,
596                 v->pcm_current*sizeof(double));
597     }
598   }
599
600   v->lW=v->W;
601   v->W=vb->W;
602   v->nW=-1;
603
604   v->glue_bits+=vb->glue_bits;
605   v->time_bits+=vb->time_bits;
606   v->floor_bits+=vb->floor_bits;
607   v->res_bits+=vb->res_bits;
608
609   if(v->sequence+1 != vb->sequence)v->frameno=-1; /* out of sequence;
610                                                      lose count */
611
612   v->sequence=vb->sequence;
613
614   {
615     int sizeW=vi->blocksizes[v->W];
616     int centerW=v->centerW+vi->blocksizes[v->lW]/4+sizeW/4;
617     int beginW=centerW-sizeW/2;
618     int endW=beginW+sizeW;
619     int beginSl;
620     int endSl;
621     int i,j;
622
623     /* Do we have enough PCM/mult storage for the block? */
624     if(endW>v->pcm_storage){
625       /* expand the storage */
626       v->pcm_storage=endW+vi->blocksizes[1];
627    
628       for(i=0;i<vi->channels;i++)
629         v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double)); 
630     }
631
632     /* overlap/add PCM */
633
634     switch(v->W){
635     case 0:
636       beginSl=0;
637       endSl=vi->blocksizes[0]/2;
638       break;
639     case 1:
640       beginSl=vi->blocksizes[1]/4-vi->blocksizes[v->lW]/4;
641       endSl=beginSl+vi->blocksizes[v->lW]/2;
642       break;
643     }
644
645     for(j=0;j<vi->channels;j++){
646       double *pcm=v->pcm[j]+beginW;
647       
648       /* the overlap/add section */
649       for(i=beginSl;i<endSl;i++)
650         pcm[i]+=vb->pcm[j][i];
651       /* the remaining section */
652       for(;i<sizeW;i++)
653         pcm[i]=vb->pcm[j][i];
654     }
655
656     /* track the frame number... This is for convenience, but also
657        making sure our last packet doesn't end with added padding.  If
658        the last packet is partial, the number of samples we'll have to
659        return will be past the vb->frameno.
660        
661        This is not foolproof!  It will be confused if we begin
662        decoding at the last page after a seek or hole.  In that case,
663        we don't have a starting point to judge where the last frame
664        is.  For this reason, vorbisfile will always try to make sure
665        it reads the last two marked pages in proper sequence */
666
667     if(v->frameno==-1)
668       v->frameno=vb->frameno;
669     else{
670       v->frameno+=(centerW-v->centerW);
671       if(vb->frameno!=-1 && v->frameno!=vb->frameno){
672         if(v->frameno>vb->frameno && vb->eofflag){
673           /* partial last frame.  Strip the padding off */
674           centerW-=(v->frameno-vb->frameno);
675         }/* else{ Shouldn't happen *unless* the bitstream is out of
676             spec.  Either way, believe the bitstream } */
677         v->frameno=vb->frameno;
678       }
679     }
680
681     /* Update, cleanup */
682
683     v->centerW=centerW;
684     v->pcm_current=endW;
685
686     if(vb->eofflag)v->eofflag=1;
687   }
688
689   return(0);
690 }
691
692 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,double ***pcm){
693   vorbis_info *vi=v->vi;
694   if(v->pcm_returned<v->centerW){
695     int i;
696     for(i=0;i<vi->channels;i++)
697       v->pcmret[i]=v->pcm[i]+v->pcm_returned;
698     *pcm=v->pcmret;
699     return(v->centerW-v->pcm_returned);
700   }
701   return(0);
702 }
703
704 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
705   if(bytes && v->pcm_returned+bytes>v->centerW)return(-1);
706   v->pcm_returned+=bytes;
707   return(0);
708 }
709