]> git.jsancho.org Git - lugaru.git/blob - libvorbis-1.0.1/lib/floor0.c
Quickly created CMake to build the source
[lugaru.git] / libvorbis-1.0.1 / lib / floor0.c
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,v 1.55 2003/09/05 23:17:49 giles Exp $
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