vrshoot

diff libs/vorbis/floor0.c @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/vorbis/floor0.c	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,221 @@
     1.4 +/********************************************************************
     1.5 + *                                                                  *
     1.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
     1.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
     1.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
     1.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
    1.10 + *                                                                  *
    1.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
    1.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
    1.13 + *                                                                  *
    1.14 + ********************************************************************
    1.15 +
    1.16 + function: floor backend 0 implementation
    1.17 + last mod: $Id: floor0.c 18184 2012-02-03 20:55:12Z xiphmont $
    1.18 +
    1.19 + ********************************************************************/
    1.20 +
    1.21 +#include <stdlib.h>
    1.22 +#include <string.h>
    1.23 +#include <math.h>
    1.24 +#include <ogg/ogg.h>
    1.25 +#include "vorbis/codec.h"
    1.26 +#include "codec_internal.h"
    1.27 +#include "registry.h"
    1.28 +#include "lpc.h"
    1.29 +#include "lsp.h"
    1.30 +#include "codebook.h"
    1.31 +#include "scales.h"
    1.32 +#include "misc.h"
    1.33 +#include "os.h"
    1.34 +
    1.35 +#include "misc.h"
    1.36 +#include <stdio.h>
    1.37 +
    1.38 +typedef struct {
    1.39 +  int ln;
    1.40 +  int  m;
    1.41 +  int **linearmap;
    1.42 +  int  n[2];
    1.43 +
    1.44 +  vorbis_info_floor0 *vi;
    1.45 +
    1.46 +  long bits;
    1.47 +  long frames;
    1.48 +} vorbis_look_floor0;
    1.49 +
    1.50 +
    1.51 +/***********************************************/
    1.52 +
    1.53 +static void floor0_free_info(vorbis_info_floor *i){
    1.54 +  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
    1.55 +  if(info){
    1.56 +    memset(info,0,sizeof(*info));
    1.57 +    _ogg_free(info);
    1.58 +  }
    1.59 +}
    1.60 +
    1.61 +static void floor0_free_look(vorbis_look_floor *i){
    1.62 +  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
    1.63 +  if(look){
    1.64 +
    1.65 +    if(look->linearmap){
    1.66 +
    1.67 +      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
    1.68 +      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
    1.69 +
    1.70 +      _ogg_free(look->linearmap);
    1.71 +    }
    1.72 +    memset(look,0,sizeof(*look));
    1.73 +    _ogg_free(look);
    1.74 +  }
    1.75 +}
    1.76 +
    1.77 +static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
    1.78 +  codec_setup_info     *ci=vi->codec_setup;
    1.79 +  int j;
    1.80 +
    1.81 +  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
    1.82 +  info->order=oggpack_read(opb,8);
    1.83 +  info->rate=oggpack_read(opb,16);
    1.84 +  info->barkmap=oggpack_read(opb,16);
    1.85 +  info->ampbits=oggpack_read(opb,6);
    1.86 +  info->ampdB=oggpack_read(opb,8);
    1.87 +  info->numbooks=oggpack_read(opb,4)+1;
    1.88 +
    1.89 +  if(info->order<1)goto err_out;
    1.90 +  if(info->rate<1)goto err_out;
    1.91 +  if(info->barkmap<1)goto err_out;
    1.92 +  if(info->numbooks<1)goto err_out;
    1.93 +
    1.94 +  for(j=0;j<info->numbooks;j++){
    1.95 +    info->books[j]=oggpack_read(opb,8);
    1.96 +    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
    1.97 +    if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
    1.98 +    if(ci->book_param[info->books[j]]->dim<1)goto err_out;
    1.99 +  }
   1.100 +  return(info);
   1.101 +
   1.102 + err_out:
   1.103 +  floor0_free_info(info);
   1.104 +  return(NULL);
   1.105 +}
   1.106 +
   1.107 +/* initialize Bark scale and normalization lookups.  We could do this
   1.108 +   with static tables, but Vorbis allows a number of possible
   1.109 +   combinations, so it's best to do it computationally.
   1.110 +
   1.111 +   The below is authoritative in terms of defining scale mapping.
   1.112 +   Note that the scale depends on the sampling rate as well as the
   1.113 +   linear block and mapping sizes */
   1.114 +
   1.115 +static void floor0_map_lazy_init(vorbis_block      *vb,
   1.116 +                                 vorbis_info_floor *infoX,
   1.117 +                                 vorbis_look_floor0 *look){
   1.118 +  if(!look->linearmap[vb->W]){
   1.119 +    vorbis_dsp_state   *vd=vb->vd;
   1.120 +    vorbis_info        *vi=vd->vi;
   1.121 +    codec_setup_info   *ci=vi->codec_setup;
   1.122 +    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
   1.123 +    int W=vb->W;
   1.124 +    int n=ci->blocksizes[W]/2,j;
   1.125 +
   1.126 +    /* we choose a scaling constant so that:
   1.127 +       floor(bark(rate/2-1)*C)=mapped-1
   1.128 +     floor(bark(rate/2)*C)=mapped */
   1.129 +    float scale=look->ln/toBARK(info->rate/2.f);
   1.130 +
   1.131 +    /* the mapping from a linear scale to a smaller bark scale is
   1.132 +       straightforward.  We do *not* make sure that the linear mapping
   1.133 +       does not skip bark-scale bins; the decoder simply skips them and
   1.134 +       the encoder may do what it wishes in filling them.  They're
   1.135 +       necessary in some mapping combinations to keep the scale spacing
   1.136 +       accurate */
   1.137 +    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
   1.138 +    for(j=0;j<n;j++){
   1.139 +      int val=floor( toBARK((info->rate/2.f)/n*j)
   1.140 +                     *scale); /* bark numbers represent band edges */
   1.141 +      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
   1.142 +      look->linearmap[W][j]=val;
   1.143 +    }
   1.144 +    look->linearmap[W][j]=-1;
   1.145 +    look->n[W]=n;
   1.146 +  }
   1.147 +}
   1.148 +
   1.149 +static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
   1.150 +                                      vorbis_info_floor *i){
   1.151 +  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   1.152 +  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
   1.153 +  look->m=info->order;
   1.154 +  look->ln=info->barkmap;
   1.155 +  look->vi=info;
   1.156 +
   1.157 +  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
   1.158 +
   1.159 +  return look;
   1.160 +}
   1.161 +
   1.162 +static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
   1.163 +  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
   1.164 +  vorbis_info_floor0 *info=look->vi;
   1.165 +  int j,k;
   1.166 +
   1.167 +  int ampraw=oggpack_read(&vb->opb,info->ampbits);
   1.168 +  if(ampraw>0){ /* also handles the -1 out of data case */
   1.169 +    long maxval=(1<<info->ampbits)-1;
   1.170 +    float amp=(float)ampraw/maxval*info->ampdB;
   1.171 +    int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
   1.172 +
   1.173 +    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
   1.174 +      codec_setup_info  *ci=vb->vd->vi->codec_setup;
   1.175 +      codebook *b=ci->fullbooks+info->books[booknum];
   1.176 +      float last=0.f;
   1.177 +
   1.178 +      /* the additional b->dim is a guard against any possible stack
   1.179 +         smash; b->dim is provably more than we can overflow the
   1.180 +         vector */
   1.181 +      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
   1.182 +
   1.183 +      if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
   1.184 +      for(j=0;j<look->m;){
   1.185 +        for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
   1.186 +        last=lsp[j-1];
   1.187 +      }
   1.188 +
   1.189 +      lsp[look->m]=amp;
   1.190 +      return(lsp);
   1.191 +    }
   1.192 +  }
   1.193 + eop:
   1.194 +  return(NULL);
   1.195 +}
   1.196 +
   1.197 +static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
   1.198 +                           void *memo,float *out){
   1.199 +  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
   1.200 +  vorbis_info_floor0 *info=look->vi;
   1.201 +
   1.202 +  floor0_map_lazy_init(vb,info,look);
   1.203 +
   1.204 +  if(memo){
   1.205 +    float *lsp=(float *)memo;
   1.206 +    float amp=lsp[look->m];
   1.207 +
   1.208 +    /* take the coefficients back to a spectral envelope curve */
   1.209 +    vorbis_lsp_to_curve(out,
   1.210 +                        look->linearmap[vb->W],
   1.211 +                        look->n[vb->W],
   1.212 +                        look->ln,
   1.213 +                        lsp,look->m,amp,(float)info->ampdB);
   1.214 +    return(1);
   1.215 +  }
   1.216 +  memset(out,0,sizeof(*out)*look->n[vb->W]);
   1.217 +  return(0);
   1.218 +}
   1.219 +
   1.220 +/* export hooks */
   1.221 +const vorbis_func_floor floor0_exportbundle={
   1.222 +  NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
   1.223 +  &floor0_free_look,&floor0_inverse1,&floor0_inverse2
   1.224 +};