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.75 2003/09/02 04:39:26 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;
173 if(ci==NULL) return 1;
174 hs=ci->halfrate_flag;
176 memset(v,0,sizeof(*v));
177 b=v->backend_state=_ogg_calloc(1,sizeof(*b));
180 b->modebits=ilog2(ci->modes);
182 b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
183 b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
185 /* MDCT is tranform 0 */
187 b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
188 b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
189 mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
190 mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
192 /* Vorbis I uses only window type 0 */
193 b->window[0]=ilog2(ci->blocksizes[0])-6;
194 b->window[1]=ilog2(ci->blocksizes[1])-6;
196 if(encp){ /* encode/decode differ here */
198 /* analysis always needs an fft */
199 drft_init(&b->fft_look[0],ci->blocksizes[0]);
200 drft_init(&b->fft_look[1],ci->blocksizes[1]);
202 /* finish the codebooks */
204 ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
205 for(i=0;i<ci->books;i++)
206 vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
209 b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
210 for(i=0;i<ci->psys;i++){
211 _vp_psy_init(b->psy+i,
214 ci->blocksizes[ci->psy_param[i]->blockflag]/2,
220 /* finish the codebooks */
222 ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
223 for(i=0;i<ci->books;i++){
224 vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
225 /* decode codebooks are now standalone after init */
226 vorbis_staticbook_destroy(ci->book_param[i]);
227 ci->book_param[i]=NULL;
232 /* initialize the storage vectors. blocksize[1] is small for encode,
233 but the correct size for decode */
234 v->pcm_storage=ci->blocksizes[1];
235 v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
236 v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
239 for(i=0;i<vi->channels;i++)
240 v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
243 /* all 1 (large block) or 0 (small block) */
244 /* explicitly set for the sake of clarity */
245 v->lW=0; /* previous window size */
246 v->W=0; /* current window size */
248 /* all vector indexes */
249 v->centerW=ci->blocksizes[1]/2;
251 v->pcm_current=v->centerW;
253 /* initialize all the backend lookups */
254 b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
255 b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
257 for(i=0;i<ci->floors;i++)
258 b->flr[i]=_floor_P[ci->floor_type[i]]->
259 look(v,ci->floor_param[i]);
261 for(i=0;i<ci->residues;i++)
262 b->residue[i]=_residue_P[ci->residue_type[i]]->
263 look(v,ci->residue_param[i]);
268 /* arbitrary settings and spec-mandated numbers get filled in here */
269 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
270 private_state *b=NULL;
272 if(_vds_shared_init(v,vi,1))return 1;
274 b->psy_g_look=_vp_global_look(vi);
276 /* Initialize the envelope state storage */
277 b->ve=_ogg_calloc(1,sizeof(*b->ve));
278 _ve_envelope_init(b->ve,vi);
280 vorbis_bitrate_init(vi,&b->bms);
285 void vorbis_dsp_clear(vorbis_dsp_state *v){
288 vorbis_info *vi=v->vi;
289 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
290 private_state *b=v->backend_state;
295 _ve_envelope_clear(b->ve);
300 mdct_clear(b->transform[0][0]);
301 _ogg_free(b->transform[0][0]);
302 _ogg_free(b->transform[0]);
305 mdct_clear(b->transform[1][0]);
306 _ogg_free(b->transform[1][0]);
307 _ogg_free(b->transform[1]);
311 for(i=0;i<ci->floors;i++)
312 _floor_P[ci->floor_type[i]]->
313 free_look(b->flr[i]);
317 for(i=0;i<ci->residues;i++)
318 _residue_P[ci->residue_type[i]]->
319 free_look(b->residue[i]);
320 _ogg_free(b->residue);
323 for(i=0;i<ci->psys;i++)
324 _vp_psy_clear(b->psy+i);
328 if(b->psy_g_look)_vp_global_free(b->psy_g_look);
329 vorbis_bitrate_clear(&b->bms);
331 drft_clear(&b->fft_look[0]);
332 drft_clear(&b->fft_look[1]);
337 for(i=0;i<vi->channels;i++)
338 if(v->pcm[i])_ogg_free(v->pcm[i]);
340 if(v->pcmret)_ogg_free(v->pcmret);
344 /* free header, header1, header2 */
345 if(b->header)_ogg_free(b->header);
346 if(b->header1)_ogg_free(b->header1);
347 if(b->header2)_ogg_free(b->header2);
351 memset(v,0,sizeof(*v));
355 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
357 vorbis_info *vi=v->vi;
358 private_state *b=v->backend_state;
360 /* free header, header1, header2 */
361 if(b->header)_ogg_free(b->header);b->header=NULL;
362 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
363 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
365 /* Do we have enough storage space for the requested buffer? If not,
366 expand the PCM (and envelope) storage */
368 if(v->pcm_current+vals>=v->pcm_storage){
369 v->pcm_storage=v->pcm_current+vals*2;
371 for(i=0;i<vi->channels;i++){
372 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
376 for(i=0;i<vi->channels;i++)
377 v->pcmret[i]=v->pcm[i]+v->pcm_current;
382 static void _preextrapolate_helper(vorbis_dsp_state *v){
385 float *lpc=alloca(order*sizeof(*lpc));
386 float *work=alloca(v->pcm_current*sizeof(*work));
390 if(v->pcm_current-v->centerW>order*2){ /* safety */
391 for(i=0;i<v->vi->channels;i++){
392 /* need to run the extrapolation in reverse! */
393 for(j=0;j<v->pcm_current;j++)
394 work[j]=v->pcm[i][v->pcm_current-j-1];
397 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
399 /* run the predictor filter */
400 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
402 work+v->pcm_current-v->centerW,
405 for(j=0;j<v->pcm_current;j++)
406 v->pcm[i][v->pcm_current-j-1]=work[j];
413 /* call with val<=0 to set eof */
415 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
416 vorbis_info *vi=v->vi;
417 codec_setup_info *ci=vi->codec_setup;
422 float *lpc=alloca(order*sizeof(*lpc));
424 /* if it wasn't done earlier (very short sample) */
425 if(!v->preextrapolate)
426 _preextrapolate_helper(v);
428 /* We're encoding the end of the stream. Just make sure we have
429 [at least] a few full blocks of zeroes at the end. */
430 /* actually, we don't want zeroes; that could drop a large
431 amplitude off a cliff, creating spread spectrum noise that will
432 suck to encode. Extrapolate for the sake of cleanliness. */
434 vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
435 v->eofflag=v->pcm_current;
436 v->pcm_current+=ci->blocksizes[1]*3;
438 for(i=0;i<vi->channels;i++){
439 if(v->eofflag>order*2){
440 /* extrapolate with LPC to fill in */
443 /* make a predictor filter */
445 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
446 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
448 /* run the predictor filter */
449 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
450 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
452 /* not enough data to extrapolate (unlikely to happen due to
453 guarding the overlap, but bulletproof in case that
454 assumtion goes away). zeroes will do. */
455 memset(v->pcm[i]+v->eofflag,0,
456 (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
462 if(v->pcm_current+vals>v->pcm_storage)
465 v->pcm_current+=vals;
467 /* we may want to reverse extrapolate the beginning of a stream
468 too... in case we're beginning on a cliff! */
469 /* clumsy, but simple. It only runs once, so simple is good. */
470 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
471 _preextrapolate_helper(v);
477 /* do the deltas, envelope shaping, pre-echo and determine the size of
478 the next block on which to continue analysis */
479 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
481 vorbis_info *vi=v->vi;
482 codec_setup_info *ci=vi->codec_setup;
483 private_state *b=v->backend_state;
484 vorbis_look_psy_global *g=b->psy_g_look;
485 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
486 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
488 /* check to see if we're started... */
489 if(!v->preextrapolate)return(0);
491 /* check to see if we're done... */
492 if(v->eofflag==-1)return(0);
494 /* By our invariant, we have lW, W and centerW set. Search for
495 the next boundary so we can determine nW (the next window size)
496 which lets us compute the shape of the current block's window */
498 /* we do an envelope search even on a single blocksize; we may still
499 be throwing more bits at impulses, and envelope search handles
500 marking impulses too. */
502 long bp=_ve_envelope_search(v);
505 if(v->eofflag==0)return(0); /* not enough data currently to search for a
510 if(ci->blocksizes[0]==ci->blocksizes[1])
517 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
520 /* center of next block + next block maximum right side. */
522 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
523 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
524 although this check is
527 the search is not run
534 /* fill in the block. Note that for a short window, lW and nW are *short*
535 regardless of actual settings in the stream */
537 _vorbis_block_ripcord(vb);
543 if(!v->lW || !v->nW){
544 vbi->blocktype=BLOCKTYPE_TRANSITION;
545 /*fprintf(stderr,"-");*/
547 vbi->blocktype=BLOCKTYPE_LONG;
548 /*fprintf(stderr,"_");*/
551 if(_ve_envelope_mark(v)){
552 vbi->blocktype=BLOCKTYPE_IMPULSE;
553 /*fprintf(stderr,"|");*/
556 vbi->blocktype=BLOCKTYPE_PADDING;
557 /*fprintf(stderr,".");*/
563 vb->sequence=v->sequence++;
564 vb->granulepos=v->granulepos;
565 vb->pcmend=ci->blocksizes[v->W];
567 /* copy the vectors; this uses the local storage in vb */
569 /* this tracks 'strongest peak' for later psychoacoustics */
570 /* moved to the global psy state; clean this mess up */
571 if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
572 g->ampmax=_vp_ampmax_decay(g->ampmax,v);
573 vbi->ampmax=g->ampmax;
575 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
576 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
577 for(i=0;i<vi->channels;i++){
579 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
580 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
581 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
583 /* before we added the delay
584 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
585 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
590 /* handle eof detection: eof==0 means that we've not yet received EOF
591 eof>0 marks the last 'real' sample in pcm[]
592 eof<0 'no more to do'; doesn't get here */
595 if(v->centerW>=v->eofflag){
602 /* advance storage vectors and clean up */
604 int new_centerNext=ci->blocksizes[1]/2;
605 int movementW=centerNext-new_centerNext;
609 _ve_envelope_shift(b->ve,movementW);
610 v->pcm_current-=movementW;
612 for(i=0;i<vi->channels;i++)
613 memmove(v->pcm[i],v->pcm[i]+movementW,
614 v->pcm_current*sizeof(*v->pcm[i]));
619 v->centerW=new_centerNext;
622 v->eofflag-=movementW;
623 if(v->eofflag<=0)v->eofflag=-1;
624 /* do not add padding to end of stream! */
625 if(v->centerW>=v->eofflag){
626 v->granulepos+=movementW-(v->centerW-v->eofflag);
628 v->granulepos+=movementW;
631 v->granulepos+=movementW;
640 int vorbis_synthesis_restart(vorbis_dsp_state *v){
641 vorbis_info *vi=v->vi;
642 codec_setup_info *ci;
645 if(!v->backend_state)return -1;
649 hs=ci->halfrate_flag;
651 v->centerW=ci->blocksizes[1]>>(hs+1);
652 v->pcm_current=v->centerW>>hs;
658 ((private_state *)(v->backend_state))->sample_count=-1;
663 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
664 if(_vds_shared_init(v,vi,0)) return 1;
665 vorbis_synthesis_restart(v);
670 /* Unlike in analysis, the window is only partially applied for each
671 block. The time domain envelope is not yet handled at the point of
672 calling (as it relies on the previous block). */
674 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
675 vorbis_info *vi=v->vi;
676 codec_setup_info *ci=vi->codec_setup;
677 private_state *b=v->backend_state;
678 int hs=ci->halfrate_flag;
681 if(!vb)return(OV_EINVAL);
682 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
688 if((v->sequence==-1)||
689 (v->sequence+1 != vb->sequence)){
690 v->granulepos=-1; /* out of sequence; lose count */
694 v->sequence=vb->sequence;
696 if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
697 was called on block */
698 int n=ci->blocksizes[v->W]>>(hs+1);
699 int n0=ci->blocksizes[0]>>(hs+1);
700 int n1=ci->blocksizes[1]>>(hs+1);
705 v->glue_bits+=vb->glue_bits;
706 v->time_bits+=vb->time_bits;
707 v->floor_bits+=vb->floor_bits;
708 v->res_bits+=vb->res_bits;
718 /* v->pcm is now used like a two-stage double buffer. We don't want
719 to have to constantly shift *or* adjust memory usage. Don't
720 accept a new block until the old is shifted out */
722 for(j=0;j<vi->channels;j++){
723 /* the overlap/add section */
727 float *w=_vorbis_window_get(b->window[1]-hs);
728 float *pcm=v->pcm[j]+prevCenter;
731 pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
734 float *w=_vorbis_window_get(b->window[0]-hs);
735 float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
738 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
743 float *w=_vorbis_window_get(b->window[0]-hs);
744 float *pcm=v->pcm[j]+prevCenter;
745 float *p=vb->pcm[j]+n1/2-n0/2;
747 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
748 for(;i<n1/2+n0/2;i++)
752 float *w=_vorbis_window_get(b->window[0]-hs);
753 float *pcm=v->pcm[j]+prevCenter;
756 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
760 /* the copy section */
762 float *pcm=v->pcm[j]+thisCenter;
763 float *p=vb->pcm[j]+n;
774 /* deal with initial packet state; we do this using the explicit
775 pcm_returned==-1 flag otherwise we're sensitive to first block
776 being short or long */
778 if(v->pcm_returned==-1){
779 v->pcm_returned=thisCenter;
780 v->pcm_current=thisCenter;
782 v->pcm_returned=prevCenter;
783 v->pcm_current=prevCenter+
784 ((ci->blocksizes[v->lW]/4+
785 ci->blocksizes[v->W]/4)>>hs);
790 /* track the frame number... This is for convenience, but also
791 making sure our last packet doesn't end with added padding. If
792 the last packet is partial, the number of samples we'll have to
793 return will be past the vb->granulepos.
795 This is not foolproof! It will be confused if we begin
796 decoding at the last page after a seek or hole. In that case,
797 we don't have a starting point to judge where the last frame
798 is. For this reason, vorbisfile will always try to make sure
799 it reads the last two marked pages in proper sequence */
801 if(b->sample_count==-1){
804 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
807 if(v->granulepos==-1){
808 if(vb->granulepos!=-1){ /* only set if we have a position to set to */
810 v->granulepos=vb->granulepos;
812 /* is this a short page? */
813 if(b->sample_count>v->granulepos){
814 /* corner case; if this is both the first and last audio page,
815 then spec says the end is cut, not beginning */
818 /* no preceeding granulepos; assume we started at zero (we'd
819 have to in a short single-page stream) */
820 /* granulepos could be -1 due to a seek, but that would result
821 in a long count, not short count */
823 v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
825 /* trim the beginning */
826 v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
827 if(v->pcm_returned>v->pcm_current)
828 v->pcm_returned=v->pcm_current;
835 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
836 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
838 if(v->granulepos>vb->granulepos){
839 long extra=v->granulepos-vb->granulepos;
843 /* partial last frame. Strip the extra samples off */
844 v->pcm_current-=extra>>hs;
845 } /* else {Shouldn't happen *unless* the bitstream is out of
846 spec. Either way, believe the bitstream } */
847 } /* else {Shouldn't happen *unless* the bitstream is out of
848 spec. Either way, believe the bitstream } */
849 v->granulepos=vb->granulepos;
853 /* Update, cleanup */
855 if(vb->eofflag)v->eofflag=1;
860 /* pcm==NULL indicates we just want the pending samples, no more */
861 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
862 vorbis_info *vi=v->vi;
864 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
867 for(i=0;i<vi->channels;i++)
868 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
871 return(v->pcm_current-v->pcm_returned);
876 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
877 if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
882 /* intended for use with a specific vorbisfile feature; we want access
883 to the [usually synthetic/postextrapolated] buffer and lapping at
884 the end of a decode cycle, specifically, a half-short-block worth.
885 This funtion works like pcmout above, except it will also expose
886 this implicit buffer data not normally decoded. */
887 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
888 vorbis_info *vi=v->vi;
889 codec_setup_info *ci=vi->codec_setup;
890 int hs=ci->halfrate_flag;
892 int n=ci->blocksizes[v->W]>>(hs+1);
893 int n0=ci->blocksizes[0]>>(hs+1);
894 int n1=ci->blocksizes[1]>>(hs+1);
897 if(v->pcm_returned<0)return 0;
899 /* our returned data ends at pcm_returned; because the synthesis pcm
900 buffer is a two-fragment ring, that means our data block may be
901 fragmented by buffering, wrapping or a short block not filling
902 out a buffer. To simplify things, we unfragment if it's at all
903 possibly needed. Otherwise, we'd need to call lapout more than
904 once as well as hold additional dsp state. Opt for
907 /* centerW was advanced by blockin; it would be the center of the
910 /* the data buffer wraps; swap the halves */
911 /* slow, sure, small */
912 for(j=0;j<vi->channels;j++){
926 /* solidify buffer into contiguous space */
928 /* long/short or short/long */
929 for(j=0;j<vi->channels;j++){
931 float *d=v->pcm[j]+(n1-n0)/2;
932 for(i=(n1+n0)/2-1;i>=0;--i)
935 v->pcm_returned+=(n1-n0)/2;
936 v->pcm_current+=(n1-n0)/2;
940 for(j=0;j<vi->channels;j++){
942 float *d=v->pcm[j]+n1-n0;
946 v->pcm_returned+=n1-n0;
947 v->pcm_current+=n1-n0;
953 for(i=0;i<vi->channels;i++)
954 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
958 return(n1+n-v->pcm_returned);
962 float *vorbis_window(vorbis_dsp_state *v,int W){
963 vorbis_info *vi=v->vi;
964 codec_setup_info *ci=vi->codec_setup;
965 int hs=ci->halfrate_flag;
966 private_state *b=v->backend_state;
968 if(b->window[W]-1<0)return NULL;
969 return _vorbis_window_get(b->window[W]-hs);