• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ilog2(unsigned int v)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 
vorbis_block_init(vorbis_dsp_state * v,vorbis_block * vb)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 
_vorbis_block_alloc(vorbis_block * vb,long bytes)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 */
_vorbis_block_ripcord(vorbis_block * vb)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 
vorbis_block_clear(vorbis_block * vb)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 
_vds_shared_init(vorbis_dsp_state * v,vorbis_info * vi,int encp)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 */
vorbis_analysis_init(vorbis_dsp_state * v,vorbis_info * vi)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 
vorbis_dsp_clear(vorbis_dsp_state * v)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 
vorbis_analysis_buffer(vorbis_dsp_state * v,int vals)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 
_preextrapolate_helper(vorbis_dsp_state * v)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 
vorbis_analysis_wrote(vorbis_dsp_state * v,int vals)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 */
vorbis_analysis_blockout(vorbis_dsp_state * v,vorbis_block * vb)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 
vorbis_synthesis_restart(vorbis_dsp_state * v)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 
vorbis_synthesis_init(vorbis_dsp_state * v,vorbis_info * vi)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 
vorbis_synthesis_blockin(vorbis_dsp_state * v,vorbis_block * vb)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 */
vorbis_synthesis_pcmout(vorbis_dsp_state * v,float *** pcm)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 
vorbis_synthesis_read(vorbis_dsp_state * v,int n)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. */
vorbis_synthesis_lapout(vorbis_dsp_state * v,float *** pcm)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 
vorbis_window(vorbis_dsp_state * v,int W)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 }
1017