tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

vorbis_floor0.c (6889B)


      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 https://xiph.org/                     *
     10 *                                                                  *
     11 ********************************************************************
     12 
     13 function: floor backend 0 implementation
     14 
     15 ********************************************************************/
     16 
     17 #include <stdlib.h>
     18 #include <string.h>
     19 #include <math.h>
     20 #include <ogg/ogg.h>
     21 #include "vorbis/codec.h"
     22 #include "codec_internal.h"
     23 #include "registry.h"
     24 #include "lpc.h"
     25 #include "lsp.h"
     26 #include "codebook.h"
     27 #include "scales.h"
     28 #include "misc.h"
     29 #include "os.h"
     30 
     31 #include "misc.h"
     32 #include <stdio.h>
     33 
     34 typedef struct {
     35  int ln;
     36  int  m;
     37  int **linearmap;
     38  int  n[2];
     39 
     40  vorbis_info_floor0 *vi;
     41 
     42  long bits;
     43  long frames;
     44 } vorbis_look_floor0;
     45 
     46 
     47 /***********************************************/
     48 
     49 static void floor0_free_info(vorbis_info_floor *i){
     50  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
     51  if(info){
     52    memset(info,0,sizeof(*info));
     53    _ogg_free(info);
     54  }
     55 }
     56 
     57 static void floor0_free_look(vorbis_look_floor *i){
     58  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
     59  if(look){
     60 
     61    if(look->linearmap){
     62 
     63      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
     64      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
     65 
     66      _ogg_free(look->linearmap);
     67    }
     68    memset(look,0,sizeof(*look));
     69    _ogg_free(look);
     70  }
     71 }
     72 
     73 static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
     74  codec_setup_info     *ci=vi->codec_setup;
     75  int j;
     76 
     77  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
     78  info->order=oggpack_read(opb,8);
     79  info->rate=oggpack_read(opb,16);
     80  info->barkmap=oggpack_read(opb,16);
     81  info->ampbits=oggpack_read(opb,6);
     82  info->ampdB=oggpack_read(opb,8);
     83  info->numbooks=oggpack_read(opb,4)+1;
     84 
     85  if(info->order<1)goto err_out;
     86  if(info->rate<1)goto err_out;
     87  if(info->barkmap<1)goto err_out;
     88  if(info->numbooks<1)goto err_out;
     89 
     90  for(j=0;j<info->numbooks;j++){
     91    info->books[j]=oggpack_read(opb,8);
     92    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
     93    if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
     94    if(ci->book_param[info->books[j]]->dim<1)goto err_out;
     95  }
     96  return(info);
     97 
     98 err_out:
     99  floor0_free_info(info);
    100  return(NULL);
    101 }
    102 
    103 /* initialize Bark scale and normalization lookups.  We could do this
    104   with static tables, but Vorbis allows a number of possible
    105   combinations, so it's best to do it computationally.
    106 
    107   The below is authoritative in terms of defining scale mapping.
    108   Note that the scale depends on the sampling rate as well as the
    109   linear block and mapping sizes */
    110 
    111 static void floor0_map_lazy_init(vorbis_block      *vb,
    112                                 vorbis_info_floor *infoX,
    113                                 vorbis_look_floor0 *look){
    114  if(!look->linearmap[vb->W]){
    115    vorbis_dsp_state   *vd=vb->vd;
    116    vorbis_info        *vi=vd->vi;
    117    codec_setup_info   *ci=vi->codec_setup;
    118    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
    119    int W=vb->W;
    120    int n=ci->blocksizes[W]/2,j;
    121 
    122    /* we choose a scaling constant so that:
    123       floor(bark(rate/2-1)*C)=mapped-1
    124     floor(bark(rate/2)*C)=mapped */
    125    float scale=look->ln/toBARK(info->rate/2.f);
    126 
    127    /* the mapping from a linear scale to a smaller bark scale is
    128       straightforward.  We do *not* make sure that the linear mapping
    129       does not skip bark-scale bins; the decoder simply skips them and
    130       the encoder may do what it wishes in filling them.  They're
    131       necessary in some mapping combinations to keep the scale spacing
    132       accurate */
    133    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
    134    for(j=0;j<n;j++){
    135      int val=floor( toBARK((info->rate/2.f)/n*j)
    136                     *scale); /* bark numbers represent band edges */
    137      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
    138      look->linearmap[W][j]=val;
    139    }
    140    look->linearmap[W][j]=-1;
    141    look->n[W]=n;
    142  }
    143 }
    144 
    145 static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
    146                                      vorbis_info_floor *i){
    147  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
    148  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
    149 
    150  (void)vd;
    151 
    152  look->m=info->order;
    153  look->ln=info->barkmap;
    154  look->vi=info;
    155 
    156  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
    157 
    158  return look;
    159 }
    160 
    161 static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
    162  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
    163  vorbis_info_floor0 *info=look->vi;
    164  int j,k;
    165 
    166  int ampraw=oggpack_read(&vb->opb,info->ampbits);
    167  if(ampraw>0){ /* also handles the -1 out of data case */
    168    long maxval=(1<<info->ampbits)-1;
    169    float amp=(float)ampraw/maxval*info->ampdB;
    170    int booknum=oggpack_read(&vb->opb,ov_ilog(info->numbooks));
    171 
    172    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
    173      codec_setup_info  *ci=vb->vd->vi->codec_setup;
    174      codebook *b=ci->fullbooks+info->books[booknum];
    175      float last=0.f;
    176 
    177      /* the additional b->dim is a guard against any possible stack
    178         smash; b->dim is provably more than we can overflow the
    179         vector */
    180      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
    181 
    182      if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
    183      for(j=0;j<look->m;){
    184        for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
    185        last=lsp[j-1];
    186      }
    187 
    188      lsp[look->m]=amp;
    189      return(lsp);
    190    }
    191  }
    192 eop:
    193  return(NULL);
    194 }
    195 
    196 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
    197                           void *memo,float *out){
    198  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
    199  vorbis_info_floor0 *info=look->vi;
    200 
    201  floor0_map_lazy_init(vb,info,look);
    202 
    203  if(memo){
    204    float *lsp=(float *)memo;
    205    float amp=lsp[look->m];
    206 
    207    /* take the coefficients back to a spectral envelope curve */
    208    vorbis_lsp_to_curve(out,
    209                        look->linearmap[vb->W],
    210                        look->n[vb->W],
    211                        look->ln,
    212                        lsp,look->m,amp,(float)info->ampdB);
    213    return(1);
    214  }
    215  memset(out,0,sizeof(*out)*look->n[vb->W]);
    216  return(0);
    217 }
    218 
    219 /* export hooks */
    220 const vorbis_func_floor floor0_exportbundle={
    221  NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
    222  &floor0_free_look,&floor0_inverse1,&floor0_inverse2
    223 };