Mercurial > libavcodec.hg
annotate wma.c @ 4697:8e460c6a85a7 libavcodec
make high precision mode accessible at compile time
author | michael |
---|---|
date | Wed, 21 Mar 2007 22:39:00 +0000 |
parents | 6679d37a3338 |
children | 99d9dd34903b |
rev | line source |
---|---|
4490 | 1 /* |
2 * WMA compatible codec | |
3 * Copyright (c) 2002-2007 The FFmpeg Project. | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 #include "avcodec.h" | |
23 #include "wma.h" | |
24 #include "wmadata.h" | |
25 | |
26 #undef NDEBUG | |
27 #include <assert.h> | |
28 | |
29 /* XXX: use same run/length optimization as mpeg decoders */ | |
30 //FIXME maybe split decode / encode or pass flag | |
31 static void init_coef_vlc(VLC *vlc, | |
32 uint16_t **prun_table, uint16_t **plevel_table, uint16_t **pint_table, | |
33 const CoefVLCTable *vlc_table) | |
34 { | |
35 int n = vlc_table->n; | |
36 const uint8_t *table_bits = vlc_table->huffbits; | |
37 const uint32_t *table_codes = vlc_table->huffcodes; | |
38 const uint16_t *levels_table = vlc_table->levels; | |
39 uint16_t *run_table, *level_table, *int_table; | |
40 int i, l, j, k, level; | |
41 | |
42 init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0); | |
43 | |
44 run_table = av_malloc(n * sizeof(uint16_t)); | |
45 level_table = av_malloc(n * sizeof(uint16_t)); | |
46 int_table = av_malloc(n * sizeof(uint16_t)); | |
47 i = 2; | |
48 level = 1; | |
49 k = 0; | |
50 while (i < n) { | |
51 int_table[k]= i; | |
52 l = levels_table[k++]; | |
53 for(j=0;j<l;j++) { | |
54 run_table[i] = j; | |
55 level_table[i] = level; | |
56 i++; | |
57 } | |
58 level++; | |
59 } | |
60 *prun_table = run_table; | |
61 *plevel_table = level_table; | |
62 *pint_table= int_table; | |
63 } | |
64 | |
65 int ff_wma_init(AVCodecContext * avctx, int flags2) | |
66 { | |
4601 | 67 WMACodecContext *s = avctx->priv_data; |
4490 | 68 int i; |
69 float *window; | |
70 float bps1, high_freq; | |
71 volatile float bps; | |
72 int sample_rate1; | |
73 int coef_vlc_table; | |
74 | |
75 s->sample_rate = avctx->sample_rate; | |
76 s->nb_channels = avctx->channels; | |
77 s->bit_rate = avctx->bit_rate; | |
78 s->block_align = avctx->block_align; | |
79 | |
80 dsputil_init(&s->dsp, avctx); | |
81 | |
82 if (avctx->codec->id == CODEC_ID_WMAV1) { | |
83 s->version = 1; | |
84 } else { | |
85 s->version = 2; | |
86 } | |
87 | |
88 /* compute MDCT block size */ | |
89 if (s->sample_rate <= 16000) { | |
90 s->frame_len_bits = 9; | |
91 } else if (s->sample_rate <= 22050 || | |
92 (s->sample_rate <= 32000 && s->version == 1)) { | |
93 s->frame_len_bits = 10; | |
94 } else { | |
95 s->frame_len_bits = 11; | |
96 } | |
97 s->frame_len = 1 << s->frame_len_bits; | |
98 if (s->use_variable_block_len) { | |
99 int nb_max, nb; | |
100 nb = ((flags2 >> 3) & 3) + 1; | |
101 if ((s->bit_rate / s->nb_channels) >= 32000) | |
102 nb += 2; | |
103 nb_max = s->frame_len_bits - BLOCK_MIN_BITS; | |
104 if (nb > nb_max) | |
105 nb = nb_max; | |
106 s->nb_block_sizes = nb + 1; | |
107 } else { | |
108 s->nb_block_sizes = 1; | |
109 } | |
110 | |
4588
fc155ff94878
cosmetics: Fix another common typo, dependAnt --> dependEnt.
diego
parents:
4490
diff
changeset
|
111 /* init rate dependent parameters */ |
4490 | 112 s->use_noise_coding = 1; |
113 high_freq = s->sample_rate * 0.5; | |
114 | |
115 /* if version 2, then the rates are normalized */ | |
116 sample_rate1 = s->sample_rate; | |
117 if (s->version == 2) { | |
118 if (sample_rate1 >= 44100) | |
119 sample_rate1 = 44100; | |
120 else if (sample_rate1 >= 22050) | |
121 sample_rate1 = 22050; | |
122 else if (sample_rate1 >= 16000) | |
123 sample_rate1 = 16000; | |
124 else if (sample_rate1 >= 11025) | |
125 sample_rate1 = 11025; | |
126 else if (sample_rate1 >= 8000) | |
127 sample_rate1 = 8000; | |
128 } | |
129 | |
130 bps = (float)s->bit_rate / (float)(s->nb_channels * s->sample_rate); | |
131 s->byte_offset_bits = av_log2((int)(bps * s->frame_len / 8.0 + 0.5)) + 2; | |
132 | |
133 /* compute high frequency value and choose if noise coding should | |
134 be activated */ | |
135 bps1 = bps; | |
136 if (s->nb_channels == 2) | |
137 bps1 = bps * 1.6; | |
138 if (sample_rate1 == 44100) { | |
139 if (bps1 >= 0.61) | |
140 s->use_noise_coding = 0; | |
141 else | |
142 high_freq = high_freq * 0.4; | |
143 } else if (sample_rate1 == 22050) { | |
144 if (bps1 >= 1.16) | |
145 s->use_noise_coding = 0; | |
146 else if (bps1 >= 0.72) | |
147 high_freq = high_freq * 0.7; | |
148 else | |
149 high_freq = high_freq * 0.6; | |
150 } else if (sample_rate1 == 16000) { | |
151 if (bps > 0.5) | |
152 high_freq = high_freq * 0.5; | |
153 else | |
154 high_freq = high_freq * 0.3; | |
155 } else if (sample_rate1 == 11025) { | |
156 high_freq = high_freq * 0.7; | |
157 } else if (sample_rate1 == 8000) { | |
158 if (bps <= 0.625) { | |
159 high_freq = high_freq * 0.5; | |
160 } else if (bps > 0.75) { | |
161 s->use_noise_coding = 0; | |
162 } else { | |
163 high_freq = high_freq * 0.65; | |
164 } | |
165 } else { | |
166 if (bps >= 0.8) { | |
167 high_freq = high_freq * 0.75; | |
168 } else if (bps >= 0.6) { | |
169 high_freq = high_freq * 0.6; | |
170 } else { | |
171 high_freq = high_freq * 0.5; | |
172 } | |
173 } | |
4652 | 174 dprintf(s->avctx, "flags2=0x%x\n", flags2); |
175 dprintf(s->avctx, "version=%d channels=%d sample_rate=%d bitrate=%d block_align=%d\n", | |
4490 | 176 s->version, s->nb_channels, s->sample_rate, s->bit_rate, |
177 s->block_align); | |
4652 | 178 dprintf(s->avctx, "bps=%f bps1=%f high_freq=%f bitoffset=%d\n", |
4490 | 179 bps, bps1, high_freq, s->byte_offset_bits); |
4652 | 180 dprintf(s->avctx, "use_noise_coding=%d use_exp_vlc=%d nb_block_sizes=%d\n", |
4490 | 181 s->use_noise_coding, s->use_exp_vlc, s->nb_block_sizes); |
182 | |
183 /* compute the scale factor band sizes for each MDCT block size */ | |
184 { | |
185 int a, b, pos, lpos, k, block_len, i, j, n; | |
186 const uint8_t *table; | |
187 | |
188 if (s->version == 1) { | |
189 s->coefs_start = 3; | |
190 } else { | |
191 s->coefs_start = 0; | |
192 } | |
193 for(k = 0; k < s->nb_block_sizes; k++) { | |
194 block_len = s->frame_len >> k; | |
195 | |
196 if (s->version == 1) { | |
197 lpos = 0; | |
198 for(i=0;i<25;i++) { | |
199 a = wma_critical_freqs[i]; | |
200 b = s->sample_rate; | |
201 pos = ((block_len * 2 * a) + (b >> 1)) / b; | |
202 if (pos > block_len) | |
203 pos = block_len; | |
204 s->exponent_bands[0][i] = pos - lpos; | |
205 if (pos >= block_len) { | |
206 i++; | |
207 break; | |
208 } | |
209 lpos = pos; | |
210 } | |
211 s->exponent_sizes[0] = i; | |
212 } else { | |
213 /* hardcoded tables */ | |
214 table = NULL; | |
215 a = s->frame_len_bits - BLOCK_MIN_BITS - k; | |
216 if (a < 3) { | |
217 if (s->sample_rate >= 44100) | |
218 table = exponent_band_44100[a]; | |
219 else if (s->sample_rate >= 32000) | |
220 table = exponent_band_32000[a]; | |
221 else if (s->sample_rate >= 22050) | |
222 table = exponent_band_22050[a]; | |
223 } | |
224 if (table) { | |
225 n = *table++; | |
226 for(i=0;i<n;i++) | |
227 s->exponent_bands[k][i] = table[i]; | |
228 s->exponent_sizes[k] = n; | |
229 } else { | |
230 j = 0; | |
231 lpos = 0; | |
232 for(i=0;i<25;i++) { | |
233 a = wma_critical_freqs[i]; | |
234 b = s->sample_rate; | |
235 pos = ((block_len * 2 * a) + (b << 1)) / (4 * b); | |
236 pos <<= 2; | |
237 if (pos > block_len) | |
238 pos = block_len; | |
239 if (pos > lpos) | |
240 s->exponent_bands[k][j++] = pos - lpos; | |
241 if (pos >= block_len) | |
242 break; | |
243 lpos = pos; | |
244 } | |
245 s->exponent_sizes[k] = j; | |
246 } | |
247 } | |
248 | |
249 /* max number of coefs */ | |
250 s->coefs_end[k] = (s->frame_len - ((s->frame_len * 9) / 100)) >> k; | |
251 /* high freq computation */ | |
252 s->high_band_start[k] = (int)((block_len * 2 * high_freq) / | |
253 s->sample_rate + 0.5); | |
254 n = s->exponent_sizes[k]; | |
255 j = 0; | |
256 pos = 0; | |
257 for(i=0;i<n;i++) { | |
258 int start, end; | |
259 start = pos; | |
260 pos += s->exponent_bands[k][i]; | |
261 end = pos; | |
262 if (start < s->high_band_start[k]) | |
263 start = s->high_band_start[k]; | |
264 if (end > s->coefs_end[k]) | |
265 end = s->coefs_end[k]; | |
266 if (end > start) | |
267 s->exponent_high_bands[k][j++] = end - start; | |
268 } | |
269 s->exponent_high_sizes[k] = j; | |
270 #if 0 | |
4600 | 271 tprintf(s->avctx, "%5d: coefs_end=%d high_band_start=%d nb_high_bands=%d: ", |
4490 | 272 s->frame_len >> k, |
273 s->coefs_end[k], | |
274 s->high_band_start[k], | |
275 s->exponent_high_sizes[k]); | |
276 for(j=0;j<s->exponent_high_sizes[k];j++) | |
4600 | 277 tprintf(s->avctx, " %d", s->exponent_high_bands[k][j]); |
278 tprintf(s->avctx, "\n"); | |
4490 | 279 #endif |
280 } | |
281 } | |
282 | |
283 #ifdef TRACE | |
284 { | |
285 int i, j; | |
286 for(i = 0; i < s->nb_block_sizes; i++) { | |
4600 | 287 tprintf(s->avctx, "%5d: n=%2d:", |
4490 | 288 s->frame_len >> i, |
289 s->exponent_sizes[i]); | |
290 for(j=0;j<s->exponent_sizes[i];j++) | |
4600 | 291 tprintf(s->avctx, " %d", s->exponent_bands[i][j]); |
292 tprintf(s->avctx, "\n"); | |
4490 | 293 } |
294 } | |
295 #endif | |
296 | |
297 /* init MDCT windows : simple sinus window */ | |
298 for(i = 0; i < s->nb_block_sizes; i++) { | |
299 int n, j; | |
300 float alpha; | |
301 n = 1 << (s->frame_len_bits - i); | |
302 window = av_malloc(sizeof(float) * n); | |
303 alpha = M_PI / (2.0 * n); | |
304 for(j=0;j<n;j++) { | |
305 window[n - j - 1] = sin((j + 0.5) * alpha); | |
306 } | |
307 s->windows[i] = window; | |
308 } | |
309 | |
310 s->reset_block_lengths = 1; | |
311 | |
312 if (s->use_noise_coding) { | |
313 | |
314 /* init the noise generator */ | |
315 if (s->use_exp_vlc) | |
316 s->noise_mult = 0.02; | |
317 else | |
318 s->noise_mult = 0.04; | |
319 | |
320 #ifdef TRACE | |
321 for(i=0;i<NOISE_TAB_SIZE;i++) | |
322 s->noise_table[i] = 1.0 * s->noise_mult; | |
323 #else | |
324 { | |
325 unsigned int seed; | |
326 float norm; | |
327 seed = 1; | |
328 norm = (1.0 / (float)(1LL << 31)) * sqrt(3) * s->noise_mult; | |
329 for(i=0;i<NOISE_TAB_SIZE;i++) { | |
330 seed = seed * 314159 + 1; | |
331 s->noise_table[i] = (float)((int)seed) * norm; | |
332 } | |
333 } | |
334 #endif | |
335 } | |
336 | |
337 /* choose the VLC tables for the coefficients */ | |
338 coef_vlc_table = 2; | |
339 if (s->sample_rate >= 32000) { | |
340 if (bps1 < 0.72) | |
341 coef_vlc_table = 0; | |
342 else if (bps1 < 1.16) | |
343 coef_vlc_table = 1; | |
344 } | |
345 s->coef_vlcs[0]= &coef_vlcs[coef_vlc_table * 2 ]; | |
346 s->coef_vlcs[1]= &coef_vlcs[coef_vlc_table * 2 + 1]; | |
347 init_coef_vlc(&s->coef_vlc[0], &s->run_table[0], &s->level_table[0], &s->int_table[0], | |
348 s->coef_vlcs[0]); | |
349 init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1], &s->int_table[1], | |
350 s->coef_vlcs[1]); | |
351 | |
352 return 0; | |
353 } | |
354 | |
355 int ff_wma_total_gain_to_bits(int total_gain){ | |
356 if (total_gain < 15) return 13; | |
357 else if (total_gain < 32) return 12; | |
358 else if (total_gain < 40) return 11; | |
359 else if (total_gain < 45) return 10; | |
360 else return 9; | |
361 } | |
362 | |
363 int ff_wma_end(AVCodecContext *avctx) | |
364 { | |
4601 | 365 WMACodecContext *s = avctx->priv_data; |
4490 | 366 int i; |
367 | |
368 for(i = 0; i < s->nb_block_sizes; i++) | |
369 ff_mdct_end(&s->mdct_ctx[i]); | |
370 for(i = 0; i < s->nb_block_sizes; i++) | |
371 av_free(s->windows[i]); | |
372 | |
373 if (s->use_exp_vlc) { | |
374 free_vlc(&s->exp_vlc); | |
375 } | |
376 if (s->use_noise_coding) { | |
377 free_vlc(&s->hgain_vlc); | |
378 } | |
379 for(i = 0;i < 2; i++) { | |
380 free_vlc(&s->coef_vlc[i]); | |
381 av_free(s->run_table[i]); | |
382 av_free(s->level_table[i]); | |
383 } | |
384 | |
385 return 0; | |
386 } |