Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / libvorbis / lib / block.c
blob753311890b6e767e172f5b31e8c87b98a66a0630
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 ********************************************************************
13 function: PCM data vector blocking, windowing and dis/reassembly
14 last mod: $Id: block.c 16227 2009-07-08 06:58:46Z xiphmont $
16 Handle windowing, overlap-add, etc of the PCM vectors. This is made
17 more amusing by Vorbis' current two allowed block sizes.
19 ********************************************************************/
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"
28 #include "window.h"
29 #include "mdct.h"
30 #include "lpc.h"
31 #include "registry.h"
32 #include "misc.h"
34 static int ilog2(unsigned int v){
35 int ret=0;
36 if(v)--v;
37 while(v){
38 ret++;
39 v>>=1;
41 return(ret);
44 /* pcm accumulator examples (not exhaustive):
46 <-------------- lW ---------------->
47 <--------------- W ---------------->
48 : .....|..... _______________ |
49 : .''' | '''_--- | |\ |
50 :.....''' |_____--- '''......| | \_______|
51 :.................|__________________|_______|__|______|
52 |<------ Sl ------>| > Sr < |endW
53 |beginSl |endSl | |endSr
54 |beginW |endlW |beginSr
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]
68 <-------------- lW ----------------->
69 |<--W-->|
70 : .............. ___ | |
71 : .''' |`/ \ | |
72 :.....''' |/`....\|...|
73 :.........................|___|___|___|
74 |Sl |Sr |endW
75 | | |endSr
76 | |beginSr
77 | |endSl
78 |beginSl
79 |beginW
82 /* block abstraction setup *********************************************/
84 #ifndef WORD_ALIGN
85 #define WORD_ALIGN 8
86 #endif
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;
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));
106 oggpack_writeinit(vbi->packetblob[i]);
110 return(0);
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;
124 /* highly conservative */
125 vb->localalloc=bytes;
126 vb->localstore=_ogg_malloc(vb->localalloc);
127 vb->localtop=0;
130 void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
131 vb->localtop+=bytes;
132 return ret;
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;
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;
154 /* pull the ripcord */
155 vb->localtop=0;
156 vb->reap=NULL;
159 int vorbis_block_clear(vorbis_block *vb){
160 int i;
161 vorbis_block_internal *vbi=vb->internal;
163 _vorbis_block_ripcord(vb);
164 if(vb->localstore)_ogg_free(vb->localstore);
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]);
171 _ogg_free(vbi);
173 memset(vb,0,sizeof(*vb));
174 return(0);
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 */
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;
187 if(ci==NULL) return 1;
188 hs=ci->halfrate_flag;
190 memset(v,0,sizeof(*v));
191 b=v->backend_state=_ogg_calloc(1,sizeof(*b));
193 v->vi=vi;
194 b->modebits=ilog2(ci->modes);
196 b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
197 b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
199 /* MDCT is tranform 0 */
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);
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;
210 if(encp){ /* encode/decode differ here */
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]);
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]);
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);
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(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
239 return -1;
240 /* decode codebooks are now standalone after init */
241 vorbis_staticbook_destroy(ci->book_param[i]);
242 ci->book_param[i]=NULL;
247 /* initialize the storage vectors. blocksize[1] is small for encode,
248 but the correct size for decode */
249 v->pcm_storage=ci->blocksizes[1];
250 v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
251 v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
253 int i;
254 for(i=0;i<vi->channels;i++)
255 v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
258 /* all 1 (large block) or 0 (small block) */
259 /* explicitly set for the sake of clarity */
260 v->lW=0; /* previous window size */
261 v->W=0; /* current window size */
263 /* all vector indexes */
264 v->centerW=ci->blocksizes[1]/2;
266 v->pcm_current=v->centerW;
268 /* initialize all the backend lookups */
269 b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
270 b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
272 for(i=0;i<ci->floors;i++)
273 b->flr[i]=_floor_P[ci->floor_type[i]]->
274 look(v,ci->floor_param[i]);
276 for(i=0;i<ci->residues;i++)
277 b->residue[i]=_residue_P[ci->residue_type[i]]->
278 look(v,ci->residue_param[i]);
280 return 0;
283 /* arbitrary settings and spec-mandated numbers get filled in here */
284 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
285 private_state *b=NULL;
287 if(_vds_shared_init(v,vi,1))return 1;
288 b=v->backend_state;
289 b->psy_g_look=_vp_global_look(vi);
291 /* Initialize the envelope state storage */
292 b->ve=_ogg_calloc(1,sizeof(*b->ve));
293 _ve_envelope_init(b->ve,vi);
295 vorbis_bitrate_init(vi,&b->bms);
297 /* compressed audio packets start after the headers
298 with sequence number 3 */
299 v->sequence=3;
301 return(0);
304 void vorbis_dsp_clear(vorbis_dsp_state *v){
305 int i;
306 if(v){
307 vorbis_info *vi=v->vi;
308 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
309 private_state *b=v->backend_state;
311 if(b){
313 if(b->ve){
314 _ve_envelope_clear(b->ve);
315 _ogg_free(b->ve);
318 if(b->transform[0]){
319 mdct_clear(b->transform[0][0]);
320 _ogg_free(b->transform[0][0]);
321 _ogg_free(b->transform[0]);
323 if(b->transform[1]){
324 mdct_clear(b->transform[1][0]);
325 _ogg_free(b->transform[1][0]);
326 _ogg_free(b->transform[1]);
329 if(b->flr){
330 if(ci)
331 for(i=0;i<ci->floors;i++)
332 _floor_P[ci->floor_type[i]]->
333 free_look(b->flr[i]);
334 _ogg_free(b->flr);
336 if(b->residue){
337 if(ci)
338 for(i=0;i<ci->residues;i++)
339 _residue_P[ci->residue_type[i]]->
340 free_look(b->residue[i]);
341 _ogg_free(b->residue);
343 if(b->psy){
344 if(ci)
345 for(i=0;i<ci->psys;i++)
346 _vp_psy_clear(b->psy+i);
347 _ogg_free(b->psy);
350 if(b->psy_g_look)_vp_global_free(b->psy_g_look);
351 vorbis_bitrate_clear(&b->bms);
353 drft_clear(&b->fft_look[0]);
354 drft_clear(&b->fft_look[1]);
358 if(v->pcm){
359 if(vi)
360 for(i=0;i<vi->channels;i++)
361 if(v->pcm[i])_ogg_free(v->pcm[i]);
362 _ogg_free(v->pcm);
363 if(v->pcmret)_ogg_free(v->pcmret);
366 if(b){
367 /* free header, header1, header2 */
368 if(b->header)_ogg_free(b->header);
369 if(b->header1)_ogg_free(b->header1);
370 if(b->header2)_ogg_free(b->header2);
371 _ogg_free(b);
374 memset(v,0,sizeof(*v));
378 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
379 int i;
380 vorbis_info *vi=v->vi;
381 private_state *b=v->backend_state;
383 /* free header, header1, header2 */
384 if(b->header)_ogg_free(b->header);b->header=NULL;
385 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
386 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
388 /* Do we have enough storage space for the requested buffer? If not,
389 expand the PCM (and envelope) storage */
391 if(v->pcm_current+vals>=v->pcm_storage){
392 v->pcm_storage=v->pcm_current+vals*2;
394 for(i=0;i<vi->channels;i++){
395 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
399 for(i=0;i<vi->channels;i++)
400 v->pcmret[i]=v->pcm[i]+v->pcm_current;
402 return(v->pcmret);
405 static void _preextrapolate_helper(vorbis_dsp_state *v){
406 int i;
407 int order=16;
408 float *lpc=alloca(order*sizeof(*lpc));
409 float *work=alloca(v->pcm_current*sizeof(*work));
410 long j;
411 v->preextrapolate=1;
413 if(v->pcm_current-v->centerW>order*2){ /* safety */
414 for(i=0;i<v->vi->channels;i++){
415 /* need to run the extrapolation in reverse! */
416 for(j=0;j<v->pcm_current;j++)
417 work[j]=v->pcm[i][v->pcm_current-j-1];
419 /* prime as above */
420 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
422 #if 0
423 if(v->vi->channels==2){
424 if(i==0)
425 _analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
426 else
427 _analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
428 }else{
429 _analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
431 #endif
433 /* run the predictor filter */
434 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
435 order,
436 work+v->pcm_current-v->centerW,
437 v->centerW);
439 for(j=0;j<v->pcm_current;j++)
440 v->pcm[i][v->pcm_current-j-1]=work[j];
447 /* call with val<=0 to set eof */
449 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
450 vorbis_info *vi=v->vi;
451 codec_setup_info *ci=vi->codec_setup;
453 if(vals<=0){
454 int order=32;
455 int i;
456 float *lpc=alloca(order*sizeof(*lpc));
458 /* if it wasn't done earlier (very short sample) */
459 if(!v->preextrapolate)
460 _preextrapolate_helper(v);
462 /* We're encoding the end of the stream. Just make sure we have
463 [at least] a few full blocks of zeroes at the end. */
464 /* actually, we don't want zeroes; that could drop a large
465 amplitude off a cliff, creating spread spectrum noise that will
466 suck to encode. Extrapolate for the sake of cleanliness. */
468 vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
469 v->eofflag=v->pcm_current;
470 v->pcm_current+=ci->blocksizes[1]*3;
472 for(i=0;i<vi->channels;i++){
473 if(v->eofflag>order*2){
474 /* extrapolate with LPC to fill in */
475 long n;
477 /* make a predictor filter */
478 n=v->eofflag;
479 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
480 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
482 /* run the predictor filter */
483 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
484 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
485 }else{
486 /* not enough data to extrapolate (unlikely to happen due to
487 guarding the overlap, but bulletproof in case that
488 assumtion goes away). zeroes will do. */
489 memset(v->pcm[i]+v->eofflag,0,
490 (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
494 }else{
496 if(v->pcm_current+vals>v->pcm_storage)
497 return(OV_EINVAL);
499 v->pcm_current+=vals;
501 /* we may want to reverse extrapolate the beginning of a stream
502 too... in case we're beginning on a cliff! */
503 /* clumsy, but simple. It only runs once, so simple is good. */
504 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
505 _preextrapolate_helper(v);
508 return(0);
511 /* do the deltas, envelope shaping, pre-echo and determine the size of
512 the next block on which to continue analysis */
513 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
514 int i;
515 vorbis_info *vi=v->vi;
516 codec_setup_info *ci=vi->codec_setup;
517 private_state *b=v->backend_state;
518 vorbis_look_psy_global *g=b->psy_g_look;
519 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
520 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
522 /* check to see if we're started... */
523 if(!v->preextrapolate)return(0);
525 /* check to see if we're done... */
526 if(v->eofflag==-1)return(0);
528 /* By our invariant, we have lW, W and centerW set. Search for
529 the next boundary so we can determine nW (the next window size)
530 which lets us compute the shape of the current block's window */
532 /* we do an envelope search even on a single blocksize; we may still
533 be throwing more bits at impulses, and envelope search handles
534 marking impulses too. */
536 long bp=_ve_envelope_search(v);
537 if(bp==-1){
539 if(v->eofflag==0)return(0); /* not enough data currently to search for a
540 full long block */
541 v->nW=0;
542 }else{
544 if(ci->blocksizes[0]==ci->blocksizes[1])
545 v->nW=0;
546 else
547 v->nW=bp;
551 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
554 /* center of next block + next block maximum right side. */
556 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
557 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
558 although this check is
559 less strict that the
560 _ve_envelope_search,
561 the search is not run
562 if we only use one
563 block size */
568 /* fill in the block. Note that for a short window, lW and nW are *short*
569 regardless of actual settings in the stream */
571 _vorbis_block_ripcord(vb);
572 vb->lW=v->lW;
573 vb->W=v->W;
574 vb->nW=v->nW;
576 if(v->W){
577 if(!v->lW || !v->nW){
578 vbi->blocktype=BLOCKTYPE_TRANSITION;
579 /*fprintf(stderr,"-");*/
580 }else{
581 vbi->blocktype=BLOCKTYPE_LONG;
582 /*fprintf(stderr,"_");*/
584 }else{
585 if(_ve_envelope_mark(v)){
586 vbi->blocktype=BLOCKTYPE_IMPULSE;
587 /*fprintf(stderr,"|");*/
589 }else{
590 vbi->blocktype=BLOCKTYPE_PADDING;
591 /*fprintf(stderr,".");*/
596 vb->vd=v;
597 vb->sequence=v->sequence++;
598 vb->granulepos=v->granulepos;
599 vb->pcmend=ci->blocksizes[v->W];
601 /* copy the vectors; this uses the local storage in vb */
603 /* this tracks 'strongest peak' for later psychoacoustics */
604 /* moved to the global psy state; clean this mess up */
605 if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
606 g->ampmax=_vp_ampmax_decay(g->ampmax,v);
607 vbi->ampmax=g->ampmax;
609 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
610 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
611 for(i=0;i<vi->channels;i++){
612 vbi->pcmdelay[i]=
613 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
614 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
615 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
617 /* before we added the delay
618 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
619 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
624 /* handle eof detection: eof==0 means that we've not yet received EOF
625 eof>0 marks the last 'real' sample in pcm[]
626 eof<0 'no more to do'; doesn't get here */
628 if(v->eofflag){
629 if(v->centerW>=v->eofflag){
630 v->eofflag=-1;
631 vb->eofflag=1;
632 return(1);
636 /* advance storage vectors and clean up */
638 int new_centerNext=ci->blocksizes[1]/2;
639 int movementW=centerNext-new_centerNext;
641 if(movementW>0){
643 _ve_envelope_shift(b->ve,movementW);
644 v->pcm_current-=movementW;
646 for(i=0;i<vi->channels;i++)
647 memmove(v->pcm[i],v->pcm[i]+movementW,
648 v->pcm_current*sizeof(*v->pcm[i]));
651 v->lW=v->W;
652 v->W=v->nW;
653 v->centerW=new_centerNext;
655 if(v->eofflag){
656 v->eofflag-=movementW;
657 if(v->eofflag<=0)v->eofflag=-1;
658 /* do not add padding to end of stream! */
659 if(v->centerW>=v->eofflag){
660 v->granulepos+=movementW-(v->centerW-v->eofflag);
661 }else{
662 v->granulepos+=movementW;
664 }else{
665 v->granulepos+=movementW;
670 /* done */
671 return(1);
674 int vorbis_synthesis_restart(vorbis_dsp_state *v){
675 vorbis_info *vi=v->vi;
676 codec_setup_info *ci;
677 int hs;
679 if(!v->backend_state)return -1;
680 if(!vi)return -1;
681 ci=vi->codec_setup;
682 if(!ci)return -1;
683 hs=ci->halfrate_flag;
685 v->centerW=ci->blocksizes[1]>>(hs+1);
686 v->pcm_current=v->centerW>>hs;
688 v->pcm_returned=-1;
689 v->granulepos=-1;
690 v->sequence=-1;
691 v->eofflag=0;
692 ((private_state *)(v->backend_state))->sample_count=-1;
694 return(0);
697 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
698 if(_vds_shared_init(v,vi,0)){
699 vorbis_dsp_clear(v);
700 return 1;
702 vorbis_synthesis_restart(v);
703 return 0;
706 /* Unlike in analysis, the window is only partially applied for each
707 block. The time domain envelope is not yet handled at the point of
708 calling (as it relies on the previous block). */
710 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
711 vorbis_info *vi=v->vi;
712 codec_setup_info *ci=vi->codec_setup;
713 private_state *b=v->backend_state;
714 int hs=ci->halfrate_flag;
715 int i,j;
717 if(!vb)return(OV_EINVAL);
718 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
720 v->lW=v->W;
721 v->W=vb->W;
722 v->nW=-1;
724 if((v->sequence==-1)||
725 (v->sequence+1 != vb->sequence)){
726 v->granulepos=-1; /* out of sequence; lose count */
727 b->sample_count=-1;
730 v->sequence=vb->sequence;
732 if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
733 was called on block */
734 int n=ci->blocksizes[v->W]>>(hs+1);
735 int n0=ci->blocksizes[0]>>(hs+1);
736 int n1=ci->blocksizes[1]>>(hs+1);
738 int thisCenter;
739 int prevCenter;
741 v->glue_bits+=vb->glue_bits;
742 v->time_bits+=vb->time_bits;
743 v->floor_bits+=vb->floor_bits;
744 v->res_bits+=vb->res_bits;
746 if(v->centerW){
747 thisCenter=n1;
748 prevCenter=0;
749 }else{
750 thisCenter=0;
751 prevCenter=n1;
754 /* v->pcm is now used like a two-stage double buffer. We don't want
755 to have to constantly shift *or* adjust memory usage. Don't
756 accept a new block until the old is shifted out */
758 for(j=0;j<vi->channels;j++){
759 /* the overlap/add section */
760 if(v->lW){
761 if(v->W){
762 /* large/large */
763 float *w=_vorbis_window_get(b->window[1]-hs);
764 float *pcm=v->pcm[j]+prevCenter;
765 float *p=vb->pcm[j];
766 for(i=0;i<n1;i++)
767 pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
768 }else{
769 /* large/small */
770 float *w=_vorbis_window_get(b->window[0]-hs);
771 float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
772 float *p=vb->pcm[j];
773 for(i=0;i<n0;i++)
774 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
776 }else{
777 if(v->W){
778 /* small/large */
779 float *w=_vorbis_window_get(b->window[0]-hs);
780 float *pcm=v->pcm[j]+prevCenter;
781 float *p=vb->pcm[j]+n1/2-n0/2;
782 for(i=0;i<n0;i++)
783 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
784 for(;i<n1/2+n0/2;i++)
785 pcm[i]=p[i];
786 }else{
787 /* small/small */
788 float *w=_vorbis_window_get(b->window[0]-hs);
789 float *pcm=v->pcm[j]+prevCenter;
790 float *p=vb->pcm[j];
791 for(i=0;i<n0;i++)
792 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
796 /* the copy section */
798 float *pcm=v->pcm[j]+thisCenter;
799 float *p=vb->pcm[j]+n;
800 for(i=0;i<n;i++)
801 pcm[i]=p[i];
805 if(v->centerW)
806 v->centerW=0;
807 else
808 v->centerW=n1;
810 /* deal with initial packet state; we do this using the explicit
811 pcm_returned==-1 flag otherwise we're sensitive to first block
812 being short or long */
814 if(v->pcm_returned==-1){
815 v->pcm_returned=thisCenter;
816 v->pcm_current=thisCenter;
817 }else{
818 v->pcm_returned=prevCenter;
819 v->pcm_current=prevCenter+
820 ((ci->blocksizes[v->lW]/4+
821 ci->blocksizes[v->W]/4)>>hs);
826 /* track the frame number... This is for convenience, but also
827 making sure our last packet doesn't end with added padding. If
828 the last packet is partial, the number of samples we'll have to
829 return will be past the vb->granulepos.
831 This is not foolproof! It will be confused if we begin
832 decoding at the last page after a seek or hole. In that case,
833 we don't have a starting point to judge where the last frame
834 is. For this reason, vorbisfile will always try to make sure
835 it reads the last two marked pages in proper sequence */
837 if(b->sample_count==-1){
838 b->sample_count=0;
839 }else{
840 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
843 if(v->granulepos==-1){
844 if(vb->granulepos!=-1){ /* only set if we have a position to set to */
846 v->granulepos=vb->granulepos;
848 /* is this a short page? */
849 if(b->sample_count>v->granulepos){
850 /* corner case; if this is both the first and last audio page,
851 then spec says the end is cut, not beginning */
852 if(vb->eofflag){
853 /* trim the end */
854 /* no preceeding granulepos; assume we started at zero (we'd
855 have to in a short single-page stream) */
856 /* granulepos could be -1 due to a seek, but that would result
857 in a long count, not short count */
859 v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
860 }else{
861 /* trim the beginning */
862 v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
863 if(v->pcm_returned>v->pcm_current)
864 v->pcm_returned=v->pcm_current;
870 }else{
871 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
872 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
874 if(v->granulepos>vb->granulepos){
875 long extra=v->granulepos-vb->granulepos;
877 if(extra)
878 if(vb->eofflag){
879 /* partial last frame. Strip the extra samples off */
880 v->pcm_current-=extra>>hs;
881 } /* else {Shouldn't happen *unless* the bitstream is out of
882 spec. Either way, believe the bitstream } */
883 } /* else {Shouldn't happen *unless* the bitstream is out of
884 spec. Either way, believe the bitstream } */
885 v->granulepos=vb->granulepos;
889 /* Update, cleanup */
891 if(vb->eofflag)v->eofflag=1;
892 return(0);
896 /* pcm==NULL indicates we just want the pending samples, no more */
897 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
898 vorbis_info *vi=v->vi;
900 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
901 if(pcm){
902 int i;
903 for(i=0;i<vi->channels;i++)
904 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
905 *pcm=v->pcmret;
907 return(v->pcm_current-v->pcm_returned);
909 return(0);
912 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
913 if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
914 v->pcm_returned+=n;
915 return(0);
918 /* intended for use with a specific vorbisfile feature; we want access
919 to the [usually synthetic/postextrapolated] buffer and lapping at
920 the end of a decode cycle, specifically, a half-short-block worth.
921 This funtion works like pcmout above, except it will also expose
922 this implicit buffer data not normally decoded. */
923 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
924 vorbis_info *vi=v->vi;
925 codec_setup_info *ci=vi->codec_setup;
926 int hs=ci->halfrate_flag;
928 int n=ci->blocksizes[v->W]>>(hs+1);
929 int n0=ci->blocksizes[0]>>(hs+1);
930 int n1=ci->blocksizes[1]>>(hs+1);
931 int i,j;
933 if(v->pcm_returned<0)return 0;
935 /* our returned data ends at pcm_returned; because the synthesis pcm
936 buffer is a two-fragment ring, that means our data block may be
937 fragmented by buffering, wrapping or a short block not filling
938 out a buffer. To simplify things, we unfragment if it's at all
939 possibly needed. Otherwise, we'd need to call lapout more than
940 once as well as hold additional dsp state. Opt for
941 simplicity. */
943 /* centerW was advanced by blockin; it would be the center of the
944 *next* block */
945 if(v->centerW==n1){
946 /* the data buffer wraps; swap the halves */
947 /* slow, sure, small */
948 for(j=0;j<vi->channels;j++){
949 float *p=v->pcm[j];
950 for(i=0;i<n1;i++){
951 float temp=p[i];
952 p[i]=p[i+n1];
953 p[i+n1]=temp;
957 v->pcm_current-=n1;
958 v->pcm_returned-=n1;
959 v->centerW=0;
962 /* solidify buffer into contiguous space */
963 if((v->lW^v->W)==1){
964 /* long/short or short/long */
965 for(j=0;j<vi->channels;j++){
966 float *s=v->pcm[j];
967 float *d=v->pcm[j]+(n1-n0)/2;
968 for(i=(n1+n0)/2-1;i>=0;--i)
969 d[i]=s[i];
971 v->pcm_returned+=(n1-n0)/2;
972 v->pcm_current+=(n1-n0)/2;
973 }else{
974 if(v->lW==0){
975 /* short/short */
976 for(j=0;j<vi->channels;j++){
977 float *s=v->pcm[j];
978 float *d=v->pcm[j]+n1-n0;
979 for(i=n0-1;i>=0;--i)
980 d[i]=s[i];
982 v->pcm_returned+=n1-n0;
983 v->pcm_current+=n1-n0;
987 if(pcm){
988 int i;
989 for(i=0;i<vi->channels;i++)
990 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
991 *pcm=v->pcmret;
994 return(n1+n-v->pcm_returned);
998 float *vorbis_window(vorbis_dsp_state *v,int W){
999 vorbis_info *vi=v->vi;
1000 codec_setup_info *ci=vi->codec_setup;
1001 int hs=ci->halfrate_flag;
1002 private_state *b=v->backend_state;
1004 if(b->window[W]-1<0)return NULL;
1005 return _vorbis_window_get(b->window[W]-hs);