Mercurial > libavcodec.hg
comparison nellymoserdec.c @ 5869:a03b4172939c libavcodec
Use the ffmpeg mdct function, patch by Fabrice Bellard. Thread: [FFmpeg-devel] NellyMoser transform bug, 10/25/2007 12:24 PM
author | banan |
---|---|
date | Sat, 03 Nov 2007 14:34:25 +0000 |
parents | fd8b56703750 |
children | ce9415dd447a |
comparison
equal
deleted
inserted
replaced
5868:2cc044ac80d4 | 5869:a03b4172939c |
---|---|
44 #define NELLY_BUF_LEN 128 | 44 #define NELLY_BUF_LEN 128 |
45 #define NELLY_FILL_LEN 124 | 45 #define NELLY_FILL_LEN 124 |
46 #define NELLY_BIT_CAP 6 | 46 #define NELLY_BIT_CAP 6 |
47 #define NELLY_BASE_OFF 4228 | 47 #define NELLY_BASE_OFF 4228 |
48 #define NELLY_BASE_SHIFT 19 | 48 #define NELLY_BASE_SHIFT 19 |
49 #define NELLY_SAMPLES 256 | 49 #define NELLY_SAMPLES (2 * NELLY_BUF_LEN) |
50 | 50 |
51 static const float dequantization_table[127] = { | 51 static const float dequantization_table[127] = { |
52 0.0000000000,-0.8472560048, 0.7224709988, -1.5247479677, -0.4531480074, 0.3753609955, 1.4717899561, | 52 0.0000000000,-0.8472560048, 0.7224709988, -1.5247479677, -0.4531480074, 0.3753609955, 1.4717899561, |
53 -1.9822579622, -1.1929379702, -0.5829370022, -0.0693780035, 0.3909569979,0.9069200158, 1.4862740040, | 53 -1.9822579622, -1.1929379702, -0.5829370022, -0.0693780035, 0.3909569979,0.9069200158, 1.4862740040, |
54 2.2215409279, -2.3887870312, -1.8067539930, -1.4105420113, -1.0773609877, -0.7995010018,-0.5558109879, | 54 2.2215409279, -2.3887870312, -1.8067539930, -1.4105420113, -1.0773609877, -0.7995010018,-0.5558109879, |
96 AVRandomState random_state; | 96 AVRandomState random_state; |
97 GetBitContext gb; | 97 GetBitContext gb; |
98 int add_bias; | 98 int add_bias; |
99 int scale_bias; | 99 int scale_bias; |
100 DSPContext dsp; | 100 DSPContext dsp; |
101 FFTContext fftc; | 101 MDCTContext imdct_ctx; |
102 DECLARE_ALIGNED_16(float,imdct_tmp[NELLY_BUF_LEN]); | |
103 DECLARE_ALIGNED_16(float,imdct_out[NELLY_BUF_LEN * 2]); | |
102 } NellyMoserDecodeContext; | 104 } NellyMoserDecodeContext; |
103 | 105 |
104 | |
105 DECLARE_ALIGNED_16(float,sine_window[128]); | 106 DECLARE_ALIGNED_16(float,sine_window[128]); |
106 DECLARE_ALIGNED_16(float,tcos[64]); | |
107 DECLARE_ALIGNED_16(float,tsin[64]); | |
108 DECLARE_ALIGNED_16(float,cos_tab[64]); | |
109 | 107 |
110 static inline int signed_shift(int i, int shift) { | 108 static inline int signed_shift(int i, int shift) { |
111 if (shift > 0) | 109 if (shift > 0) |
112 return i << shift; | 110 return i << shift; |
113 return i >> -shift; | 111 return i >> -shift; |
114 } | |
115 | |
116 static void antialias(float *buf, float *audio) | |
117 { | |
118 int i, end, mid_hi, mid_lo; | |
119 | |
120 end = NELLY_BUF_LEN-1; | |
121 mid_hi = NELLY_BUF_LEN/2; | |
122 mid_lo = mid_hi-1; | |
123 | |
124 for (i = 0; i < NELLY_BUF_LEN/4; i++) { | |
125 audio[2*i] = buf[2*i ]*tcos[i ] - buf[end-2*i]*tsin[i]; | |
126 audio[2*i+1] = -(buf[end-2*i ]*tcos[i ] + buf[2*i ]*tsin[i]); | |
127 audio[end-2*i-1]= buf[end-2*i-1]*tcos[mid_lo-i] - buf[2*i+1 ]*tsin[mid_lo-i]; | |
128 audio[end-2*i ]= -(buf[2*i+1 ]*tcos[mid_lo-i] + buf[end-2*i]*tsin[mid_lo-i]); | |
129 } | |
130 } | |
131 | |
132 static void complex2signal(float *audio) | |
133 { | |
134 int i, end, mid_hi, mid_lo; | |
135 float *aptr, *sigptr, a, b, c, d, e, f, g; | |
136 | |
137 end = NELLY_BUF_LEN-1; | |
138 mid_hi = NELLY_BUF_LEN/2; | |
139 mid_lo = mid_hi-1; | |
140 | |
141 a = -audio[end]; | |
142 b = audio[end-1]; | |
143 c = -audio[1]; | |
144 d = cos_tab[0]; | |
145 e = audio[0]; | |
146 f = cos_tab[mid_lo]; | |
147 g = cos_tab[1]; | |
148 | |
149 audio[0] = d*e; | |
150 audio[1] = b*g-a*f; | |
151 audio[end-1] = a*g+b*f; | |
152 audio[end] = c*(-d); | |
153 | |
154 aptr = audio+end-2; | |
155 sigptr = cos_tab+mid_hi-1; | |
156 | |
157 for (i = 3; i < NELLY_BUF_LEN/2; i += 2) { | |
158 a = audio[i-1]; | |
159 b = -audio[i]; | |
160 c = cos_tab[i/2]; | |
161 d = *sigptr; | |
162 e = *(aptr-1); | |
163 f = -(*aptr); | |
164 | |
165 audio[i-1] = a*c+b*d; | |
166 *aptr = a*d-b*c; | |
167 | |
168 a = cos_tab[(i/2)+1]; | |
169 b = *(sigptr-1); | |
170 | |
171 *(aptr-1) = b*e+a*f; | |
172 audio[i] = a*e-b*f; | |
173 | |
174 sigptr--; | |
175 aptr -= 2; | |
176 } | |
177 } | 112 } |
178 | 113 |
179 static void overlap_and_window(NellyMoserDecodeContext *s, float *state, float *audio) | 114 static void overlap_and_window(NellyMoserDecodeContext *s, float *state, float *audio) |
180 { | 115 { |
181 int bot, mid_up, mid_down, top; | 116 int bot, mid_up, mid_down, top; |
227 *la <<= l; | 162 *la <<= l; |
228 return l; | 163 return l; |
229 } | 164 } |
230 | 165 |
231 | 166 |
232 static void get_sample_bits(float *buf, int *bits) | 167 static void get_sample_bits(const float *buf, int *bits) |
233 { | 168 { |
234 int i, j; | 169 int i, j; |
235 short sbuf[128]; | 170 short sbuf[128]; |
236 int bitsum = 0, last_bitsum, small_bitsum, big_bitsum; | 171 int bitsum = 0, last_bitsum, small_bitsum, big_bitsum; |
237 short shift, shift_saved; | 172 short shift, shift_saved; |
340 } | 275 } |
341 | 276 |
342 void nelly_decode_block(NellyMoserDecodeContext *s, unsigned char block[NELLY_BLOCK_LEN], float audio[NELLY_SAMPLES]) | 277 void nelly_decode_block(NellyMoserDecodeContext *s, unsigned char block[NELLY_BLOCK_LEN], float audio[NELLY_SAMPLES]) |
343 { | 278 { |
344 int i,j; | 279 int i,j; |
345 float buf[NELLY_BUF_LEN], pows[NELLY_BUF_LEN]; | 280 float buf[NELLY_FILL_LEN], pows[NELLY_FILL_LEN]; |
346 float *aptr, *bptr, *pptr, val, pval; | 281 float *aptr, *bptr, *pptr, val, pval; |
347 int bits[NELLY_BUF_LEN]; | 282 int bits[NELLY_BUF_LEN]; |
348 unsigned char v; | 283 unsigned char v; |
284 float a; | |
349 | 285 |
350 init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); | 286 init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); |
351 | 287 |
352 bptr = buf; | 288 bptr = buf; |
353 pptr = pows; | 289 pptr = pows; |
361 *pptr++ = pval; | 297 *pptr++ = pval; |
362 } | 298 } |
363 | 299 |
364 } | 300 } |
365 | 301 |
366 memset(&buf[NELLY_FILL_LEN],0,4*sizeof(float)); | |
367 memset(&pows[NELLY_FILL_LEN],0,4*sizeof(float)); | |
368 | |
369 get_sample_bits(buf, bits); | 302 get_sample_bits(buf, bits); |
370 | 303 |
371 for (i = 0; i < 2; i++) { | 304 for (i = 0; i < 2; i++) { |
372 aptr = audio+i*128; | 305 aptr = audio + i * NELLY_BUF_LEN; |
306 | |
373 init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); | 307 init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); |
374 skip_bits(&s->gb, NELLY_HEADER_BITS + i*NELLY_DETAIL_BITS); | 308 skip_bits(&s->gb, NELLY_HEADER_BITS + i*NELLY_DETAIL_BITS); |
375 | 309 |
376 for (j = 0; j < NELLY_FILL_LEN; j++) { | 310 for (j = 0; j < NELLY_FILL_LEN; j++) { |
377 if (bits[j] <= 0) { | 311 if (bits[j] <= 0) { |
378 buf[j] = M_SQRT1_2*pows[j]; | 312 aptr[j] = M_SQRT1_2*pows[j]; |
379 if (av_random(&s->random_state) & 1) | 313 if (av_random(&s->random_state) & 1) |
380 buf[j] *= -1.0; | 314 aptr[j] *= -1.0; |
381 } else { | 315 } else { |
382 v = get_bits(&s->gb, bits[j]); | 316 v = get_bits(&s->gb, bits[j]); |
383 buf[j] = dequantization_table[(1<<bits[j])-1+v]*pows[j]; | 317 aptr[j] = dequantization_table[(1<<bits[j])-1+v]*pows[j]; |
384 } | 318 } |
385 } | 319 } |
386 | 320 memset(&aptr[NELLY_FILL_LEN], 0, |
387 antialias(buf, aptr); | 321 (NELLY_BUF_LEN - NELLY_FILL_LEN) * sizeof(float)); |
388 ff_fft_permute(&s->fftc, (FFTComplex*)aptr); | 322 |
389 ff_fft_calc(&s->fftc, (FFTComplex*)aptr); | 323 s->imdct_ctx.fft.imdct_calc(&s->imdct_ctx, s->imdct_out, |
390 complex2signal(aptr); | 324 aptr, s->imdct_tmp); |
325 /* XXX: overlapping and windowing should be part of a more | |
326 generic imdct function */ | |
327 a = 1.0 / 8.0; | |
328 for(j = 0; j < NELLY_BUF_LEN / 2; j++) { | |
329 aptr[j] = s->imdct_out[j + NELLY_BUF_LEN + NELLY_BUF_LEN / 2] * a; | |
330 aptr[j + NELLY_BUF_LEN / 2] = -s->imdct_out[j] * a; | |
331 } | |
391 overlap_and_window(s, s->state, aptr); | 332 overlap_and_window(s, s->state, aptr); |
392 } | 333 } |
393 } | 334 } |
394 | 335 |
395 static int decode_init(AVCodecContext * avctx) { | 336 static int decode_init(AVCodecContext * avctx) { |
397 int i; | 338 int i; |
398 float alpha; | 339 float alpha; |
399 | 340 |
400 s->avctx = avctx; | 341 s->avctx = avctx; |
401 av_init_random(0, &s->random_state); | 342 av_init_random(0, &s->random_state); |
402 ff_fft_init(&s->fftc, 6, 1); | 343 ff_mdct_init(&s->imdct_ctx, 8, 1); |
344 | |
403 dsputil_init(&s->dsp, avctx); | 345 dsputil_init(&s->dsp, avctx); |
404 | 346 |
405 if(s->dsp.float_to_int16 == ff_float_to_int16_c) { | 347 if(s->dsp.float_to_int16 == ff_float_to_int16_c) { |
406 s->add_bias = 385; | 348 s->add_bias = 385; |
407 s->scale_bias = 32768; | 349 s->scale_bias = 32768; |
412 | 354 |
413 /* Generate overlap window */ | 355 /* Generate overlap window */ |
414 if (!sine_window[0]) | 356 if (!sine_window[0]) |
415 for (i=0 ; i<128; i++) { | 357 for (i=0 ; i<128; i++) { |
416 sine_window[i] = sin((i + 0.5) / 256.0 * M_PI); | 358 sine_window[i] = sin((i + 0.5) / 256.0 * M_PI); |
417 } | |
418 | |
419 /* Generate tables */ | |
420 if (!tcos[0]) | |
421 for(i=0;i<64;i++) { | |
422 alpha = 2*M_PI * (i + 1.0 / 4.0) / 256; | |
423 tcos[i] = cos(alpha); | |
424 tsin[i] = -sin(alpha); | |
425 cos_tab[i] = cos(i/128.0*M_PI)/8.0; | |
426 } | 359 } |
427 | 360 |
428 return 0; | 361 return 0; |
429 } | 362 } |
430 | 363 |
462 } | 395 } |
463 | 396 |
464 static int decode_end(AVCodecContext * avctx) { | 397 static int decode_end(AVCodecContext * avctx) { |
465 NellyMoserDecodeContext *s = avctx->priv_data; | 398 NellyMoserDecodeContext *s = avctx->priv_data; |
466 | 399 |
467 ff_fft_end(&s->fftc); | 400 ff_mdct_end(&s->imdct_ctx); |
468 return 0; | 401 return 0; |
469 } | 402 } |
470 | 403 |
471 AVCodec nellymoser_decoder = { | 404 AVCodec nellymoser_decoder = { |
472 "nellymoser", | 405 "nellymoser", |