Add pre-cliff and post-cliff interpolation so that sample
[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.36 2000/08/23 10:16:56 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 */
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 state storage */
259   v->ve=calloc(1,sizeof(envelope_lookup));
260   _ve_envelope_init(v->ve,vi);
261
262   return(0);
263 }
264
265 void vorbis_dsp_clear(vorbis_dsp_state *v){
266   int i,j,k;
267   if(v){
268     vorbis_info *vi=v->vi;
269
270     if(v->window[0][0][0]){
271       for(i=0;i<VI_WINDOWB;i++)
272         if(v->window[0][0][0][i])free(v->window[0][0][0][i]);
273       free(v->window[0][0][0]);
274
275       for(j=0;j<2;j++)
276         for(k=0;k<2;k++){
277           for(i=0;i<VI_WINDOWB;i++)
278             if(v->window[1][j][k][i])free(v->window[1][j][k][i]);
279           free(v->window[1][j][k]);
280         }
281     }
282     
283     if(v->pcm){
284       for(i=0;i<vi->channels;i++)
285         if(v->pcm[i])free(v->pcm[i]);
286       free(v->pcm);
287       if(v->pcmret)free(v->pcmret);
288     }
289
290     if(v->ve){
291       _ve_envelope_clear(v->ve);
292       free(v->ve);
293     }
294
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    
345     for(i=0;i<vi->channels;i++){
346       v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
347     }
348   }
349
350   for(i=0;i<vi->channels;i++)
351     v->pcmret[i]=v->pcm[i]+v->pcm_current;
352     
353   return(v->pcmret);
354 }
355
356 static void _preinterpolate_helper(vorbis_dsp_state *v){
357   int i;
358   int order=32;
359   double *lpc=alloca(order*sizeof(double));
360   double *work=alloca(v->pcm_current*sizeof(double));
361   long j;
362   v->preinterp=1;
363
364   if(v->pcm_current-v->centerW>order*2){ /* safety */
365     for(i=0;i<v->vi->channels;i++){
366       
367       /* need to run the interpolation in reverse! */
368       for(j=0;j<v->pcm_current;j++)
369         work[j]=v->pcm[i][v->pcm_current-j-1];
370       
371       /* prime as above */
372       vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
373       
374       /* run the predictor filter */
375       vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
376                          order,
377                          work+v->pcm_current-v->centerW,
378                          v->centerW);
379       for(j=0;j<v->pcm_current;j++)
380         v->pcm[i][v->pcm_current-j-1]=work[j];
381     }
382   }
383 }
384
385
386 /* call with val<=0 to set eof */
387
388 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
389   vorbis_info *vi=v->vi;
390   if(vals<=0){
391     int order=32;
392     int i;
393     double *lpc=alloca(order*sizeof(double));
394
395     /* if it wasn't done earlier (very short sample) */
396     if(!v->preinterp)
397       _preinterpolate_helper(v);
398
399     /* We're encoding the end of the stream.  Just make sure we have
400        [at least] a full block of zeroes at the end. */
401     /* actually, we don't want zeroes; that could drop a large
402        amplitude off a cliff, creating spread spectrum noise that will
403        suck to encode.  Extrapolate for the sake of cleanliness. */
404
405     vorbis_analysis_buffer(v,v->vi->blocksizes[1]*2);
406     v->eofflag=v->pcm_current;
407     v->pcm_current+=v->vi->blocksizes[1]*2;
408
409     for(i=0;i<vi->channels;i++){
410       if(v->eofflag>order*2){
411         /* extrapolate with LPC to fill in */
412         long n;
413
414         /* make a predictor filter */
415         n=v->eofflag;
416         if(n>v->vi->blocksizes[1])n=v->vi->blocksizes[1];
417         vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
418
419         /* run the predictor filter */
420         vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
421                            v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
422       }else{
423         /* not enough data to interpolate (unlikely to happen due to
424            guarding the overlap, but bulletproof in case that
425            assumtion goes away). zeroes will do. */
426         memset(v->pcm[i]+v->eofflag,0,
427                (v->pcm_current-v->eofflag)*sizeof(double));
428
429       }
430     }
431   }else{
432
433     if(v->pcm_current+vals>v->pcm_storage)
434       return(-1);
435
436     v->pcm_current+=vals;
437
438     /* we may want to reverse interpolate the beginning of a stream
439        too... in case we're beginning on a cliff! */
440     /* clumsy, but simple.  It only runs once, so simple is good. */
441     if(!v->preinterp && v->pcm_current-v->centerW>v->vi->blocksizes[1])
442       _preinterpolate_helper(v);
443
444   }
445   return(0);
446 }
447
448 /* do the deltas, envelope shaping, pre-echo and determine the size of
449    the next block on which to continue analysis */
450 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
451   int i;
452   vorbis_info *vi=v->vi;
453   long beginW=v->centerW-vi->blocksizes[v->W]/2,centerNext;
454
455   /* check to see if we're started... */
456   if(!v->preinterp)return(0);
457
458   /* check to see if we're done... */
459   if(v->eofflag==-1)return(0);
460
461   /* By our invariant, we have lW, W and centerW set.  Search for
462      the next boundary so we can determine nW (the next window size)
463      which lets us compute the shape of the current block's window */
464   
465   if(vi->blocksizes[0]<vi->blocksizes[1]){
466     long largebound;
467     long bp;
468
469     if(v->W)
470       /* min boundary; nW large, next small */
471       largebound=v->centerW+vi->blocksizes[1]*3/4+vi->blocksizes[0]/4;
472     else
473       /* min boundary; nW large, next small */
474       largebound=v->centerW+vi->blocksizes[1]*3/4+vi->blocksizes[0]*3/4;
475
476     bp=_ve_envelope_search(v,largebound);
477     if(bp==-1)return(0); /* not enough data currently to search for a
478                             full long block */
479     v->nW=bp;
480
481   }else
482     v->nW=0;
483   
484   centerNext=v->centerW+vi->blocksizes[v->W]/4+vi->blocksizes[v->nW]/4;
485
486   {
487     /* center of next block + next block maximum right side. */
488
489     long blockbound=centerNext+vi->blocksizes[v->nW]/2;
490     if(v->pcm_current<blockbound)return(0); /* not enough data yet;
491                                                although this check is
492                                                less strict that the
493                                                _ve_envelope_search,
494                                                the search is not run
495                                                if we only use one
496                                                block size */
497   }
498   
499   /* fill in the block.  Note that for a short window, lW and nW are *short*
500      regardless of actual settings in the stream */
501
502   _vorbis_block_ripcord(vb);
503   if(v->W){
504     vb->lW=v->lW;
505     vb->W=v->W;
506     vb->nW=v->nW;
507   }else{
508     vb->lW=0;
509     vb->W=v->W;
510     vb->nW=0;
511   }
512   vb->vd=v;
513   vb->sequence=v->sequence;
514   vb->frameno=v->frameno;
515   vb->pcmend=vi->blocksizes[v->W];
516   
517   /* copy the vectors; this uses the local storage in vb */
518   {
519     vb->pcm=_vorbis_block_alloc(vb,sizeof(double *)*vi->channels);
520     for(i=0;i<vi->channels;i++){
521       vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(double));
522       memcpy(vb->pcm[i],v->pcm[i]+beginW,vi->blocksizes[v->W]*sizeof(double));
523     }
524   }
525   
526   /* handle eof detection: eof==0 means that we've not yet received EOF
527                            eof>0  marks the last 'real' sample in pcm[]
528                            eof<0  'no more to do'; doesn't get here */
529
530   if(v->eofflag){
531     if(v->centerW>=v->eofflag){
532       v->eofflag=-1;
533       vb->eofflag=1;
534       return(1);
535     }
536   }
537
538   /* advance storage vectors and clean up */
539   {
540     int new_centerNext=vi->blocksizes[1]/2;
541     int movementW=centerNext-new_centerNext;
542
543     _ve_envelope_shift(v->ve,movementW);
544     v->pcm_current-=movementW;
545
546     for(i=0;i<vi->channels;i++)
547       memmove(v->pcm[i],v->pcm[i]+movementW,
548               v->pcm_current*sizeof(double));
549
550
551     v->lW=v->W;
552     v->W=v->nW;
553     v->centerW=new_centerNext;
554
555     v->sequence++;
556
557     if(v->eofflag){
558       v->eofflag-=movementW;
559       /* do not add padding to end of stream! */
560       if(v->centerW>=v->eofflag){
561         v->frameno+=movementW-(v->centerW-v->eofflag);
562       }else{
563         v->frameno+=movementW;
564       }
565     }else{
566       v->frameno+=movementW;
567     }
568   }
569
570   /* done */
571   return(1);
572 }
573
574 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
575   _vds_shared_init(v,vi,0);
576
577   /* Adjust centerW to allow an easier mechanism for determining output */
578   v->pcm_returned=v->centerW;
579   v->centerW-= vi->blocksizes[v->W]/4+vi->blocksizes[v->lW]/4;
580   v->frameno=-1;
581   v->sequence=-1;
582
583   return(0);
584 }
585
586 /* Unike in analysis, the window is only partially applied for each
587    block.  The time domain envelope is not yet handled at the point of
588    calling (as it relies on the previous block). */
589
590 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
591   vorbis_info *vi=v->vi;
592
593   /* Shift out any PCM that we returned previously */
594   /* centerW is currently the center of the last block added */
595   if(v->pcm_returned  && v->centerW>vi->blocksizes[1]/2){
596
597     /* don't shift too much; we need to have a minimum PCM buffer of
598        1/2 long block */
599
600     int shiftPCM=v->centerW-vi->blocksizes[1]/2;
601     shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
602
603     v->pcm_current-=shiftPCM;
604     v->centerW-=shiftPCM;
605     v->pcm_returned-=shiftPCM;
606     
607     if(shiftPCM){
608       int i;
609       for(i=0;i<vi->channels;i++)
610         memmove(v->pcm[i],v->pcm[i]+shiftPCM,
611                 v->pcm_current*sizeof(double));
612     }
613   }
614
615   v->lW=v->W;
616   v->W=vb->W;
617   v->nW=-1;
618
619   v->glue_bits+=vb->glue_bits;
620   v->time_bits+=vb->time_bits;
621   v->floor_bits+=vb->floor_bits;
622   v->res_bits+=vb->res_bits;
623
624   if(v->sequence+1 != vb->sequence)v->frameno=-1; /* out of sequence;
625                                                      lose count */
626
627   v->sequence=vb->sequence;
628
629   {
630     int sizeW=vi->blocksizes[v->W];
631     int centerW=v->centerW+vi->blocksizes[v->lW]/4+sizeW/4;
632     int beginW=centerW-sizeW/2;
633     int endW=beginW+sizeW;
634     int beginSl;
635     int endSl;
636     int i,j;
637
638     /* Do we have enough PCM/mult storage for the block? */
639     if(endW>v->pcm_storage){
640       /* expand the storage */
641       v->pcm_storage=endW+vi->blocksizes[1];
642    
643       for(i=0;i<vi->channels;i++)
644         v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double)); 
645     }
646
647     /* overlap/add PCM */
648
649     switch(v->W){
650     case 0:
651       beginSl=0;
652       endSl=vi->blocksizes[0]/2;
653       break;
654     case 1:
655       beginSl=vi->blocksizes[1]/4-vi->blocksizes[v->lW]/4;
656       endSl=beginSl+vi->blocksizes[v->lW]/2;
657       break;
658     }
659
660     for(j=0;j<vi->channels;j++){
661       double *pcm=v->pcm[j]+beginW;
662       
663       /* the overlap/add section */
664       for(i=beginSl;i<endSl;i++)
665         pcm[i]+=vb->pcm[j][i];
666       /* the remaining section */
667       for(;i<sizeW;i++)
668         pcm[i]=vb->pcm[j][i];
669     }
670
671     /* track the frame number... This is for convenience, but also
672        making sure our last packet doesn't end with added padding.  If
673        the last packet is partial, the number of samples we'll have to
674        return will be past the vb->frameno.
675        
676        This is not foolproof!  It will be confused if we begin
677        decoding at the last page after a seek or hole.  In that case,
678        we don't have a starting point to judge where the last frame
679        is.  For this reason, vorbisfile will always try to make sure
680        it reads the last two marked pages in proper sequence */
681
682     if(v->frameno==-1)
683       v->frameno=vb->frameno;
684     else{
685       v->frameno+=(centerW-v->centerW);
686       if(vb->frameno!=-1 && v->frameno!=vb->frameno){
687         if(v->frameno>vb->frameno && vb->eofflag){
688           /* partial last frame.  Strip the padding off */
689           centerW-=(v->frameno-vb->frameno);
690         }/* else{ Shouldn't happen *unless* the bitstream is out of
691             spec.  Either way, believe the bitstream } */
692         v->frameno=vb->frameno;
693       }
694     }
695
696     /* Update, cleanup */
697
698     v->centerW=centerW;
699     v->pcm_current=endW;
700
701     if(vb->eofflag)v->eofflag=1;
702   }
703
704   return(0);
705 }
706
707 /* pcm==NULL indicates we just want the pending samples, no more */
708 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,double ***pcm){
709   vorbis_info *vi=v->vi;
710   if(v->pcm_returned<v->centerW){
711     if(pcm){
712       int i;
713       for(i=0;i<vi->channels;i++)
714         v->pcmret[i]=v->pcm[i]+v->pcm_returned;
715       *pcm=v->pcmret;
716     }
717     return(v->centerW-v->pcm_returned);
718   }
719   return(0);
720 }
721
722 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
723   if(bytes && v->pcm_returned+bytes>v->centerW)return(-1);
724   v->pcm_returned+=bytes;
725   return(0);
726 }
727