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
14 last mod: $Id: block.c,v 1.73 2003/08/18 05:34:01 xiphmont Exp $
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){
89 memset(vb,0,sizeof(*vb));
94 vorbis_block_internal *vbi=
95 vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
96 oggpack_writeinit(&vb->opb);
103 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
104 bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
105 if(bytes+vb->localtop>vb->localalloc){
106 /* can't just _ogg_realloc... there are outstanding pointers */
108 struct alloc_chain *link=_ogg_malloc(sizeof(*link));
109 vb->totaluse+=vb->localtop;
111 link->ptr=vb->localstore;
114 /* highly conservative */
115 vb->localalloc=bytes;
116 vb->localstore=_ogg_malloc(vb->localalloc);
120 void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
126 /* reap the chain, pull the ripcord */
127 void _vorbis_block_ripcord(vorbis_block *vb){
129 struct alloc_chain *reap=vb->reap;
131 struct alloc_chain *next=reap->next;
132 _ogg_free(reap->ptr);
133 memset(reap,0,sizeof(*reap));
137 /* consolidate storage */
139 vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
140 vb->localalloc+=vb->totaluse;
144 /* pull the ripcord */
149 int vorbis_block_clear(vorbis_block *vb){
151 if(vb->vd->analysisp)
152 oggpack_writeclear(&vb->opb);
153 _vorbis_block_ripcord(vb);
154 if(vb->localstore)_ogg_free(vb->localstore);
157 _ogg_free(vb->internal);
159 memset(vb,0,sizeof(*vb));
163 /* Analysis side code, but directly related to blocking. Thus it's
164 here and not in analysis.c (which is for analysis transforms only).
165 The init is here because some of it is shared */
167 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
169 codec_setup_info *ci=vi->codec_setup;
170 private_state *b=NULL;
171 int hs=ci->halfrate_flag;
173 memset(v,0,sizeof(*v));
174 b=v->backend_state=_ogg_calloc(1,sizeof(*b));
177 b->modebits=ilog2(ci->modes);
179 b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
180 b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
182 /* MDCT is tranform 0 */
184 b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
185 b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
186 mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
187 mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
189 /* Vorbis I uses only window type 0 */
190 b->window[0]=ilog2(ci->blocksizes[0])-6;
191 b->window[1]=ilog2(ci->blocksizes[1])-6;
193 if(encp){ /* encode/decode differ here */
195 /* analysis always needs an fft */
196 drft_init(&b->fft_look[0],ci->blocksizes[0]);
197 drft_init(&b->fft_look[1],ci->blocksizes[1]);
199 /* finish the codebooks */
201 ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
202 for(i=0;i<ci->books;i++)
203 vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
206 b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
207 for(i=0;i<ci->psys;i++){
208 _vp_psy_init(b->psy+i,
211 ci->blocksizes[ci->psy_param[i]->blockflag]/2,
217 /* finish the codebooks */
219 ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
220 for(i=0;i<ci->books;i++){
221 vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
222 /* decode codebooks are now standalone after init */
223 vorbis_staticbook_destroy(ci->book_param[i]);
224 ci->book_param[i]=NULL;
229 /* initialize the storage vectors. blocksize[1] is small for encode,
230 but the correct size for decode */
231 v->pcm_storage=ci->blocksizes[1];
232 v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
233 v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
236 for(i=0;i<vi->channels;i++)
237 v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
240 /* all 1 (large block) or 0 (small block) */
241 /* explicitly set for the sake of clarity */
242 v->lW=0; /* previous window size */
243 v->W=0; /* current window size */
245 /* all vector indexes */
246 v->centerW=ci->blocksizes[1]/2;
248 v->pcm_current=v->centerW;
250 /* initialize all the backend lookups */
251 b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
252 b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
254 for(i=0;i<ci->floors;i++)
255 b->flr[i]=_floor_P[ci->floor_type[i]]->
256 look(v,ci->floor_param[i]);
258 for(i=0;i<ci->residues;i++)
259 b->residue[i]=_residue_P[ci->residue_type[i]]->
260 look(v,ci->residue_param[i]);
265 /* arbitrary settings and spec-mandated numbers get filled in here */
266 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
267 private_state *b=NULL;
269 _vds_shared_init(v,vi,1);
271 b->psy_g_look=_vp_global_look(vi);
273 /* Initialize the envelope state storage */
274 b->ve=_ogg_calloc(1,sizeof(*b->ve));
275 _ve_envelope_init(b->ve,vi);
277 vorbis_bitrate_init(vi,&b->bms);
282 void vorbis_dsp_clear(vorbis_dsp_state *v){
285 vorbis_info *vi=v->vi;
286 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
287 private_state *b=v->backend_state;
292 _ve_envelope_clear(b->ve);
297 mdct_clear(b->transform[0][0]);
298 _ogg_free(b->transform[0][0]);
299 _ogg_free(b->transform[0]);
302 mdct_clear(b->transform[1][0]);
303 _ogg_free(b->transform[1][0]);
304 _ogg_free(b->transform[1]);
308 for(i=0;i<ci->floors;i++)
309 _floor_P[ci->floor_type[i]]->
310 free_look(b->flr[i]);
314 for(i=0;i<ci->residues;i++)
315 _residue_P[ci->residue_type[i]]->
316 free_look(b->residue[i]);
317 _ogg_free(b->residue);
320 for(i=0;i<ci->psys;i++)
321 _vp_psy_clear(b->psy+i);
325 if(b->psy_g_look)_vp_global_free(b->psy_g_look);
326 vorbis_bitrate_clear(&b->bms);
328 drft_clear(&b->fft_look[0]);
329 drft_clear(&b->fft_look[1]);
334 for(i=0;i<vi->channels;i++)
335 if(v->pcm[i])_ogg_free(v->pcm[i]);
337 if(v->pcmret)_ogg_free(v->pcmret);
341 /* free header, header1, header2 */
342 if(b->header)_ogg_free(b->header);
343 if(b->header1)_ogg_free(b->header1);
344 if(b->header2)_ogg_free(b->header2);
348 memset(v,0,sizeof(*v));
352 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
354 vorbis_info *vi=v->vi;
355 private_state *b=v->backend_state;
357 /* free header, header1, header2 */
358 if(b->header)_ogg_free(b->header);b->header=NULL;
359 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
360 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
362 /* Do we have enough storage space for the requested buffer? If not,
363 expand the PCM (and envelope) storage */
365 if(v->pcm_current+vals>=v->pcm_storage){
366 v->pcm_storage=v->pcm_current+vals*2;
368 for(i=0;i<vi->channels;i++){
369 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
373 for(i=0;i<vi->channels;i++)
374 v->pcmret[i]=v->pcm[i]+v->pcm_current;
379 static void _preextrapolate_helper(vorbis_dsp_state *v){
382 float *lpc=alloca(order*sizeof(*lpc));
383 float *work=alloca(v->pcm_current*sizeof(*work));
387 if(v->pcm_current-v->centerW>order*2){ /* safety */
388 for(i=0;i<v->vi->channels;i++){
389 /* need to run the extrapolation in reverse! */
390 for(j=0;j<v->pcm_current;j++)
391 work[j]=v->pcm[i][v->pcm_current-j-1];
394 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
396 /* run the predictor filter */
397 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
399 work+v->pcm_current-v->centerW,
402 for(j=0;j<v->pcm_current;j++)
403 v->pcm[i][v->pcm_current-j-1]=work[j];
410 /* call with val<=0 to set eof */
412 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
413 vorbis_info *vi=v->vi;
414 codec_setup_info *ci=vi->codec_setup;
419 float *lpc=alloca(order*sizeof(*lpc));
421 /* if it wasn't done earlier (very short sample) */
422 if(!v->preextrapolate)
423 _preextrapolate_helper(v);
425 /* We're encoding the end of the stream. Just make sure we have
426 [at least] a few full blocks of zeroes at the end. */
427 /* actually, we don't want zeroes; that could drop a large
428 amplitude off a cliff, creating spread spectrum noise that will
429 suck to encode. Extrapolate for the sake of cleanliness. */
431 vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
432 v->eofflag=v->pcm_current;
433 v->pcm_current+=ci->blocksizes[1]*3;
435 for(i=0;i<vi->channels;i++){
436 if(v->eofflag>order*2){
437 /* extrapolate with LPC to fill in */
440 /* make a predictor filter */
442 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
443 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
445 /* run the predictor filter */
446 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
447 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
449 /* not enough data to extrapolate (unlikely to happen due to
450 guarding the overlap, but bulletproof in case that
451 assumtion goes away). zeroes will do. */
452 memset(v->pcm[i]+v->eofflag,0,
453 (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
459 if(v->pcm_current+vals>v->pcm_storage)
462 v->pcm_current+=vals;
464 /* we may want to reverse extrapolate the beginning of a stream
465 too... in case we're beginning on a cliff! */
466 /* clumsy, but simple. It only runs once, so simple is good. */
467 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
468 _preextrapolate_helper(v);
474 /* do the deltas, envelope shaping, pre-echo and determine the size of
475 the next block on which to continue analysis */
476 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
478 vorbis_info *vi=v->vi;
479 codec_setup_info *ci=vi->codec_setup;
480 private_state *b=v->backend_state;
481 vorbis_look_psy_global *g=b->psy_g_look;
482 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
483 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
485 /* check to see if we're started... */
486 if(!v->preextrapolate)return(0);
488 /* check to see if we're done... */
489 if(v->eofflag==-1)return(0);
491 /* By our invariant, we have lW, W and centerW set. Search for
492 the next boundary so we can determine nW (the next window size)
493 which lets us compute the shape of the current block's window */
495 /* we do an envelope search even on a single blocksize; we may still
496 be throwing more bits at impulses, and envelope search handles
497 marking impulses too. */
499 long bp=_ve_envelope_search(v);
502 if(v->eofflag==0)return(0); /* not enough data currently to search for a
507 if(ci->blocksizes[0]==ci->blocksizes[1])
514 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
517 /* center of next block + next block maximum right side. */
519 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
520 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
521 although this check is
524 the search is not run
531 /* fill in the block. Note that for a short window, lW and nW are *short*
532 regardless of actual settings in the stream */
534 _vorbis_block_ripcord(vb);
540 if(!v->lW || !v->nW){
541 vbi->blocktype=BLOCKTYPE_TRANSITION;
542 /*fprintf(stderr,"-");*/
544 vbi->blocktype=BLOCKTYPE_LONG;
545 /*fprintf(stderr,"_");*/
548 if(_ve_envelope_mark(v)){
549 vbi->blocktype=BLOCKTYPE_IMPULSE;
550 /*fprintf(stderr,"|");*/
553 vbi->blocktype=BLOCKTYPE_PADDING;
554 /*fprintf(stderr,".");*/
560 vb->sequence=v->sequence++;
561 vb->granulepos=v->granulepos;
562 vb->pcmend=ci->blocksizes[v->W];
564 /* copy the vectors; this uses the local storage in vb */
566 /* this tracks 'strongest peak' for later psychoacoustics */
567 /* moved to the global psy state; clean this mess up */
568 if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
569 g->ampmax=_vp_ampmax_decay(g->ampmax,v);
570 vbi->ampmax=g->ampmax;
572 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
573 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
574 for(i=0;i<vi->channels;i++){
576 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
577 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
578 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
580 /* before we added the delay
581 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
582 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
587 /* handle eof detection: eof==0 means that we've not yet received EOF
588 eof>0 marks the last 'real' sample in pcm[]
589 eof<0 'no more to do'; doesn't get here */
592 if(v->centerW>=v->eofflag){
599 /* advance storage vectors and clean up */
601 int new_centerNext=ci->blocksizes[1]/2;
602 int movementW=centerNext-new_centerNext;
606 _ve_envelope_shift(b->ve,movementW);
607 v->pcm_current-=movementW;
609 for(i=0;i<vi->channels;i++)
610 memmove(v->pcm[i],v->pcm[i]+movementW,
611 v->pcm_current*sizeof(*v->pcm[i]));
616 v->centerW=new_centerNext;
619 v->eofflag-=movementW;
620 if(v->eofflag<=0)v->eofflag=-1;
621 /* do not add padding to end of stream! */
622 if(v->centerW>=v->eofflag){
623 v->granulepos+=movementW-(v->centerW-v->eofflag);
625 v->granulepos+=movementW;
628 v->granulepos+=movementW;
637 int vorbis_synthesis_restart(vorbis_dsp_state *v){
638 vorbis_info *vi=v->vi;
639 codec_setup_info *ci;
642 if(!v->backend_state)return -1;
646 hs=ci->halfrate_flag;
648 v->centerW=ci->blocksizes[1]>>(hs+1);
649 v->pcm_current=v->centerW>>hs;
655 ((private_state *)(v->backend_state))->sample_count=-1;
660 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
661 _vds_shared_init(v,vi,0);
662 vorbis_synthesis_restart(v);
667 /* Unlike in analysis, the window is only partially applied for each
668 block. The time domain envelope is not yet handled at the point of
669 calling (as it relies on the previous block). */
671 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
672 vorbis_info *vi=v->vi;
673 codec_setup_info *ci=vi->codec_setup;
674 private_state *b=v->backend_state;
675 int hs=ci->halfrate_flag;
678 if(!vb)return(OV_EINVAL);
679 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
685 if((v->sequence==-1)||
686 (v->sequence+1 != vb->sequence)){
687 v->granulepos=-1; /* out of sequence; lose count */
691 v->sequence=vb->sequence;
693 if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
694 was called on block */
695 int n=ci->blocksizes[v->W]>>(hs+1);
696 int n0=ci->blocksizes[0]>>(hs+1);
697 int n1=ci->blocksizes[1]>>(hs+1);
702 v->glue_bits+=vb->glue_bits;
703 v->time_bits+=vb->time_bits;
704 v->floor_bits+=vb->floor_bits;
705 v->res_bits+=vb->res_bits;
715 /* v->pcm is now used like a two-stage double buffer. We don't want
716 to have to constantly shift *or* adjust memory usage. Don't
717 accept a new block until the old is shifted out */
719 for(j=0;j<vi->channels;j++){
720 /* the overlap/add section */
724 float *w=_vorbis_window_get(b->window[1]-hs);
725 float *pcm=v->pcm[j]+prevCenter;
728 pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
731 float *w=_vorbis_window_get(b->window[0]-hs);
732 float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
735 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
740 float *w=_vorbis_window_get(b->window[0]-hs);
741 float *pcm=v->pcm[j]+prevCenter;
742 float *p=vb->pcm[j]+n1/2-n0/2;
744 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
745 for(;i<n1/2+n0/2;i++)
749 float *w=_vorbis_window_get(b->window[0]-hs);
750 float *pcm=v->pcm[j]+prevCenter;
753 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
757 /* the copy section */
759 float *pcm=v->pcm[j]+thisCenter;
760 float *p=vb->pcm[j]+n;
771 /* deal with initial packet state; we do this using the explicit
772 pcm_returned==-1 flag otherwise we're sensitive to first block
773 being short or long */
775 if(v->pcm_returned==-1){
776 v->pcm_returned=thisCenter;
777 v->pcm_current=thisCenter;
779 v->pcm_returned=prevCenter;
780 v->pcm_current=prevCenter+
781 ((ci->blocksizes[v->lW]/4+
782 ci->blocksizes[v->W]/4)>>hs);
787 /* track the frame number... This is for convenience, but also
788 making sure our last packet doesn't end with added padding. If
789 the last packet is partial, the number of samples we'll have to
790 return will be past the vb->granulepos.
792 This is not foolproof! It will be confused if we begin
793 decoding at the last page after a seek or hole. In that case,
794 we don't have a starting point to judge where the last frame
795 is. For this reason, vorbisfile will always try to make sure
796 it reads the last two marked pages in proper sequence */
798 if(b->sample_count==-1){
801 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
804 if(v->granulepos==-1){
805 if(vb->granulepos!=-1){ /* only set if we have a position to set to */
807 v->granulepos=vb->granulepos;
809 /* is this a short page? */
810 if(b->sample_count>v->granulepos){
811 /* corner case; if this is both the first and last audio page,
812 then spec says the end is cut, not beginning */
815 /* no preceeding granulepos; assume we started at zero (we'd
816 have to in a short single-page stream) */
817 /* granulepos could be -1 due to a seek, but that would result
818 in a long count, not short count */
820 v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
822 /* trim the beginning */
823 v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
824 if(v->pcm_returned>v->pcm_current)
825 v->pcm_returned=v->pcm_current;
832 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
833 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
835 if(v->granulepos>vb->granulepos){
836 long extra=v->granulepos-vb->granulepos;
840 /* partial last frame. Strip the extra samples off */
841 v->pcm_current-=extra>>hs;
842 } /* else {Shouldn't happen *unless* the bitstream is out of
843 spec. Either way, believe the bitstream } */
844 } /* else {Shouldn't happen *unless* the bitstream is out of
845 spec. Either way, believe the bitstream } */
846 v->granulepos=vb->granulepos;
850 /* Update, cleanup */
852 if(vb->eofflag)v->eofflag=1;
857 /* pcm==NULL indicates we just want the pending samples, no more */
858 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
859 vorbis_info *vi=v->vi;
861 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
864 for(i=0;i<vi->channels;i++)
865 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
868 return(v->pcm_current-v->pcm_returned);
873 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
874 if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
879 /* intended for use with a specific vorbisfile feature; we want access
880 to the [usually synthetic/postextrapolated] buffer and lapping at
881 the end of a decode cycle, specifically, a half-short-block worth.
882 This funtion works like pcmout above, except it will also expose
883 this implicit buffer data not normally decoded. */
884 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
885 vorbis_info *vi=v->vi;
886 codec_setup_info *ci=vi->codec_setup;
887 int hs=ci->halfrate_flag;
889 int n=ci->blocksizes[v->W]>>(hs+1);
890 int n0=ci->blocksizes[0]>>(hs+1);
891 int n1=ci->blocksizes[1]>>(hs+1);
894 if(v->pcm_returned<0)return 0;
896 /* our returned data ends at pcm_returned; because the synthesis pcm
897 buffer is a two-fragment ring, that means our data block may be
898 fragmented by buffering, wrapping or a short block not filling
899 out a buffer. To simplify things, we unfragment if it's at all
900 possibly needed. Otherwise, we'd need to call lapout more than
901 once as well as hold additional dsp state. Opt for
904 /* centerW was advanced by blockin; it would be the center of the
907 /* the data buffer wraps; swap the halves */
908 /* slow, sure, small */
909 for(j=0;j<vi->channels;j++){
923 /* solidify buffer into contiguous space */
925 /* long/short or short/long */
926 for(j=0;j<vi->channels;j++){
928 float *d=v->pcm[j]+(n1-n0)/2;
929 for(i=(n1+n0)/2-1;i>=0;--i)
932 v->pcm_returned+=(n1-n0)/2;
933 v->pcm_current+=(n1-n0)/2;
937 for(j=0;j<vi->channels;j++){
939 float *d=v->pcm[j]+n1-n0;
943 v->pcm_returned+=n1-n0;
944 v->pcm_current+=n1-n0;
950 for(i=0;i<vi->channels;i++)
951 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
955 return(n1+n-v->pcm_returned);
959 float *vorbis_window(vorbis_dsp_state *v,int W){
960 private_state *b=v->backend_state;
961 return _vorbis_window_get(b->window[W]);