Merge branch_beta3 onto the mainline.
[platform/upstream/libvorbis.git] / lib / block.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5  * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH    *
6  * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.        *
7  *                                                                  *
8  * THE OggVorbis 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.40 2000/11/06 00:07:00 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 <ogg/ogg.h>
30 #include "vorbis/codec.h"
31
32 #include "window.h"
33 #include "envelope.h"
34 #include "mdct.h"
35 #include "lpc.h"
36 #include "registry.h"
37 #include "codebook.h"
38 #include "misc.h"
39 #include "os.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 _ogg_realloc... there are outstanding pointers */
109     if(vb->localstore){
110       struct alloc_chain *link=_ogg_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=_ogg_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=_ogg_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   codec_setup_info *ci=vi->codec_setup;
169   backend_lookup_state *b=NULL;
170
171   memset(v,0,sizeof(vorbis_dsp_state));
172   b=v->backend_state=_ogg_calloc(1,sizeof(backend_lookup_state));
173
174   v->vi=vi;
175   b->modebits=ilog2(ci->modes);
176
177   b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
178   b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
179
180   /* MDCT is tranform 0 */
181
182   b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
183   b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
184   mdct_init(b->transform[0][0],ci->blocksizes[0]);
185   mdct_init(b->transform[1][0],ci->blocksizes[1]);
186
187   b->window[0][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
188   b->window[0][0][1]=b->window[0][0][0];
189   b->window[0][1][0]=b->window[0][0][0];
190   b->window[0][1][1]=b->window[0][0][0];
191   b->window[1][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
192   b->window[1][0][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
193   b->window[1][1][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
194   b->window[1][1][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
195
196   for(i=0;i<VI_WINDOWB;i++){
197     b->window[0][0][0][i]=
198       _vorbis_window(i,ci->blocksizes[0],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
199     b->window[1][0][0][i]=
200       _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
201     b->window[1][0][1][i]=
202       _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[1]/2);
203     b->window[1][1][0][i]=
204       _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[0]/2);
205     b->window[1][1][1][i]=
206       _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[1]/2);
207   }
208
209   if(encp){ /* encode/decode differ here */
210     /* finish the codebooks */
211     b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
212     for(i=0;i<ci->books;i++)
213       vorbis_book_init_encode(b->fullbooks+i,ci->book_param[i]);
214     v->analysisp=1;
215   }else{
216     /* finish the codebooks */
217     b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
218     for(i=0;i<ci->books;i++)
219       vorbis_book_init_decode(b->fullbooks+i,ci->book_param[i]);
220   }
221
222   /* initialize the storage vectors to a decent size greater than the
223      minimum */
224   
225   v->pcm_storage=8192; /* we'll assume later that we have
226                           a minimum of twice the blocksize of
227                           accumulated samples in analysis */
228   v->pcm=_ogg_malloc(vi->channels*sizeof(float *));
229   v->pcmret=_ogg_malloc(vi->channels*sizeof(float *));
230   {
231     int i;
232     for(i=0;i<vi->channels;i++)
233       v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(float));
234   }
235
236   /* all 1 (large block) or 0 (small block) */
237   /* explicitly set for the sake of clarity */
238   v->lW=0; /* previous window size */
239   v->W=0;  /* current window size */
240
241   /* all vector indexes */
242   v->centerW=ci->blocksizes[1]/2;
243
244   v->pcm_current=v->centerW;
245
246   /* initialize all the mapping/backend lookups */
247   b->mode=_ogg_calloc(ci->modes,sizeof(vorbis_look_mapping *));
248   for(i=0;i<ci->modes;i++){
249     int mapnum=ci->mode_param[i]->mapping;
250     int maptype=ci->map_type[mapnum];
251     b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
252                                          ci->map_param[mapnum]);
253   }
254
255   return(0);
256 }
257
258 /* arbitrary settings and spec-mandated numbers get filled in here */
259 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
260   backend_lookup_state *b=NULL;
261
262   _vds_shared_init(v,vi,1);
263   b=v->backend_state;
264
265   /* Initialize the envelope state storage */
266   b->ve=_ogg_calloc(1,sizeof(envelope_lookup));
267   _ve_envelope_init(b->ve,vi);
268
269   return(0);
270 }
271
272 void vorbis_dsp_clear(vorbis_dsp_state *v){
273   int i,j,k;
274   if(v){
275     vorbis_info *vi=v->vi;
276     codec_setup_info *ci=(vi?vi->codec_setup:NULL);
277     backend_lookup_state *b=v->backend_state;
278
279     if(b){
280       if(b->window[0][0][0]){
281         for(i=0;i<VI_WINDOWB;i++)
282           if(b->window[0][0][0][i])free(b->window[0][0][0][i]);
283         free(b->window[0][0][0]);
284         
285         for(j=0;j<2;j++)
286           for(k=0;k<2;k++){
287             for(i=0;i<VI_WINDOWB;i++)
288               if(b->window[1][j][k][i])free(b->window[1][j][k][i]);
289             free(b->window[1][j][k]);
290           }
291       }
292
293       if(b->ve){
294         _ve_envelope_clear(b->ve);
295         free(b->ve);
296       }
297
298       if(b->transform[0]){
299         mdct_clear(b->transform[0][0]);
300         free(b->transform[0][0]);
301         free(b->transform[0]);
302       }
303       if(b->transform[1]){
304         mdct_clear(b->transform[1][0]);
305         free(b->transform[1][0]);
306         free(b->transform[1]);
307       }
308       
309     }
310     
311     if(v->pcm){
312       for(i=0;i<vi->channels;i++)
313         if(v->pcm[i])free(v->pcm[i]);
314       free(v->pcm);
315       if(v->pcmret)free(v->pcmret);
316     }
317
318     /* free mode lookups; these are actually vorbis_look_mapping structs */
319     if(ci){
320       for(i=0;i<ci->modes;i++){
321         int mapnum=ci->mode_param[i]->mapping;
322         int maptype=ci->map_type[mapnum];
323         if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
324       }
325       /* free codebooks */
326       for(i=0;i<ci->books;i++)
327         if(b && b->fullbooks)vorbis_book_clear(b->fullbooks+i);
328     }
329
330     if(b){
331       if(b->mode)free(b->mode);    
332       if(b->fullbooks)free(b->fullbooks);
333       
334       /* free header, header1, header2 */
335       if(b->header)free(b->header);
336       if(b->header1)free(b->header1);
337       if(b->header2)free(b->header2);
338       free(b);
339     }
340     
341     memset(v,0,sizeof(vorbis_dsp_state));
342   }
343 }
344
345 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
346   int i;
347   vorbis_info *vi=v->vi;
348   backend_lookup_state *b=v->backend_state;
349
350   /* free header, header1, header2 */
351   if(b->header)free(b->header);b->header=NULL;
352   if(b->header1)free(b->header1);b->header1=NULL;
353   if(b->header2)free(b->header2);b->header2=NULL;
354
355   /* Do we have enough storage space for the requested buffer? If not,
356      expand the PCM (and envelope) storage */
357     
358   if(v->pcm_current+vals>=v->pcm_storage){
359     v->pcm_storage=v->pcm_current+vals*2;
360    
361     for(i=0;i<vi->channels;i++){
362       v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float));
363     }
364   }
365
366   for(i=0;i<vi->channels;i++)
367     v->pcmret[i]=v->pcm[i]+v->pcm_current;
368     
369   return(v->pcmret);
370 }
371
372 static void _preextrapolate_helper(vorbis_dsp_state *v){
373   int i;
374   int order=32;
375   float *lpc=alloca(order*sizeof(float));
376   float *work=alloca(v->pcm_current*sizeof(float));
377   long j;
378   v->preextrapolate=1;
379
380   if(v->pcm_current-v->centerW>order*2){ /* safety */
381     for(i=0;i<v->vi->channels;i++){
382       
383       /* need to run the extrapolation in reverse! */
384       for(j=0;j<v->pcm_current;j++)
385         work[j]=v->pcm[i][v->pcm_current-j-1];
386       
387       /* prime as above */
388       vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
389       
390       /* run the predictor filter */
391       vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
392                          order,
393                          work+v->pcm_current-v->centerW,
394                          v->centerW);
395       for(j=0;j<v->pcm_current;j++)
396         v->pcm[i][v->pcm_current-j-1]=work[j];
397     }
398   }
399 }
400
401
402 /* call with val<=0 to set eof */
403
404 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
405   vorbis_info *vi=v->vi;
406   codec_setup_info *ci=vi->codec_setup;
407
408   if(vals<=0){
409     int order=32;
410     int i;
411     float *lpc=alloca(order*sizeof(float));
412
413     /* if it wasn't done earlier (very short sample) */
414     if(!v->preextrapolate)
415       _preextrapolate_helper(v);
416
417     /* We're encoding the end of the stream.  Just make sure we have
418        [at least] a full block of zeroes at the end. */
419     /* actually, we don't want zeroes; that could drop a large
420        amplitude off a cliff, creating spread spectrum noise that will
421        suck to encode.  Extrapolate for the sake of cleanliness. */
422
423     vorbis_analysis_buffer(v,ci->blocksizes[1]*2);
424     v->eofflag=v->pcm_current;
425     v->pcm_current+=ci->blocksizes[1]*2;
426
427     for(i=0;i<vi->channels;i++){
428       if(v->eofflag>order*2){
429         /* extrapolate with LPC to fill in */
430         long n;
431
432         /* make a predictor filter */
433         n=v->eofflag;
434         if(n>ci->blocksizes[1])n=ci->blocksizes[1];
435         vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
436
437         /* run the predictor filter */
438         vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
439                            v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
440       }else{
441         /* not enough data to extrapolate (unlikely to happen due to
442            guarding the overlap, but bulletproof in case that
443            assumtion goes away). zeroes will do. */
444         memset(v->pcm[i]+v->eofflag,0,
445                (v->pcm_current-v->eofflag)*sizeof(float));
446
447       }
448     }
449   }else{
450
451     if(v->pcm_current+vals>v->pcm_storage)
452       return(OV_EINVAL);
453
454     v->pcm_current+=vals;
455
456     /* we may want to reverse extrapolate the beginning of a stream
457        too... in case we're beginning on a cliff! */
458     /* clumsy, but simple.  It only runs once, so simple is good. */
459     if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
460       _preextrapolate_helper(v);
461
462   }
463   return(0);
464 }
465
466 /* do the deltas, envelope shaping, pre-echo and determine the size of
467    the next block on which to continue analysis */
468 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
469   int i;
470   vorbis_info *vi=v->vi;
471   codec_setup_info *ci=vi->codec_setup;
472   backend_lookup_state *b=v->backend_state;
473   long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
474
475   /* check to see if we're started... */
476   if(!v->preextrapolate)return(0);
477
478   /* check to see if we're done... */
479   if(v->eofflag==-1)return(0);
480
481   /* By our invariant, we have lW, W and centerW set.  Search for
482      the next boundary so we can determine nW (the next window size)
483      which lets us compute the shape of the current block's window */
484   
485   if(ci->blocksizes[0]<ci->blocksizes[1]){
486     long largebound;
487     long bp;
488
489     if(v->W)
490       /* min boundary; nW large, next small */
491       largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]/4;
492     else
493       /* min boundary; nW large, next small */
494       largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]*3/4;
495
496     bp=_ve_envelope_search(v,largebound);
497     if(bp==-1)return(0); /* not enough data currently to search for a
498                             full long block */
499     v->nW=bp;
500
501   }else
502     v->nW=0;
503   
504   centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
505
506   {
507     /* center of next block + next block maximum right side. */
508
509     long blockbound=centerNext+ci->blocksizes[v->nW]/2;
510     if(v->pcm_current<blockbound)return(0); /* not enough data yet;
511                                                although this check is
512                                                less strict that the
513                                                _ve_envelope_search,
514                                                the search is not run
515                                                if we only use one
516                                                block size */
517   }
518   
519   /* fill in the block.  Note that for a short window, lW and nW are *short*
520      regardless of actual settings in the stream */
521
522   _vorbis_block_ripcord(vb);
523   if(v->W){
524     vb->lW=v->lW;
525     vb->W=v->W;
526     vb->nW=v->nW;
527   }else{
528     vb->lW=0;
529     vb->W=v->W;
530     vb->nW=0;
531   }
532   vb->vd=v;
533   vb->sequence=v->sequence;
534   vb->granulepos=v->granulepos;
535   vb->pcmend=ci->blocksizes[v->W];
536   
537   /* copy the vectors; this uses the local storage in vb */
538   {
539     vb->pcm=_vorbis_block_alloc(vb,sizeof(float *)*vi->channels);
540     for(i=0;i<vi->channels;i++){
541       vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(float));
542       memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(float));
543     }
544   }
545   
546   /* handle eof detection: eof==0 means that we've not yet received EOF
547                            eof>0  marks the last 'real' sample in pcm[]
548                            eof<0  'no more to do'; doesn't get here */
549
550   if(v->eofflag){
551     if(v->centerW>=v->eofflag){
552       v->eofflag=-1;
553       vb->eofflag=1;
554       return(1);
555     }
556   }
557
558   /* advance storage vectors and clean up */
559   {
560     int new_centerNext=ci->blocksizes[1]/2;
561     int movementW=centerNext-new_centerNext;
562
563     _ve_envelope_shift(b->ve,movementW);
564     v->pcm_current-=movementW;
565
566     for(i=0;i<vi->channels;i++)
567       memmove(v->pcm[i],v->pcm[i]+movementW,
568               v->pcm_current*sizeof(float));
569
570
571     v->lW=v->W;
572     v->W=v->nW;
573     v->centerW=new_centerNext;
574
575     v->sequence++;
576
577     if(v->eofflag){
578       v->eofflag-=movementW;
579       /* do not add padding to end of stream! */
580       if(v->centerW>=v->eofflag){
581         v->granulepos+=movementW-(v->centerW-v->eofflag);
582       }else{
583         v->granulepos+=movementW;
584       }
585     }else{
586       v->granulepos+=movementW;
587     }
588   }
589
590   /* done */
591   return(1);
592 }
593
594 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
595   codec_setup_info *ci=vi->codec_setup;
596   _vds_shared_init(v,vi,0);
597
598   /* Adjust centerW to allow an easier mechanism for determining output */
599   v->pcm_returned=v->centerW;
600   v->centerW-= ci->blocksizes[v->W]/4+ci->blocksizes[v->lW]/4;
601   v->granulepos=-1;
602   v->sequence=-1;
603
604   return(0);
605 }
606
607 /* Unlike in analysis, the window is only partially applied for each
608    block.  The time domain envelope is not yet handled at the point of
609    calling (as it relies on the previous block). */
610
611 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
612   vorbis_info *vi=v->vi;
613   codec_setup_info *ci=vi->codec_setup;
614
615   /* Shift out any PCM that we returned previously */
616   /* centerW is currently the center of the last block added */
617   if(v->pcm_returned  && v->centerW>ci->blocksizes[1]/2){
618
619     /* don't shift too much; we need to have a minimum PCM buffer of
620        1/2 long block */
621
622     int shiftPCM=v->centerW-ci->blocksizes[1]/2;
623     shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
624
625     v->pcm_current-=shiftPCM;
626     v->centerW-=shiftPCM;
627     v->pcm_returned-=shiftPCM;
628     
629     if(shiftPCM){
630       int i;
631       for(i=0;i<vi->channels;i++)
632         memmove(v->pcm[i],v->pcm[i]+shiftPCM,
633                 v->pcm_current*sizeof(float));
634     }
635   }
636
637   v->lW=v->W;
638   v->W=vb->W;
639   v->nW=-1;
640
641   v->glue_bits+=vb->glue_bits;
642   v->time_bits+=vb->time_bits;
643   v->floor_bits+=vb->floor_bits;
644   v->res_bits+=vb->res_bits;
645
646   if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence;
647                                                      lose count */
648
649   v->sequence=vb->sequence;
650
651   {
652     int sizeW=ci->blocksizes[v->W];
653     int centerW=v->centerW+ci->blocksizes[v->lW]/4+sizeW/4;
654     int beginW=centerW-sizeW/2;
655     int endW=beginW+sizeW;
656     int beginSl;
657     int endSl;
658     int i,j;
659
660     /* Do we have enough PCM/mult storage for the block? */
661     if(endW>v->pcm_storage){
662       /* expand the storage */
663       v->pcm_storage=endW+ci->blocksizes[1];
664    
665       for(i=0;i<vi->channels;i++)
666         v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float)); 
667     }
668
669     /* overlap/add PCM */
670
671     switch(v->W){
672     case 0:
673       beginSl=0;
674       endSl=ci->blocksizes[0]/2;
675       break;
676     case 1:
677       beginSl=ci->blocksizes[1]/4-ci->blocksizes[v->lW]/4;
678       endSl=beginSl+ci->blocksizes[v->lW]/2;
679       break;
680     }
681
682     for(j=0;j<vi->channels;j++){
683       float *pcm=v->pcm[j]+beginW;
684       float *p=vb->pcm[j];
685
686       /* the overlap/add section */
687       for(i=beginSl;i<endSl;i++)
688         pcm[i]+=p[i];
689       /* the remaining section */
690       for(;i<sizeW;i++)
691         pcm[i]=p[i];
692     }
693
694     /* track the frame number... This is for convenience, but also
695        making sure our last packet doesn't end with added padding.  If
696        the last packet is partial, the number of samples we'll have to
697        return will be past the vb->granulepos.
698        
699        This is not foolproof!  It will be confused if we begin
700        decoding at the last page after a seek or hole.  In that case,
701        we don't have a starting point to judge where the last frame
702        is.  For this reason, vorbisfile will always try to make sure
703        it reads the last two marked pages in proper sequence */
704
705     if(v->granulepos==-1)
706       if(vb->granulepos==-1){
707         v->granulepos=0;
708       }else{
709         v->granulepos=vb->granulepos;
710       }
711     else{
712       v->granulepos+=(centerW-v->centerW);
713       if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
714
715         if(v->granulepos>vb->granulepos){
716           long extra=v->granulepos-vb->granulepos;
717
718           if(vb->eofflag){
719             /* partial last frame.  Strip the extra samples off */
720             centerW-=extra;
721           }else if(vb->sequence == 1){
722             /* partial first frame.  Discard extra leading samples */
723             v->pcm_returned+=extra;
724             if(v->pcm_returned>centerW)v->pcm_returned=centerW;
725             
726           }
727           
728         }/* else{ Shouldn't happen *unless* the bitstream is out of
729             spec.  Either way, believe the bitstream } */
730         v->granulepos=vb->granulepos;
731       }
732     }
733
734     /* Update, cleanup */
735
736     v->centerW=centerW;
737     v->pcm_current=endW;
738
739     if(vb->eofflag)v->eofflag=1;
740   }
741
742   return(0);
743 }
744
745 /* pcm==NULL indicates we just want the pending samples, no more */
746 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
747   vorbis_info *vi=v->vi;
748   if(v->pcm_returned<v->centerW){
749     if(pcm){
750       int i;
751       for(i=0;i<vi->channels;i++)
752         v->pcmret[i]=v->pcm[i]+v->pcm_returned;
753       *pcm=v->pcmret;
754     }
755     return(v->centerW-v->pcm_returned);
756   }
757   return(0);
758 }
759
760 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
761   if(bytes && v->pcm_returned+bytes>v->centerW)return(OV_EINVAL);
762   v->pcm_returned+=bytes;
763   return(0);
764 }
765