1 /********************************************************************
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. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: PCM data vector blocking, windowing and dis/reassembly
16 Handle windowing, overlap-add, etc of the PCM vectors. This is made
17 more amusing by Vorbis' current two allowed block sizes.
19 ********************************************************************/
25 #include "vorbis/codec.h"
26 #include "codec_internal.h"
34 static int ilog2(unsigned int v){
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
58 <--------------- W ---------------->
59 | | .. ______________ |
61 |___.'___/`. | ---_____|
62 |_______|__|_______|_________________|
63 | >|Sl|< |<------ Sr ----->|endW
64 | | |endSl |beginSr |endSr
66 mult[0] |beginSl mult[n]
68 <-------------- lW ----------------->
70 : .............. ___ | |
72 :.....''' |/`....\|...|
73 :.........................|___|___|___|
82 /* block abstraction setup *********************************************/
88 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
90 memset(vb,0,sizeof(*vb));
95 vorbis_block_internal *vbi=
96 vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
99 for(i=0;i<PACKETBLOBS;i++){
100 if(i==PACKETBLOBS/2){
101 vbi->packetblob[i]=&vb->opb;
104 _ogg_calloc(1,sizeof(oggpack_buffer));
106 oggpack_writeinit(vbi->packetblob[i]);
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 */
118 struct alloc_chain *link=_ogg_malloc(sizeof(*link));
119 vb->totaluse+=vb->localtop;
121 link->ptr=vb->localstore;
124 /* highly conservative */
125 vb->localalloc=bytes;
126 vb->localstore=_ogg_malloc(vb->localalloc);
130 void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
136 /* reap the chain, pull the ripcord */
137 void _vorbis_block_ripcord(vorbis_block *vb){
139 struct alloc_chain *reap=vb->reap;
141 struct alloc_chain *next=reap->next;
142 _ogg_free(reap->ptr);
143 memset(reap,0,sizeof(*reap));
147 /* consolidate storage */
149 vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
150 vb->localalloc+=vb->totaluse;
154 /* pull the ripcord */
159 int vorbis_block_clear(vorbis_block *vb){
161 vorbis_block_internal *vbi=vb->internal;
163 _vorbis_block_ripcord(vb);
164 if(vb->localstore)_ogg_free(vb->localstore);
167 for(i=0;i<PACKETBLOBS;i++){
168 oggpack_writeclear(vbi->packetblob[i]);
169 if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
173 memset(vb,0,sizeof(*vb));
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){
183 codec_setup_info *ci=vi->codec_setup;
184 private_state *b=NULL;
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));
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 */
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,
228 ci->blocksizes[ci->psy_param[i]->blockflag]/2,
234 /* finish the codebooks */
236 ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
237 for(i=0;i<ci->books;i++){
238 vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
239 /* decode codebooks are now standalone after init */
240 vorbis_staticbook_destroy(ci->book_param[i]);
241 ci->book_param[i]=NULL;
246 /* initialize the storage vectors. blocksize[1] is small for encode,
247 but the correct size for decode */
248 v->pcm_storage=ci->blocksizes[1];
249 v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
250 v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
253 for(i=0;i<vi->channels;i++)
254 v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
257 /* all 1 (large block) or 0 (small block) */
258 /* explicitly set for the sake of clarity */
259 v->lW=0; /* previous window size */
260 v->W=0; /* current window size */
262 /* all vector indexes */
263 v->centerW=ci->blocksizes[1]/2;
265 v->pcm_current=v->centerW;
267 /* initialize all the backend lookups */
268 b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
269 b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
271 for(i=0;i<ci->floors;i++)
272 b->flr[i]=_floor_P[ci->floor_type[i]]->
273 look(v,ci->floor_param[i]);
275 for(i=0;i<ci->residues;i++)
276 b->residue[i]=_residue_P[ci->residue_type[i]]->
277 look(v,ci->residue_param[i]);
282 /* arbitrary settings and spec-mandated numbers get filled in here */
283 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
284 private_state *b=NULL;
286 if(_vds_shared_init(v,vi,1))return 1;
288 b->psy_g_look=_vp_global_look(vi);
290 /* Initialize the envelope state storage */
291 b->ve=_ogg_calloc(1,sizeof(*b->ve));
292 _ve_envelope_init(b->ve,vi);
294 vorbis_bitrate_init(vi,&b->bms);
296 /* compressed audio packets start after the headers
297 with sequence number 3 */
303 void vorbis_dsp_clear(vorbis_dsp_state *v){
306 vorbis_info *vi=v->vi;
307 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
308 private_state *b=v->backend_state;
313 _ve_envelope_clear(b->ve);
318 mdct_clear(b->transform[0][0]);
319 _ogg_free(b->transform[0][0]);
320 _ogg_free(b->transform[0]);
323 mdct_clear(b->transform[1][0]);
324 _ogg_free(b->transform[1][0]);
325 _ogg_free(b->transform[1]);
330 for(i=0;i<ci->floors;i++)
331 _floor_P[ci->floor_type[i]]->
332 free_look(b->flr[i]);
337 for(i=0;i<ci->residues;i++)
338 _residue_P[ci->residue_type[i]]->
339 free_look(b->residue[i]);
340 _ogg_free(b->residue);
344 for(i=0;i<ci->psys;i++)
345 _vp_psy_clear(b->psy+i);
349 if(b->psy_g_look)_vp_global_free(b->psy_g_look);
350 vorbis_bitrate_clear(&b->bms);
352 drft_clear(&b->fft_look[0]);
353 drft_clear(&b->fft_look[1]);
359 for(i=0;i<vi->channels;i++)
360 if(v->pcm[i])_ogg_free(v->pcm[i]);
362 if(v->pcmret)_ogg_free(v->pcmret);
366 /* free header, header1, header2 */
367 if(b->header)_ogg_free(b->header);
368 if(b->header1)_ogg_free(b->header1);
369 if(b->header2)_ogg_free(b->header2);
373 memset(v,0,sizeof(*v));
377 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
379 vorbis_info *vi=v->vi;
380 private_state *b=v->backend_state;
382 /* free header, header1, header2 */
383 if(b->header)_ogg_free(b->header);b->header=NULL;
384 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
385 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
387 /* Do we have enough storage space for the requested buffer? If not,
388 expand the PCM (and envelope) storage */
390 if(v->pcm_current+vals>=v->pcm_storage){
391 v->pcm_storage=v->pcm_current+vals*2;
393 for(i=0;i<vi->channels;i++){
394 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
398 for(i=0;i<vi->channels;i++)
399 v->pcmret[i]=v->pcm[i]+v->pcm_current;
404 static void _preextrapolate_helper(vorbis_dsp_state *v){
407 float *lpc=alloca(order*sizeof(*lpc));
408 float *work=alloca(v->pcm_current*sizeof(*work));
412 if(v->pcm_current-v->centerW>order*2){ /* safety */
413 for(i=0;i<v->vi->channels;i++){
414 /* need to run the extrapolation in reverse! */
415 for(j=0;j<v->pcm_current;j++)
416 work[j]=v->pcm[i][v->pcm_current-j-1];
419 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
421 /* run the predictor filter */
422 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
424 work+v->pcm_current-v->centerW,
427 for(j=0;j<v->pcm_current;j++)
428 v->pcm[i][v->pcm_current-j-1]=work[j];
435 /* call with val<=0 to set eof */
437 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
438 vorbis_info *vi=v->vi;
439 codec_setup_info *ci=vi->codec_setup;
444 float *lpc=alloca(order*sizeof(*lpc));
446 /* if it wasn't done earlier (very short sample) */
447 if(!v->preextrapolate)
448 _preextrapolate_helper(v);
450 /* We're encoding the end of the stream. Just make sure we have
451 [at least] a few full blocks of zeroes at the end. */
452 /* actually, we don't want zeroes; that could drop a large
453 amplitude off a cliff, creating spread spectrum noise that will
454 suck to encode. Extrapolate for the sake of cleanliness. */
456 vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
457 v->eofflag=v->pcm_current;
458 v->pcm_current+=ci->blocksizes[1]*3;
460 for(i=0;i<vi->channels;i++){
461 if(v->eofflag>order*2){
462 /* extrapolate with LPC to fill in */
465 /* make a predictor filter */
467 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
468 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
470 /* run the predictor filter */
471 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
472 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
474 /* not enough data to extrapolate (unlikely to happen due to
475 guarding the overlap, but bulletproof in case that
476 assumtion goes away). zeroes will do. */
477 memset(v->pcm[i]+v->eofflag,0,
478 (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
484 if(v->pcm_current+vals>v->pcm_storage)
487 v->pcm_current+=vals;
489 /* we may want to reverse extrapolate the beginning of a stream
490 too... in case we're beginning on a cliff! */
491 /* clumsy, but simple. It only runs once, so simple is good. */
492 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
493 _preextrapolate_helper(v);
499 /* do the deltas, envelope shaping, pre-echo and determine the size of
500 the next block on which to continue analysis */
501 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
503 vorbis_info *vi=v->vi;
504 codec_setup_info *ci=vi->codec_setup;
505 private_state *b=v->backend_state;
506 vorbis_look_psy_global *g=b->psy_g_look;
507 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
508 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
510 /* check to see if we're started... */
511 if(!v->preextrapolate)return(0);
513 /* check to see if we're done... */
514 if(v->eofflag==-1)return(0);
516 /* By our invariant, we have lW, W and centerW set. Search for
517 the next boundary so we can determine nW (the next window size)
518 which lets us compute the shape of the current block's window */
520 /* we do an envelope search even on a single blocksize; we may still
521 be throwing more bits at impulses, and envelope search handles
522 marking impulses too. */
524 long bp=_ve_envelope_search(v);
527 if(v->eofflag==0)return(0); /* not enough data currently to search for a
532 if(ci->blocksizes[0]==ci->blocksizes[1])
539 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
542 /* center of next block + next block maximum right side. */
544 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
545 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
546 although this check is
549 the search is not run
556 /* fill in the block. Note that for a short window, lW and nW are *short*
557 regardless of actual settings in the stream */
559 _vorbis_block_ripcord(vb);
565 if(!v->lW || !v->nW){
566 vbi->blocktype=BLOCKTYPE_TRANSITION;
567 /*fprintf(stderr,"-");*/
569 vbi->blocktype=BLOCKTYPE_LONG;
570 /*fprintf(stderr,"_");*/
573 if(_ve_envelope_mark(v)){
574 vbi->blocktype=BLOCKTYPE_IMPULSE;
575 /*fprintf(stderr,"|");*/
578 vbi->blocktype=BLOCKTYPE_PADDING;
579 /*fprintf(stderr,".");*/
585 vb->sequence=v->sequence++;
586 vb->granulepos=v->granulepos;
587 vb->pcmend=ci->blocksizes[v->W];
589 /* copy the vectors; this uses the local storage in vb */
591 /* this tracks 'strongest peak' for later psychoacoustics */
592 /* moved to the global psy state; clean this mess up */
593 if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
594 g->ampmax=_vp_ampmax_decay(g->ampmax,v);
595 vbi->ampmax=g->ampmax;
597 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
598 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
599 for(i=0;i<vi->channels;i++){
601 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
602 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
603 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
605 /* before we added the delay
606 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
607 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
612 /* handle eof detection: eof==0 means that we've not yet received EOF
613 eof>0 marks the last 'real' sample in pcm[]
614 eof<0 'no more to do'; doesn't get here */
617 if(v->centerW>=v->eofflag){
624 /* advance storage vectors and clean up */
626 int new_centerNext=ci->blocksizes[1]/2;
627 int movementW=centerNext-new_centerNext;
631 _ve_envelope_shift(b->ve,movementW);
632 v->pcm_current-=movementW;
634 for(i=0;i<vi->channels;i++)
635 memmove(v->pcm[i],v->pcm[i]+movementW,
636 v->pcm_current*sizeof(*v->pcm[i]));
641 v->centerW=new_centerNext;
644 v->eofflag-=movementW;
645 if(v->eofflag<=0)v->eofflag=-1;
646 /* do not add padding to end of stream! */
647 if(v->centerW>=v->eofflag){
648 v->granulepos+=movementW-(v->centerW-v->eofflag);
650 v->granulepos+=movementW;
653 v->granulepos+=movementW;
662 int vorbis_synthesis_restart(vorbis_dsp_state *v){
663 vorbis_info *vi=v->vi;
664 codec_setup_info *ci;
667 if(!v->backend_state)return -1;
671 hs=ci->halfrate_flag;
673 v->centerW=ci->blocksizes[1]>>(hs+1);
674 v->pcm_current=v->centerW>>hs;
680 ((private_state *)(v->backend_state))->sample_count=-1;
685 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
686 if(_vds_shared_init(v,vi,0)) return 1;
687 vorbis_synthesis_restart(v);
692 /* Unlike in analysis, the window is only partially applied for each
693 block. The time domain envelope is not yet handled at the point of
694 calling (as it relies on the previous block). */
696 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
697 vorbis_info *vi=v->vi;
698 codec_setup_info *ci=vi->codec_setup;
699 private_state *b=v->backend_state;
700 int hs=ci->halfrate_flag;
703 if(!vb)return(OV_EINVAL);
704 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
710 if((v->sequence==-1)||
711 (v->sequence+1 != vb->sequence)){
712 v->granulepos=-1; /* out of sequence; lose count */
716 v->sequence=vb->sequence;
718 if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
719 was called on block */
720 int n=ci->blocksizes[v->W]>>(hs+1);
721 int n0=ci->blocksizes[0]>>(hs+1);
722 int n1=ci->blocksizes[1]>>(hs+1);
727 v->glue_bits+=vb->glue_bits;
728 v->time_bits+=vb->time_bits;
729 v->floor_bits+=vb->floor_bits;
730 v->res_bits+=vb->res_bits;
740 /* v->pcm is now used like a two-stage double buffer. We don't want
741 to have to constantly shift *or* adjust memory usage. Don't
742 accept a new block until the old is shifted out */
744 for(j=0;j<vi->channels;j++){
745 /* the overlap/add section */
749 float *w=_vorbis_window_get(b->window[1]-hs);
750 float *pcm=v->pcm[j]+prevCenter;
753 pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
756 float *w=_vorbis_window_get(b->window[0]-hs);
757 float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
760 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
765 float *w=_vorbis_window_get(b->window[0]-hs);
766 float *pcm=v->pcm[j]+prevCenter;
767 float *p=vb->pcm[j]+n1/2-n0/2;
769 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
770 for(;i<n1/2+n0/2;i++)
774 float *w=_vorbis_window_get(b->window[0]-hs);
775 float *pcm=v->pcm[j]+prevCenter;
778 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
782 /* the copy section */
784 float *pcm=v->pcm[j]+thisCenter;
785 float *p=vb->pcm[j]+n;
796 /* deal with initial packet state; we do this using the explicit
797 pcm_returned==-1 flag otherwise we're sensitive to first block
798 being short or long */
800 if(v->pcm_returned==-1){
801 v->pcm_returned=thisCenter;
802 v->pcm_current=thisCenter;
804 v->pcm_returned=prevCenter;
805 v->pcm_current=prevCenter+
806 ((ci->blocksizes[v->lW]/4+
807 ci->blocksizes[v->W]/4)>>hs);
812 /* track the frame number... This is for convenience, but also
813 making sure our last packet doesn't end with added padding. If
814 the last packet is partial, the number of samples we'll have to
815 return will be past the vb->granulepos.
817 This is not foolproof! It will be confused if we begin
818 decoding at the last page after a seek or hole. In that case,
819 we don't have a starting point to judge where the last frame
820 is. For this reason, vorbisfile will always try to make sure
821 it reads the last two marked pages in proper sequence */
823 if(b->sample_count==-1){
826 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
829 if(v->granulepos==-1){
830 if(vb->granulepos!=-1){ /* only set if we have a position to set to */
832 v->granulepos=vb->granulepos;
834 /* is this a short page? */
835 if(b->sample_count>v->granulepos){
836 /* corner case; if this is both the first and last audio page,
837 then spec says the end is cut, not beginning */
840 /* no preceeding granulepos; assume we started at zero (we'd
841 have to in a short single-page stream) */
842 /* granulepos could be -1 due to a seek, but that would result
843 in a long count, not short count */
845 v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
847 /* trim the beginning */
848 v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
849 if(v->pcm_returned>v->pcm_current)
850 v->pcm_returned=v->pcm_current;
857 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
858 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
860 if(v->granulepos>vb->granulepos){
861 long extra=v->granulepos-vb->granulepos;
865 /* partial last frame. Strip the extra samples off */
866 v->pcm_current-=extra>>hs;
867 } /* else {Shouldn't happen *unless* the bitstream is out of
868 spec. Either way, believe the bitstream } */
869 } /* else {Shouldn't happen *unless* the bitstream is out of
870 spec. Either way, believe the bitstream } */
871 v->granulepos=vb->granulepos;
875 /* Update, cleanup */
877 if(vb->eofflag)v->eofflag=1;
882 /* pcm==NULL indicates we just want the pending samples, no more */
883 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
884 vorbis_info *vi=v->vi;
886 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
889 for(i=0;i<vi->channels;i++)
890 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
893 return(v->pcm_current-v->pcm_returned);
898 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
899 if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
904 /* intended for use with a specific vorbisfile feature; we want access
905 to the [usually synthetic/postextrapolated] buffer and lapping at
906 the end of a decode cycle, specifically, a half-short-block worth.
907 This funtion works like pcmout above, except it will also expose
908 this implicit buffer data not normally decoded. */
909 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
910 vorbis_info *vi=v->vi;
911 codec_setup_info *ci=vi->codec_setup;
912 int hs=ci->halfrate_flag;
914 int n=ci->blocksizes[v->W]>>(hs+1);
915 int n0=ci->blocksizes[0]>>(hs+1);
916 int n1=ci->blocksizes[1]>>(hs+1);
919 if(v->pcm_returned<0)return 0;
921 /* our returned data ends at pcm_returned; because the synthesis pcm
922 buffer is a two-fragment ring, that means our data block may be
923 fragmented by buffering, wrapping or a short block not filling
924 out a buffer. To simplify things, we unfragment if it's at all
925 possibly needed. Otherwise, we'd need to call lapout more than
926 once as well as hold additional dsp state. Opt for
929 /* centerW was advanced by blockin; it would be the center of the
932 /* the data buffer wraps; swap the halves */
933 /* slow, sure, small */
934 for(j=0;j<vi->channels;j++){
948 /* solidify buffer into contiguous space */
950 /* long/short or short/long */
951 for(j=0;j<vi->channels;j++){
953 float *d=v->pcm[j]+(n1-n0)/2;
954 for(i=(n1+n0)/2-1;i>=0;--i)
957 v->pcm_returned+=(n1-n0)/2;
958 v->pcm_current+=(n1-n0)/2;
962 for(j=0;j<vi->channels;j++){
964 float *d=v->pcm[j]+n1-n0;
968 v->pcm_returned+=n1-n0;
969 v->pcm_current+=n1-n0;
975 for(i=0;i<vi->channels;i++)
976 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
980 return(n1+n-v->pcm_returned);
984 float *vorbis_window(vorbis_dsp_state *v,int W){
985 vorbis_info *vi=v->vi;
986 codec_setup_info *ci=vi->codec_setup;
987 int hs=ci->halfrate_flag;
988 private_state *b=v->backend_state;
990 if(b->window[W]-1<0)return NULL;
991 return _vorbis_window_get(b->window[W]-hs);