Mercurial > libavcodec.hg
annotate mdct.c @ 9830:bd0879f752e6 libavcodec
Express the H.264 parser dependency on the golomb code in configure instead of
in the Makefile as it is done for all other parts that depend on golomb.
author | diego |
---|---|
date | Tue, 09 Jun 2009 20:29:52 +0000 |
parents | 67a20f0eb42c |
children | 50ec8930f99e |
rev | line source |
---|---|
781 | 1 /* |
2 * MDCT/IMDCT transforms | |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8567
diff
changeset
|
3 * Copyright (c) 2002 Fabrice Bellard |
781 | 4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
781 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
781 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
781 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
781 | 20 */ |
21 #include "dsputil.h" | |
22 | |
1106 | 23 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8629
diff
changeset
|
24 * @file libavcodec/mdct.c |
1106 | 25 * MDCT/IMDCT transforms. |
26 */ | |
27 | |
6139
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
28 // Generate a Kaiser-Bessel Derived Window. |
6142
a35b838ab955
Add variable alpha and size of half window for Kaiser-Bessel Derived window
superdump
parents:
6139
diff
changeset
|
29 #define BESSEL_I0_ITER 50 // default: 50 iterations of Bessel I0 approximation |
8737
eeca2fc122f8
Add av_cold attributes to *_init and *_end functions.
alexc
parents:
8718
diff
changeset
|
30 av_cold void ff_kbd_window_init(float *window, float alpha, int n) |
6139
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
31 { |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
32 int i, j; |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
33 double sum = 0.0, bessel, tmp; |
6142
a35b838ab955
Add variable alpha and size of half window for Kaiser-Bessel Derived window
superdump
parents:
6139
diff
changeset
|
34 double local_window[n]; |
a35b838ab955
Add variable alpha and size of half window for Kaiser-Bessel Derived window
superdump
parents:
6139
diff
changeset
|
35 double alpha2 = (alpha * M_PI / n) * (alpha * M_PI / n); |
6139
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
36 |
6142
a35b838ab955
Add variable alpha and size of half window for Kaiser-Bessel Derived window
superdump
parents:
6139
diff
changeset
|
37 for (i = 0; i < n; i++) { |
a35b838ab955
Add variable alpha and size of half window for Kaiser-Bessel Derived window
superdump
parents:
6139
diff
changeset
|
38 tmp = i * (n - i) * alpha2; |
6139
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
39 bessel = 1.0; |
6142
a35b838ab955
Add variable alpha and size of half window for Kaiser-Bessel Derived window
superdump
parents:
6139
diff
changeset
|
40 for (j = BESSEL_I0_ITER; j > 0; j--) |
6139
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
41 bessel = bessel * tmp / (j * j) + 1; |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
42 sum += bessel; |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
43 local_window[i] = sum; |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
44 } |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
45 |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
46 sum++; |
6142
a35b838ab955
Add variable alpha and size of half window for Kaiser-Bessel Derived window
superdump
parents:
6139
diff
changeset
|
47 for (i = 0; i < n; i++) |
6139
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
48 window[i] = sqrt(local_window[i] / sum); |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
49 } |
5077d1562573
Make the Kaiser-Bessel window generator a common function
andoma
parents:
3947
diff
changeset
|
50 |
7577
ed956c3c2cf3
The ff_sine_#[] should be aligned as they will commonly be used in dsputil
superdump
parents:
7573
diff
changeset
|
51 DECLARE_ALIGNED(16, float, ff_sine_128 [ 128]); |
ed956c3c2cf3
The ff_sine_#[] should be aligned as they will commonly be used in dsputil
superdump
parents:
7573
diff
changeset
|
52 DECLARE_ALIGNED(16, float, ff_sine_256 [ 256]); |
ed956c3c2cf3
The ff_sine_#[] should be aligned as they will commonly be used in dsputil
superdump
parents:
7573
diff
changeset
|
53 DECLARE_ALIGNED(16, float, ff_sine_512 [ 512]); |
ed956c3c2cf3
The ff_sine_#[] should be aligned as they will commonly be used in dsputil
superdump
parents:
7573
diff
changeset
|
54 DECLARE_ALIGNED(16, float, ff_sine_1024[1024]); |
ed956c3c2cf3
The ff_sine_#[] should be aligned as they will commonly be used in dsputil
superdump
parents:
7573
diff
changeset
|
55 DECLARE_ALIGNED(16, float, ff_sine_2048[2048]); |
8567 | 56 DECLARE_ALIGNED(16, float, ff_sine_4096[4096]); |
57 float *ff_sine_windows[6] = { | |
58 ff_sine_128, ff_sine_256, ff_sine_512, ff_sine_1024, ff_sine_2048, ff_sine_4096 | |
7573
7802295cae6f
Add declarations for the sine tables used in wma.c (half window sizes: 128,
superdump
parents:
7547
diff
changeset
|
59 }; |
7802295cae6f
Add declarations for the sine tables used in wma.c (half window sizes: 128,
superdump
parents:
7547
diff
changeset
|
60 |
7094
b0820b8bd4dd
Add generic ff_sine_window_init function and implement in codecs appropriately
superdump
parents:
6498
diff
changeset
|
61 // Generate a sine window. |
8737
eeca2fc122f8
Add av_cold attributes to *_init and *_end functions.
alexc
parents:
8718
diff
changeset
|
62 av_cold void ff_sine_window_init(float *window, int n) { |
7094
b0820b8bd4dd
Add generic ff_sine_window_init function and implement in codecs appropriately
superdump
parents:
6498
diff
changeset
|
63 int i; |
b0820b8bd4dd
Add generic ff_sine_window_init function and implement in codecs appropriately
superdump
parents:
6498
diff
changeset
|
64 for(i = 0; i < n; i++) |
7822 | 65 window[i] = sinf((i + 0.5) * (M_PI / (2.0 * n))); |
7094
b0820b8bd4dd
Add generic ff_sine_window_init function and implement in codecs appropriately
superdump
parents:
6498
diff
changeset
|
66 } |
b0820b8bd4dd
Add generic ff_sine_window_init function and implement in codecs appropriately
superdump
parents:
6498
diff
changeset
|
67 |
1106 | 68 /** |
69 * init MDCT or IMDCT computation. | |
781 | 70 */ |
9658
67a20f0eb42c
Support for getting (i)MDCT output multiplied by a constant scaling factor.
serge
parents:
9480
diff
changeset
|
71 av_cold int ff_mdct_init(MDCTContext *s, int nbits, int inverse, double scale) |
781 | 72 { |
73 int n, n4, i; | |
9658
67a20f0eb42c
Support for getting (i)MDCT output multiplied by a constant scaling factor.
serge
parents:
9480
diff
changeset
|
74 double alpha, theta; |
781 | 75 |
76 memset(s, 0, sizeof(*s)); | |
77 n = 1 << nbits; | |
78 s->nbits = nbits; | |
79 s->n = n; | |
80 n4 = n >> 2; | |
970 | 81 s->tcos = av_malloc(n4 * sizeof(FFTSample)); |
781 | 82 if (!s->tcos) |
83 goto fail; | |
970 | 84 s->tsin = av_malloc(n4 * sizeof(FFTSample)); |
781 | 85 if (!s->tsin) |
86 goto fail; | |
87 | |
9658
67a20f0eb42c
Support for getting (i)MDCT output multiplied by a constant scaling factor.
serge
parents:
9480
diff
changeset
|
88 theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0); |
67a20f0eb42c
Support for getting (i)MDCT output multiplied by a constant scaling factor.
serge
parents:
9480
diff
changeset
|
89 scale = sqrt(fabs(scale)); |
781 | 90 for(i=0;i<n4;i++) { |
9658
67a20f0eb42c
Support for getting (i)MDCT output multiplied by a constant scaling factor.
serge
parents:
9480
diff
changeset
|
91 alpha = 2 * M_PI * (i + theta) / n; |
67a20f0eb42c
Support for getting (i)MDCT output multiplied by a constant scaling factor.
serge
parents:
9480
diff
changeset
|
92 s->tcos[i] = -cos(alpha) * scale; |
67a20f0eb42c
Support for getting (i)MDCT output multiplied by a constant scaling factor.
serge
parents:
9480
diff
changeset
|
93 s->tsin[i] = -sin(alpha) * scale; |
781 | 94 } |
1879
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
95 if (ff_fft_init(&s->fft, s->nbits - 2, inverse) < 0) |
781 | 96 goto fail; |
97 return 0; | |
98 fail: | |
99 av_freep(&s->tcos); | |
100 av_freep(&s->tsin); | |
101 return -1; | |
102 } | |
103 | |
104 /* complex multiplication: p = a * b */ | |
105 #define CMUL(pre, pim, are, aim, bre, bim) \ | |
106 {\ | |
7545 | 107 FFTSample _are = (are);\ |
108 FFTSample _aim = (aim);\ | |
109 FFTSample _bre = (bre);\ | |
110 FFTSample _bim = (bim);\ | |
781 | 111 (pre) = _are * _bre - _aim * _bim;\ |
112 (pim) = _are * _bim + _aim * _bre;\ | |
113 } | |
114 | |
7544 | 115 /** |
116 * Compute the middle half of the inverse MDCT of size N = 2^nbits, | |
117 * thus excluding the parts that can be derived by symmetry | |
118 * @param output N/2 samples | |
119 * @param input N/2 samples | |
120 */ | |
7547 | 121 void ff_imdct_half_c(MDCTContext *s, FFTSample *output, const FFTSample *input) |
781 | 122 { |
7544 | 123 int k, n8, n4, n2, n, j; |
781 | 124 const uint16_t *revtab = s->fft.revtab; |
125 const FFTSample *tcos = s->tcos; | |
126 const FFTSample *tsin = s->tsin; | |
127 const FFTSample *in1, *in2; | |
7544 | 128 FFTComplex *z = (FFTComplex *)output; |
781 | 129 |
130 n = 1 << s->nbits; | |
131 n2 = n >> 1; | |
132 n4 = n >> 2; | |
7544 | 133 n8 = n >> 3; |
781 | 134 |
135 /* pre rotation */ | |
136 in1 = input; | |
137 in2 = input + n2 - 1; | |
138 for(k = 0; k < n4; k++) { | |
139 j=revtab[k]; | |
140 CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]); | |
141 in1 += 2; | |
142 in2 -= 2; | |
143 } | |
1879
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
144 ff_fft_calc(&s->fft, z); |
781 | 145 |
146 /* post rotation + reordering */ | |
7544 | 147 for(k = 0; k < n8; k++) { |
148 FFTSample r0, i0, r1, i1; | |
149 CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]); | |
150 CMUL(r1, i0, z[n8+k ].im, z[n8+k ].re, tsin[n8+k ], tcos[n8+k ]); | |
151 z[n8-k-1].re = r0; | |
152 z[n8-k-1].im = i0; | |
153 z[n8+k ].re = r1; | |
154 z[n8+k ].im = i1; | |
781 | 155 } |
7263 | 156 } |
157 | |
158 /** | |
159 * Compute inverse MDCT of size N = 2^nbits | |
160 * @param output N samples | |
161 * @param input N/2 samples | |
162 */ | |
7547 | 163 void ff_imdct_calc_c(MDCTContext *s, FFTSample *output, const FFTSample *input) |
7263 | 164 { |
7544 | 165 int k; |
166 int n = 1 << s->nbits; | |
167 int n2 = n >> 1; | |
168 int n4 = n >> 2; | |
781 | 169 |
7547 | 170 ff_imdct_half_c(s, output+n4, input); |
7263 | 171 |
7544 | 172 for(k = 0; k < n4; k++) { |
173 output[k] = -output[n2-k-1]; | |
174 output[n-k-1] = output[n2+k]; | |
7263 | 175 } |
176 } | |
177 | |
178 /** | |
781 | 179 * Compute MDCT of size N = 2^nbits |
180 * @param input N samples | |
181 * @param out N/2 samples | |
182 */ | |
7546 | 183 void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input) |
781 | 184 { |
185 int i, j, n, n8, n4, n2, n3; | |
7546 | 186 FFTSample re, im; |
781 | 187 const uint16_t *revtab = s->fft.revtab; |
188 const FFTSample *tcos = s->tcos; | |
189 const FFTSample *tsin = s->tsin; | |
7544 | 190 FFTComplex *x = (FFTComplex *)out; |
781 | 191 |
192 n = 1 << s->nbits; | |
193 n2 = n >> 1; | |
194 n4 = n >> 2; | |
195 n8 = n >> 3; | |
196 n3 = 3 * n4; | |
197 | |
198 /* pre rotation */ | |
199 for(i=0;i<n8;i++) { | |
200 re = -input[2*i+3*n4] - input[n3-1-2*i]; | |
201 im = -input[n4+2*i] + input[n4-1-2*i]; | |
202 j = revtab[i]; | |
203 CMUL(x[j].re, x[j].im, re, im, -tcos[i], tsin[i]); | |
204 | |
205 re = input[2*i] - input[n2-1-2*i]; | |
206 im = -(input[n2+2*i] + input[n-1-2*i]); | |
207 j = revtab[n8 + i]; | |
208 CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]); | |
209 } | |
210 | |
1879
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
211 ff_fft_calc(&s->fft, x); |
2967 | 212 |
781 | 213 /* post rotation */ |
7544 | 214 for(i=0;i<n8;i++) { |
215 FFTSample r0, i0, r1, i1; | |
216 CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]); | |
217 CMUL(i0, r1, x[n8+i ].re, x[n8+i ].im, -tsin[n8+i ], -tcos[n8+i ]); | |
218 x[n8-i-1].re = r0; | |
219 x[n8-i-1].im = i0; | |
220 x[n8+i ].re = r1; | |
221 x[n8+i ].im = i1; | |
781 | 222 } |
223 } | |
224 | |
8737
eeca2fc122f8
Add av_cold attributes to *_init and *_end functions.
alexc
parents:
8718
diff
changeset
|
225 av_cold void ff_mdct_end(MDCTContext *s) |
781 | 226 { |
227 av_freep(&s->tcos); | |
228 av_freep(&s->tsin); | |
1879
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
229 ff_fft_end(&s->fft); |
781 | 230 } |