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