floor0.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) 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