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-2001 *
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.47 2001/03/26 23:27:42 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"
38 static int ilog2(unsigned int v){
47 /* pcm accumulator examples (not exhaustive):
49 <-------------- lW ---------------->
50 <--------------- W ---------------->
51 : .....|..... _______________ |
52 : .''' | '''_--- | |\ |
53 :.....''' |_____--- '''......| | \_______|
54 :.................|__________________|_______|__|______|
55 |<------ Sl ------>| > Sr < |endW
56 |beginSl |endSl | |endSr
57 |beginW |endlW |beginSr
61 <--------------- W ---------------->
62 | | .. ______________ |
64 |___.'___/`. | ---_____|
65 |_______|__|_______|_________________|
66 | >|Sl|< |<------ Sr ----->|endW
67 | | |endSl |beginSr |endSr
69 mult[0] |beginSl mult[n]
71 <-------------- lW ----------------->
73 : .............. ___ | |
75 :.....''' |/`....\|...|
76 :.........................|___|___|___|
85 /* block abstraction setup *********************************************/
91 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
92 memset(vb,0,sizeof(vorbis_block));
97 oggpack_writeinit(&vb->opb);
98 vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
99 ((vorbis_block_internal *)vb->internal)->ampmax=-9999;
105 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
106 bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
107 if(bytes+vb->localtop>vb->localalloc){
108 /* can't just _ogg_realloc... there are outstanding pointers */
110 struct alloc_chain *link=_ogg_malloc(sizeof(struct alloc_chain));
111 vb->totaluse+=vb->localtop;
113 link->ptr=vb->localstore;
116 /* highly conservative */
117 vb->localalloc=bytes;
118 vb->localstore=_ogg_malloc(vb->localalloc);
122 void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
128 /* reap the chain, pull the ripcord */
129 void _vorbis_block_ripcord(vorbis_block *vb){
131 struct alloc_chain *reap=vb->reap;
133 struct alloc_chain *next=reap->next;
134 _ogg_free(reap->ptr);
135 memset(reap,0,sizeof(struct alloc_chain));
139 /* consolidate storage */
141 vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
142 vb->localalloc+=vb->totaluse;
146 /* pull the ripcord */
151 int vorbis_block_clear(vorbis_block *vb){
153 if(vb->vd->analysisp)
154 oggpack_writeclear(&vb->opb);
155 _vorbis_block_ripcord(vb);
156 if(vb->localstore)_ogg_free(vb->localstore);
157 if(vb->internal)_ogg_free(vb->internal);
159 memset(vb,0,sizeof(vorbis_block));
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 backend_lookup_state *b=NULL;
172 memset(v,0,sizeof(vorbis_dsp_state));
173 b=v->backend_state=_ogg_calloc(1,sizeof(backend_lookup_state));
176 b->modebits=ilog2(ci->modes);
179 b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
180 b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
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]);
187 mdct_init(b->transform[1][0],ci->blocksizes[1]);
189 b->window[0][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
190 b->window[0][0][1]=b->window[0][0][0];
191 b->window[0][1][0]=b->window[0][0][0];
192 b->window[0][1][1]=b->window[0][0][0];
193 b->window[1][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
194 b->window[1][0][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
195 b->window[1][1][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
196 b->window[1][1][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
198 for(i=0;i<VI_WINDOWB;i++){
199 b->window[0][0][0][i]=
200 _vorbis_window(i,ci->blocksizes[0],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
201 b->window[1][0][0][i]=
202 _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
203 b->window[1][0][1][i]=
204 _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[1]/2);
205 b->window[1][1][0][i]=
206 _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[0]/2);
207 b->window[1][1][1][i]=
208 _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[1]/2);
211 if(encp){ /* encode/decode differ here */
212 /* finish the codebooks */
213 b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
214 for(i=0;i<ci->books;i++)
215 vorbis_book_init_encode(b->fullbooks+i,ci->book_param[i]);
218 /* finish the codebooks */
219 b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
220 for(i=0;i<ci->books;i++)
221 vorbis_book_init_decode(b->fullbooks+i,ci->book_param[i]);
224 /* initialize the storage vectors to a decent size greater than the
227 v->pcm_storage=8192; /* we'll assume later that we have
228 a minimum of twice the blocksize of
229 accumulated samples in analysis */
230 v->pcm=_ogg_malloc(vi->channels*sizeof(float *));
231 v->pcmret=_ogg_malloc(vi->channels*sizeof(float *));
234 for(i=0;i<vi->channels;i++)
235 v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(float));
238 /* all 1 (large block) or 0 (small block) */
239 /* explicitly set for the sake of clarity */
240 v->lW=0; /* previous window size */
241 v->W=0; /* current window size */
243 /* all vector indexes */
244 v->centerW=ci->blocksizes[1]/2;
246 v->pcm_current=v->centerW;
248 /* initialize all the mapping/backend lookups */
249 b->mode=_ogg_calloc(ci->modes,sizeof(vorbis_look_mapping *));
250 for(i=0;i<ci->modes;i++){
251 int mapnum=ci->mode_param[i]->mapping;
252 int maptype=ci->map_type[mapnum];
253 b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
254 ci->map_param[mapnum]);
260 /* arbitrary settings and spec-mandated numbers get filled in here */
261 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
262 backend_lookup_state *b=NULL;
264 _vds_shared_init(v,vi,1);
267 /* Initialize the envelope state storage */
268 b->ve=_ogg_calloc(1,sizeof(envelope_lookup));
269 _ve_envelope_init(b->ve,vi);
274 void vorbis_dsp_clear(vorbis_dsp_state *v){
277 vorbis_info *vi=v->vi;
278 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
279 backend_lookup_state *b=v->backend_state;
282 if(b->window[0][0][0]){
283 for(i=0;i<VI_WINDOWB;i++)
284 if(b->window[0][0][0][i])_ogg_free(b->window[0][0][0][i]);
285 _ogg_free(b->window[0][0][0]);
289 for(i=0;i<VI_WINDOWB;i++)
290 if(b->window[1][j][k][i])_ogg_free(b->window[1][j][k][i]);
291 _ogg_free(b->window[1][j][k]);
296 _ve_envelope_clear(b->ve);
301 mdct_clear(b->transform[0][0]);
302 _ogg_free(b->transform[0][0]);
303 _ogg_free(b->transform[0]);
306 mdct_clear(b->transform[1][0]);
307 _ogg_free(b->transform[1][0]);
308 _ogg_free(b->transform[1]);
314 for(i=0;i<vi->channels;i++)
315 if(v->pcm[i])_ogg_free(v->pcm[i]);
317 if(v->pcmret)_ogg_free(v->pcmret);
320 /* free mode lookups; these are actually vorbis_look_mapping structs */
322 for(i=0;i<ci->modes;i++){
323 int mapnum=ci->mode_param[i]->mapping;
324 int maptype=ci->map_type[mapnum];
325 if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
328 for(i=0;i<ci->books;i++)
329 if(b && b->fullbooks)vorbis_book_clear(b->fullbooks+i);
333 if(b->mode)_ogg_free(b->mode);
334 if(b->fullbooks)_ogg_free(b->fullbooks);
336 /* free header, header1, header2 */
337 if(b->header)_ogg_free(b->header);
338 if(b->header1)_ogg_free(b->header1);
339 if(b->header2)_ogg_free(b->header2);
343 memset(v,0,sizeof(vorbis_dsp_state));
347 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
349 vorbis_info *vi=v->vi;
350 backend_lookup_state *b=v->backend_state;
352 /* free header, header1, header2 */
353 if(b->header)_ogg_free(b->header);b->header=NULL;
354 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
355 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
357 /* Do we have enough storage space for the requested buffer? If not,
358 expand the PCM (and envelope) storage */
360 if(v->pcm_current+vals>=v->pcm_storage){
361 v->pcm_storage=v->pcm_current+vals*2;
363 for(i=0;i<vi->channels;i++){
364 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float));
368 for(i=0;i<vi->channels;i++)
369 v->pcmret[i]=v->pcm[i]+v->pcm_current;
374 static void _preextrapolate_helper(vorbis_dsp_state *v){
377 float *lpc=alloca(order*sizeof(float));
378 float *work=alloca(v->pcm_current*sizeof(float));
382 if(v->pcm_current-v->centerW>order*2){ /* safety */
383 for(i=0;i<v->vi->channels;i++){
385 /* need to run the extrapolation in reverse! */
386 for(j=0;j<v->pcm_current;j++)
387 work[j]=v->pcm[i][v->pcm_current-j-1];
390 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
392 /* run the predictor filter */
393 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
395 work+v->pcm_current-v->centerW,
397 for(j=0;j<v->pcm_current;j++)
398 v->pcm[i][v->pcm_current-j-1]=work[j];
404 /* call with val<=0 to set eof */
406 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
407 vorbis_info *vi=v->vi;
408 codec_setup_info *ci=vi->codec_setup;
413 float *lpc=alloca(order*sizeof(float));
415 /* if it wasn't done earlier (very short sample) */
416 if(!v->preextrapolate)
417 _preextrapolate_helper(v);
419 /* We're encoding the end of the stream. Just make sure we have
420 [at least] a full block of zeroes at the end. */
421 /* actually, we don't want zeroes; that could drop a large
422 amplitude off a cliff, creating spread spectrum noise that will
423 suck to encode. Extrapolate for the sake of cleanliness. */
425 vorbis_analysis_buffer(v,ci->blocksizes[1]*2);
426 v->eofflag=v->pcm_current;
427 v->pcm_current+=ci->blocksizes[1]*2;
429 for(i=0;i<vi->channels;i++){
430 if(v->eofflag>order*2){
431 /* extrapolate with LPC to fill in */
434 /* make a predictor filter */
436 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
437 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
439 /* run the predictor filter */
440 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
441 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
443 /* not enough data to extrapolate (unlikely to happen due to
444 guarding the overlap, but bulletproof in case that
445 assumtion goes away). zeroes will do. */
446 memset(v->pcm[i]+v->eofflag,0,
447 (v->pcm_current-v->eofflag)*sizeof(float));
453 if(v->pcm_current+vals>v->pcm_storage)
456 v->pcm_current+=vals;
458 /* we may want to reverse extrapolate the beginning of a stream
459 too... in case we're beginning on a cliff! */
460 /* clumsy, but simple. It only runs once, so simple is good. */
461 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
462 _preextrapolate_helper(v);
468 /* do the deltas, envelope shaping, pre-echo and determine the size of
469 the next block on which to continue analysis */
470 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
472 vorbis_info *vi=v->vi;
473 codec_setup_info *ci=vi->codec_setup;
474 backend_lookup_state *b=v->backend_state;
475 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
477 /* check to see if we're started... */
478 if(!v->preextrapolate)return(0);
480 /* check to see if we're done... */
481 if(v->eofflag==-1)return(0);
483 /* By our invariant, we have lW, W and centerW set. Search for
484 the next boundary so we can determine nW (the next window size)
485 which lets us compute the shape of the current block's window */
487 if(ci->blocksizes[0]<ci->blocksizes[1]){
492 /* min boundary; nW large, next small */
493 largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]/4;
495 /* min boundary; nW large, next small */
496 largebound=v->centerW+ci->blocksizes[1]/2+ci->blocksizes[0]/2;
498 bp=_ve_envelope_search(v,largebound);
499 if(bp==-1)return(0); /* not enough data currently to search for a
506 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
509 /* center of next block + next block maximum right side. */
511 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
512 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
513 although this check is
516 the search is not run
521 /* fill in the block. Note that for a short window, lW and nW are *short*
522 regardless of actual settings in the stream */
524 _vorbis_block_ripcord(vb);
535 vb->sequence=v->sequence;
536 vb->granulepos=v->granulepos;
537 vb->pcmend=ci->blocksizes[v->W];
540 /* copy the vectors; this uses the local storage in vb */
542 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
544 /* this tracks 'strongest peak' for later psychoacoustics */
545 if(vbi->ampmax>b->ampmax)b->ampmax=vbi->ampmax;
546 b->ampmax=_vp_ampmax_decay(b->ampmax,v);
547 vbi->ampmax=b->ampmax;
549 vb->pcm=_vorbis_block_alloc(vb,sizeof(float *)*vi->channels);
550 vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(float *)*vi->channels);
551 for(i=0;i<vi->channels;i++){
553 _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(float));
554 memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(float));
555 vb->pcm[i]=vbi->pcmdelay[i]+beginW;
557 /* before we added the delay
558 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(float));
559 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(float));
565 /* handle eof detection: eof==0 means that we've not yet received EOF
566 eof>0 marks the last 'real' sample in pcm[]
567 eof<0 'no more to do'; doesn't get here */
570 if(v->centerW>=v->eofflag){
577 /* advance storage vectors and clean up */
579 int new_centerNext=ci->blocksizes[1]/2+ci->delaycache;
580 int movementW=centerNext-new_centerNext;
584 _ve_envelope_shift(b->ve,movementW);
585 v->pcm_current-=movementW;
587 for(i=0;i<vi->channels;i++)
588 memmove(v->pcm[i],v->pcm[i]+movementW,
589 v->pcm_current*sizeof(float));
594 v->centerW=new_centerNext;
599 v->eofflag-=movementW;
600 /* do not add padding to end of stream! */
601 if(v->centerW>=v->eofflag){
602 v->granulepos+=movementW-(v->centerW-v->eofflag);
604 v->granulepos+=movementW;
607 v->granulepos+=movementW;
616 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
617 codec_setup_info *ci=vi->codec_setup;
618 _vds_shared_init(v,vi,0);
627 /* Unlike in analysis, the window is only partially applied for each
628 block. The time domain envelope is not yet handled at the point of
629 calling (as it relies on the previous block). */
631 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
632 vorbis_info *vi=v->vi;
633 codec_setup_info *ci=vi->codec_setup;
635 /* Shift out any PCM that we returned previously */
636 /* centerW is currently the center of the last block added */
638 if(v->centerW>ci->blocksizes[1]/2 &&
639 /* Quick additional hack; to avoid *alot* of shifts, use an
640 oversized buffer. This increases memory usage, but doesn't make
641 much difference wrt L1/L2 cache pressure. */
642 v->pcm_returned>8192){
644 /* don't shift too much; we need to have a minimum PCM buffer of
647 int shiftPCM=v->centerW-ci->blocksizes[1]/2;
648 shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
650 v->pcm_current-=shiftPCM;
651 v->centerW-=shiftPCM;
652 v->pcm_returned-=shiftPCM;
656 for(i=0;i<vi->channels;i++)
657 memmove(v->pcm[i],v->pcm[i]+shiftPCM,
658 v->pcm_current*sizeof(float));
666 v->glue_bits+=vb->glue_bits;
667 v->time_bits+=vb->time_bits;
668 v->floor_bits+=vb->floor_bits;
669 v->res_bits+=vb->res_bits;
671 if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence;
674 v->sequence=vb->sequence;
677 int sizeW=ci->blocksizes[v->W];
678 int centerW=v->centerW+ci->blocksizes[v->lW]/4+sizeW/4;
679 int beginW=centerW-sizeW/2;
680 int endW=beginW+sizeW;
685 /* Do we have enough PCM/mult storage for the block? */
686 if(endW>v->pcm_storage){
687 /* expand the storage */
688 v->pcm_storage=endW+ci->blocksizes[1];
690 for(i=0;i<vi->channels;i++)
691 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float));
694 /* overlap/add PCM */
699 endSl=ci->blocksizes[0]/2;
702 beginSl=ci->blocksizes[1]/4-ci->blocksizes[v->lW]/4;
703 endSl=beginSl+ci->blocksizes[v->lW]/2;
709 for(j=0;j<vi->channels;j++){
711 float *pcm=v->pcm[j]+beginW;
714 /* the overlap/add section */
715 for(i=beginSl;i<endSl;i++)
717 /* the remaining section */
721 _analysis_output("lapped",seq,pcm,sizeW,0,0);
722 _analysis_output("buffered",seq++,v->pcm[j],sizeW+beginW,0,0);
726 /* deal with initial packet state; we do this using the explicit
727 pcm_returned==-1 flag otherwise we're sensitive to first block
728 being short or long */
730 if(v->pcm_returned==-1)
731 v->pcm_returned=centerW;
733 /* track the frame number... This is for convenience, but also
734 making sure our last packet doesn't end with added padding. If
735 the last packet is partial, the number of samples we'll have to
736 return will be past the vb->granulepos.
738 This is not foolproof! It will be confused if we begin
739 decoding at the last page after a seek or hole. In that case,
740 we don't have a starting point to judge where the last frame
741 is. For this reason, vorbisfile will always try to make sure
742 it reads the last two marked pages in proper sequence */
744 if(v->granulepos==-1)
745 if(vb->granulepos==-1){
748 v->granulepos=vb->granulepos;
751 v->granulepos+=(centerW-v->centerW);
752 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
754 if(v->granulepos>vb->granulepos){
755 long extra=v->granulepos-vb->granulepos;
758 /* partial last frame. Strip the extra samples off */
760 }else if(vb->sequence == 1){
761 /* ^^^ argh, this can be 1 from seeking! */
764 /* partial first frame. Discard extra leading samples */
765 v->pcm_returned+=extra;
766 if(v->pcm_returned>centerW)v->pcm_returned=centerW;
770 }/* else{ Shouldn't happen *unless* the bitstream is out of
771 spec. Either way, believe the bitstream } */
772 v->granulepos=vb->granulepos;
776 /* Update, cleanup */
781 if(vb->eofflag)v->eofflag=1;
787 /* pcm==NULL indicates we just want the pending samples, no more */
788 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
789 vorbis_info *vi=v->vi;
790 if(v->pcm_returned<v->centerW){
793 for(i=0;i<vi->channels;i++)
794 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
797 return(v->centerW-v->pcm_returned);
802 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
803 if(bytes && v->pcm_returned+bytes>v->centerW)return(OV_EINVAL);
804 v->pcm_returned+=bytes;