Mercurial > libavcodec.hg
comparison fft.c @ 12047:c80c7a717156 libavcodec
Remove vestiges of radix-2 FFT
Patch (mostly) by Loren Merritt
author | mru |
---|---|
date | Thu, 01 Jul 2010 23:21:42 +0000 |
parents | 7dd2a45249a9 |
children | a2e5b142776b |
comparison
equal
deleted
inserted
replaced
12046:ae57be2ef58c | 12047:c80c7a717156 |
---|---|
78 #endif | 78 #endif |
79 } | 79 } |
80 | 80 |
81 av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) | 81 av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse) |
82 { | 82 { |
83 int i, j, m, n; | 83 int i, j, n; |
84 float alpha, c1, s1, s2; | |
85 int av_unused has_vectors; | |
86 | 84 |
87 if (nbits < 2 || nbits > 16) | 85 if (nbits < 2 || nbits > 16) |
88 goto fail; | 86 goto fail; |
89 s->nbits = nbits; | 87 s->nbits = nbits; |
90 n = 1 << nbits; | 88 n = 1 << nbits; |
91 | 89 |
92 s->tmp_buf = NULL; | |
93 s->exptab = av_malloc((n / 2) * sizeof(FFTComplex)); | |
94 if (!s->exptab) | |
95 goto fail; | |
96 s->revtab = av_malloc(n * sizeof(uint16_t)); | 90 s->revtab = av_malloc(n * sizeof(uint16_t)); |
97 if (!s->revtab) | 91 if (!s->revtab) |
98 goto fail; | 92 goto fail; |
93 s->tmp_buf = av_malloc(n * sizeof(FFTComplex)); | |
94 if (!s->tmp_buf) | |
95 goto fail; | |
99 s->inverse = inverse; | 96 s->inverse = inverse; |
100 | |
101 s2 = inverse ? 1.0 : -1.0; | |
102 | 97 |
103 s->fft_permute = ff_fft_permute_c; | 98 s->fft_permute = ff_fft_permute_c; |
104 s->fft_calc = ff_fft_calc_c; | 99 s->fft_calc = ff_fft_calc_c; |
105 #if CONFIG_MDCT | 100 #if CONFIG_MDCT |
106 s->imdct_calc = ff_imdct_calc_c; | 101 s->imdct_calc = ff_imdct_calc_c; |
107 s->imdct_half = ff_imdct_half_c; | 102 s->imdct_half = ff_imdct_half_c; |
108 s->mdct_calc = ff_mdct_calc_c; | 103 s->mdct_calc = ff_mdct_calc_c; |
109 #endif | 104 #endif |
110 s->exptab1 = NULL; | |
111 s->split_radix = 1; | |
112 | 105 |
113 if (ARCH_ARM) ff_fft_init_arm(s); | 106 if (ARCH_ARM) ff_fft_init_arm(s); |
114 if (HAVE_ALTIVEC) ff_fft_init_altivec(s); | 107 if (HAVE_ALTIVEC) ff_fft_init_altivec(s); |
115 if (HAVE_MMX) ff_fft_init_mmx(s); | 108 if (HAVE_MMX) ff_fft_init_mmx(s); |
116 | 109 |
117 if (s->split_radix) { | |
118 for(j=4; j<=nbits; j++) { | 110 for(j=4; j<=nbits; j++) { |
119 ff_init_ff_cos_tabs(j); | 111 ff_init_ff_cos_tabs(j); |
120 } | 112 } |
121 for(i=0; i<n; i++) | 113 for(i=0; i<n; i++) |
122 s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = i; | 114 s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = i; |
123 s->tmp_buf = av_malloc(n * sizeof(FFTComplex)); | |
124 } else { | |
125 int np, nblocks, np2, l; | |
126 FFTComplex *q; | |
127 | |
128 for(i=0; i<(n/2); i++) { | |
129 alpha = 2 * M_PI * (float)i / (float)n; | |
130 c1 = cos(alpha); | |
131 s1 = sin(alpha) * s2; | |
132 s->exptab[i].re = c1; | |
133 s->exptab[i].im = s1; | |
134 } | |
135 | |
136 np = 1 << nbits; | |
137 nblocks = np >> 3; | |
138 np2 = np >> 1; | |
139 s->exptab1 = av_malloc(np * 2 * sizeof(FFTComplex)); | |
140 if (!s->exptab1) | |
141 goto fail; | |
142 q = s->exptab1; | |
143 do { | |
144 for(l = 0; l < np2; l += 2 * nblocks) { | |
145 *q++ = s->exptab[l]; | |
146 *q++ = s->exptab[l + nblocks]; | |
147 | |
148 q->re = -s->exptab[l].im; | |
149 q->im = s->exptab[l].re; | |
150 q++; | |
151 q->re = -s->exptab[l + nblocks].im; | |
152 q->im = s->exptab[l + nblocks].re; | |
153 q++; | |
154 } | |
155 nblocks = nblocks >> 1; | |
156 } while (nblocks != 0); | |
157 av_freep(&s->exptab); | |
158 | |
159 /* compute bit reverse table */ | |
160 for(i=0;i<n;i++) { | |
161 m=0; | |
162 for(j=0;j<nbits;j++) { | |
163 m |= ((i >> j) & 1) << (nbits-j-1); | |
164 } | |
165 s->revtab[i]=m; | |
166 } | |
167 } | |
168 | 115 |
169 return 0; | 116 return 0; |
170 fail: | 117 fail: |
171 av_freep(&s->revtab); | 118 av_freep(&s->revtab); |
172 av_freep(&s->exptab); | |
173 av_freep(&s->exptab1); | |
174 av_freep(&s->tmp_buf); | 119 av_freep(&s->tmp_buf); |
175 return -1; | 120 return -1; |
176 } | 121 } |
177 | 122 |
178 void ff_fft_permute_c(FFTContext *s, FFTComplex *z) | 123 void ff_fft_permute_c(FFTContext *s, FFTComplex *z) |
179 { | 124 { |
180 int j, k, np; | 125 int j, np; |
181 FFTComplex tmp; | |
182 const uint16_t *revtab = s->revtab; | 126 const uint16_t *revtab = s->revtab; |
183 np = 1 << s->nbits; | 127 np = 1 << s->nbits; |
184 | |
185 if (s->tmp_buf) { | |
186 /* TODO: handle split-radix permute in a more optimal way, probably in-place */ | 128 /* TODO: handle split-radix permute in a more optimal way, probably in-place */ |
187 for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j]; | 129 for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j]; |
188 memcpy(z, s->tmp_buf, np * sizeof(FFTComplex)); | 130 memcpy(z, s->tmp_buf, np * sizeof(FFTComplex)); |
189 return; | |
190 } | |
191 | |
192 /* reverse */ | |
193 for(j=0;j<np;j++) { | |
194 k = revtab[j]; | |
195 if (k < j) { | |
196 tmp = z[k]; | |
197 z[k] = z[j]; | |
198 z[j] = tmp; | |
199 } | |
200 } | |
201 } | 131 } |
202 | 132 |
203 av_cold void ff_fft_end(FFTContext *s) | 133 av_cold void ff_fft_end(FFTContext *s) |
204 { | 134 { |
205 av_freep(&s->revtab); | 135 av_freep(&s->revtab); |
206 av_freep(&s->exptab); | |
207 av_freep(&s->exptab1); | |
208 av_freep(&s->tmp_buf); | 136 av_freep(&s->tmp_buf); |
209 } | 137 } |
210 | 138 |
211 #define sqrthalf (float)M_SQRT1_2 | 139 #define sqrthalf (float)M_SQRT1_2 |
212 | 140 |