]> git.jsancho.org Git - lugaru.git/blob - libvorbis-1.0.1/lib/block.c
Cleaned up some things that don't compile on Mac OS X.
[lugaru.git] / libvorbis-1.0.1 / lib / block.c
1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003             *
9  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
10  *                                                                  *
11  ********************************************************************
12
13  function: PCM data vector blocking, windowing and dis/reassembly
14  last mod: $Id: block.c,v 1.75 2003/09/02 04:39:26 xiphmont Exp $
15
16  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
17  more amusing by Vorbis' current two allowed block sizes.
18  
19  ********************************************************************/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ogg/ogg.h>
25 #include "vorbis/codec.h"
26 #include "codec_internal.h"
27
28 #include "window.h"
29 #include "mdct.h"
30 #include "lpc.h"
31 #include "registry.h"
32 #include "misc.h"
33
34 static int ilog2(unsigned int v){
35   int ret=0;
36   if(v)--v;
37   while(v){
38     ret++;
39     v>>=1;
40   }
41   return(ret);
42 }
43
44 /* pcm accumulator examples (not exhaustive):
45
46  <-------------- lW ---------------->
47                    <--------------- W ---------------->
48 :            .....|.....       _______________         |
49 :        .'''     |     '''_---      |       |\        |
50 :.....'''         |_____--- '''......|       | \_______|
51 :.................|__________________|_______|__|______|
52                   |<------ Sl ------>|      > Sr <     |endW
53                   |beginSl           |endSl  |  |endSr   
54                   |beginW            |endlW  |beginSr
55
56
57                       |< lW >|       
58                    <--------------- W ---------------->
59                   |   |  ..  ______________            |
60                   |   | '  `/        |     ---_        |
61                   |___.'___/`.       |         ---_____| 
62                   |_______|__|_______|_________________|
63                   |      >|Sl|<      |<------ Sr ----->|endW
64                   |       |  |endSl  |beginSr          |endSr
65                   |beginW |  |endlW                     
66                   mult[0] |beginSl                     mult[n]
67
68  <-------------- lW ----------------->
69                           |<--W-->|                               
70 :            ..............  ___  |   |                    
71 :        .'''             |`/   \ |   |                       
72 :.....'''                 |/`....\|...|                    
73 :.........................|___|___|___|                  
74                           |Sl |Sr |endW    
75                           |   |   |endSr
76                           |   |beginSr
77                           |   |endSl
78                           |beginSl
79                           |beginW
80 */
81
82 /* block abstraction setup *********************************************/
83
84 #ifndef WORD_ALIGN
85 #define WORD_ALIGN 8
86 #endif
87
88 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
89   memset(vb,0,sizeof(*vb));
90   vb->vd=v;
91   vb->localalloc=0;
92   vb->localstore=NULL;
93   if(v->analysisp){
94     vorbis_block_internal *vbi=
95       vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
96     oggpack_writeinit(&vb->opb);
97     vbi->ampmax=-9999;
98   }
99   
100   return(0);
101 }
102
103 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
104   bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
105   if(bytes+vb->localtop>vb->localalloc){
106     /* can't just _ogg_realloc... there are outstanding pointers */
107     if(vb->localstore){
108       struct alloc_chain *link=_ogg_malloc(sizeof(*link));
109       vb->totaluse+=vb->localtop;
110       link->next=vb->reap;
111       link->ptr=vb->localstore;
112       vb->reap=link;
113     }
114     /* highly conservative */
115     vb->localalloc=bytes;
116     vb->localstore=_ogg_malloc(vb->localalloc);
117     vb->localtop=0;
118   }
119   {
120     void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
121     vb->localtop+=bytes;
122     return ret;
123   }
124 }
125
126 /* reap the chain, pull the ripcord */
127 void _vorbis_block_ripcord(vorbis_block *vb){
128   /* reap the chain */
129   struct alloc_chain *reap=vb->reap;
130   while(reap){
131     struct alloc_chain *next=reap->next;
132     _ogg_free(reap->ptr);
133     memset(reap,0,sizeof(*reap));
134     _ogg_free(reap);
135     reap=next;
136   }
137   /* consolidate storage */
138   if(vb->totaluse){
139     vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
140     vb->localalloc+=vb->totaluse;
141     vb->totaluse=0;
142   }
143
144   /* pull the ripcord */
145   vb->localtop=0;
146   vb->reap=NULL;
147 }
148
149 int vorbis_block_clear(vorbis_block *vb){
150   if(vb->vd)
151     if(vb->vd->analysisp)
152       oggpack_writeclear(&vb->opb);
153   _vorbis_block_ripcord(vb);
154   if(vb->localstore)_ogg_free(vb->localstore);
155
156   if(vb->internal)
157     _ogg_free(vb->internal);
158
159   memset(vb,0,sizeof(*vb));
160   return(0);
161 }
162
163 /* Analysis side code, but directly related to blocking.  Thus it's
164    here and not in analysis.c (which is for analysis transforms only).
165    The init is here because some of it is shared */
166
167 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
168   int i;
169   codec_setup_info *ci=vi->codec_setup;
170   private_state *b=NULL;
171   int hs;
172
173   if(ci==NULL) return 1;
174   hs=ci->halfrate_flag; 
175
176   memset(v,0,sizeof(*v));
177   b=v->backend_state=_ogg_calloc(1,sizeof(*b));
178
179   v->vi=vi;
180   b->modebits=ilog2(ci->modes);
181
182   b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
183   b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
184
185   /* MDCT is tranform 0 */
186
187   b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
188   b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
189   mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
190   mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
191
192   /* Vorbis I uses only window type 0 */
193   b->window[0]=ilog2(ci->blocksizes[0])-6;
194   b->window[1]=ilog2(ci->blocksizes[1])-6;
195
196   if(encp){ /* encode/decode differ here */
197
198     /* analysis always needs an fft */
199     drft_init(&b->fft_look[0],ci->blocksizes[0]);
200     drft_init(&b->fft_look[1],ci->blocksizes[1]);
201
202     /* finish the codebooks */
203     if(!ci->fullbooks){
204       ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
205       for(i=0;i<ci->books;i++)
206         vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
207     }
208
209     b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
210     for(i=0;i<ci->psys;i++){
211       _vp_psy_init(b->psy+i,
212                    ci->psy_param[i],
213                    &ci->psy_g_param,
214                    ci->blocksizes[ci->psy_param[i]->blockflag]/2,
215                    vi->rate);
216     }
217
218     v->analysisp=1;
219   }else{
220     /* finish the codebooks */
221     if(!ci->fullbooks){
222       ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
223       for(i=0;i<ci->books;i++){
224         vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
225         /* decode codebooks are now standalone after init */
226         vorbis_staticbook_destroy(ci->book_param[i]);
227         ci->book_param[i]=NULL;
228       }
229     }
230   }
231
232   /* initialize the storage vectors. blocksize[1] is small for encode,
233      but the correct size for decode */
234   v->pcm_storage=ci->blocksizes[1];
235   v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
236   v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
237   {
238     int i;
239     for(i=0;i<vi->channels;i++)
240       v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
241   }
242
243   /* all 1 (large block) or 0 (small block) */
244   /* explicitly set for the sake of clarity */
245   v->lW=0; /* previous window size */
246   v->W=0;  /* current window size */
247
248   /* all vector indexes */
249   v->centerW=ci->blocksizes[1]/2;
250
251   v->pcm_current=v->centerW;
252
253   /* initialize all the backend lookups */
254   b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
255   b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
256
257   for(i=0;i<ci->floors;i++)
258     b->flr[i]=_floor_P[ci->floor_type[i]]->
259       look(v,ci->floor_param[i]);
260
261   for(i=0;i<ci->residues;i++)
262     b->residue[i]=_residue_P[ci->residue_type[i]]->
263       look(v,ci->residue_param[i]);    
264
265   return 0;
266 }
267
268 /* arbitrary settings and spec-mandated numbers get filled in here */
269 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
270   private_state *b=NULL;
271
272   if(_vds_shared_init(v,vi,1))return 1;
273   b=v->backend_state;
274   b->psy_g_look=_vp_global_look(vi);
275
276   /* Initialize the envelope state storage */
277   b->ve=_ogg_calloc(1,sizeof(*b->ve));
278   _ve_envelope_init(b->ve,vi);
279
280   vorbis_bitrate_init(vi,&b->bms);
281
282   return(0);
283 }
284
285 void vorbis_dsp_clear(vorbis_dsp_state *v){
286   int i;
287   if(v){
288     vorbis_info *vi=v->vi;
289     codec_setup_info *ci=(vi?vi->codec_setup:NULL);
290     private_state *b=v->backend_state;
291
292     if(b){
293         
294       if(b->ve){
295         _ve_envelope_clear(b->ve);
296         _ogg_free(b->ve);
297       }
298
299       if(b->transform[0]){
300         mdct_clear(b->transform[0][0]);
301         _ogg_free(b->transform[0][0]);
302         _ogg_free(b->transform[0]);
303       }
304       if(b->transform[1]){
305         mdct_clear(b->transform[1][0]);
306         _ogg_free(b->transform[1][0]);
307         _ogg_free(b->transform[1]);
308       }
309
310       if(b->flr){
311         for(i=0;i<ci->floors;i++)
312           _floor_P[ci->floor_type[i]]->
313             free_look(b->flr[i]);
314         _ogg_free(b->flr);
315       }
316       if(b->residue){
317         for(i=0;i<ci->residues;i++)
318           _residue_P[ci->residue_type[i]]->
319             free_look(b->residue[i]);
320         _ogg_free(b->residue);
321       }
322       if(b->psy){
323         for(i=0;i<ci->psys;i++)
324           _vp_psy_clear(b->psy+i);
325         _ogg_free(b->psy);
326       }
327
328       if(b->psy_g_look)_vp_global_free(b->psy_g_look);
329       vorbis_bitrate_clear(&b->bms);
330
331       drft_clear(&b->fft_look[0]);
332       drft_clear(&b->fft_look[1]);
333
334     }
335     
336     if(v->pcm){
337       for(i=0;i<vi->channels;i++)
338         if(v->pcm[i])_ogg_free(v->pcm[i]);
339       _ogg_free(v->pcm);
340       if(v->pcmret)_ogg_free(v->pcmret);
341     }
342
343     if(b){
344       /* free header, header1, header2 */
345       if(b->header)_ogg_free(b->header);
346       if(b->header1)_ogg_free(b->header1);
347       if(b->header2)_ogg_free(b->header2);
348       _ogg_free(b);
349     }
350     
351     memset(v,0,sizeof(*v));
352   }
353 }
354
355 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
356   int i;
357   vorbis_info *vi=v->vi;
358   private_state *b=v->backend_state;
359
360   /* free header, header1, header2 */
361   if(b->header)_ogg_free(b->header);b->header=NULL;
362   if(b->header1)_ogg_free(b->header1);b->header1=NULL;
363   if(b->header2)_ogg_free(b->header2);b->header2=NULL;
364
365   /* Do we have enough storage space for the requested buffer? If not,
366      expand the PCM (and envelope) storage */
367     
368   if(v->pcm_current+vals>=v->pcm_storage){
369     v->pcm_storage=v->pcm_current+vals*2;
370    
371     for(i=0;i<vi->channels;i++){
372       v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
373     }
374   }
375
376   for(i=0;i<vi->channels;i++)
377     v->pcmret[i]=v->pcm[i]+v->pcm_current;
378     
379   return(v->pcmret);
380 }
381
382 static void _preextrapolate_helper(vorbis_dsp_state *v){
383   int i;
384   int order=32;
385   float *lpc=alloca(order*sizeof(*lpc));
386   float *work=alloca(v->pcm_current*sizeof(*work));
387   long j;
388   v->preextrapolate=1;
389
390   if(v->pcm_current-v->centerW>order*2){ /* safety */
391     for(i=0;i<v->vi->channels;i++){
392       /* need to run the extrapolation in reverse! */
393       for(j=0;j<v->pcm_current;j++)
394         work[j]=v->pcm[i][v->pcm_current-j-1];
395       
396       /* prime as above */
397       vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
398       
399       /* run the predictor filter */
400       vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
401                          order,
402                          work+v->pcm_current-v->centerW,
403                          v->centerW);
404
405       for(j=0;j<v->pcm_current;j++)
406         v->pcm[i][v->pcm_current-j-1]=work[j];
407
408     }
409   }
410 }
411
412
413 /* call with val<=0 to set eof */
414
415 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
416   vorbis_info *vi=v->vi;
417   codec_setup_info *ci=vi->codec_setup;
418
419   if(vals<=0){
420     int order=32;
421     int i;
422     float *lpc=alloca(order*sizeof(*lpc));
423
424     /* if it wasn't done earlier (very short sample) */
425     if(!v->preextrapolate)
426       _preextrapolate_helper(v);
427
428     /* We're encoding the end of the stream.  Just make sure we have
429        [at least] a few full blocks of zeroes at the end. */
430     /* actually, we don't want zeroes; that could drop a large
431        amplitude off a cliff, creating spread spectrum noise that will
432        suck to encode.  Extrapolate for the sake of cleanliness. */
433
434     vorbis_analysis_buffer(v,ci->blocksizes[1]*3); 
435     v->eofflag=v->pcm_current;
436     v->pcm_current+=ci->blocksizes[1]*3;
437
438     for(i=0;i<vi->channels;i++){
439       if(v->eofflag>order*2){
440         /* extrapolate with LPC to fill in */
441         long n;
442
443         /* make a predictor filter */
444         n=v->eofflag;
445         if(n>ci->blocksizes[1])n=ci->blocksizes[1];
446         vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
447
448         /* run the predictor filter */
449         vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
450                            v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
451       }else{
452         /* not enough data to extrapolate (unlikely to happen due to
453            guarding the overlap, but bulletproof in case that
454            assumtion goes away). zeroes will do. */
455         memset(v->pcm[i]+v->eofflag,0,
456                (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
457
458       }
459     }
460   }else{
461
462     if(v->pcm_current+vals>v->pcm_storage)
463       return(OV_EINVAL);
464
465     v->pcm_current+=vals;
466
467     /* we may want to reverse extrapolate the beginning of a stream
468        too... in case we're beginning on a cliff! */
469     /* clumsy, but simple.  It only runs once, so simple is good. */
470     if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
471       _preextrapolate_helper(v);
472
473   }
474   return(0);
475 }
476
477 /* do the deltas, envelope shaping, pre-echo and determine the size of
478    the next block on which to continue analysis */
479 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
480   int i;
481   vorbis_info *vi=v->vi;
482   codec_setup_info *ci=vi->codec_setup;
483   private_state *b=v->backend_state;
484   vorbis_look_psy_global *g=b->psy_g_look;
485   long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
486   vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
487
488   /* check to see if we're started... */
489   if(!v->preextrapolate)return(0);
490
491   /* check to see if we're done... */
492   if(v->eofflag==-1)return(0);
493
494   /* By our invariant, we have lW, W and centerW set.  Search for
495      the next boundary so we can determine nW (the next window size)
496      which lets us compute the shape of the current block's window */
497
498   /* we do an envelope search even on a single blocksize; we may still
499      be throwing more bits at impulses, and envelope search handles
500      marking impulses too. */
501   {  
502     long bp=_ve_envelope_search(v);
503     if(bp==-1){
504
505       if(v->eofflag==0)return(0); /* not enough data currently to search for a
506                                      full long block */
507       v->nW=0;
508     }else{
509
510       if(ci->blocksizes[0]==ci->blocksizes[1])
511         v->nW=0;
512       else
513         v->nW=bp;
514     }
515   }
516
517   centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
518
519   {
520     /* center of next block + next block maximum right side. */
521
522     long blockbound=centerNext+ci->blocksizes[v->nW]/2;
523     if(v->pcm_current<blockbound)return(0); /* not enough data yet;
524                                                although this check is
525                                                less strict that the
526                                                _ve_envelope_search,
527                                                the search is not run
528                                                if we only use one
529                                                block size */
530
531
532   }
533   
534   /* fill in the block.  Note that for a short window, lW and nW are *short*
535      regardless of actual settings in the stream */
536
537   _vorbis_block_ripcord(vb);
538   vb->lW=v->lW;
539   vb->W=v->W;
540   vb->nW=v->nW;
541
542   if(v->W){
543     if(!v->lW || !v->nW){
544       vbi->blocktype=BLOCKTYPE_TRANSITION;
545       /*fprintf(stderr,"-");*/
546     }else{
547       vbi->blocktype=BLOCKTYPE_LONG;
548       /*fprintf(stderr,"_");*/
549     }
550   }else{
551     if(_ve_envelope_mark(v)){
552       vbi->blocktype=BLOCKTYPE_IMPULSE;
553       /*fprintf(stderr,"|");*/
554
555     }else{
556       vbi->blocktype=BLOCKTYPE_PADDING;
557       /*fprintf(stderr,".");*/
558
559     }
560   }
561  
562   vb->vd=v;
563   vb->sequence=v->sequence++;
564   vb->granulepos=v->granulepos;
565   vb->pcmend=ci->blocksizes[v->W];
566   
567   /* copy the vectors; this uses the local storage in vb */
568
569   /* this tracks 'strongest peak' for later psychoacoustics */
570   /* moved to the global psy state; clean this mess up */
571   if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
572   g->ampmax=_vp_ampmax_decay(g->ampmax,v);
573   vbi->ampmax=g->ampmax;
574   
575   vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
576   vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
577   for(i=0;i<vi->channels;i++){
578     vbi->pcmdelay[i]=
579       _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
580     memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
581     vb->pcm[i]=vbi->pcmdelay[i]+beginW;
582     
583     /* before we added the delay 
584        vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
585        memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
586     */
587     
588   }
589   
590   /* handle eof detection: eof==0 means that we've not yet received EOF
591                            eof>0  marks the last 'real' sample in pcm[]
592                            eof<0  'no more to do'; doesn't get here */
593
594   if(v->eofflag){
595     if(v->centerW>=v->eofflag){
596       v->eofflag=-1;
597       vb->eofflag=1;
598       return(1);
599     }
600   }
601
602   /* advance storage vectors and clean up */
603   {
604     int new_centerNext=ci->blocksizes[1]/2;
605     int movementW=centerNext-new_centerNext;
606
607     if(movementW>0){
608
609       _ve_envelope_shift(b->ve,movementW);
610       v->pcm_current-=movementW;
611       
612       for(i=0;i<vi->channels;i++)
613         memmove(v->pcm[i],v->pcm[i]+movementW,
614                 v->pcm_current*sizeof(*v->pcm[i]));
615       
616       
617       v->lW=v->W;
618       v->W=v->nW;
619       v->centerW=new_centerNext;
620       
621       if(v->eofflag){
622         v->eofflag-=movementW;
623         if(v->eofflag<=0)v->eofflag=-1;
624         /* do not add padding to end of stream! */
625         if(v->centerW>=v->eofflag){
626           v->granulepos+=movementW-(v->centerW-v->eofflag);
627         }else{
628           v->granulepos+=movementW;
629         }
630       }else{
631         v->granulepos+=movementW;
632       }
633     }
634   }
635
636   /* done */
637   return(1);
638 }
639
640 int vorbis_synthesis_restart(vorbis_dsp_state *v){
641   vorbis_info *vi=v->vi;
642   codec_setup_info *ci;
643   int hs;
644
645   if(!v->backend_state)return -1;
646   if(!vi)return -1;
647   ci=vi->codec_setup;
648   if(!ci)return -1;
649   hs=ci->halfrate_flag; 
650
651   v->centerW=ci->blocksizes[1]>>(hs+1);
652   v->pcm_current=v->centerW>>hs;
653   
654   v->pcm_returned=-1;
655   v->granulepos=-1;
656   v->sequence=-1;
657   v->eofflag=0;
658   ((private_state *)(v->backend_state))->sample_count=-1;
659
660   return(0);
661 }
662
663 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
664   if(_vds_shared_init(v,vi,0)) return 1;
665   vorbis_synthesis_restart(v);
666
667   return 0;
668 }
669
670 /* Unlike in analysis, the window is only partially applied for each
671    block.  The time domain envelope is not yet handled at the point of
672    calling (as it relies on the previous block). */
673
674 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
675   vorbis_info *vi=v->vi;
676   codec_setup_info *ci=vi->codec_setup;
677   private_state *b=v->backend_state;
678   int hs=ci->halfrate_flag; 
679   int i,j;
680
681   if(!vb)return(OV_EINVAL);
682   if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
683     
684   v->lW=v->W;
685   v->W=vb->W;
686   v->nW=-1;
687   
688   if((v->sequence==-1)||
689      (v->sequence+1 != vb->sequence)){
690     v->granulepos=-1; /* out of sequence; lose count */
691     b->sample_count=-1;
692   }
693
694   v->sequence=vb->sequence;
695   
696   if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly 
697                    was called on block */
698     int n=ci->blocksizes[v->W]>>(hs+1);
699     int n0=ci->blocksizes[0]>>(hs+1);
700     int n1=ci->blocksizes[1]>>(hs+1);
701
702     int thisCenter;
703     int prevCenter;
704     
705     v->glue_bits+=vb->glue_bits;
706     v->time_bits+=vb->time_bits;
707     v->floor_bits+=vb->floor_bits;
708     v->res_bits+=vb->res_bits;
709     
710     if(v->centerW){
711       thisCenter=n1;
712       prevCenter=0;
713     }else{
714       thisCenter=0;
715       prevCenter=n1;
716     }
717     
718     /* v->pcm is now used like a two-stage double buffer.  We don't want
719        to have to constantly shift *or* adjust memory usage.  Don't
720        accept a new block until the old is shifted out */
721     
722     for(j=0;j<vi->channels;j++){
723       /* the overlap/add section */
724       if(v->lW){
725         if(v->W){
726           /* large/large */
727           float *w=_vorbis_window_get(b->window[1]-hs);
728           float *pcm=v->pcm[j]+prevCenter;
729           float *p=vb->pcm[j];
730           for(i=0;i<n1;i++)
731             pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
732         }else{
733           /* large/small */
734           float *w=_vorbis_window_get(b->window[0]-hs);
735           float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
736           float *p=vb->pcm[j];
737           for(i=0;i<n0;i++)
738             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
739         }
740       }else{
741         if(v->W){
742           /* small/large */
743           float *w=_vorbis_window_get(b->window[0]-hs);
744           float *pcm=v->pcm[j]+prevCenter;
745           float *p=vb->pcm[j]+n1/2-n0/2;
746           for(i=0;i<n0;i++)
747             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
748           for(;i<n1/2+n0/2;i++)
749             pcm[i]=p[i];
750         }else{
751           /* small/small */
752           float *w=_vorbis_window_get(b->window[0]-hs);
753           float *pcm=v->pcm[j]+prevCenter;
754           float *p=vb->pcm[j];
755           for(i=0;i<n0;i++)
756             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
757         }
758       }
759       
760       /* the copy section */
761       {
762         float *pcm=v->pcm[j]+thisCenter;
763         float *p=vb->pcm[j]+n;
764         for(i=0;i<n;i++)
765           pcm[i]=p[i];
766       }
767     }
768     
769     if(v->centerW)
770       v->centerW=0;
771     else
772       v->centerW=n1;
773     
774     /* deal with initial packet state; we do this using the explicit
775        pcm_returned==-1 flag otherwise we're sensitive to first block
776        being short or long */
777     
778     if(v->pcm_returned==-1){
779       v->pcm_returned=thisCenter;
780       v->pcm_current=thisCenter;
781     }else{
782       v->pcm_returned=prevCenter;
783       v->pcm_current=prevCenter+
784         ((ci->blocksizes[v->lW]/4+
785         ci->blocksizes[v->W]/4)>>hs);
786     }
787     
788   }
789
790   /* track the frame number... This is for convenience, but also
791      making sure our last packet doesn't end with added padding.  If
792      the last packet is partial, the number of samples we'll have to
793      return will be past the vb->granulepos.
794      
795      This is not foolproof!  It will be confused if we begin
796      decoding at the last page after a seek or hole.  In that case,
797      we don't have a starting point to judge where the last frame
798      is.  For this reason, vorbisfile will always try to make sure
799      it reads the last two marked pages in proper sequence */
800
801   if(b->sample_count==-1){
802     b->sample_count=0;
803   }else{
804     b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
805   }
806   
807   if(v->granulepos==-1){
808     if(vb->granulepos!=-1){ /* only set if we have a position to set to */
809
810       v->granulepos=vb->granulepos;
811
812       /* is this a short page? */
813       if(b->sample_count>v->granulepos){
814         /* corner case; if this is both the first and last audio page,
815            then spec says the end is cut, not beginning */
816         if(vb->eofflag){
817           /* trim the end */
818           /* no preceeding granulepos; assume we started at zero (we'd
819              have to in a short single-page stream) */
820           /* granulepos could be -1 due to a seek, but that would result
821              in a long count, not short count */
822           
823           v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
824         }else{
825           /* trim the beginning */
826           v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
827           if(v->pcm_returned>v->pcm_current)
828             v->pcm_returned=v->pcm_current;
829         }
830
831       }
832
833     }
834   }else{
835     v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
836     if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
837       
838       if(v->granulepos>vb->granulepos){
839         long extra=v->granulepos-vb->granulepos;
840
841         if(extra)
842           if(vb->eofflag){
843             /* partial last frame.  Strip the extra samples off */
844             v->pcm_current-=extra>>hs;
845           } /* else {Shouldn't happen *unless* the bitstream is out of
846                spec.  Either way, believe the bitstream } */
847       } /* else {Shouldn't happen *unless* the bitstream is out of
848            spec.  Either way, believe the bitstream } */
849       v->granulepos=vb->granulepos;
850     }
851   }
852   
853   /* Update, cleanup */
854   
855   if(vb->eofflag)v->eofflag=1;
856   return(0);
857   
858 }
859
860 /* pcm==NULL indicates we just want the pending samples, no more */
861 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
862   vorbis_info *vi=v->vi;
863
864   if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
865     if(pcm){
866       int i;
867       for(i=0;i<vi->channels;i++)
868         v->pcmret[i]=v->pcm[i]+v->pcm_returned;
869       *pcm=v->pcmret;
870     }
871     return(v->pcm_current-v->pcm_returned);
872   }
873   return(0);
874 }
875
876 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
877   if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
878   v->pcm_returned+=n;
879   return(0);
880 }
881
882 /* intended for use with a specific vorbisfile feature; we want access
883    to the [usually synthetic/postextrapolated] buffer and lapping at
884    the end of a decode cycle, specifically, a half-short-block worth.
885    This funtion works like pcmout above, except it will also expose
886    this implicit buffer data not normally decoded. */
887 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
888   vorbis_info *vi=v->vi;
889   codec_setup_info *ci=vi->codec_setup;
890   int hs=ci->halfrate_flag; 
891   
892   int n=ci->blocksizes[v->W]>>(hs+1);
893   int n0=ci->blocksizes[0]>>(hs+1);
894   int n1=ci->blocksizes[1]>>(hs+1);
895   int i,j;
896
897   if(v->pcm_returned<0)return 0;
898
899   /* our returned data ends at pcm_returned; because the synthesis pcm
900      buffer is a two-fragment ring, that means our data block may be
901      fragmented by buffering, wrapping or a short block not filling
902      out a buffer.  To simplify things, we unfragment if it's at all
903      possibly needed. Otherwise, we'd need to call lapout more than
904      once as well as hold additional dsp state.  Opt for
905      simplicity. */
906
907   /* centerW was advanced by blockin; it would be the center of the
908      *next* block */
909   if(v->centerW==n1){
910     /* the data buffer wraps; swap the halves */
911     /* slow, sure, small */
912     for(j=0;j<vi->channels;j++){
913       float *p=v->pcm[j];
914       for(i=0;i<n1;i++){
915         float temp=p[i];
916         p[i]=p[i+n1];
917         p[i+n1]=temp;
918       }
919     }
920
921     v->pcm_current-=n1;
922     v->pcm_returned-=n1;
923     v->centerW=0;
924   }
925   
926   /* solidify buffer into contiguous space */
927   if((v->lW^v->W)==1){
928     /* long/short or short/long */
929     for(j=0;j<vi->channels;j++){
930       float *s=v->pcm[j];
931       float *d=v->pcm[j]+(n1-n0)/2;
932       for(i=(n1+n0)/2-1;i>=0;--i)
933         d[i]=s[i];
934     }
935     v->pcm_returned+=(n1-n0)/2;
936     v->pcm_current+=(n1-n0)/2;
937   }else{
938     if(v->lW==0){
939       /* short/short */
940       for(j=0;j<vi->channels;j++){
941         float *s=v->pcm[j];
942         float *d=v->pcm[j]+n1-n0;
943         for(i=n0-1;i>=0;--i)
944           d[i]=s[i];
945       }
946       v->pcm_returned+=n1-n0;
947       v->pcm_current+=n1-n0;
948     }
949   }
950     
951   if(pcm){
952     int i;
953     for(i=0;i<vi->channels;i++)
954       v->pcmret[i]=v->pcm[i]+v->pcm_returned;
955     *pcm=v->pcmret;
956   }
957
958   return(n1+n-v->pcm_returned);
959
960 }
961
962 float *vorbis_window(vorbis_dsp_state *v,int W){
963   vorbis_info *vi=v->vi;
964   codec_setup_info *ci=vi->codec_setup;
965   int hs=ci->halfrate_flag; 
966   private_state *b=v->backend_state;
967
968   if(b->window[W]-1<0)return NULL;
969   return _vorbis_window_get(b->window[W]-hs);
970 }
971