1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
6 * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: PCM data vector blocking, windowing and dis/reassembly
15 last mod: $Id: block.c,v 1.42 2000/12/21 21:04:38 xiphmont Exp $
17 Handle windowing, overlap-add, etc of the PCM vectors. This is made
18 more amusing by Vorbis' current two allowed block sizes.
20 ********************************************************************/
26 #include "vorbis/codec.h"
37 static int ilog2(unsigned int v){
46 /* pcm accumulator examples (not exhaustive):
48 <-------------- lW ---------------->
49 <--------------- W ---------------->
50 : .....|..... _______________ |
51 : .''' | '''_--- | |\ |
52 :.....''' |_____--- '''......| | \_______|
53 :.................|__________________|_______|__|______|
54 |<------ Sl ------>| > Sr < |endW
55 |beginSl |endSl | |endSr
56 |beginW |endlW |beginSr
60 <--------------- W ---------------->
61 | | .. ______________ |
63 |___.'___/`. | ---_____|
64 |_______|__|_______|_________________|
65 | >|Sl|< |<------ Sr ----->|endW
66 | | |endSl |beginSr |endSr
68 mult[0] |beginSl mult[n]
70 <-------------- lW ----------------->
72 : .............. ___ | |
74 :.....''' |/`....\|...|
75 :.........................|___|___|___|
84 /* block abstraction setup *********************************************/
90 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
91 memset(vb,0,sizeof(vorbis_block));
96 oggpack_writeinit(&vb->opb);
101 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
102 bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
103 if(bytes+vb->localtop>vb->localalloc){
104 /* can't just _ogg_realloc... there are outstanding pointers */
106 struct alloc_chain *link=_ogg_malloc(sizeof(struct alloc_chain));
107 vb->totaluse+=vb->localtop;
109 link->ptr=vb->localstore;
112 /* highly conservative */
113 vb->localalloc=bytes;
114 vb->localstore=_ogg_malloc(vb->localalloc);
118 void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
124 /* reap the chain, pull the ripcord */
125 void _vorbis_block_ripcord(vorbis_block *vb){
127 struct alloc_chain *reap=vb->reap;
129 struct alloc_chain *next=reap->next;
130 _ogg_free(reap->ptr);
131 memset(reap,0,sizeof(struct alloc_chain));
135 /* consolidate storage */
137 vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
138 vb->localalloc+=vb->totaluse;
142 /* pull the ripcord */
147 int vorbis_block_clear(vorbis_block *vb){
149 if(vb->vd->analysisp)
150 oggpack_writeclear(&vb->opb);
151 _vorbis_block_ripcord(vb);
152 if(vb->localstore)_ogg_free(vb->localstore);
154 memset(vb,0,sizeof(vorbis_block));
158 /* Analysis side code, but directly related to blocking. Thus it's
159 here and not in analysis.c (which is for analysis transforms only).
160 The init is here because some of it is shared */
162 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
164 codec_setup_info *ci=vi->codec_setup;
165 backend_lookup_state *b=NULL;
167 memset(v,0,sizeof(vorbis_dsp_state));
168 b=v->backend_state=_ogg_calloc(1,sizeof(backend_lookup_state));
171 b->modebits=ilog2(ci->modes);
173 b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
174 b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
176 /* MDCT is tranform 0 */
178 b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
179 b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
180 mdct_init(b->transform[0][0],ci->blocksizes[0]);
181 mdct_init(b->transform[1][0],ci->blocksizes[1]);
183 b->window[0][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
184 b->window[0][0][1]=b->window[0][0][0];
185 b->window[0][1][0]=b->window[0][0][0];
186 b->window[0][1][1]=b->window[0][0][0];
187 b->window[1][0][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
188 b->window[1][0][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
189 b->window[1][1][0]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
190 b->window[1][1][1]=_ogg_calloc(VI_WINDOWB,sizeof(float *));
192 for(i=0;i<VI_WINDOWB;i++){
193 b->window[0][0][0][i]=
194 _vorbis_window(i,ci->blocksizes[0],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
195 b->window[1][0][0][i]=
196 _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[0]/2);
197 b->window[1][0][1][i]=
198 _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[0]/2,ci->blocksizes[1]/2);
199 b->window[1][1][0][i]=
200 _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[0]/2);
201 b->window[1][1][1][i]=
202 _vorbis_window(i,ci->blocksizes[1],ci->blocksizes[1]/2,ci->blocksizes[1]/2);
205 if(encp){ /* encode/decode differ here */
206 /* finish the codebooks */
207 b->fullbooks=_ogg_calloc(ci->books,sizeof(codebook));
208 for(i=0;i<ci->books;i++)
209 vorbis_book_init_encode(b->fullbooks+i,ci->book_param[i]);
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_decode(b->fullbooks+i,ci->book_param[i]);
218 /* initialize the storage vectors to a decent size greater than the
221 v->pcm_storage=8192; /* we'll assume later that we have
222 a minimum of twice the blocksize of
223 accumulated samples in analysis */
224 v->pcm=_ogg_malloc(vi->channels*sizeof(float *));
225 v->pcmret=_ogg_malloc(vi->channels*sizeof(float *));
228 for(i=0;i<vi->channels;i++)
229 v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(float));
232 /* all 1 (large block) or 0 (small block) */
233 /* explicitly set for the sake of clarity */
234 v->lW=0; /* previous window size */
235 v->W=0; /* current window size */
237 /* all vector indexes */
238 v->centerW=ci->blocksizes[1]/2;
240 v->pcm_current=v->centerW;
242 /* initialize all the mapping/backend lookups */
243 b->mode=_ogg_calloc(ci->modes,sizeof(vorbis_look_mapping *));
244 for(i=0;i<ci->modes;i++){
245 int mapnum=ci->mode_param[i]->mapping;
246 int maptype=ci->map_type[mapnum];
247 b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
248 ci->map_param[mapnum]);
254 /* arbitrary settings and spec-mandated numbers get filled in here */
255 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
256 backend_lookup_state *b=NULL;
258 _vds_shared_init(v,vi,1);
261 /* Initialize the envelope state storage */
262 b->ve=_ogg_calloc(1,sizeof(envelope_lookup));
263 _ve_envelope_init(b->ve,vi);
268 void vorbis_dsp_clear(vorbis_dsp_state *v){
271 vorbis_info *vi=v->vi;
272 codec_setup_info *ci=(vi?vi->codec_setup:NULL);
273 backend_lookup_state *b=v->backend_state;
276 if(b->window[0][0][0]){
277 for(i=0;i<VI_WINDOWB;i++)
278 if(b->window[0][0][0][i])_ogg_free(b->window[0][0][0][i]);
279 _ogg_free(b->window[0][0][0]);
283 for(i=0;i<VI_WINDOWB;i++)
284 if(b->window[1][j][k][i])_ogg_free(b->window[1][j][k][i]);
285 _ogg_free(b->window[1][j][k]);
290 _ve_envelope_clear(b->ve);
295 mdct_clear(b->transform[0][0]);
296 _ogg_free(b->transform[0][0]);
297 _ogg_free(b->transform[0]);
300 mdct_clear(b->transform[1][0]);
301 _ogg_free(b->transform[1][0]);
302 _ogg_free(b->transform[1]);
308 for(i=0;i<vi->channels;i++)
309 if(v->pcm[i])_ogg_free(v->pcm[i]);
311 if(v->pcmret)_ogg_free(v->pcmret);
314 /* free mode lookups; these are actually vorbis_look_mapping structs */
316 for(i=0;i<ci->modes;i++){
317 int mapnum=ci->mode_param[i]->mapping;
318 int maptype=ci->map_type[mapnum];
319 if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
322 for(i=0;i<ci->books;i++)
323 if(b && b->fullbooks)vorbis_book_clear(b->fullbooks+i);
327 if(b->mode)_ogg_free(b->mode);
328 if(b->fullbooks)_ogg_free(b->fullbooks);
330 /* free header, header1, header2 */
331 if(b->header)_ogg_free(b->header);
332 if(b->header1)_ogg_free(b->header1);
333 if(b->header2)_ogg_free(b->header2);
337 memset(v,0,sizeof(vorbis_dsp_state));
341 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
343 vorbis_info *vi=v->vi;
344 backend_lookup_state *b=v->backend_state;
346 /* free header, header1, header2 */
347 if(b->header)_ogg_free(b->header);b->header=NULL;
348 if(b->header1)_ogg_free(b->header1);b->header1=NULL;
349 if(b->header2)_ogg_free(b->header2);b->header2=NULL;
351 /* Do we have enough storage space for the requested buffer? If not,
352 expand the PCM (and envelope) storage */
354 if(v->pcm_current+vals>=v->pcm_storage){
355 v->pcm_storage=v->pcm_current+vals*2;
357 for(i=0;i<vi->channels;i++){
358 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float));
362 for(i=0;i<vi->channels;i++)
363 v->pcmret[i]=v->pcm[i]+v->pcm_current;
368 static void _preextrapolate_helper(vorbis_dsp_state *v){
371 float *lpc=alloca(order*sizeof(float));
372 float *work=alloca(v->pcm_current*sizeof(float));
376 if(v->pcm_current-v->centerW>order*2){ /* safety */
377 for(i=0;i<v->vi->channels;i++){
379 /* need to run the extrapolation in reverse! */
380 for(j=0;j<v->pcm_current;j++)
381 work[j]=v->pcm[i][v->pcm_current-j-1];
384 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
386 /* run the predictor filter */
387 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
389 work+v->pcm_current-v->centerW,
391 for(j=0;j<v->pcm_current;j++)
392 v->pcm[i][v->pcm_current-j-1]=work[j];
398 /* call with val<=0 to set eof */
400 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
401 vorbis_info *vi=v->vi;
402 codec_setup_info *ci=vi->codec_setup;
407 float *lpc=alloca(order*sizeof(float));
409 /* if it wasn't done earlier (very short sample) */
410 if(!v->preextrapolate)
411 _preextrapolate_helper(v);
413 /* We're encoding the end of the stream. Just make sure we have
414 [at least] a full block of zeroes at the end. */
415 /* actually, we don't want zeroes; that could drop a large
416 amplitude off a cliff, creating spread spectrum noise that will
417 suck to encode. Extrapolate for the sake of cleanliness. */
419 vorbis_analysis_buffer(v,ci->blocksizes[1]*2);
420 v->eofflag=v->pcm_current;
421 v->pcm_current+=ci->blocksizes[1]*2;
423 for(i=0;i<vi->channels;i++){
424 if(v->eofflag>order*2){
425 /* extrapolate with LPC to fill in */
428 /* make a predictor filter */
430 if(n>ci->blocksizes[1])n=ci->blocksizes[1];
431 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
433 /* run the predictor filter */
434 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
435 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
437 /* not enough data to extrapolate (unlikely to happen due to
438 guarding the overlap, but bulletproof in case that
439 assumtion goes away). zeroes will do. */
440 memset(v->pcm[i]+v->eofflag,0,
441 (v->pcm_current-v->eofflag)*sizeof(float));
447 if(v->pcm_current+vals>v->pcm_storage)
450 v->pcm_current+=vals;
452 /* we may want to reverse extrapolate the beginning of a stream
453 too... in case we're beginning on a cliff! */
454 /* clumsy, but simple. It only runs once, so simple is good. */
455 if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
456 _preextrapolate_helper(v);
462 /* do the deltas, envelope shaping, pre-echo and determine the size of
463 the next block on which to continue analysis */
464 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
466 vorbis_info *vi=v->vi;
467 codec_setup_info *ci=vi->codec_setup;
468 backend_lookup_state *b=v->backend_state;
469 long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
471 /* check to see if we're started... */
472 if(!v->preextrapolate)return(0);
474 /* check to see if we're done... */
475 if(v->eofflag==-1)return(0);
477 /* By our invariant, we have lW, W and centerW set. Search for
478 the next boundary so we can determine nW (the next window size)
479 which lets us compute the shape of the current block's window */
481 if(ci->blocksizes[0]<ci->blocksizes[1]){
486 /* min boundary; nW large, next small */
487 largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]/4;
489 /* min boundary; nW large, next small */
490 largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]*3/4;
492 bp=_ve_envelope_search(v,largebound);
493 if(bp==-1)return(0); /* not enough data currently to search for a
500 centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
503 /* center of next block + next block maximum right side. */
505 long blockbound=centerNext+ci->blocksizes[v->nW]/2;
506 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
507 although this check is
510 the search is not run
515 /* fill in the block. Note that for a short window, lW and nW are *short*
516 regardless of actual settings in the stream */
518 _vorbis_block_ripcord(vb);
529 vb->sequence=v->sequence;
530 vb->granulepos=v->granulepos;
531 vb->pcmend=ci->blocksizes[v->W];
533 /* copy the vectors; this uses the local storage in vb */
535 vb->pcm=_vorbis_block_alloc(vb,sizeof(float *)*vi->channels);
536 for(i=0;i<vi->channels;i++){
537 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(float));
538 memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(float));
542 /* handle eof detection: eof==0 means that we've not yet received EOF
543 eof>0 marks the last 'real' sample in pcm[]
544 eof<0 'no more to do'; doesn't get here */
547 if(v->centerW>=v->eofflag){
554 /* advance storage vectors and clean up */
556 int new_centerNext=ci->blocksizes[1]/2;
557 int movementW=centerNext-new_centerNext;
559 _ve_envelope_shift(b->ve,movementW);
560 v->pcm_current-=movementW;
562 for(i=0;i<vi->channels;i++)
563 memmove(v->pcm[i],v->pcm[i]+movementW,
564 v->pcm_current*sizeof(float));
569 v->centerW=new_centerNext;
574 v->eofflag-=movementW;
575 /* do not add padding to end of stream! */
576 if(v->centerW>=v->eofflag){
577 v->granulepos+=movementW-(v->centerW-v->eofflag);
579 v->granulepos+=movementW;
582 v->granulepos+=movementW;
590 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
591 codec_setup_info *ci=vi->codec_setup;
592 _vds_shared_init(v,vi,0);
594 /* Adjust centerW to allow an easier mechanism for determining output */
595 v->pcm_returned=v->centerW;
596 v->centerW-= ci->blocksizes[v->W]/4+ci->blocksizes[v->lW]/4;
603 /* Unlike in analysis, the window is only partially applied for each
604 block. The time domain envelope is not yet handled at the point of
605 calling (as it relies on the previous block). */
607 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
608 vorbis_info *vi=v->vi;
609 codec_setup_info *ci=vi->codec_setup;
611 /* Shift out any PCM that we returned previously */
612 /* centerW is currently the center of the last block added */
614 if(v->centerW>ci->blocksizes[1]/2 &&
615 /* Quick additional hack; to avoid *alot* of shifts, use an
616 oversized buffer. This increases memory usage, but doesn't make
617 much difference wrt L1/L2 cache pressure. */
618 v->pcm_returned>8192){
620 /* don't shift too much; we need to have a minimum PCM buffer of
623 int shiftPCM=v->centerW-ci->blocksizes[1]/2;
624 shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
626 v->pcm_current-=shiftPCM;
627 v->centerW-=shiftPCM;
628 v->pcm_returned-=shiftPCM;
632 for(i=0;i<vi->channels;i++)
633 memmove(v->pcm[i],v->pcm[i]+shiftPCM,
634 v->pcm_current*sizeof(float));
642 v->glue_bits+=vb->glue_bits;
643 v->time_bits+=vb->time_bits;
644 v->floor_bits+=vb->floor_bits;
645 v->res_bits+=vb->res_bits;
647 if(v->sequence+1 != vb->sequence)v->granulepos=-1; /* out of sequence;
650 v->sequence=vb->sequence;
653 int sizeW=ci->blocksizes[v->W];
654 int centerW=v->centerW+ci->blocksizes[v->lW]/4+sizeW/4;
655 int beginW=centerW-sizeW/2;
656 int endW=beginW+sizeW;
661 /* Do we have enough PCM/mult storage for the block? */
662 if(endW>v->pcm_storage){
663 /* expand the storage */
664 v->pcm_storage=endW+ci->blocksizes[1];
666 for(i=0;i<vi->channels;i++)
667 v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(float));
670 /* overlap/add PCM */
675 endSl=ci->blocksizes[0]/2;
678 beginSl=ci->blocksizes[1]/4-ci->blocksizes[v->lW]/4;
679 endSl=beginSl+ci->blocksizes[v->lW]/2;
685 for(j=0;j<vi->channels;j++){
686 float *pcm=v->pcm[j]+beginW;
689 /* the overlap/add section */
690 for(i=beginSl;i<endSl;i++)
692 /* the remaining section */
697 /* track the frame number... This is for convenience, but also
698 making sure our last packet doesn't end with added padding. If
699 the last packet is partial, the number of samples we'll have to
700 return will be past the vb->granulepos.
702 This is not foolproof! It will be confused if we begin
703 decoding at the last page after a seek or hole. In that case,
704 we don't have a starting point to judge where the last frame
705 is. For this reason, vorbisfile will always try to make sure
706 it reads the last two marked pages in proper sequence */
708 if(v->granulepos==-1)
709 if(vb->granulepos==-1){
712 v->granulepos=vb->granulepos;
715 v->granulepos+=(centerW-v->centerW);
716 if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
718 if(v->granulepos>vb->granulepos){
719 long extra=v->granulepos-vb->granulepos;
722 /* partial last frame. Strip the extra samples off */
724 }else if(vb->sequence == 1){
725 /* partial first frame. Discard extra leading samples */
726 v->pcm_returned+=extra;
727 if(v->pcm_returned>centerW)v->pcm_returned=centerW;
731 }/* else{ Shouldn't happen *unless* the bitstream is out of
732 spec. Either way, believe the bitstream } */
733 v->granulepos=vb->granulepos;
737 /* Update, cleanup */
742 if(vb->eofflag)v->eofflag=1;
748 /* pcm==NULL indicates we just want the pending samples, no more */
749 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
750 vorbis_info *vi=v->vi;
751 if(v->pcm_returned<v->centerW){
754 for(i=0;i<vi->channels;i++)
755 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
758 return(v->centerW-v->pcm_returned);
763 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
764 if(bytes && v->pcm_returned+bytes>v->centerW)return(OV_EINVAL);
765 v->pcm_returned+=bytes;