vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

floor0.c (6643B)


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