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.76 2003/12/30 11:02:22 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){
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);
299 void vorbis_dsp_clear(vorbis_dsp_state *v){
302 vorbis_info *vi=v->vi;
303 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
304 private_state *b=v->backend_state;
309 _ve_envelope_clear(b->ve);
314 mdct_clear(b->transform[0][0]);
315 _ogg_free(b->transform[0][0]);
316 _ogg_free(b->transform[0]);
319 mdct_clear(b->transform[1][0]);
320 _ogg_free(b->transform[1][0]);
321 _ogg_free(b->transform[1]);
325 for(i=0;i<ci->floors;i++)
326 _floor_P[ci->floor_type[i]]->
327 free_look(b->flr[i]);
331 for(i=0;i<ci->residues;i++)
332 _residue_P[ci->residue_type[i]]->
333 free_look(b->residue[i]);
334 _ogg_free(b->residue);
337 for(i=0;i<ci->psys;i++)
338 _vp_psy_clear(b->psy+i);
342 if(b->psy_g_look)_vp_global_free(b->psy_g_look);
343 vorbis_bitrate_clear(&b->bms);
345 drft_clear(&b->fft_look[0]);
346 drft_clear(&b->fft_look[1]);
351 for(i=0;i<vi->channels;i++)
352 if(v->pcm[i])_ogg_free(v->pcm[i]);
354 if(v->pcmret)_ogg_free(v->pcmret);
358 /* free header, header1, header2 */
359 if(b->header)_ogg_free(b->header);
360 if(b->header1)_ogg_free(b->header1);
361 if(b->header2)_ogg_free(b->header2);
365 memset(v,0,sizeof(*v));
369 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
371 vorbis_info *vi=v->vi;
372 private_state *b=v->backend_state;
374 /* free header, header1, header2 */
375 if(b->header)_ogg_free(b->header);b->header=NULL;
376 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
377 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
379 /* Do we have enough storage space for the requested buffer? If not,
380 expand the PCM (and envelope) storage */
382 if(v->pcm_current+vals>=v->pcm_storage){
383 v->pcm_storage=v->pcm_current+vals*2;
385 for(i=0;i<vi->channels;i++){
386 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
390 for(i=0;i<vi->channels;i++)
391 v->pcmret[i]=v->pcm[i]+v->pcm_current;
396 static void _preextrapolate_helper(vorbis_dsp_state *v){
399 float *lpc=alloca(order*sizeof(*lpc));
400 float *work=alloca(v->pcm_current*sizeof(*work));
404 if(v->pcm_current-v->centerW>order*2){ /* safety */
405 for(i=0;i<v->vi->channels;i++){
406 /* need to run the extrapolation in reverse! */
407 for(j=0;j<v->pcm_current;j++)
408 work[j]=v->pcm[i][v->pcm_current-j-1];
411 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
413 /* run the predictor filter */
414 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
416 work+v->pcm_current-v->centerW,
419 for(j=0;j<v->pcm_current;j++)
420 v->pcm[i][v->pcm_current-j-1]=work[j];
427 /* call with val<=0 to set eof */
429 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
430 vorbis_info *vi=v->vi;
431 codec_setup_info *ci=vi->codec_setup;
436 float *lpc=alloca(order*sizeof(*lpc));
438 /* if it wasn't done earlier (very short sample) */
439 if(!v->preextrapolate)
440 _preextrapolate_helper(v);
442 /* We're encoding the end of the stream. Just make sure we have
443 [at least] a few full blocks of zeroes at the end. */
444 /* actually, we don't want zeroes; that could drop a large
445 amplitude off a cliff, creating spread spectrum noise that will
446 suck to encode. Extrapolate for the sake of cleanliness. */
448 vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
449 v->eofflag=v->pcm_current;
450 v->pcm_current+=ci->blocksizes[1]*3;
452 for(i=0;i<vi->channels;i++){
453 if(v->eofflag>order*2){
454 /* extrapolate with LPC to fill in */
457 /* make a predictor filter */
459 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
460 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
462 /* run the predictor filter */
463 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
464 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
466 /* not enough data to extrapolate (unlikely to happen due to
467 guarding the overlap, but bulletproof in case that
468 assumtion goes away). zeroes will do. */
469 memset(v->pcm[i]+v->eofflag,0,
470 (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
476 if(v->pcm_current+vals>v->pcm_storage)
479 v->pcm_current+=vals;
481 /* we may want to reverse extrapolate the beginning of a stream
482 too... in case we're beginning on a cliff! */
483 /* clumsy, but simple. It only runs once, so simple is good. */
484 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
485 _preextrapolate_helper(v);
491 /* do the deltas, envelope shaping, pre-echo and determine the size of
492 the next block on which to continue analysis */
493 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
495 vorbis_info *vi=v->vi;
496 codec_setup_info *ci=vi->codec_setup;
497 private_state *b=v->backend_state;
498 vorbis_look_psy_global *g=b->psy_g_look;
499 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
500 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
502 /* check to see if we're started... */
503 if(!v->preextrapolate)return(0);
505 /* check to see if we're done... */
506 if(v->eofflag==-1)return(0);
508 /* By our invariant, we have lW, W and centerW set. Search for
509 the next boundary so we can determine nW (the next window size)
510 which lets us compute the shape of the current block's window */
512 /* we do an envelope search even on a single blocksize; we may still
513 be throwing more bits at impulses, and envelope search handles
514 marking impulses too. */
516 long bp=_ve_envelope_search(v);
519 if(v->eofflag==0)return(0); /* not enough data currently to search for a
524 if(ci->blocksizes[0]==ci->blocksizes[1])
531 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
534 /* center of next block + next block maximum right side. */
536 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
537 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
538 although this check is
541 the search is not run
548 /* fill in the block. Note that for a short window, lW and nW are *short*
549 regardless of actual settings in the stream */
551 _vorbis_block_ripcord(vb);
557 if(!v->lW || !v->nW){
558 vbi->blocktype=BLOCKTYPE_TRANSITION;
559 /*fprintf(stderr,"-");*/
561 vbi->blocktype=BLOCKTYPE_LONG;
562 /*fprintf(stderr,"_");*/
565 if(_ve_envelope_mark(v)){
566 vbi->blocktype=BLOCKTYPE_IMPULSE;
567 /*fprintf(stderr,"|");*/
570 vbi->blocktype=BLOCKTYPE_PADDING;
571 /*fprintf(stderr,".");*/
577 vb->sequence=v->sequence++;
578 vb->granulepos=v->granulepos;
579 vb->pcmend=ci->blocksizes[v->W];
581 /* copy the vectors; this uses the local storage in vb */
583 /* this tracks 'strongest peak' for later psychoacoustics */
584 /* moved to the global psy state; clean this mess up */
585 if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
586 g->ampmax=_vp_ampmax_decay(g->ampmax,v);
587 vbi->ampmax=g->ampmax;
589 vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
590 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
591 for(i=0;i<vi->channels;i++){
593 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
594 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
595 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
597 /* before we added the delay
598 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
599 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
604 /* handle eof detection: eof==0 means that we've not yet received EOF
605 eof>0 marks the last 'real' sample in pcm[]
606 eof<0 'no more to do'; doesn't get here */
609 if(v->centerW>=v->eofflag){
616 /* advance storage vectors and clean up */
618 int new_centerNext=ci->blocksizes[1]/2;
619 int movementW=centerNext-new_centerNext;
623 _ve_envelope_shift(b->ve,movementW);
624 v->pcm_current-=movementW;
626 for(i=0;i<vi->channels;i++)
627 memmove(v->pcm[i],v->pcm[i]+movementW,
628 v->pcm_current*sizeof(*v->pcm[i]));
633 v->centerW=new_centerNext;
636 v->eofflag-=movementW;
637 if(v->eofflag<=0)v->eofflag=-1;
638 /* do not add padding to end of stream! */
639 if(v->centerW>=v->eofflag){
640 v->granulepos+=movementW-(v->centerW-v->eofflag);
642 v->granulepos+=movementW;
645 v->granulepos+=movementW;
654 int vorbis_synthesis_restart(vorbis_dsp_state *v){
655 vorbis_info *vi=v->vi;
656 codec_setup_info *ci;
659 if(!v->backend_state)return -1;
663 hs=ci->halfrate_flag;
665 v->centerW=ci->blocksizes[1]>>(hs+1);
666 v->pcm_current=v->centerW>>hs;
672 ((private_state *)(v->backend_state))->sample_count=-1;
677 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
678 if(_vds_shared_init(v,vi,0)) return 1;
679 vorbis_synthesis_restart(v);
684 /* Unlike in analysis, the window is only partially applied for each
685 block. The time domain envelope is not yet handled at the point of
686 calling (as it relies on the previous block). */
688 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
689 vorbis_info *vi=v->vi;
690 codec_setup_info *ci=vi->codec_setup;
691 private_state *b=v->backend_state;
692 int hs=ci->halfrate_flag;
695 if(!vb)return(OV_EINVAL);
696 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
702 if((v->sequence==-1)||
703 (v->sequence+1 != vb->sequence)){
704 v->granulepos=-1; /* out of sequence; lose count */
708 v->sequence=vb->sequence;
710 if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
711 was called on block */
712 int n=ci->blocksizes[v->W]>>(hs+1);
713 int n0=ci->blocksizes[0]>>(hs+1);
714 int n1=ci->blocksizes[1]>>(hs+1);
719 v->glue_bits+=vb->glue_bits;
720 v->time_bits+=vb->time_bits;
721 v->floor_bits+=vb->floor_bits;
722 v->res_bits+=vb->res_bits;
732 /* v->pcm is now used like a two-stage double buffer. We don't want
733 to have to constantly shift *or* adjust memory usage. Don't
734 accept a new block until the old is shifted out */
736 for(j=0;j<vi->channels;j++){
737 /* the overlap/add section */
741 float *w=_vorbis_window_get(b->window[1]-hs);
742 float *pcm=v->pcm[j]+prevCenter;
745 pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
748 float *w=_vorbis_window_get(b->window[0]-hs);
749 float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
752 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
757 float *w=_vorbis_window_get(b->window[0]-hs);
758 float *pcm=v->pcm[j]+prevCenter;
759 float *p=vb->pcm[j]+n1/2-n0/2;
761 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
762 for(;i<n1/2+n0/2;i++)
766 float *w=_vorbis_window_get(b->window[0]-hs);
767 float *pcm=v->pcm[j]+prevCenter;
770 pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
774 /* the copy section */
776 float *pcm=v->pcm[j]+thisCenter;
777 float *p=vb->pcm[j]+n;
788 /* deal with initial packet state; we do this using the explicit
789 pcm_returned==-1 flag otherwise we're sensitive to first block
790 being short or long */
792 if(v->pcm_returned==-1){
793 v->pcm_returned=thisCenter;
794 v->pcm_current=thisCenter;
796 v->pcm_returned=prevCenter;
797 v->pcm_current=prevCenter+
798 ((ci->blocksizes[v->lW]/4+
799 ci->blocksizes[v->W]/4)>>hs);
804 /* track the frame number... This is for convenience, but also
805 making sure our last packet doesn't end with added padding. If
806 the last packet is partial, the number of samples we'll have to
807 return will be past the vb->granulepos.
809 This is not foolproof! It will be confused if we begin
810 decoding at the last page after a seek or hole. In that case,
811 we don't have a starting point to judge where the last frame
812 is. For this reason, vorbisfile will always try to make sure
813 it reads the last two marked pages in proper sequence */
815 if(b->sample_count==-1){
818 b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
821 if(v->granulepos==-1){
822 if(vb->granulepos!=-1){ /* only set if we have a position to set to */
824 v->granulepos=vb->granulepos;
826 /* is this a short page? */
827 if(b->sample_count>v->granulepos){
828 /* corner case; if this is both the first and last audio page,
829 then spec says the end is cut, not beginning */
832 /* no preceeding granulepos; assume we started at zero (we'd
833 have to in a short single-page stream) */
834 /* granulepos could be -1 due to a seek, but that would result
835 in a long count, not short count */
837 v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
839 /* trim the beginning */
840 v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
841 if(v->pcm_returned>v->pcm_current)
842 v->pcm_returned=v->pcm_current;
849 v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
850 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
852 if(v->granulepos>vb->granulepos){
853 long extra=v->granulepos-vb->granulepos;
857 /* partial last frame. Strip the extra samples off */
858 v->pcm_current-=extra>>hs;
859 } /* else {Shouldn't happen *unless* the bitstream is out of
860 spec. Either way, believe the bitstream } */
861 } /* else {Shouldn't happen *unless* the bitstream is out of
862 spec. Either way, believe the bitstream } */
863 v->granulepos=vb->granulepos;
867 /* Update, cleanup */
869 if(vb->eofflag)v->eofflag=1;
874 /* pcm==NULL indicates we just want the pending samples, no more */
875 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
876 vorbis_info *vi=v->vi;
878 if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
881 for(i=0;i<vi->channels;i++)
882 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
885 return(v->pcm_current-v->pcm_returned);
890 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
891 if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
896 /* intended for use with a specific vorbisfile feature; we want access
897 to the [usually synthetic/postextrapolated] buffer and lapping at
898 the end of a decode cycle, specifically, a half-short-block worth.
899 This funtion works like pcmout above, except it will also expose
900 this implicit buffer data not normally decoded. */
901 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
902 vorbis_info *vi=v->vi;
903 codec_setup_info *ci=vi->codec_setup;
904 int hs=ci->halfrate_flag;
906 int n=ci->blocksizes[v->W]>>(hs+1);
907 int n0=ci->blocksizes[0]>>(hs+1);
908 int n1=ci->blocksizes[1]>>(hs+1);
911 if(v->pcm_returned<0)return 0;
913 /* our returned data ends at pcm_returned; because the synthesis pcm
914 buffer is a two-fragment ring, that means our data block may be
915 fragmented by buffering, wrapping or a short block not filling
916 out a buffer. To simplify things, we unfragment if it's at all
917 possibly needed. Otherwise, we'd need to call lapout more than
918 once as well as hold additional dsp state. Opt for
921 /* centerW was advanced by blockin; it would be the center of the
924 /* the data buffer wraps; swap the halves */
925 /* slow, sure, small */
926 for(j=0;j<vi->channels;j++){
940 /* solidify buffer into contiguous space */
942 /* long/short or short/long */
943 for(j=0;j<vi->channels;j++){
945 float *d=v->pcm[j]+(n1-n0)/2;
946 for(i=(n1+n0)/2-1;i>=0;--i)
949 v->pcm_returned+=(n1-n0)/2;
950 v->pcm_current+=(n1-n0)/2;
954 for(j=0;j<vi->channels;j++){
956 float *d=v->pcm[j]+n1-n0;
960 v->pcm_returned+=n1-n0;
961 v->pcm_current+=n1-n0;
967 for(i=0;i<vi->channels;i++)
968 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
972 return(n1+n-v->pcm_returned);
976 float *vorbis_window(vorbis_dsp_state *v,int W){
977 vorbis_info *vi=v->vi;
978 codec_setup_info *ci=vi->codec_setup;
979 int hs=ci->halfrate_flag;
980 private_state *b=v->backend_state;
982 if(b->window[W]-1<0)return NULL;
983 return _vorbis_window_get(b->window[W]-hs);