X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Ffloor0.c;h=99a083b06918c6cf8ab64d8df1894be573ed2aa7;hb=1b0aa969c7bebfad37c5d2dea4055c50c766aa96;hp=e18689f9ec1cd6abaadf2077d79ae865708db788;hpb=f6246535ae25ac62560acecb35036dd4239a95d5;p=platform%2Fupstream%2Flibvorbis.git diff --git a/lib/floor0.c b/lib/floor0.c index e18689f..99a083b 100644 --- a/lib/floor0.c +++ b/lib/floor0.c @@ -1,188 +1,221 @@ /******************************************************************** * * - * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * - * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. * - * PLEASE READ THESE TERMS DISTRIBUTING. * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 * - * by Monty and The XIPHOPHORUS Company * - * http://www.xiph.org/ * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * + * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: floor backend 0 implementation - last mod: $Id: floor0.c,v 1.6 2000/02/06 13:39:40 xiphmont Exp $ + last mod: $Id$ ********************************************************************/ #include #include #include +#include #include "vorbis/codec.h" -#include "bitwise.h" +#include "codec_internal.h" #include "registry.h" #include "lpc.h" #include "lsp.h" -#include "bookinternal.h" +#include "codebook.h" +#include "scales.h" +#include "misc.h" +#include "os.h" + +#include "misc.h" +#include typedef struct { - long n; - long m; + int ln; + int m; + int **linearmap; + int n[2]; + vorbis_info_floor0 *vi; - lpc_lookup lpclook; + + long bits; + long frames; } vorbis_look_floor0; -static void free_info(vorbis_info_floor *i){ - if(i){ - memset(i,0,sizeof(vorbis_info_floor0)); - free(i); + +/***********************************************/ + +static void floor0_free_info(vorbis_info_floor *i){ + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + if(info){ + memset(info,0,sizeof(*info)); + _ogg_free(info); } } -static void free_look(vorbis_look_floor *i){ - vorbis_look_floor0 *f=(vorbis_look_floor0 *)i; - if(i){ - lpc_clear(&f->lpclook); - memset(f,0,sizeof(vorbis_look_floor0)); - free(f); +static void floor0_free_look(vorbis_look_floor *i){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + if(look){ + + if(look->linearmap){ + + if(look->linearmap[0])_ogg_free(look->linearmap[0]); + if(look->linearmap[1])_ogg_free(look->linearmap[1]); + + _ogg_free(look->linearmap); + } + memset(look,0,sizeof(*look)); + _ogg_free(look); } } -static void pack (vorbis_info_floor *i,oggpack_buffer *opb){ - vorbis_info_floor0 *d=(vorbis_info_floor0 *)i; +static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){ + codec_setup_info *ci=vi->codec_setup; int j; - _oggpack_write(opb,d->order,8); - _oggpack_write(opb,d->rate,16); - _oggpack_write(opb,d->barkmap,16); - _oggpack_write(opb,d->stages-1,4); - for(j=0;jstages;j++) - _oggpack_write(opb,d->books[j],8); -} -static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){ - int j; - vorbis_info_floor0 *d=malloc(sizeof(vorbis_info_floor0)); - d->order=_oggpack_read(opb,8); - d->rate=_oggpack_read(opb,16); - d->barkmap=_oggpack_read(opb,16); - d->stages=_oggpack_read(opb,4)+1; - - if(d->order<1)goto err_out; - if(d->rate<1)goto err_out; - if(d->barkmap<1)goto err_out; - if(d->stages<1)goto err_out; - - for(j=0;jstages;j++){ - d->books[j]=_oggpack_read(opb,8); - if(d->books[j]<0 || d->books[j]>=vi->books)goto err_out; + vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info)); + info->order=oggpack_read(opb,8); + info->rate=oggpack_read(opb,16); + info->barkmap=oggpack_read(opb,16); + info->ampbits=oggpack_read(opb,6); + info->ampdB=oggpack_read(opb,8); + info->numbooks=oggpack_read(opb,4)+1; + + if(info->order<1)goto err_out; + if(info->rate<1)goto err_out; + if(info->barkmap<1)goto err_out; + if(info->numbooks<1)goto err_out; + + for(j=0;jnumbooks;j++){ + info->books[j]=oggpack_read(opb,8); + if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out; + if(ci->book_param[info->books[j]]->maptype==0)goto err_out; + if(ci->book_param[info->books[j]]->dim<1)goto err_out; } - return(d); + return(info); + err_out: - free_info(d); + floor0_free_info(info); return(NULL); } -static vorbis_look_floor *look (vorbis_info *vi,vorbis_info_mode *mi, - vorbis_info_floor *i){ - vorbis_info_floor0 *d=(vorbis_info_floor0 *)i; - vorbis_look_floor0 *ret=malloc(sizeof(vorbis_look_floor0)); - ret->m=d->order; - ret->n=vi->blocksizes[mi->blockflag]/2; - ret->vi=d; - lpc_init(&ret->lpclook,ret->n,d->barkmap,d->rate,ret->m); - return ret; -} - -#include - -static int forward(vorbis_block *vb,vorbis_look_floor *i, - double *in,double *out){ - long j,k,l; - vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; - vorbis_info_floor0 *info=look->vi; - - /* use 'out' as temp storage */ - /* Convert our floor to a set of lpc coefficients */ - double amp=sqrt(vorbis_curve_to_lpc(in,out,&look->lpclook)); - double *work=alloca(sizeof(double)*look->m); - - /* LSP <-> LPC is orthogonal and LSP quantizes more stably */ - vorbis_lpc_to_lsp(out,out,look->m); - memcpy(work,out,sizeof(double)*look->m); - - for(j=12;j<20;j++) - fprintf(stderr,"%0.3g, ",out[j]); - fprintf(stderr,"\n"); - - /* code the spectral envelope, and keep track of the actual quantized - values */ - _oggpack_write(&vb->opb,amp*32768,18); - { - codebook *b=vb->vd->fullbooks+info->books[0]; - double last=0.; - for(j=0;jm;){ - double next=out[j+b->dim-1]; - for(k=0;kdim;k++,j++)out[j]-=last; - last=next; +/* initialize Bark scale and normalization lookups. We could do this + with static tables, but Vorbis allows a number of possible + combinations, so it's best to do it computationally. + + The below is authoritative in terms of defining scale mapping. + Note that the scale depends on the sampling rate as well as the + linear block and mapping sizes */ + +static void floor0_map_lazy_init(vorbis_block *vb, + vorbis_info_floor *infoX, + vorbis_look_floor0 *look){ + if(!look->linearmap[vb->W]){ + vorbis_dsp_state *vd=vb->vd; + vorbis_info *vi=vd->vi; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX; + int W=vb->W; + int n=ci->blocksizes[W]/2,j; + + /* we choose a scaling constant so that: + floor(bark(rate/2-1)*C)=mapped-1 + floor(bark(rate/2)*C)=mapped */ + float scale=look->ln/toBARK(info->rate/2.f); + + /* the mapping from a linear scale to a smaller bark scale is + straightforward. We do *not* make sure that the linear mapping + does not skip bark-scale bins; the decoder simply skips them and + the encoder may do what it wishes in filling them. They're + necessary in some mapping combinations to keep the scale spacing + accurate */ + look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap)); + for(j=0;jrate/2.f)/n*j) + *scale); /* bark numbers represent band edges */ + if(val>=look->ln)val=look->ln-1; /* guard against the approximation */ + look->linearmap[W][j]=val; } + look->linearmap[W][j]=-1; + look->n[W]=n; } +} - for(k=0;kstages;k++){ - codebook *b=vb->vd->fullbooks+info->books[k]; - for(j=0;jm;j+=b->dim) - vorbis_book_encodev(b,out+j,&vb->opb); - } - - for(j=0;jm;j++) - out[j]=work[j]-out[j]; - - +static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd, + vorbis_info_floor *i){ + vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; + vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look)); + look->m=info->order; + look->ln=info->barkmap; + look->vi=info; - /* take the coefficients back to a spectral envelope curve */ - vorbis_lsp_to_lpc(out,out,look->m); - vorbis_lpc_to_curve(out,out,amp,&look->lpclook); + look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap)); - return(0); + return look; } -static int inverse(vorbis_block *vb,vorbis_look_floor *i,double *out){ +static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; vorbis_info_floor0 *info=look->vi; int j,k; - - double amp=_oggpack_read(&vb->opb,18)/32768.; - memset(out,0,sizeof(double)*look->m); - for(k=0;kstages;k++){ - codebook *b=vb->vd->fullbooks+info->books[k]; - for(j=0;jm;j+=b->dim) - vorbis_book_decodev(b,out+j,&vb->opb); - } - - { - codebook *b=vb->vd->fullbooks+info->books[0]; - double last=0.; - for(j=0;jm;){ - for(k=0;kdim;k++,j++)out[j]+=last; - last=out[j-1]; + + int ampraw=oggpack_read(&vb->opb,info->ampbits); + if(ampraw>0){ /* also handles the -1 out of data case */ + long maxval=(1<ampbits)-1; + float amp=(float)ampraw/maxval*info->ampdB; + int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); + + if(booknum!=-1 && booknumnumbooks){ /* be paranoid */ + codec_setup_info *ci=vb->vd->vi->codec_setup; + codebook *b=ci->fullbooks+info->books[booknum]; + float last=0.f; + + /* the additional b->dim is a guard against any possible stack + smash; b->dim is provably more than we can overflow the + vector */ + float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1)); + + if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop; + for(j=0;jm;){ + for(k=0;jm && kdim;k++,j++)lsp[j]+=last; + last=lsp[j-1]; + } + + lsp[look->m]=amp; + return(lsp); } } + eop: + return(NULL); +} + +static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i, + void *memo,float *out){ + vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; + vorbis_info_floor0 *info=look->vi; - for(j=12;j<20;j++) - fprintf(stderr,"%0.3g, ",out[j]); - fprintf(stderr,"\n"); - + floor0_map_lazy_init(vb,info,look); - /* take the coefficients back to a spectral envelope curve */ - vorbis_lsp_to_lpc(out,out,look->m); - vorbis_lpc_to_curve(out,out,amp,&look->lpclook); + if(memo){ + float *lsp=(float *)memo; + float amp=lsp[look->m]; + /* take the coefficients back to a spectral envelope curve */ + vorbis_lsp_to_curve(out, + look->linearmap[vb->W], + look->n[vb->W], + look->ln, + lsp,look->m,amp,(float)info->ampdB); + return(1); + } + memset(out,0,sizeof(*out)*look->n[vb->W]); return(0); } /* export hooks */ -vorbis_func_floor floor0_exportbundle={ - &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse +const vorbis_func_floor floor0_exportbundle={ + NULL,&floor0_unpack,&floor0_look,&floor0_free_info, + &floor0_free_look,&floor0_inverse1,&floor0_inverse2 }; - -