media/libvorbis/lib/vorbis_block.c

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /********************************************************************
     2  *                                                                  *
     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.       *
     7  *                                                                  *
     8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
     9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
    10  *                                                                  *
    11  ********************************************************************
    13  function: PCM data vector blocking, windowing and dis/reassembly
    14  last mod: $Id: block.c 19031 2013-12-03 19:20:50Z tterribe $
    16  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
    17  more amusing by Vorbis' current two allowed block sizes.
    19  ********************************************************************/
    21 #include <stdio.h>
    22 #include <stdlib.h>
    23 #include <string.h>
    24 #include <ogg/ogg.h>
    25 #include "vorbis/codec.h"
    26 #include "codec_internal.h"
    28 #include "window.h"
    29 #include "mdct.h"
    30 #include "lpc.h"
    31 #include "registry.h"
    32 #include "misc.h"
    34 static int ilog2(unsigned int v){
    35   int ret=0;
    36   if(v)--v;
    37   while(v){
    38     ret++;
    39     v>>=1;
    40   }
    41   return(ret);
    42 }
    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
    57                       |< lW >|
    58                    <--------------- W ---------------->
    59                   |   |  ..  ______________            |
    60                   |   | '  `/        |     ---_        |
    61                   |___.'___/`.       |         ---_____|
    62                   |_______|__|_______|_________________|
    63                   |      >|Sl|<      |<------ Sr ----->|endW
    64                   |       |  |endSl  |beginSr          |endSr
    65                   |beginW |  |endlW
    66                   mult[0] |beginSl                     mult[n]
    68  <-------------- lW ----------------->
    69                           |<--W-->|
    70 :            ..............  ___  |   |
    71 :        .'''             |`/   \ |   |
    72 :.....'''                 |/`....\|...|
    73 :.........................|___|___|___|
    74                           |Sl |Sr |endW
    75                           |   |   |endSr
    76                           |   |beginSr
    77                           |   |endSl
    78                           |beginSl
    79                           |beginW
    80 */
    82 /* block abstraction setup *********************************************/
    84 #ifndef WORD_ALIGN
    85 #define WORD_ALIGN 8
    86 #endif
    88 int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
    89   int i;
    90   memset(vb,0,sizeof(*vb));
    91   vb->vd=v;
    92   vb->localalloc=0;
    93   vb->localstore=NULL;
    94   if(v->analysisp){
    95     vorbis_block_internal *vbi=
    96       vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
    97     vbi->ampmax=-9999;
    99     for(i=0;i<PACKETBLOBS;i++){
   100       if(i==PACKETBLOBS/2){
   101         vbi->packetblob[i]=&vb->opb;
   102       }else{
   103         vbi->packetblob[i]=
   104           _ogg_calloc(1,sizeof(oggpack_buffer));
   105       }
   106       oggpack_writeinit(vbi->packetblob[i]);
   107     }
   108   }
   110   return(0);
   111 }
   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 */
   117     if(vb->localstore){
   118       struct alloc_chain *link=_ogg_malloc(sizeof(*link));
   119       vb->totaluse+=vb->localtop;
   120       link->next=vb->reap;
   121       link->ptr=vb->localstore;
   122       vb->reap=link;
   123     }
   124     /* highly conservative */
   125     vb->localalloc=bytes;
   126     vb->localstore=_ogg_malloc(vb->localalloc);
   127     vb->localtop=0;
   128   }
   129   {
   130     void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
   131     vb->localtop+=bytes;
   132     return ret;
   133   }
   134 }
   136 /* reap the chain, pull the ripcord */
   137 void _vorbis_block_ripcord(vorbis_block *vb){
   138   /* reap the chain */
   139   struct alloc_chain *reap=vb->reap;
   140   while(reap){
   141     struct alloc_chain *next=reap->next;
   142     _ogg_free(reap->ptr);
   143     memset(reap,0,sizeof(*reap));
   144     _ogg_free(reap);
   145     reap=next;
   146   }
   147   /* consolidate storage */
   148   if(vb->totaluse){
   149     vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
   150     vb->localalloc+=vb->totaluse;
   151     vb->totaluse=0;
   152   }
   154   /* pull the ripcord */
   155   vb->localtop=0;
   156   vb->reap=NULL;
   157 }
   159 int vorbis_block_clear(vorbis_block *vb){
   160   int i;
   161   vorbis_block_internal *vbi=vb->internal;
   163   _vorbis_block_ripcord(vb);
   164   if(vb->localstore)_ogg_free(vb->localstore);
   166   if(vbi){
   167     for(i=0;i<PACKETBLOBS;i++){
   168       oggpack_writeclear(vbi->packetblob[i]);
   169       if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
   170     }
   171     _ogg_free(vbi);
   172   }
   173   memset(vb,0,sizeof(*vb));
   174   return(0);
   175 }
   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){
   182   int i;
   183   codec_setup_info *ci=vi->codec_setup;
   184   private_state *b=NULL;
   185   int hs;
   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));
   193   v->vi=vi;
   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 */
   217     if(!ci->fullbooks){
   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]);
   221     }
   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,
   226                    ci->psy_param[i],
   227                    &ci->psy_g_param,
   228                    ci->blocksizes[ci->psy_param[i]->blockflag]/2,
   229                    vi->rate);
   230     }
   232     v->analysisp=1;
   233   }else{
   234     /* finish the codebooks */
   235     if(!ci->fullbooks){
   236       ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
   237       for(i=0;i<ci->books;i++){
   238         if(ci->book_param[i]==NULL)
   239           goto abort_books;
   240         if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
   241           goto abort_books;
   242         /* decode codebooks are now standalone after init */
   243         vorbis_staticbook_destroy(ci->book_param[i]);
   244         ci->book_param[i]=NULL;
   245       }
   246     }
   247   }
   249   /* initialize the storage vectors. blocksize[1] is small for encode,
   250      but the correct size for decode */
   251   v->pcm_storage=ci->blocksizes[1];
   252   v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
   253   v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
   254   {
   255     int i;
   256     for(i=0;i<vi->channels;i++)
   257       v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
   258   }
   260   /* all 1 (large block) or 0 (small block) */
   261   /* explicitly set for the sake of clarity */
   262   v->lW=0; /* previous window size */
   263   v->W=0;  /* current window size */
   265   /* all vector indexes */
   266   v->centerW=ci->blocksizes[1]/2;
   268   v->pcm_current=v->centerW;
   270   /* initialize all the backend lookups */
   271   b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
   272   b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
   274   for(i=0;i<ci->floors;i++)
   275     b->flr[i]=_floor_P[ci->floor_type[i]]->
   276       look(v,ci->floor_param[i]);
   278   for(i=0;i<ci->residues;i++)
   279     b->residue[i]=_residue_P[ci->residue_type[i]]->
   280       look(v,ci->residue_param[i]);
   282   return 0;
   283  abort_books:
   284   for(i=0;i<ci->books;i++){
   285     if(ci->book_param[i]!=NULL){
   286       vorbis_staticbook_destroy(ci->book_param[i]);
   287       ci->book_param[i]=NULL;
   288     }
   289   }
   290   vorbis_dsp_clear(v);
   291   return -1;
   292 }
   294 /* arbitrary settings and spec-mandated numbers get filled in here */
   295 int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
   296   private_state *b=NULL;
   298   if(_vds_shared_init(v,vi,1))return 1;
   299   b=v->backend_state;
   300   b->psy_g_look=_vp_global_look(vi);
   302   /* Initialize the envelope state storage */
   303   b->ve=_ogg_calloc(1,sizeof(*b->ve));
   304   _ve_envelope_init(b->ve,vi);
   306   vorbis_bitrate_init(vi,&b->bms);
   308   /* compressed audio packets start after the headers
   309      with sequence number 3 */
   310   v->sequence=3;
   312   return(0);
   313 }
   315 void vorbis_dsp_clear(vorbis_dsp_state *v){
   316   int i;
   317   if(v){
   318     vorbis_info *vi=v->vi;
   319     codec_setup_info *ci=(vi?vi->codec_setup:NULL);
   320     private_state *b=v->backend_state;
   322     if(b){
   324       if(b->ve){
   325         _ve_envelope_clear(b->ve);
   326         _ogg_free(b->ve);
   327       }
   329       if(b->transform[0]){
   330         mdct_clear(b->transform[0][0]);
   331         _ogg_free(b->transform[0][0]);
   332         _ogg_free(b->transform[0]);
   333       }
   334       if(b->transform[1]){
   335         mdct_clear(b->transform[1][0]);
   336         _ogg_free(b->transform[1][0]);
   337         _ogg_free(b->transform[1]);
   338       }
   340       if(b->flr){
   341         if(ci)
   342           for(i=0;i<ci->floors;i++)
   343             _floor_P[ci->floor_type[i]]->
   344               free_look(b->flr[i]);
   345         _ogg_free(b->flr);
   346       }
   347       if(b->residue){
   348         if(ci)
   349           for(i=0;i<ci->residues;i++)
   350             _residue_P[ci->residue_type[i]]->
   351               free_look(b->residue[i]);
   352         _ogg_free(b->residue);
   353       }
   354       if(b->psy){
   355         if(ci)
   356           for(i=0;i<ci->psys;i++)
   357             _vp_psy_clear(b->psy+i);
   358         _ogg_free(b->psy);
   359       }
   361       if(b->psy_g_look)_vp_global_free(b->psy_g_look);
   362       vorbis_bitrate_clear(&b->bms);
   364       drft_clear(&b->fft_look[0]);
   365       drft_clear(&b->fft_look[1]);
   367     }
   369     if(v->pcm){
   370       if(vi)
   371         for(i=0;i<vi->channels;i++)
   372           if(v->pcm[i])_ogg_free(v->pcm[i]);
   373       _ogg_free(v->pcm);
   374       if(v->pcmret)_ogg_free(v->pcmret);
   375     }
   377     if(b){
   378       /* free header, header1, header2 */
   379       if(b->header)_ogg_free(b->header);
   380       if(b->header1)_ogg_free(b->header1);
   381       if(b->header2)_ogg_free(b->header2);
   382       _ogg_free(b);
   383     }
   385     memset(v,0,sizeof(*v));
   386   }
   387 }
   389 float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
   390   int i;
   391   vorbis_info *vi=v->vi;
   392   private_state *b=v->backend_state;
   394   /* free header, header1, header2 */
   395   if(b->header)_ogg_free(b->header);b->header=NULL;
   396   if(b->header1)_ogg_free(b->header1);b->header1=NULL;
   397   if(b->header2)_ogg_free(b->header2);b->header2=NULL;
   399   /* Do we have enough storage space for the requested buffer? If not,
   400      expand the PCM (and envelope) storage */
   402   if(v->pcm_current+vals>=v->pcm_storage){
   403     v->pcm_storage=v->pcm_current+vals*2;
   405     for(i=0;i<vi->channels;i++){
   406       v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
   407     }
   408   }
   410   for(i=0;i<vi->channels;i++)
   411     v->pcmret[i]=v->pcm[i]+v->pcm_current;
   413   return(v->pcmret);
   414 }
   416 static void _preextrapolate_helper(vorbis_dsp_state *v){
   417   int i;
   418   int order=16;
   419   float *lpc=alloca(order*sizeof(*lpc));
   420   float *work=alloca(v->pcm_current*sizeof(*work));
   421   long j;
   422   v->preextrapolate=1;
   424   if(v->pcm_current-v->centerW>order*2){ /* safety */
   425     for(i=0;i<v->vi->channels;i++){
   426       /* need to run the extrapolation in reverse! */
   427       for(j=0;j<v->pcm_current;j++)
   428         work[j]=v->pcm[i][v->pcm_current-j-1];
   430       /* prime as above */
   431       vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
   433 #if 0
   434       if(v->vi->channels==2){
   435         if(i==0)
   436           _analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
   437         else
   438           _analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
   439       }else{
   440         _analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
   441       }
   442 #endif
   444       /* run the predictor filter */
   445       vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
   446                          order,
   447                          work+v->pcm_current-v->centerW,
   448                          v->centerW);
   450       for(j=0;j<v->pcm_current;j++)
   451         v->pcm[i][v->pcm_current-j-1]=work[j];
   453     }
   454   }
   455 }
   458 /* call with val<=0 to set eof */
   460 int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
   461   vorbis_info *vi=v->vi;
   462   codec_setup_info *ci=vi->codec_setup;
   464   if(vals<=0){
   465     int order=32;
   466     int i;
   467     float *lpc=alloca(order*sizeof(*lpc));
   469     /* if it wasn't done earlier (very short sample) */
   470     if(!v->preextrapolate)
   471       _preextrapolate_helper(v);
   473     /* We're encoding the end of the stream.  Just make sure we have
   474        [at least] a few full blocks of zeroes at the end. */
   475     /* actually, we don't want zeroes; that could drop a large
   476        amplitude off a cliff, creating spread spectrum noise that will
   477        suck to encode.  Extrapolate for the sake of cleanliness. */
   479     vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
   480     v->eofflag=v->pcm_current;
   481     v->pcm_current+=ci->blocksizes[1]*3;
   483     for(i=0;i<vi->channels;i++){
   484       if(v->eofflag>order*2){
   485         /* extrapolate with LPC to fill in */
   486         long n;
   488         /* make a predictor filter */
   489         n=v->eofflag;
   490         if(n>ci->blocksizes[1])n=ci->blocksizes[1];
   491         vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
   493         /* run the predictor filter */
   494         vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
   495                            v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
   496       }else{
   497         /* not enough data to extrapolate (unlikely to happen due to
   498            guarding the overlap, but bulletproof in case that
   499            assumtion goes away). zeroes will do. */
   500         memset(v->pcm[i]+v->eofflag,0,
   501                (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
   503       }
   504     }
   505   }else{
   507     if(v->pcm_current+vals>v->pcm_storage)
   508       return(OV_EINVAL);
   510     v->pcm_current+=vals;
   512     /* we may want to reverse extrapolate the beginning of a stream
   513        too... in case we're beginning on a cliff! */
   514     /* clumsy, but simple.  It only runs once, so simple is good. */
   515     if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
   516       _preextrapolate_helper(v);
   518   }
   519   return(0);
   520 }
   522 /* do the deltas, envelope shaping, pre-echo and determine the size of
   523    the next block on which to continue analysis */
   524 int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
   525   int i;
   526   vorbis_info *vi=v->vi;
   527   codec_setup_info *ci=vi->codec_setup;
   528   private_state *b=v->backend_state;
   529   vorbis_look_psy_global *g=b->psy_g_look;
   530   long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
   531   vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
   533   /* check to see if we're started... */
   534   if(!v->preextrapolate)return(0);
   536   /* check to see if we're done... */
   537   if(v->eofflag==-1)return(0);
   539   /* By our invariant, we have lW, W and centerW set.  Search for
   540      the next boundary so we can determine nW (the next window size)
   541      which lets us compute the shape of the current block's window */
   543   /* we do an envelope search even on a single blocksize; we may still
   544      be throwing more bits at impulses, and envelope search handles
   545      marking impulses too. */
   546   {
   547     long bp=_ve_envelope_search(v);
   548     if(bp==-1){
   550       if(v->eofflag==0)return(0); /* not enough data currently to search for a
   551                                      full long block */
   552       v->nW=0;
   553     }else{
   555       if(ci->blocksizes[0]==ci->blocksizes[1])
   556         v->nW=0;
   557       else
   558         v->nW=bp;
   559     }
   560   }
   562   centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
   564   {
   565     /* center of next block + next block maximum right side. */
   567     long blockbound=centerNext+ci->blocksizes[v->nW]/2;
   568     if(v->pcm_current<blockbound)return(0); /* not enough data yet;
   569                                                although this check is
   570                                                less strict that the
   571                                                _ve_envelope_search,
   572                                                the search is not run
   573                                                if we only use one
   574                                                block size */
   577   }
   579   /* fill in the block.  Note that for a short window, lW and nW are *short*
   580      regardless of actual settings in the stream */
   582   _vorbis_block_ripcord(vb);
   583   vb->lW=v->lW;
   584   vb->W=v->W;
   585   vb->nW=v->nW;
   587   if(v->W){
   588     if(!v->lW || !v->nW){
   589       vbi->blocktype=BLOCKTYPE_TRANSITION;
   590       /*fprintf(stderr,"-");*/
   591     }else{
   592       vbi->blocktype=BLOCKTYPE_LONG;
   593       /*fprintf(stderr,"_");*/
   594     }
   595   }else{
   596     if(_ve_envelope_mark(v)){
   597       vbi->blocktype=BLOCKTYPE_IMPULSE;
   598       /*fprintf(stderr,"|");*/
   600     }else{
   601       vbi->blocktype=BLOCKTYPE_PADDING;
   602       /*fprintf(stderr,".");*/
   604     }
   605   }
   607   vb->vd=v;
   608   vb->sequence=v->sequence++;
   609   vb->granulepos=v->granulepos;
   610   vb->pcmend=ci->blocksizes[v->W];
   612   /* copy the vectors; this uses the local storage in vb */
   614   /* this tracks 'strongest peak' for later psychoacoustics */
   615   /* moved to the global psy state; clean this mess up */
   616   if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
   617   g->ampmax=_vp_ampmax_decay(g->ampmax,v);
   618   vbi->ampmax=g->ampmax;
   620   vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
   621   vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
   622   for(i=0;i<vi->channels;i++){
   623     vbi->pcmdelay[i]=
   624       _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
   625     memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
   626     vb->pcm[i]=vbi->pcmdelay[i]+beginW;
   628     /* before we added the delay
   629        vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
   630        memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
   631     */
   633   }
   635   /* handle eof detection: eof==0 means that we've not yet received EOF
   636                            eof>0  marks the last 'real' sample in pcm[]
   637                            eof<0  'no more to do'; doesn't get here */
   639   if(v->eofflag){
   640     if(v->centerW>=v->eofflag){
   641       v->eofflag=-1;
   642       vb->eofflag=1;
   643       return(1);
   644     }
   645   }
   647   /* advance storage vectors and clean up */
   648   {
   649     int new_centerNext=ci->blocksizes[1]/2;
   650     int movementW=centerNext-new_centerNext;
   652     if(movementW>0){
   654       _ve_envelope_shift(b->ve,movementW);
   655       v->pcm_current-=movementW;
   657       for(i=0;i<vi->channels;i++)
   658         memmove(v->pcm[i],v->pcm[i]+movementW,
   659                 v->pcm_current*sizeof(*v->pcm[i]));
   662       v->lW=v->W;
   663       v->W=v->nW;
   664       v->centerW=new_centerNext;
   666       if(v->eofflag){
   667         v->eofflag-=movementW;
   668         if(v->eofflag<=0)v->eofflag=-1;
   669         /* do not add padding to end of stream! */
   670         if(v->centerW>=v->eofflag){
   671           v->granulepos+=movementW-(v->centerW-v->eofflag);
   672         }else{
   673           v->granulepos+=movementW;
   674         }
   675       }else{
   676         v->granulepos+=movementW;
   677       }
   678     }
   679   }
   681   /* done */
   682   return(1);
   683 }
   685 int vorbis_synthesis_restart(vorbis_dsp_state *v){
   686   vorbis_info *vi=v->vi;
   687   codec_setup_info *ci;
   688   int hs;
   690   if(!v->backend_state)return -1;
   691   if(!vi)return -1;
   692   ci=vi->codec_setup;
   693   if(!ci)return -1;
   694   hs=ci->halfrate_flag;
   696   v->centerW=ci->blocksizes[1]>>(hs+1);
   697   v->pcm_current=v->centerW>>hs;
   699   v->pcm_returned=-1;
   700   v->granulepos=-1;
   701   v->sequence=-1;
   702   v->eofflag=0;
   703   ((private_state *)(v->backend_state))->sample_count=-1;
   705   return(0);
   706 }
   708 int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
   709   if(_vds_shared_init(v,vi,0)){
   710     vorbis_dsp_clear(v);
   711     return 1;
   712   }
   713   vorbis_synthesis_restart(v);
   714   return 0;
   715 }
   717 /* Unlike in analysis, the window is only partially applied for each
   718    block.  The time domain envelope is not yet handled at the point of
   719    calling (as it relies on the previous block). */
   721 int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
   722   vorbis_info *vi=v->vi;
   723   codec_setup_info *ci=vi->codec_setup;
   724   private_state *b=v->backend_state;
   725   int hs=ci->halfrate_flag;
   726   int i,j;
   728   if(!vb)return(OV_EINVAL);
   729   if(v->pcm_current>v->pcm_returned  && v->pcm_returned!=-1)return(OV_EINVAL);
   731   v->lW=v->W;
   732   v->W=vb->W;
   733   v->nW=-1;
   735   if((v->sequence==-1)||
   736      (v->sequence+1 != vb->sequence)){
   737     v->granulepos=-1; /* out of sequence; lose count */
   738     b->sample_count=-1;
   739   }
   741   v->sequence=vb->sequence;
   743   if(vb->pcm){  /* no pcm to process if vorbis_synthesis_trackonly
   744                    was called on block */
   745     int n=ci->blocksizes[v->W]>>(hs+1);
   746     int n0=ci->blocksizes[0]>>(hs+1);
   747     int n1=ci->blocksizes[1]>>(hs+1);
   749     int thisCenter;
   750     int prevCenter;
   752     v->glue_bits+=vb->glue_bits;
   753     v->time_bits+=vb->time_bits;
   754     v->floor_bits+=vb->floor_bits;
   755     v->res_bits+=vb->res_bits;
   757     if(v->centerW){
   758       thisCenter=n1;
   759       prevCenter=0;
   760     }else{
   761       thisCenter=0;
   762       prevCenter=n1;
   763     }
   765     /* v->pcm is now used like a two-stage double buffer.  We don't want
   766        to have to constantly shift *or* adjust memory usage.  Don't
   767        accept a new block until the old is shifted out */
   769     for(j=0;j<vi->channels;j++){
   770       /* the overlap/add section */
   771       if(v->lW){
   772         if(v->W){
   773           /* large/large */
   774           const float *w=_vorbis_window_get(b->window[1]-hs);
   775           float *pcm=v->pcm[j]+prevCenter;
   776           float *p=vb->pcm[j];
   777           for(i=0;i<n1;i++)
   778             pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
   779         }else{
   780           /* large/small */
   781           const float *w=_vorbis_window_get(b->window[0]-hs);
   782           float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
   783           float *p=vb->pcm[j];
   784           for(i=0;i<n0;i++)
   785             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
   786         }
   787       }else{
   788         if(v->W){
   789           /* small/large */
   790           const float *w=_vorbis_window_get(b->window[0]-hs);
   791           float *pcm=v->pcm[j]+prevCenter;
   792           float *p=vb->pcm[j]+n1/2-n0/2;
   793           for(i=0;i<n0;i++)
   794             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
   795           for(;i<n1/2+n0/2;i++)
   796             pcm[i]=p[i];
   797         }else{
   798           /* small/small */
   799           const float *w=_vorbis_window_get(b->window[0]-hs);
   800           float *pcm=v->pcm[j]+prevCenter;
   801           float *p=vb->pcm[j];
   802           for(i=0;i<n0;i++)
   803             pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
   804         }
   805       }
   807       /* the copy section */
   808       {
   809         float *pcm=v->pcm[j]+thisCenter;
   810         float *p=vb->pcm[j]+n;
   811         for(i=0;i<n;i++)
   812           pcm[i]=p[i];
   813       }
   814     }
   816     if(v->centerW)
   817       v->centerW=0;
   818     else
   819       v->centerW=n1;
   821     /* deal with initial packet state; we do this using the explicit
   822        pcm_returned==-1 flag otherwise we're sensitive to first block
   823        being short or long */
   825     if(v->pcm_returned==-1){
   826       v->pcm_returned=thisCenter;
   827       v->pcm_current=thisCenter;
   828     }else{
   829       v->pcm_returned=prevCenter;
   830       v->pcm_current=prevCenter+
   831         ((ci->blocksizes[v->lW]/4+
   832         ci->blocksizes[v->W]/4)>>hs);
   833     }
   835   }
   837   /* track the frame number... This is for convenience, but also
   838      making sure our last packet doesn't end with added padding.  If
   839      the last packet is partial, the number of samples we'll have to
   840      return will be past the vb->granulepos.
   842      This is not foolproof!  It will be confused if we begin
   843      decoding at the last page after a seek or hole.  In that case,
   844      we don't have a starting point to judge where the last frame
   845      is.  For this reason, vorbisfile will always try to make sure
   846      it reads the last two marked pages in proper sequence */
   848   if(b->sample_count==-1){
   849     b->sample_count=0;
   850   }else{
   851     b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
   852   }
   854   if(v->granulepos==-1){
   855     if(vb->granulepos!=-1){ /* only set if we have a position to set to */
   857       v->granulepos=vb->granulepos;
   859       /* is this a short page? */
   860       if(b->sample_count>v->granulepos){
   861         /* corner case; if this is both the first and last audio page,
   862            then spec says the end is cut, not beginning */
   863        long extra=b->sample_count-vb->granulepos;
   865         /* we use ogg_int64_t for granule positions because a
   866            uint64 isn't universally available.  Unfortunately,
   867            that means granposes can be 'negative' and result in
   868            extra being negative */
   869         if(extra<0)
   870           extra=0;
   872         if(vb->eofflag){
   873           /* trim the end */
   874           /* no preceding granulepos; assume we started at zero (we'd
   875              have to in a short single-page stream) */
   876           /* granulepos could be -1 due to a seek, but that would result
   877              in a long count, not short count */
   879           /* Guard against corrupt/malicious frames that set EOP and
   880              a backdated granpos; don't rewind more samples than we
   881              actually have */
   882           if(extra > (v->pcm_current - v->pcm_returned)<<hs)
   883             extra = (v->pcm_current - v->pcm_returned)<<hs;
   885           v->pcm_current-=extra>>hs;
   886         }else{
   887           /* trim the beginning */
   888           v->pcm_returned+=extra>>hs;
   889           if(v->pcm_returned>v->pcm_current)
   890             v->pcm_returned=v->pcm_current;
   891         }
   893       }
   895     }
   896   }else{
   897     v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
   898     if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
   900       if(v->granulepos>vb->granulepos){
   901         long extra=v->granulepos-vb->granulepos;
   903         if(extra)
   904           if(vb->eofflag){
   905             /* partial last frame.  Strip the extra samples off */
   907             /* Guard against corrupt/malicious frames that set EOP and
   908                a backdated granpos; don't rewind more samples than we
   909                actually have */
   910             if(extra > (v->pcm_current - v->pcm_returned)<<hs)
   911               extra = (v->pcm_current - v->pcm_returned)<<hs;
   913             /* we use ogg_int64_t for granule positions because a
   914                uint64 isn't universally available.  Unfortunately,
   915                that means granposes can be 'negative' and result in
   916                extra being negative */
   917             if(extra<0)
   918               extra=0;
   920             v->pcm_current-=extra>>hs;
   921           } /* else {Shouldn't happen *unless* the bitstream is out of
   922                spec.  Either way, believe the bitstream } */
   923       } /* else {Shouldn't happen *unless* the bitstream is out of
   924            spec.  Either way, believe the bitstream } */
   925       v->granulepos=vb->granulepos;
   926     }
   927   }
   929   /* Update, cleanup */
   931   if(vb->eofflag)v->eofflag=1;
   932   return(0);
   934 }
   936 /* pcm==NULL indicates we just want the pending samples, no more */
   937 int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
   938   vorbis_info *vi=v->vi;
   940   if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
   941     if(pcm){
   942       int i;
   943       for(i=0;i<vi->channels;i++)
   944         v->pcmret[i]=v->pcm[i]+v->pcm_returned;
   945       *pcm=v->pcmret;
   946     }
   947     return(v->pcm_current-v->pcm_returned);
   948   }
   949   return(0);
   950 }
   952 int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
   953   if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
   954   v->pcm_returned+=n;
   955   return(0);
   956 }
   958 /* intended for use with a specific vorbisfile feature; we want access
   959    to the [usually synthetic/postextrapolated] buffer and lapping at
   960    the end of a decode cycle, specifically, a half-short-block worth.
   961    This funtion works like pcmout above, except it will also expose
   962    this implicit buffer data not normally decoded. */
   963 int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
   964   vorbis_info *vi=v->vi;
   965   codec_setup_info *ci=vi->codec_setup;
   966   int hs=ci->halfrate_flag;
   968   int n=ci->blocksizes[v->W]>>(hs+1);
   969   int n0=ci->blocksizes[0]>>(hs+1);
   970   int n1=ci->blocksizes[1]>>(hs+1);
   971   int i,j;
   973   if(v->pcm_returned<0)return 0;
   975   /* our returned data ends at pcm_returned; because the synthesis pcm
   976      buffer is a two-fragment ring, that means our data block may be
   977      fragmented by buffering, wrapping or a short block not filling
   978      out a buffer.  To simplify things, we unfragment if it's at all
   979      possibly needed. Otherwise, we'd need to call lapout more than
   980      once as well as hold additional dsp state.  Opt for
   981      simplicity. */
   983   /* centerW was advanced by blockin; it would be the center of the
   984      *next* block */
   985   if(v->centerW==n1){
   986     /* the data buffer wraps; swap the halves */
   987     /* slow, sure, small */
   988     for(j=0;j<vi->channels;j++){
   989       float *p=v->pcm[j];
   990       for(i=0;i<n1;i++){
   991         float temp=p[i];
   992         p[i]=p[i+n1];
   993         p[i+n1]=temp;
   994       }
   995     }
   997     v->pcm_current-=n1;
   998     v->pcm_returned-=n1;
   999     v->centerW=0;
  1002   /* solidify buffer into contiguous space */
  1003   if((v->lW^v->W)==1){
  1004     /* long/short or short/long */
  1005     for(j=0;j<vi->channels;j++){
  1006       float *s=v->pcm[j];
  1007       float *d=v->pcm[j]+(n1-n0)/2;
  1008       for(i=(n1+n0)/2-1;i>=0;--i)
  1009         d[i]=s[i];
  1011     v->pcm_returned+=(n1-n0)/2;
  1012     v->pcm_current+=(n1-n0)/2;
  1013   }else{
  1014     if(v->lW==0){
  1015       /* short/short */
  1016       for(j=0;j<vi->channels;j++){
  1017         float *s=v->pcm[j];
  1018         float *d=v->pcm[j]+n1-n0;
  1019         for(i=n0-1;i>=0;--i)
  1020           d[i]=s[i];
  1022       v->pcm_returned+=n1-n0;
  1023       v->pcm_current+=n1-n0;
  1027   if(pcm){
  1028     int i;
  1029     for(i=0;i<vi->channels;i++)
  1030       v->pcmret[i]=v->pcm[i]+v->pcm_returned;
  1031     *pcm=v->pcmret;
  1034   return(n1+n-v->pcm_returned);
  1038 const float *vorbis_window(vorbis_dsp_state *v,int W){
  1039   vorbis_info *vi=v->vi;
  1040   codec_setup_info *ci=vi->codec_setup;
  1041   int hs=ci->halfrate_flag;
  1042   private_state *b=v->backend_state;
  1044   if(b->window[W]-1<0)return NULL;
  1045   return _vorbis_window_get(b->window[W]-hs);

mercurial