Mercurial > hg > sv-dependency-builds
comparison src/libvorbis-1.3.3/lib/floor0.c @ 1:05aa0afa9217
Bring in flac, ogg, vorbis
author | Chris Cannam |
---|---|
date | Tue, 19 Mar 2013 17:37:49 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:c7265573341e | 1:05aa0afa9217 |
---|---|
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-2009 * | |
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 18184 2012-02-03 20:55:12Z 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 | |
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 if(ci->book_param[info->books[j]]->maptype==0)goto err_out; | |
95 if(ci->book_param[info->books[j]]->dim<1)goto err_out; | |
96 } | |
97 return(info); | |
98 | |
99 err_out: | |
100 floor0_free_info(info); | |
101 return(NULL); | |
102 } | |
103 | |
104 /* initialize Bark scale and normalization lookups. We could do this | |
105 with static tables, but Vorbis allows a number of possible | |
106 combinations, so it's best to do it computationally. | |
107 | |
108 The below is authoritative in terms of defining scale mapping. | |
109 Note that the scale depends on the sampling rate as well as the | |
110 linear block and mapping sizes */ | |
111 | |
112 static void floor0_map_lazy_init(vorbis_block *vb, | |
113 vorbis_info_floor *infoX, | |
114 vorbis_look_floor0 *look){ | |
115 if(!look->linearmap[vb->W]){ | |
116 vorbis_dsp_state *vd=vb->vd; | |
117 vorbis_info *vi=vd->vi; | |
118 codec_setup_info *ci=vi->codec_setup; | |
119 vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX; | |
120 int W=vb->W; | |
121 int n=ci->blocksizes[W]/2,j; | |
122 | |
123 /* we choose a scaling constant so that: | |
124 floor(bark(rate/2-1)*C)=mapped-1 | |
125 floor(bark(rate/2)*C)=mapped */ | |
126 float scale=look->ln/toBARK(info->rate/2.f); | |
127 | |
128 /* the mapping from a linear scale to a smaller bark scale is | |
129 straightforward. We do *not* make sure that the linear mapping | |
130 does not skip bark-scale bins; the decoder simply skips them and | |
131 the encoder may do what it wishes in filling them. They're | |
132 necessary in some mapping combinations to keep the scale spacing | |
133 accurate */ | |
134 look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap)); | |
135 for(j=0;j<n;j++){ | |
136 int val=floor( toBARK((info->rate/2.f)/n*j) | |
137 *scale); /* bark numbers represent band edges */ | |
138 if(val>=look->ln)val=look->ln-1; /* guard against the approximation */ | |
139 look->linearmap[W][j]=val; | |
140 } | |
141 look->linearmap[W][j]=-1; | |
142 look->n[W]=n; | |
143 } | |
144 } | |
145 | |
146 static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd, | |
147 vorbis_info_floor *i){ | |
148 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; | |
149 vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look)); | |
150 look->m=info->order; | |
151 look->ln=info->barkmap; | |
152 look->vi=info; | |
153 | |
154 look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap)); | |
155 | |
156 return look; | |
157 } | |
158 | |
159 static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ | |
160 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; | |
161 vorbis_info_floor0 *info=look->vi; | |
162 int j,k; | |
163 | |
164 int ampraw=oggpack_read(&vb->opb,info->ampbits); | |
165 if(ampraw>0){ /* also handles the -1 out of data case */ | |
166 long maxval=(1<<info->ampbits)-1; | |
167 float amp=(float)ampraw/maxval*info->ampdB; | |
168 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); | |
169 | |
170 if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */ | |
171 codec_setup_info *ci=vb->vd->vi->codec_setup; | |
172 codebook *b=ci->fullbooks+info->books[booknum]; | |
173 float last=0.f; | |
174 | |
175 /* the additional b->dim is a guard against any possible stack | |
176 smash; b->dim is provably more than we can overflow the | |
177 vector */ | |
178 float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1)); | |
179 | |
180 if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop; | |
181 for(j=0;j<look->m;){ | |
182 for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last; | |
183 last=lsp[j-1]; | |
184 } | |
185 | |
186 lsp[look->m]=amp; | |
187 return(lsp); | |
188 } | |
189 } | |
190 eop: | |
191 return(NULL); | |
192 } | |
193 | |
194 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i, | |
195 void *memo,float *out){ | |
196 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; | |
197 vorbis_info_floor0 *info=look->vi; | |
198 | |
199 floor0_map_lazy_init(vb,info,look); | |
200 | |
201 if(memo){ | |
202 float *lsp=(float *)memo; | |
203 float amp=lsp[look->m]; | |
204 | |
205 /* take the coefficients back to a spectral envelope curve */ | |
206 vorbis_lsp_to_curve(out, | |
207 look->linearmap[vb->W], | |
208 look->n[vb->W], | |
209 look->ln, | |
210 lsp,look->m,amp,(float)info->ampdB); | |
211 return(1); | |
212 } | |
213 memset(out,0,sizeof(*out)*look->n[vb->W]); | |
214 return(0); | |
215 } | |
216 | |
217 /* export hooks */ | |
218 const vorbis_func_floor floor0_exportbundle={ | |
219 NULL,&floor0_unpack,&floor0_look,&floor0_free_info, | |
220 &floor0_free_look,&floor0_inverse1,&floor0_inverse2 | |
221 }; |