1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH 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.36 2000/08/23 10:16:56 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 Vorbis manipulates the dynamic range of the incoming PCM data
21 envelope to minimise time-domain energy leakage from percussive and
22 plosive waveforms being quantized in the MDCT domain.
24 ********************************************************************/
29 #include "vorbis/codec.h"
37 #include "sharedbook.h"
38 #include "bookinternal.h"
41 static int ilog2(unsigned int v){
50 /* pcm accumulator examples (not exhaustive):
52 <-------------- lW ---------------->
53 <--------------- W ---------------->
54 : .....|..... _______________ |
55 : .''' | '''_--- | |\ |
56 :.....''' |_____--- '''......| | \_______|
57 :.................|__________________|_______|__|______|
58 |<------ Sl ------>| > Sr < |endW
59 |beginSl |endSl | |endSr
60 |beginW |endlW |beginSr
64 <--------------- W ---------------->
65 | | .. ______________ |
67 |___.'___/`. | ---_____|
68 |_______|__|_______|_________________|
69 | >|Sl|< |<------ Sr ----->|endW
70 | | |endSl |beginSr |endSr
72 mult[0] |beginSl mult[n]
74 <-------------- lW ----------------->
76 : .............. ___ | |
78 :.....''' |/`....\|...|
79 :.........................|___|___|___|
88 /* block abstraction setup *********************************************/
94 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
95 memset(vb,0,sizeof(vorbis_block));
100 _oggpack_writeinit(&vb->opb);
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 realloc... there are outstanding pointers */
110 struct alloc_chain *link=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=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;
135 memset(reap,0,sizeof(struct alloc_chain));
139 /* consolidate storage */
141 vb->localstore=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)free(vb->localstore);
158 memset(vb,0,sizeof(vorbis_block));
162 /* Analysis side code, but directly related to blocking. Thus it's
163 here and not in analysis.c (which is for analysis transforms only).
164 The init is here because some of it is shared */
166 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
168 memset(v,0,sizeof(vorbis_dsp_state));
171 v->modebits=ilog2(vi->modes);
173 v->transform[0]=calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
174 v->transform[1]=calloc(VI_TRANSFORMB,sizeof(vorbis_look_transform *));
176 /* MDCT is tranform 0 */
178 v->transform[0][0]=calloc(1,sizeof(mdct_lookup));
179 v->transform[1][0]=calloc(1,sizeof(mdct_lookup));
180 mdct_init(v->transform[0][0],vi->blocksizes[0]);
181 mdct_init(v->transform[1][0],vi->blocksizes[1]);
183 v->window[0][0][0]=calloc(VI_WINDOWB,sizeof(double *));
184 v->window[0][0][1]=v->window[0][0][0];
185 v->window[0][1][0]=v->window[0][0][0];
186 v->window[0][1][1]=v->window[0][0][0];
187 v->window[1][0][0]=calloc(VI_WINDOWB,sizeof(double *));
188 v->window[1][0][1]=calloc(VI_WINDOWB,sizeof(double *));
189 v->window[1][1][0]=calloc(VI_WINDOWB,sizeof(double *));
190 v->window[1][1][1]=calloc(VI_WINDOWB,sizeof(double *));
192 for(i=0;i<VI_WINDOWB;i++){
193 v->window[0][0][0][i]=
194 _vorbis_window(i,vi->blocksizes[0],vi->blocksizes[0]/2,vi->blocksizes[0]/2);
195 v->window[1][0][0][i]=
196 _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[0]/2,vi->blocksizes[0]/2);
197 v->window[1][0][1][i]=
198 _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[0]/2,vi->blocksizes[1]/2);
199 v->window[1][1][0][i]=
200 _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[1]/2,vi->blocksizes[0]/2);
201 v->window[1][1][1][i]=
202 _vorbis_window(i,vi->blocksizes[1],vi->blocksizes[1]/2,vi->blocksizes[1]/2);
205 if(encp){ /* encode/decode differ here */
206 /* finish the codebooks */
207 v->fullbooks=calloc(vi->books,sizeof(codebook));
208 for(i=0;i<vi->books;i++)
209 vorbis_book_init_encode(v->fullbooks+i,vi->book_param[i]);
212 /* finish the codebooks */
213 v->fullbooks=calloc(vi->books,sizeof(codebook));
214 for(i=0;i<vi->books;i++)
215 vorbis_book_init_decode(v->fullbooks+i,vi->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=malloc(vi->channels*sizeof(double *));
225 v->pcmret=malloc(vi->channels*sizeof(double *));
228 for(i=0;i<vi->channels;i++)
229 v->pcm[i]=calloc(v->pcm_storage,sizeof(double));
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=vi->blocksizes[1]/2;
240 v->pcm_current=v->centerW;
242 /* initialize all the mapping/backend lookups */
243 v->mode=calloc(vi->modes,sizeof(vorbis_look_mapping *));
244 for(i=0;i<vi->modes;i++){
245 int mapnum=vi->mode_param[i]->mapping;
246 int maptype=vi->map_type[mapnum];
247 v->mode[i]=_mapping_P[maptype]->look(v,vi->mode_param[i],
248 vi->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 _vds_shared_init(v,vi,1);
258 /* Initialize the envelope state storage */
259 v->ve=calloc(1,sizeof(envelope_lookup));
260 _ve_envelope_init(v->ve,vi);
265 void vorbis_dsp_clear(vorbis_dsp_state *v){
268 vorbis_info *vi=v->vi;
270 if(v->window[0][0][0]){
271 for(i=0;i<VI_WINDOWB;i++)
272 if(v->window[0][0][0][i])free(v->window[0][0][0][i]);
273 free(v->window[0][0][0]);
277 for(i=0;i<VI_WINDOWB;i++)
278 if(v->window[1][j][k][i])free(v->window[1][j][k][i]);
279 free(v->window[1][j][k]);
284 for(i=0;i<vi->channels;i++)
285 if(v->pcm[i])free(v->pcm[i]);
287 if(v->pcmret)free(v->pcmret);
291 _ve_envelope_clear(v->ve);
296 mdct_clear(v->transform[0][0]);
297 free(v->transform[0][0]);
298 free(v->transform[0]);
301 mdct_clear(v->transform[1][0]);
302 free(v->transform[1][0]);
303 free(v->transform[1]);
306 /* free mode lookups; these are actually vorbis_look_mapping structs */
308 for(i=0;i<vi->modes;i++){
309 int mapnum=vi->mode_param[i]->mapping;
310 int maptype=vi->map_type[mapnum];
311 _mapping_P[maptype]->free_look(v->mode[i]);
314 for(i=0;i<vi->books;i++)
315 vorbis_book_clear(v->fullbooks+i);
318 if(v->mode)free(v->mode);
319 if(v->fullbooks)free(v->fullbooks);
321 /* free header, header1, header2 */
322 if(v->header)free(v->header);
323 if(v->header1)free(v->header1);
324 if(v->header2)free(v->header2);
326 memset(v,0,sizeof(vorbis_dsp_state));
330 double **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
332 vorbis_info *vi=v->vi;
334 /* free header, header1, header2 */
335 if(v->header)free(v->header);v->header=NULL;
336 if(v->header1)free(v->header1);v->header1=NULL;
337 if(v->header2)free(v->header2);v->header2=NULL;
339 /* Do we have enough storage space for the requested buffer? If not,
340 expand the PCM (and envelope) storage */
342 if(v->pcm_current+vals>=v->pcm_storage){
343 v->pcm_storage=v->pcm_current+vals*2;
345 for(i=0;i<vi->channels;i++){
346 v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
350 for(i=0;i<vi->channels;i++)
351 v->pcmret[i]=v->pcm[i]+v->pcm_current;
356 static void _preinterpolate_helper(vorbis_dsp_state *v){
359 double *lpc=alloca(order*sizeof(double));
360 double *work=alloca(v->pcm_current*sizeof(double));
364 if(v->pcm_current-v->centerW>order*2){ /* safety */
365 for(i=0;i<v->vi->channels;i++){
367 /* need to run the interpolation in reverse! */
368 for(j=0;j<v->pcm_current;j++)
369 work[j]=v->pcm[i][v->pcm_current-j-1];
372 vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
374 /* run the predictor filter */
375 vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
377 work+v->pcm_current-v->centerW,
379 for(j=0;j<v->pcm_current;j++)
380 v->pcm[i][v->pcm_current-j-1]=work[j];
386 /* call with val<=0 to set eof */
388 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
389 vorbis_info *vi=v->vi;
393 double *lpc=alloca(order*sizeof(double));
395 /* if it wasn't done earlier (very short sample) */
397 _preinterpolate_helper(v);
399 /* We're encoding the end of the stream. Just make sure we have
400 [at least] a full block of zeroes at the end. */
401 /* actually, we don't want zeroes; that could drop a large
402 amplitude off a cliff, creating spread spectrum noise that will
403 suck to encode. Extrapolate for the sake of cleanliness. */
405 vorbis_analysis_buffer(v,v->vi->blocksizes[1]*2);
406 v->eofflag=v->pcm_current;
407 v->pcm_current+=v->vi->blocksizes[1]*2;
409 for(i=0;i<vi->channels;i++){
410 if(v->eofflag>order*2){
411 /* extrapolate with LPC to fill in */
414 /* make a predictor filter */
416 if(n>v->vi->blocksizes[1])n=v->vi->blocksizes[1];
417 vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
419 /* run the predictor filter */
420 vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
421 v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
423 /* not enough data to interpolate (unlikely to happen due to
424 guarding the overlap, but bulletproof in case that
425 assumtion goes away). zeroes will do. */
426 memset(v->pcm[i]+v->eofflag,0,
427 (v->pcm_current-v->eofflag)*sizeof(double));
433 if(v->pcm_current+vals>v->pcm_storage)
436 v->pcm_current+=vals;
438 /* we may want to reverse interpolate the beginning of a stream
439 too... in case we're beginning on a cliff! */
440 /* clumsy, but simple. It only runs once, so simple is good. */
441 if(!v->preinterp && v->pcm_current-v->centerW>v->vi->blocksizes[1])
442 _preinterpolate_helper(v);
448 /* do the deltas, envelope shaping, pre-echo and determine the size of
449 the next block on which to continue analysis */
450 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
452 vorbis_info *vi=v->vi;
453 long beginW=v->centerW-vi->blocksizes[v->W]/2,centerNext;
455 /* check to see if we're started... */
456 if(!v->preinterp)return(0);
458 /* check to see if we're done... */
459 if(v->eofflag==-1)return(0);
461 /* By our invariant, we have lW, W and centerW set. Search for
462 the next boundary so we can determine nW (the next window size)
463 which lets us compute the shape of the current block's window */
465 if(vi->blocksizes[0]<vi->blocksizes[1]){
470 /* min boundary; nW large, next small */
471 largebound=v->centerW+vi->blocksizes[1]*3/4+vi->blocksizes[0]/4;
473 /* min boundary; nW large, next small */
474 largebound=v->centerW+vi->blocksizes[1]*3/4+vi->blocksizes[0]*3/4;
476 bp=_ve_envelope_search(v,largebound);
477 if(bp==-1)return(0); /* not enough data currently to search for a
484 centerNext=v->centerW+vi->blocksizes[v->W]/4+vi->blocksizes[v->nW]/4;
487 /* center of next block + next block maximum right side. */
489 long blockbound=centerNext+vi->blocksizes[v->nW]/2;
490 if(v->pcm_current<blockbound)return(0); /* not enough data yet;
491 although this check is
494 the search is not run
499 /* fill in the block. Note that for a short window, lW and nW are *short*
500 regardless of actual settings in the stream */
502 _vorbis_block_ripcord(vb);
513 vb->sequence=v->sequence;
514 vb->frameno=v->frameno;
515 vb->pcmend=vi->blocksizes[v->W];
517 /* copy the vectors; this uses the local storage in vb */
519 vb->pcm=_vorbis_block_alloc(vb,sizeof(double *)*vi->channels);
520 for(i=0;i<vi->channels;i++){
521 vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(double));
522 memcpy(vb->pcm[i],v->pcm[i]+beginW,vi->blocksizes[v->W]*sizeof(double));
526 /* handle eof detection: eof==0 means that we've not yet received EOF
527 eof>0 marks the last 'real' sample in pcm[]
528 eof<0 'no more to do'; doesn't get here */
531 if(v->centerW>=v->eofflag){
538 /* advance storage vectors and clean up */
540 int new_centerNext=vi->blocksizes[1]/2;
541 int movementW=centerNext-new_centerNext;
543 _ve_envelope_shift(v->ve,movementW);
544 v->pcm_current-=movementW;
546 for(i=0;i<vi->channels;i++)
547 memmove(v->pcm[i],v->pcm[i]+movementW,
548 v->pcm_current*sizeof(double));
553 v->centerW=new_centerNext;
558 v->eofflag-=movementW;
559 /* do not add padding to end of stream! */
560 if(v->centerW>=v->eofflag){
561 v->frameno+=movementW-(v->centerW-v->eofflag);
563 v->frameno+=movementW;
566 v->frameno+=movementW;
574 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
575 _vds_shared_init(v,vi,0);
577 /* Adjust centerW to allow an easier mechanism for determining output */
578 v->pcm_returned=v->centerW;
579 v->centerW-= vi->blocksizes[v->W]/4+vi->blocksizes[v->lW]/4;
586 /* Unike in analysis, the window is only partially applied for each
587 block. The time domain envelope is not yet handled at the point of
588 calling (as it relies on the previous block). */
590 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
591 vorbis_info *vi=v->vi;
593 /* Shift out any PCM that we returned previously */
594 /* centerW is currently the center of the last block added */
595 if(v->pcm_returned && v->centerW>vi->blocksizes[1]/2){
597 /* don't shift too much; we need to have a minimum PCM buffer of
600 int shiftPCM=v->centerW-vi->blocksizes[1]/2;
601 shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
603 v->pcm_current-=shiftPCM;
604 v->centerW-=shiftPCM;
605 v->pcm_returned-=shiftPCM;
609 for(i=0;i<vi->channels;i++)
610 memmove(v->pcm[i],v->pcm[i]+shiftPCM,
611 v->pcm_current*sizeof(double));
619 v->glue_bits+=vb->glue_bits;
620 v->time_bits+=vb->time_bits;
621 v->floor_bits+=vb->floor_bits;
622 v->res_bits+=vb->res_bits;
624 if(v->sequence+1 != vb->sequence)v->frameno=-1; /* out of sequence;
627 v->sequence=vb->sequence;
630 int sizeW=vi->blocksizes[v->W];
631 int centerW=v->centerW+vi->blocksizes[v->lW]/4+sizeW/4;
632 int beginW=centerW-sizeW/2;
633 int endW=beginW+sizeW;
638 /* Do we have enough PCM/mult storage for the block? */
639 if(endW>v->pcm_storage){
640 /* expand the storage */
641 v->pcm_storage=endW+vi->blocksizes[1];
643 for(i=0;i<vi->channels;i++)
644 v->pcm[i]=realloc(v->pcm[i],v->pcm_storage*sizeof(double));
647 /* overlap/add PCM */
652 endSl=vi->blocksizes[0]/2;
655 beginSl=vi->blocksizes[1]/4-vi->blocksizes[v->lW]/4;
656 endSl=beginSl+vi->blocksizes[v->lW]/2;
660 for(j=0;j<vi->channels;j++){
661 double *pcm=v->pcm[j]+beginW;
663 /* the overlap/add section */
664 for(i=beginSl;i<endSl;i++)
665 pcm[i]+=vb->pcm[j][i];
666 /* the remaining section */
668 pcm[i]=vb->pcm[j][i];
671 /* track the frame number... This is for convenience, but also
672 making sure our last packet doesn't end with added padding. If
673 the last packet is partial, the number of samples we'll have to
674 return will be past the vb->frameno.
676 This is not foolproof! It will be confused if we begin
677 decoding at the last page after a seek or hole. In that case,
678 we don't have a starting point to judge where the last frame
679 is. For this reason, vorbisfile will always try to make sure
680 it reads the last two marked pages in proper sequence */
683 v->frameno=vb->frameno;
685 v->frameno+=(centerW-v->centerW);
686 if(vb->frameno!=-1 && v->frameno!=vb->frameno){
687 if(v->frameno>vb->frameno && vb->eofflag){
688 /* partial last frame. Strip the padding off */
689 centerW-=(v->frameno-vb->frameno);
690 }/* else{ Shouldn't happen *unless* the bitstream is out of
691 spec. Either way, believe the bitstream } */
692 v->frameno=vb->frameno;
696 /* Update, cleanup */
701 if(vb->eofflag)v->eofflag=1;
707 /* pcm==NULL indicates we just want the pending samples, no more */
708 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,double ***pcm){
709 vorbis_info *vi=v->vi;
710 if(v->pcm_returned<v->centerW){
713 for(i=0;i<vi->channels;i++)
714 v->pcmret[i]=v->pcm[i]+v->pcm_returned;
717 return(v->centerW-v->pcm_returned);
722 int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
723 if(bytes && v->pcm_returned+bytes>v->centerW)return(-1);
724 v->pcm_returned+=bytes;