Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/libvorbis-1.2.0/lib/floor0.c @ 16

Last change on this file since 16 was 16, checked in by landauf, 17 years ago

added libvorbis

File size: 6.5 KB
Line 
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-2007             *
9 * by the Xiph.Org Foundation http://www.xiph.org/                  *
10 *                                                                  *
11 ********************************************************************
12
13 function: floor backend 0 implementation
14 last mod: $Id: floor0.c 13293 2007-07-24 00:09:47Z xiphmont $
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
35typedef 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
50static 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
58static 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
74static 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
110static 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
144static 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
157static 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
193static 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 */
217vorbis_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
Note: See TracBrowser for help on using the repository browser.