LCOV - code coverage report
Current view: top level - media/libvorbis/lib - vorbis_block.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 483 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13