examples/SFExamples/oggvorbiscodec/src/libvorbis/lib/block.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2003             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013  function: PCM data vector blocking, windowing and dis/reassembly
00014  last mod: $Id: block.c 9513 2005-06-26 18:36:49Z giles $
00015 
00016  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
00017  more amusing by Vorbis' current two allowed block sizes.
00018  
00019  ********************************************************************/
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include "ogg/ogg.h"
00025 #include "vorbis/codec.h"
00026 #include "codec_internal.h"
00027 #include "window.h"
00028 #include "mdct.h"
00029 #include "lpc.h"
00030 #include "registry.h"
00031 #include "misc.h"
00032 
00033 static int ilog2(unsigned int v){
00034   int ret=0;
00035   if(v)--v;
00036   while(v){
00037     ret++;
00038     v>>=1;
00039   }
00040   return(ret);
00041 }
00042 
00043 /* pcm accumulator examples (not exhaustive):
00044 
00045  <-------------- lW ---------------->
00046                    <--------------- W ---------------->
00047 :            .....|.....       _______________         |
00048 :        .'''     |     '''_---      |       |\        |
00049 :.....'''         |_____--- '''......|       | \_______|
00050 :.................|__________________|_______|__|______|
00051                   |<------ Sl ------>|      > Sr <     |endW
00052                   |beginSl           |endSl  |  |endSr   
00053                   |beginW            |endlW  |beginSr
00054 
00055 
00056                       |< lW >|       
00057                    <--------------- W ---------------->
00058                   |   |  ..  ______________            |
00059                   |   | '  `/        |     ---_        |
00060                   |___.'___/`.       |         ---_____| 
00061                   |_______|__|_______|_________________|
00062                   |      >|Sl|<      |<------ Sr ----->|endW
00063                   |       |  |endSl  |beginSr          |endSr
00064                   |beginW |  |endlW                     
00065                   mult[0] |beginSl                     mult[n]
00066 
00067  <-------------- lW ----------------->
00068                           |<--W-->|                               
00069 :            ..............  ___  |   |                    
00070 :        .'''             |`/   \ |   |                       
00071 :.....'''                 |/`....\|...|                    
00072 :.........................|___|___|___|                  
00073                           |Sl |Sr |endW    
00074                           |   |   |endSr
00075                           |   |beginSr
00076                           |   |endSl
00077                           |beginSl
00078                           |beginW
00079 */
00080 
00081 /* block abstraction setup *********************************************/
00082 
00083 #ifndef WORD_ALIGN
00084 #define WORD_ALIGN 8
00085 #endif
00086 
00087 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
00088   int i;
00089   memset(vb,0,sizeof(*vb));
00090   vb->vd=v;
00091   vb->localalloc=0;
00092   vb->localstore=NULL;
00093   if(v->analysisp){
00094     vorbis_block_internal *vbi= NULL;
00095     vb->internal= _ogg_calloc(1,sizeof(vorbis_block_internal));
00096     vbi = (vorbis_block_internal*)vb->internal;
00097     vbi->ampmax=-9999;
00098 
00099     for(i=0;i<PACKETBLOBS;i++){
00100       if(i==PACKETBLOBS/2){
00101         vbi->packetblob[i]=&vb->opb;
00102       }else{
00103         vbi->packetblob[i]=
00104           (oggpack_buffer*)_ogg_calloc(1,sizeof(oggpack_buffer));
00105       }
00106       oggpack_writeinit(vbi->packetblob[i]);
00107     }    
00108   }
00109 
00110   return(0);
00111 }
00112 
00113 void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
00114   bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
00115   if(bytes+vb->localtop>vb->localalloc){
00116     /* can't just _ogg_realloc... there are outstanding pointers */
00117     if(vb->localstore){
00118       struct alloc_chain *link=(struct alloc_chain*)_ogg_malloc(sizeof(*link));
00119       vb->totaluse+=vb->localtop;
00120       link->next=vb->reap;
00121       link->ptr=vb->localstore;
00122       vb->reap=link;
00123     }
00124     /* highly conservative */
00125     vb->localalloc=bytes;
00126     vb->localstore=_ogg_malloc(vb->localalloc);
00127     vb->localtop=0;
00128   }
00129   {
00130     void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
00131     vb->localtop+=bytes;
00132     return ret;
00133   }
00134 }
00135 
00136 /* reap the chain, pull the ripcord */
00137 void _vorbis_block_ripcord(vorbis_block *vb){
00138   /* reap the chain */
00139   struct alloc_chain *reap=vb->reap;
00140   while(reap){
00141     struct alloc_chain *next=reap->next;
00142     _ogg_free(reap->ptr);
00143     memset(reap,0,sizeof(*reap));
00144     _ogg_free(reap);
00145     reap=next;
00146   }
00147   /* consolidate storage */
00148   if(vb->totaluse){
00149     vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
00150     vb->localalloc+=vb->totaluse;
00151     vb->totaluse=0;
00152   }
00153 
00154   /* pull the ripcord */
00155   vb->localtop=0;
00156   vb->reap=NULL;
00157 }
00158 
00159 int vorbis_block_clear(vorbis_block *vb){
00160   int i;
00161   vorbis_block_internal *vbi=(vorbis_block_internal*)vb->internal;
00162 
00163   _vorbis_block_ripcord(vb);
00164   if(vb->localstore)_ogg_free(vb->localstore);
00165 
00166   if(vbi){
00167     for(i=0;i<PACKETBLOBS;i++){
00168       oggpack_writeclear(vbi->packetblob[i]);
00169       if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
00170     }
00171     _ogg_free(vbi);
00172   }
00173   memset(vb,0,sizeof(*vb));
00174   return(0);
00175 }
00176 
00177 /* Analysis side code, but directly related to blocking.  Thus it's
00178    here and not in analysis.c (which is for analysis transforms only).
00179    The init is here because some of it is shared */
00180 static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
00181   int i;
00182   codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00183   private_state *b=NULL;
00184   int hs;
00185     
00186   if(ci==NULL) return 1;
00187   hs=ci->halfrate_flag; 
00188 
00189   memset(v,0,sizeof(*v));
00190   v->backend_state=_ogg_calloc(1,sizeof(*b));
00191   b=(private_state*)v->backend_state;
00192   
00193   v->vi=vi;
00194   b->modebits=ilog2(ci->modes);
00195 
00196   b->transform[0]=(vorbis_look_transform**)_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
00197   b->transform[1]=(vorbis_look_transform**)_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
00198 
00199   /* MDCT is tranform 0 */
00200 
00201   b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
00202   b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
00203   mdct_init((mdct_lookup*)b->transform[0][0],ci->blocksizes[0]>>hs);
00204   mdct_init((mdct_lookup*)b->transform[1][0],ci->blocksizes[1]>>hs);
00205 
00206   
00207   
00208   /* Vorbis I uses only window type 0 */
00209   b->window[0]=ilog2(ci->blocksizes[0])-6;
00210   b->window[1]=ilog2(ci->blocksizes[1])-6;
00211 
00212   if(encp){ /* encode/decode differ here */
00213 
00214     /* analysis always needs an fft */
00215     drft_init(&b->fft_look[0],ci->blocksizes[0]);
00216     drft_init(&b->fft_look[1],ci->blocksizes[1]);
00217   
00218 
00219     /* finish the codebooks */
00220     if(!ci->fullbooks){
00221       ci->fullbooks=(codebook*)_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
00222       for(i=0;i<ci->books;i++)
00223         vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
00224     
00225     }
00226 
00227     b->psy=(vorbis_look_psy*)_ogg_calloc(ci->psys,sizeof(*b->psy));
00228     for(i=0;i<ci->psys;i++){
00229       _vp_psy_init(b->psy+i,
00230                    ci->psy_param[i],
00231                    &ci->psy_g_param,
00232                    ci->blocksizes[ci->psy_param[i]->blockflag]/2,
00233                    vi->rate);
00234     }
00235         
00236     v->analysisp=1;
00237   }else{
00238     /* finish the codebooks */
00239     if(!ci->fullbooks){
00240       ci->fullbooks=(codebook*)_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
00241       for(i=0;i<ci->books;i++){
00242         vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
00243         /* decode codebooks are now standalone after init */
00244         vorbis_staticbook_destroy(ci->book_param[i]);
00245         ci->book_param[i]=NULL;
00246       }
00247     }
00248   }
00249 
00250 
00251   /* initialize the storage vectors. blocksize[1] is small for encode,
00252      but the correct size for decode */
00253   v->pcm_storage=ci->blocksizes[1];
00254   v->pcm=(float**)_ogg_malloc(vi->channels*sizeof(*v->pcm));
00255   v->pcmret=(float**)_ogg_malloc(vi->channels*sizeof(*v->pcmret));
00256   {
00257     int i;
00258     for(i=0;i<vi->channels;i++)
00259       v->pcm[i]=(float*)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
00260   }
00261 
00262   /* all 1 (large block) or 0 (small block) */
00263   /* explicitly set for the sake of clarity */
00264   v->lW=0; /* previous window size */
00265   v->W=0;  /* current window size */
00266 
00267   /* all vector indexes */
00268   v->centerW=ci->blocksizes[1]/2;
00269 
00270   v->pcm_current=v->centerW;
00271 
00272   /* initialize all the backend lookups */
00273   b->flr=(vorbis_look_floor**)_ogg_calloc(ci->floors,sizeof(*b->flr));
00274   b->residue=(vorbis_look_residue**)_ogg_calloc(ci->residues,sizeof(*b->residue));
00275 
00276   for(i=0;i<ci->floors;i++)
00277     b->flr[i]=_floor_P[ci->floor_type[i]]->
00278       look(v,ci->floor_param[i]);
00279 
00280   for(i=0;i<ci->residues;i++)
00281     b->residue[i]=_residue_P[ci->residue_type[i]]->
00282       look(v,ci->residue_param[i]);    
00283 
00284   return 0;
00285 }
00286 
00287 
00288 /* arbitrary settings and spec-mandated numbers get filled in here */
00289 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
00290   
00291   private_state *b=NULL;
00292   
00293   if(_vds_shared_init(v,vi,1))return 1;
00294   
00295   b=(private_state*)v->backend_state;
00296   b->psy_g_look=_vp_global_look(vi);
00297   
00298   /* Initialize the envelope state storage */
00299   b->ve=(envelope_lookup*)_ogg_calloc(1,sizeof(*b->ve));
00300   
00301   _ve_envelope_init(b->ve,vi);
00302   
00303   vorbis_bitrate_init(vi,&b->bms);
00304   
00305   /* compressed audio packets start after the headers
00306      with sequence number 3 */
00307   v->sequence=3;
00308 
00309   return(0);
00310 }
00311 
00312 void vorbis_dsp_clear(vorbis_dsp_state *v){
00313   int i;
00314   if(v){
00315     vorbis_info *vi=v->vi;
00316     codec_setup_info *ci=(vi?(codec_setup_info*)vi->codec_setup:NULL);
00317     private_state *b=(private_state*)v->backend_state;
00318 
00319     if(b){
00320         
00321       if(b->ve){
00322         _ve_envelope_clear(b->ve);
00323         _ogg_free(b->ve);
00324       }
00325 
00326       if(b->transform[0]){
00327         mdct_clear((mdct_lookup*)b->transform[0][0]);
00328         _ogg_free(b->transform[0][0]);
00329         _ogg_free(b->transform[0]);
00330       }
00331       if(b->transform[1]){
00332         mdct_clear((mdct_lookup*)b->transform[1][0]);
00333         _ogg_free(b->transform[1][0]);
00334         _ogg_free(b->transform[1]);
00335       }
00336 
00337       if(b->flr){
00338         for(i=0;i<ci->floors;i++)
00339           _floor_P[ci->floor_type[i]]->
00340             free_look(b->flr[i]);
00341         _ogg_free(b->flr);
00342       }
00343       if(b->residue){
00344         for(i=0;i<ci->residues;i++)
00345           _residue_P[ci->residue_type[i]]->
00346             free_look(b->residue[i]);
00347         _ogg_free(b->residue);
00348       }
00349       if(b->psy){
00350         for(i=0;i<ci->psys;i++)
00351           _vp_psy_clear(b->psy+i);
00352         _ogg_free(b->psy);
00353       }
00354 
00355       if(b->psy_g_look)_vp_global_free(b->psy_g_look);
00356       vorbis_bitrate_clear(&b->bms);
00357 
00358       drft_clear(&b->fft_look[0]);
00359       drft_clear(&b->fft_look[1]);
00360 
00361     }
00362     
00363     if(v->pcm){
00364       for(i=0;i<vi->channels;i++)
00365         if(v->pcm[i])_ogg_free(v->pcm[i]);
00366       _ogg_free(v->pcm);
00367       if(v->pcmret)_ogg_free(v->pcmret);
00368     }
00369 
00370     if(b){
00371       /* free header, header1, header2 */
00372       if(b->header)_ogg_free(b->header);
00373       if(b->header1)_ogg_free(b->header1);
00374       if(b->header2)_ogg_free(b->header2);
00375       _ogg_free(b);
00376     }
00377     
00378     memset(v,0,sizeof(*v));
00379   }
00380 }
00381 
00382 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
00383   int i;
00384   vorbis_info *vi=v->vi;
00385   private_state *b=(private_state*)v->backend_state;
00386 
00387   /* free header, header1, header2 */
00388   if(b->header)_ogg_free(b->header);b->header=NULL;
00389   if(b->header1)_ogg_free(b->header1);b->header1=NULL;
00390   if(b->header2)_ogg_free(b->header2);b->header2=NULL;
00391 
00392   /* Do we have enough storage space for the requested buffer? If not,
00393      expand the PCM (and envelope) storage */
00394     
00395   if(v->pcm_current+vals>=v->pcm_storage){
00396     v->pcm_storage=v->pcm_current+vals*2;
00397    
00398     for(i=0;i<vi->channels;i++){
00399       v->pcm[i]=(float*)_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
00400     }
00401   }
00402 
00403   for(i=0;i<vi->channels;i++)
00404     v->pcmret[i]=v->pcm[i]+v->pcm_current;
00405     
00406   return(v->pcmret);
00407 }
00408 
00409 static void _preextrapolate_helper(vorbis_dsp_state *v){
00410   int i;
00411   int order=32;
00412   //float *lpc=alloca(order*sizeof(*lpc)); //patch
00413   //float *work=alloca(v->pcm_current*sizeof(*work)); //patch
00414   float *lpc=(float*)_ogg_malloc(order*sizeof(*lpc)); //patch
00415   float *work=(float*)_ogg_malloc(v->pcm_current*sizeof(*work)); //patch
00416   
00417   long j;
00418   v->preextrapolate=1;
00419 
00420   if(v->pcm_current-v->centerW>order*2){ /* safety */
00421     for(i=0;i<v->vi->channels;i++){
00422       /* need to run the extrapolation in reverse! */
00423       for(j=0;j<v->pcm_current;j++)
00424         work[j]=v->pcm[i][v->pcm_current-j-1];
00425       
00426       /* prime as above */
00427       vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
00428       
00429       /* run the predictor filter */
00430       vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
00431                          order,
00432                          work+v->pcm_current-v->centerW,
00433                          v->centerW);
00434 
00435       for(j=0;j<v->pcm_current;j++)
00436         v->pcm[i][v->pcm_current-j-1]=work[j];
00437 
00438     }
00439   }
00440   free(lpc); //patch
00441   free(work); //patch
00442 }
00443 
00444 
00445 /* call with val<=0 to set eof */
00446 
00447 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
00448   vorbis_info *vi=v->vi;
00449   codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00450 
00451   if(vals<=0){
00452     int order=32;
00453     int i;
00454     //float *lpc=alloca(order*sizeof(*lpc)); //patch
00455         float *lpc=(float*)_ogg_malloc(order*sizeof(*lpc));
00456         
00457     /* if it wasn't done earlier (very short sample) */
00458     if(!v->preextrapolate)
00459       _preextrapolate_helper(v);
00460 
00461     /* We're encoding the end of the stream.  Just make sure we have
00462        [at least] a few full blocks of zeroes at the end. */
00463     /* actually, we don't want zeroes; that could drop a large
00464        amplitude off a cliff, creating spread spectrum noise that will
00465        suck to encode.  Extrapolate for the sake of cleanliness. */
00466 
00467     vorbis_analysis_buffer(v,ci->blocksizes[1]*3); 
00468     v->eofflag=v->pcm_current;
00469     v->pcm_current+=ci->blocksizes[1]*3;
00470 
00471     for(i=0;i<vi->channels;i++){
00472       if(v->eofflag>order*2){
00473         /* extrapolate with LPC to fill in */
00474         long n;
00475 
00476         /* make a predictor filter */
00477         n=v->eofflag;
00478         if(n>ci->blocksizes[1])n=ci->blocksizes[1];
00479         vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
00480 
00481         /* run the predictor filter */
00482         vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
00483                            v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
00484       }else{
00485         /* not enough data to extrapolate (unlikely to happen due to
00486            guarding the overlap, but bulletproof in case that
00487            assumtion goes away). zeroes will do. */
00488         memset(v->pcm[i]+v->eofflag,0,
00489                (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
00490 
00491       }
00492     }
00493     free(lpc);//patch 
00494   }else{
00495 
00496     if(v->pcm_current+vals>v->pcm_storage)
00497       return(OV_EINVAL);
00498 
00499     v->pcm_current+=vals;
00500 
00501     /* we may want to reverse extrapolate the beginning of a stream
00502        too... in case we're beginning on a cliff! */
00503     /* clumsy, but simple.  It only runs once, so simple is good. */
00504     if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
00505       _preextrapolate_helper(v);
00506 
00507   }
00508   return(0);
00509 }
00510 
00511 /* do the deltas, envelope shaping, pre-echo and determine the size of
00512    the next block on which to continue analysis */
00513 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
00514   int i;
00515   vorbis_info *vi=v->vi;
00516   codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00517   private_state *b=(private_state*)v->backend_state;
00518   vorbis_look_psy_global *g=b->psy_g_look;
00519   long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
00520   vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
00521 
00522   /* check to see if we're started... */
00523   if(!v->preextrapolate)return(0);
00524 
00525   /* check to see if we're done... */
00526   if(v->eofflag==-1)return(0);
00527 
00528   /* By our invariant, we have lW, W and centerW set.  Search for
00529      the next boundary so we can determine nW (the next window size)
00530      which lets us compute the shape of the current block's window */
00531 
00532   /* we do an envelope search even on a single blocksize; we may still
00533      be throwing more bits at impulses, and envelope search handles
00534      marking impulses too. */
00535   {  
00536     long bp=_ve_envelope_search(v);
00537     if(bp==-1){
00538 
00539       if(v->eofflag==0)return(0); /* not enough data currently to search for a
00540                                      full long block */
00541       v->nW=0;
00542     }else{
00543 
00544       if(ci->blocksizes[0]==ci->blocksizes[1])
00545         v->nW=0;
00546       else
00547         v->nW=bp;
00548     }
00549   }
00550 
00551   centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
00552 
00553   {
00554     /* center of next block + next block maximum right side. */
00555 
00556     long blockbound=centerNext+ci->blocksizes[v->nW]/2;
00557     if(v->pcm_current<blockbound)return(0); /* not enough data yet;
00558                                                although this check is
00559                                                less strict that the
00560                                                _ve_envelope_search,
00561                                                the search is not run
00562                                                if we only use one
00563                                                block size */
00564 
00565 
00566   }
00567   
00568   /* fill in the block.  Note that for a short window, lW and nW are *short*
00569      regardless of actual settings in the stream */
00570 
00571   _vorbis_block_ripcord(vb);
00572   vb->lW=v->lW;
00573   vb->W=v->W;
00574   vb->nW=v->nW;
00575 
00576   if(v->W){
00577     if(!v->lW || !v->nW){
00578       vbi->blocktype=BLOCKTYPE_TRANSITION;
00579       /*fprintf(stderr,"-");*/
00580     }else{
00581       vbi->blocktype=BLOCKTYPE_LONG;
00582       /*fprintf(stderr,"_");*/
00583     }
00584   }else{
00585     if(_ve_envelope_mark(v)){
00586       vbi->blocktype=BLOCKTYPE_IMPULSE;
00587       /*fprintf(stderr,"|");*/
00588 
00589     }else{
00590       vbi->blocktype=BLOCKTYPE_PADDING;
00591       /*fprintf(stderr,".");*/
00592 
00593     }
00594   }
00595  
00596   vb->vd=v;
00597   vb->sequence=v->sequence++;
00598   vb->granulepos=v->granulepos;
00599   vb->pcmend=ci->blocksizes[v->W];
00600   
00601   /* copy the vectors; this uses the local storage in vb */
00602 
00603   /* this tracks 'strongest peak' for later psychoacoustics */
00604   /* moved to the global psy state; clean this mess up */
00605   if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
00606   g->ampmax=_vp_ampmax_decay(g->ampmax,v);
00607   vbi->ampmax=g->ampmax;
00608   
00609   vb->pcm=(float**)_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
00610   vbi->pcmdelay=(float**)_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
00611   for(i=0;i<vi->channels;i++){
00612     vbi->pcmdelay[i]=
00613       (float*)_vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
00614     memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
00615     vb->pcm[i]=vbi->pcmdelay[i]+beginW;
00616     
00617     /* before we added the delay 
00618        vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
00619        memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
00620     */
00621     
00622   }
00623   
00624   /* handle eof detection: eof==0 means that we've not yet received EOF
00625                            eof>0  marks the last 'real' sample in pcm[]
00626                            eof<0  'no more to do'; doesn't get here */
00627 
00628   if(v->eofflag){
00629     if(v->centerW>=v->eofflag){
00630       v->eofflag=-1;
00631       vb->eofflag=1;
00632       return(1);
00633     }
00634   }
00635 
00636   /* advance storage vectors and clean up */
00637   {
00638     int new_centerNext=ci->blocksizes[1]/2;
00639     int movementW=centerNext-new_centerNext;
00640 
00641     if(movementW>0){
00642 
00643       _ve_envelope_shift(b->ve,movementW);
00644       v->pcm_current-=movementW;
00645       
00646       for(i=0;i<vi->channels;i++)
00647         memmove(v->pcm[i],v->pcm[i]+movementW,
00648                 v->pcm_current*sizeof(*v->pcm[i]));
00649       
00650       
00651       v->lW=v->W;
00652       v->W=v->nW;
00653       v->centerW=new_centerNext;
00654       
00655       if(v->eofflag){
00656         v->eofflag-=movementW;
00657         if(v->eofflag<=0)v->eofflag=-1;
00658         /* do not add padding to end of stream! */
00659         if(v->centerW>=v->eofflag){
00660           v->granulepos+=movementW-(v->centerW-v->eofflag);
00661         }else{
00662           v->granulepos+=movementW;
00663         }
00664       }else{
00665         v->granulepos+=movementW;
00666       }
00667     }
00668   }
00669 
00670   /* done */
00671   return(1);
00672 }
00673 
00674 int vorbis_synthesis_restart(vorbis_dsp_state *v){
00675   vorbis_info *vi=v->vi;
00676   codec_setup_info *ci;
00677   int hs;
00678 
00679   if(!v->backend_state)return -1;
00680   if(!vi)return -1;
00681   ci=(codec_setup_info*)vi->codec_setup;
00682   if(!ci)return -1;
00683   hs=ci->halfrate_flag; 
00684 
00685   v->centerW=ci->blocksizes[1]>>(hs+1);
00686   v->pcm_current=v->centerW>>hs;
00687   
00688   v->pcm_returned=-1;
00689   v->granulepos=-1;
00690   v->sequence=-1;
00691   v->eofflag=0;
00692   ((private_state *)(v->backend_state))->sample_count=-1;
00693 
00694   return(0);
00695 }
00696 
00697 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
00698   if(_vds_shared_init(v,vi,0)) return 1;
00699   vorbis_synthesis_restart(v);
00700 
00701   return 0;
00702 }
00703 
00704 /* Unlike in analysis, the window is only partially applied for each
00705    block.  The time domain envelope is not yet handled at the point of
00706    calling (as it relies on the previous block). */
00707 
00708 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
00709   vorbis_info *vi=v->vi;
00710   codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00711   private_state *b=(private_state*)v->backend_state;
00712   int hs=ci->halfrate_flag; 
00713   int i,j;
00714 
00715   if(!vb)return(OV_EINVAL);
00716   if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
00717     
00718   v->lW=v->W;
00719   v->W=vb->W;
00720   v->nW=-1;
00721   
00722   if((v->sequence==-1)||
00723      (v->sequence+1 != vb->sequence)){
00724     v->granulepos=-1; /* out of sequence; lose count */
00725     b->sample_count=-1;
00726   }
00727 
00728   v->sequence=vb->sequence;
00729   
00730   if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly 
00731                    was called on block */
00732     int n=ci->blocksizes[v->W]>>(hs+1);
00733     int n0=ci->blocksizes[0]>>(hs+1);
00734     int n1=ci->blocksizes[1]>>(hs+1);
00735 
00736     int thisCenter;
00737     int prevCenter;
00738     
00739     v->glue_bits+=vb->glue_bits;
00740     v->time_bits+=vb->time_bits;
00741     v->floor_bits+=vb->floor_bits;
00742     v->res_bits+=vb->res_bits;
00743     
00744     if(v->centerW){
00745       thisCenter=n1;
00746       prevCenter=0;
00747     }else{
00748       thisCenter=0;
00749       prevCenter=n1;
00750     }
00751     
00752     /* v->pcm is now used like a two-stage double buffer.  We don't want
00753        to have to constantly shift *or* adjust memory usage.  Don't
00754        accept a new block until the old is shifted out */
00755     
00756     for(j=0;j<vi->channels;j++){
00757       /* the overlap/add section */
00758       if(v->lW){
00759         if(v->W){
00760           /* large/large */
00761           float *w=_vorbis_window_get(b->window[1]-hs);
00762           float *pcm=v->pcm[j]+prevCenter;
00763           float *p=vb->pcm[j];
00764           for(i=0;i<n1;i++)
00765             pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
00766         }else{
00767           /* large/small */
00768           float *w=_vorbis_window_get(b->window[0]-hs);
00769           float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
00770           float *p=vb->pcm[j];
00771           for(i=0;i<n0;i++)
00772             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
00773         }
00774       }else{
00775         if(v->W){
00776           /* small/large */
00777           float *w=_vorbis_window_get(b->window[0]-hs);
00778           float *pcm=v->pcm[j]+prevCenter;
00779           float *p=vb->pcm[j]+n1/2-n0/2;
00780           for(i=0;i<n0;i++)
00781             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
00782           for(;i<n1/2+n0/2;i++)
00783             pcm[i]=p[i];
00784         }else{
00785           /* small/small */
00786           float *w=_vorbis_window_get(b->window[0]-hs);
00787           float *pcm=v->pcm[j]+prevCenter;
00788           float *p=vb->pcm[j];
00789           for(i=0;i<n0;i++)
00790             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
00791         }
00792       }
00793       
00794       /* the copy section */
00795       {
00796         float *pcm=v->pcm[j]+thisCenter;
00797         float *p=vb->pcm[j]+n;
00798         for(i=0;i<n;i++)
00799           pcm[i]=p[i];
00800       }
00801     }
00802     
00803     if(v->centerW)
00804       v->centerW=0;
00805     else
00806       v->centerW=n1;
00807     
00808     /* deal with initial packet state; we do this using the explicit
00809        pcm_returned==-1 flag otherwise we're sensitive to first block
00810        being short or long */
00811     
00812     if(v->pcm_returned==-1){
00813       v->pcm_returned=thisCenter;
00814       v->pcm_current=thisCenter;
00815     }else{
00816       v->pcm_returned=prevCenter;
00817       v->pcm_current=prevCenter+
00818         ((ci->blocksizes[v->lW]/4+
00819         ci->blocksizes[v->W]/4)>>hs);
00820     }
00821     
00822   }
00823 
00824   /* track the frame number... This is for convenience, but also
00825      making sure our last packet doesn't end with added padding.  If
00826      the last packet is partial, the number of samples we'll have to
00827      return will be past the vb->granulepos.
00828      
00829      This is not foolproof!  It will be confused if we begin
00830      decoding at the last page after a seek or hole.  In that case,
00831      we don't have a starting point to judge where the last frame
00832      is.  For this reason, vorbisfile will always try to make sure
00833      it reads the last two marked pages in proper sequence */
00834 
00835   if(b->sample_count==-1){
00836     b->sample_count=0;
00837   }else{
00838     b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
00839   }
00840   
00841   if(v->granulepos==-1){
00842     if(vb->granulepos!=-1){ /* only set if we have a position to set to */
00843 
00844       v->granulepos=vb->granulepos;
00845 
00846       /* is this a short page? */
00847       if(b->sample_count>v->granulepos){
00848         /* corner case; if this is both the first and last audio page,
00849            then spec says the end is cut, not beginning */
00850         if(vb->eofflag){
00851           /* trim the end */
00852           /* no preceeding granulepos; assume we started at zero (we'd
00853              have to in a short single-page stream) */
00854           /* granulepos could be -1 due to a seek, but that would result
00855              in a long count, not short count */
00856           
00857           v->pcm_current-=(b->sample_count-v->granulepos)>>hs;
00858         }else{
00859           /* trim the beginning */
00860           v->pcm_returned+=(b->sample_count-v->granulepos)>>hs;
00861           if(v->pcm_returned>v->pcm_current)
00862             v->pcm_returned=v->pcm_current;
00863         }
00864 
00865       }
00866 
00867     }
00868   }else{
00869     v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
00870     if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
00871       
00872       if(v->granulepos>vb->granulepos){
00873         long extra=v->granulepos-vb->granulepos;
00874 
00875         if(extra)
00876           if(vb->eofflag){
00877             /* partial last frame.  Strip the extra samples off */
00878             v->pcm_current-=extra>>hs;
00879           } /* else {Shouldn't happen *unless* the bitstream is out of
00880                spec.  Either way, believe the bitstream } */
00881       } /* else {Shouldn't happen *unless* the bitstream is out of
00882            spec.  Either way, believe the bitstream } */
00883       v->granulepos=vb->granulepos;
00884     }
00885   }
00886   
00887   /* Update, cleanup */
00888   
00889   if(vb->eofflag)v->eofflag=1;
00890   return(0);
00891   
00892 }
00893 
00894 /* pcm==NULL indicates we just want the pending samples, no more */
00895 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
00896   vorbis_info *vi=v->vi;
00897 
00898   if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
00899     if(pcm){
00900       int i;
00901       for(i=0;i<vi->channels;i++)
00902         v->pcmret[i]=v->pcm[i]+v->pcm_returned;
00903       *pcm=v->pcmret;
00904     }
00905     return(v->pcm_current-v->pcm_returned);
00906   }
00907   return(0);
00908 }
00909 
00910 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
00911   if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
00912   v->pcm_returned+=n;
00913   return(0);
00914 }
00915 
00916 /* intended for use with a specific vorbisfile feature; we want access
00917    to the [usually synthetic/postextrapolated] buffer and lapping at
00918    the end of a decode cycle, specifically, a half-short-block worth.
00919    This funtion works like pcmout above, except it will also expose
00920    this implicit buffer data not normally decoded. */
00921 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
00922   vorbis_info *vi=v->vi;
00923   codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00924   int hs=ci->halfrate_flag; 
00925   
00926   int n=ci->blocksizes[v->W]>>(hs+1);
00927   int n0=ci->blocksizes[0]>>(hs+1);
00928   int n1=ci->blocksizes[1]>>(hs+1);
00929   int i,j;
00930 
00931   if(v->pcm_returned<0)return 0;
00932 
00933   /* our returned data ends at pcm_returned; because the synthesis pcm
00934      buffer is a two-fragment ring, that means our data block may be
00935      fragmented by buffering, wrapping or a short block not filling
00936      out a buffer.  To simplify things, we unfragment if it's at all
00937      possibly needed. Otherwise, we'd need to call lapout more than
00938      once as well as hold additional dsp state.  Opt for
00939      simplicity. */
00940 
00941   /* centerW was advanced by blockin; it would be the center of the
00942      *next* block */
00943   if(v->centerW==n1){
00944     /* the data buffer wraps; swap the halves */
00945     /* slow, sure, small */
00946     for(j=0;j<vi->channels;j++){
00947       float *p=v->pcm[j];
00948       for(i=0;i<n1;i++){
00949         float temp=p[i];
00950         p[i]=p[i+n1];
00951         p[i+n1]=temp;
00952       }
00953     }
00954 
00955     v->pcm_current-=n1;
00956     v->pcm_returned-=n1;
00957     v->centerW=0;
00958   }
00959   
00960   /* solidify buffer into contiguous space */
00961   if((v->lW^v->W)==1){
00962     /* long/short or short/long */
00963     for(j=0;j<vi->channels;j++){
00964       float *s=v->pcm[j];
00965       float *d=v->pcm[j]+(n1-n0)/2;
00966       for(i=(n1+n0)/2-1;i>=0;--i)
00967         d[i]=s[i];
00968     }
00969     v->pcm_returned+=(n1-n0)/2;
00970     v->pcm_current+=(n1-n0)/2;
00971   }else{
00972     if(v->lW==0){
00973       /* short/short */
00974       for(j=0;j<vi->channels;j++){
00975         float *s=v->pcm[j];
00976         float *d=v->pcm[j]+n1-n0;
00977         for(i=n0-1;i>=0;--i)
00978           d[i]=s[i];
00979       }
00980       v->pcm_returned+=n1-n0;
00981       v->pcm_current+=n1-n0;
00982     }
00983   }
00984     
00985   if(pcm){
00986     int i;
00987     for(i=0;i<vi->channels;i++)
00988       v->pcmret[i]=v->pcm[i]+v->pcm_returned;
00989     *pcm=v->pcmret;
00990   }
00991 
00992   return(n1+n-v->pcm_returned);
00993 
00994 }
00995 
00996 float *vorbis_window(vorbis_dsp_state *v,int W){
00997   vorbis_info *vi=v->vi;
00998   codec_setup_info *ci=(codec_setup_info*)vi->codec_setup;
00999   int hs=ci->halfrate_flag; 
01000   private_state *b=(private_state*)v->backend_state;
01001 
01002   if(b->window[W]-1<0)return NULL;
01003   return _vorbis_window_get(b->window[W]-hs);
01004 }
01005         

Generated by  doxygen 1.6.2