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-2003 *
9 * by the XIPHOPHORUS Company 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]);
329 for(i=0;i<ci->floors;i++)
330 _floor_P[ci->floor_type[i]]->
331 free_look(b->flr[i]);
335 for(i=0;i<ci->residues;i++)
336 _residue_P[ci->residue_type[i]]->
337 free_look(b->residue[i]);
338 _ogg_free(b->residue);
341 for(i=0;i<ci->psys;i++)
342 _vp_psy_clear(b->psy+i);
346 if(b->psy_g_look)_vp_global_free(b->psy_g_look);
347 vorbis_bitrate_clear(&b->bms);
349 drft_clear(&b->fft_look[0]);
350 drft_clear(&b->fft_look[1]);
355 for(i=0;i<vi->channels;i++)
356 if(v->pcm[i])_ogg_free(v->pcm[i]);
358 if(v->pcmret)_ogg_free(v->pcmret);
362 /* free header, header1, header2 */
363 if(b->header)_ogg_free(b->header);
364 if(b->header1)_ogg_free(b->header1);
365 if(b->header2)_ogg_free(b->header2);
369 memset(v,0,sizeof(*v));
373 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
375 vorbis_info *vi=v->vi;
376 private_state *b=v->backend_state;
378 /* free header, header1, header2 */
379 if(b->header)_ogg_free(b->header);b->header=NULL;
380 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
381 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
383 /* Do we have enough storage space for the requested buffer? If not,
384 expand the PCM (and envelope) storage */
386 if(v->pcm_current+vals>=v->pcm_storage){
387 v->pcm_storage=v->pcm_current+vals*2;
389 for(i=0;i<vi->channels;i++){
390 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
394 for(i=0;i<vi->channels;i++)
395 v->pcmret[i]=v->pcm[i]+v->pcm_current;
400 static void _preextrapolate_helper(vorbis_dsp_state *v){
403 float *lpc=alloca(order*sizeof(*lpc));
404 float *work=alloca(v->pcm_current*sizeof(*work));
408 if(v->pcm_current-v->centerW>order*2){ /* safety */
409 for(i=0;i<v->vi->channels;i++){
410 /* need to run the extrapolation in reverse! */
411 for(j=0;j<v->pcm_current;j++)
412 work[j]=v->pcm[i][v->pcm_current-j-1];
415 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
417 /* run the predictor filter */
418 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
420 work+v->pcm_current-v->centerW,
423 for(j=0;j<v->pcm_current;j++)
424 v->pcm[i][v->pcm_current-j-1]=work[j];
431 /* call with val<=0 to set eof */
433 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
434 vorbis_info *vi=v->vi;
435 codec_setup_info *ci=vi->codec_setup;
440 float *lpc=alloca(order*sizeof(*lpc));
442 /* if it wasn't done earlier (very short sample) */
443 if(!v->preextrapolate)
444 _preextrapolate_helper(v);
446 /* We're encoding the end of the stream. Just make sure we have
447 [at least] a few full blocks of zeroes at the end. */
448 /* actually, we don't want zeroes; that could drop a large
449 amplitude off a cliff, creating spread spectrum noise that will
450 suck to encode. Extrapolate for the sake of cleanliness. */
452 vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
453 v->eofflag=v->pcm_current;
454 v->pcm_current+=ci->blocksizes[1]*3;
456 for(i=0;i<vi->channels;i++){
457 if(v->eofflag>order*2){
458 /* extrapolate with LPC to fill in */
461 /* make a predictor filter */
463 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
464 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
466 /* run the predictor filter */
467 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
468 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
470 /* not enough data to extrapolate (unlikely to happen due to
471 guarding the overlap, but bulletproof in case that
472 assumtion goes away). zeroes will do. */
473 memset(v->pcm[i]+v->eofflag,0,
474 (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
480 if(v->pcm_current+vals>v->pcm_storage)
483 v->pcm_current+=vals;
485 /* we may want to reverse extrapolate the beginning of a stream
486 too... in case we're beginning on a cliff! */
487 /* clumsy, but simple. It only runs once, so simple is good. */
488 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
489 _preextrapolate_helper(v);
495 /* do the deltas, envelope shaping, pre-echo and determine the size of
496 the next block on which to continue analysis */
497 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
499 vorbis_info *vi=v->vi;
500 codec_setup_info *ci=vi->codec_setup;
501 private_state *b=v->backend_state;
502 vorbis_look_psy_global *g=b->psy_g_look;
503 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
504 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
506 /* check to see if we're started... */
507 if(!v->preextrapolate)return(0);
509 /* check to see if we're done... */
510 if(v->eofflag==-1)return(0);
512 /* By our invariant, we have lW, W and centerW set. Search for
513 the next boundary so we can determine nW (the next window size)
514 which lets us compute the shape of the current block's window */
516 /* we do an envelope search even on a single blocksize; we may still
517 be throwing more bits at impulses, and envelope search handles
518 marking impulses too. */
520 long bp=_ve_envelope_search(v);
523 if(v->eofflag==0)return(0); /* not enough data currently to search for a
528 if(ci->blocksizes[0]==ci->blocksizes[1])
535 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
538 /* center of next block + next block maximum right side. */
540 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
541 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
542 although this check is
545 the search is not run
552 /* fill in the block. Note that for a short window, lW and nW are *short*
553 regardless of actual settings in the stream */
555 _vorbis_block_ripcord(vb);
561 if(!v->lW || !v->nW){
562 vbi->blocktype=BLOCKTYPE_TRANSITION;
563 /*fprintf(stderr,"-");*/
565 vbi->blocktype=BLOCKTYPE_LONG;
566 /*fprintf(stderr,"_");*/
569 if(_ve_envelope_mark(v)){
570 vbi->blocktype=BLOCKTYPE_IMPULSE;
571 /*fprintf(stderr,"|");*/
574 vbi->blocktype=BLOCKTYPE_PADDING;
575 /*fprintf(stderr,".");*/
581 vb->sequence=v->sequence++;
582 vb->granulepos=v->granulepos;
583 vb->pcmend=ci->blocksizes[v->W];
585 /* copy the vectors; this uses the local storage in vb */
587 /* this tracks 'strongest peak' for later psychoacoustics */
588 /* moved to the global psy state; clean this mess up */
589 if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
590 g->ampmax=_vp_ampmax_decay(g->ampmax,v);
591 vbi->ampmax=g->ampmax;
593 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
594 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
595 for(i=0;i<vi->channels;i++){
597 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
598 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
599 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
601 /* before we added the delay
602 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
603 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
608 /* handle eof detection: eof==0 means that we've not yet received EOF
609 eof>0 marks the last 'real' sample in pcm[]
610 eof<0 'no more to do'; doesn't get here */
613 if(v->centerW>=v->eofflag){
620 /* advance storage vectors and clean up */
622 int new_centerNext=ci->blocksizes[1]/2;
623 int movementW=centerNext-new_centerNext;
627 _ve_envelope_shift(b->ve,movementW);
628 v->pcm_current-=movementW;
630 for(i=0;i<vi->channels;i++)
631 memmove(v->pcm[i],v->pcm[i]+movementW,
632 v->pcm_current*sizeof(*v->pcm[i]));
637 v->centerW=new_centerNext;
640 v->eofflag-=movementW;
641 if(v->eofflag<=0)v->eofflag=-1;
642 /* do not add padding to end of stream! */
643 if(v->centerW>=v->eofflag){
644 v->granulepos+=movementW-(v->centerW-v->eofflag);
646 v->granulepos+=movementW;
649 v->granulepos+=movementW;
658 int vorbis_synthesis_restart(vorbis_dsp_state *v){
659 vorbis_info *vi=v->vi;
660 codec_setup_info *ci;
663 if(!v->backend_state)return -1;
667 hs=ci->halfrate_flag;
669 v->centerW=ci->blocksizes[1]>>(hs+1);
670 v->pcm_current=v->centerW>>hs;
676 ((private_state *)(v->backend_state))->sample_count=-1;
681 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
682 if(_vds_shared_init(v,vi,0)) return 1;
683 vorbis_synthesis_restart(v);
688 /* Unlike in analysis, the window is only partially applied for each
689 block. The time domain envelope is not yet handled at the point of
690 calling (as it relies on the previous block). */
692 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
693 vorbis_info *vi=v->vi;
694 codec_setup_info *ci=vi->codec_setup;
695 private_state *b=v->backend_state;
696 int hs=ci->halfrate_flag;
699 if(!vb)return(OV_EINVAL);
700 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
706 if((v->sequence==-1)||
707 (v->sequence+1 != vb->sequence)){
708 v->granulepos=-1; /* out of sequence; lose count */
712 v->sequence=vb->sequence;
714 if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
715 was called on block */
716 int n=ci->blocksizes[v->W]>>(hs+1);
717 int n0=ci->blocksizes[0]>>(hs+1);
718 int n1=ci->blocksizes[1]>>(hs+1);
723 v->glue_bits+=vb->glue_bits;
724 v->time_bits+=vb->time_bits;
725 v->floor_bits+=vb->floor_bits;
726 v->res_bits+=vb->res_bits;
736 /* v->pcm is now used like a two-stage double buffer. We don't want
737 to have to constantly shift *or* adjust memory usage. Don't
738 accept a new block until the old is shifted out */
740 for(j=0;j<vi->channels;j++){
741 /* the overlap/add section */
745 float *w=_vorbis_window_get(b->window[1]-hs);
746 float *pcm=v->pcm[j]+prevCenter;
749 pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
752 float *w=_vorbis_window_get(b->window[0]-hs);
753 float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
756 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
761 float *w=_vorbis_window_get(b->window[0]-hs);
762 float *pcm=v->pcm[j]+prevCenter;
763 float *p=vb->pcm[j]+n1/2-n0/2;
765 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
766 for(;i<n1/2+n0/2;i++)
770 float *w=_vorbis_window_get(b->window[0]-hs);
771 float *pcm=v->pcm[j]+prevCenter;
774 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
778 /* the copy section */
780 float *pcm=v->pcm[j]+thisCenter;
781 float *p=vb->pcm[j]+n;
792 /* deal with initial packet state; we do this using the explicit
793 pcm_returned==-1 flag otherwise we're sensitive to first block
794 being short or long */
796 if(v->pcm_returned==-1){
797 v->pcm_returned=thisCenter;
798 v->pcm_current=thisCenter;
800 v->pcm_returned=prevCenter;
801 v->pcm_current=prevCenter+
802 ((ci->blocksizes[v->lW]/4+
803 ci->blocksizes[v->W]/4)>>hs);
808 /* track the frame number... This is for convenience, but also
809 making sure our last packet doesn't end with added padding. If
810 the last packet is partial, the number of samples we'll have to
811 return will be past the vb->granulepos.
813 This is not foolproof! It will be confused if we begin
814 decoding at the last page after a seek or hole. In that case,
815 we don't have a starting point to judge where the last frame
816 is. For this reason, vorbisfile will always try to make sure
817 it reads the last two marked pages in proper sequence */
819 if(b->sample_count==-1){
822 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
825 if(v->granulepos==-1){
826 if(vb->granulepos!=-1){ /* only set if we have a position to set to */
828 v->granulepos=vb->granulepos;
830 /* is this a short page? */
831 if(b->sample_count>v->granulepos){
832 /* corner case; if this is both the first and last audio page,
833 then spec says the end is cut, not beginning */
836 /* no preceeding granulepos; assume we started at zero (we'd
837 have to in a short single-page stream) */
838 /* granulepos could be -1 due to a seek, but that would result
839 in a long count, not short count */
841 v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
843 /* trim the beginning */
844 v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
845 if(v->pcm_returned>v->pcm_current)
846 v->pcm_returned=v->pcm_current;
853 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
854 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
856 if(v->granulepos>vb->granulepos){
857 long extra=v->granulepos-vb->granulepos;
861 /* partial last frame. Strip the extra samples off */
862 v->pcm_current-=extra>>hs;
863 } /* else {Shouldn't happen *unless* the bitstream is out of
864 spec. Either way, believe the bitstream } */
865 } /* else {Shouldn't happen *unless* the bitstream is out of
866 spec. Either way, believe the bitstream } */
867 v->granulepos=vb->granulepos;
871 /* Update, cleanup */
873 if(vb->eofflag)v->eofflag=1;
878 /* pcm==NULL indicates we just want the pending samples, no more */
879 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
880 vorbis_info *vi=v->vi;
882 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
885 for(i=0;i<vi->channels;i++)
886 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
889 return(v->pcm_current-v->pcm_returned);
894 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
895 if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
900 /* intended for use with a specific vorbisfile feature; we want access
901 to the [usually synthetic/postextrapolated] buffer and lapping at
902 the end of a decode cycle, specifically, a half-short-block worth.
903 This funtion works like pcmout above, except it will also expose
904 this implicit buffer data not normally decoded. */
905 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
906 vorbis_info *vi=v->vi;
907 codec_setup_info *ci=vi->codec_setup;
908 int hs=ci->halfrate_flag;
910 int n=ci->blocksizes[v->W]>>(hs+1);
911 int n0=ci->blocksizes[0]>>(hs+1);
912 int n1=ci->blocksizes[1]>>(hs+1);
915 if(v->pcm_returned<0)return 0;
917 /* our returned data ends at pcm_returned; because the synthesis pcm
918 buffer is a two-fragment ring, that means our data block may be
919 fragmented by buffering, wrapping or a short block not filling
920 out a buffer. To simplify things, we unfragment if it's at all
921 possibly needed. Otherwise, we'd need to call lapout more than
922 once as well as hold additional dsp state. Opt for
925 /* centerW was advanced by blockin; it would be the center of the
928 /* the data buffer wraps; swap the halves */
929 /* slow, sure, small */
930 for(j=0;j<vi->channels;j++){
944 /* solidify buffer into contiguous space */
946 /* long/short or short/long */
947 for(j=0;j<vi->channels;j++){
949 float *d=v->pcm[j]+(n1-n0)/2;
950 for(i=(n1+n0)/2-1;i>=0;--i)
953 v->pcm_returned+=(n1-n0)/2;
954 v->pcm_current+=(n1-n0)/2;
958 for(j=0;j<vi->channels;j++){
960 float *d=v->pcm[j]+n1-n0;
964 v->pcm_returned+=n1-n0;
965 v->pcm_current+=n1-n0;
971 for(i=0;i<vi->channels;i++)
972 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
976 return(n1+n-v->pcm_returned);
980 float *vorbis_window(vorbis_dsp_state *v,int W){
981 vorbis_info *vi=v->vi;
982 codec_setup_info *ci=vi->codec_setup;
983 int hs=ci->halfrate_flag;
984 private_state *b=v->backend_state;
986 if(b->window[W]-1<0)return NULL;
987 return _vorbis_window_get(b->window[W]-hs);