comparison mdct.c @ 10199:38ab367d4231 libavcodec

Merge FFTContext and MDCTContext
author mru
date Sun, 20 Sep 2009 17:30:20 +0000
parents 89cd870ca180
children db033d1fbf44
comparison
equal deleted inserted replaced
10198:78af613fc316 10199:38ab367d4231
70 } 70 }
71 71
72 /** 72 /**
73 * init MDCT or IMDCT computation. 73 * init MDCT or IMDCT computation.
74 */ 74 */
75 av_cold int ff_mdct_init(MDCTContext *s, int nbits, int inverse, double scale) 75 av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)
76 { 76 {
77 int n, n4, i; 77 int n, n4, i;
78 double alpha, theta; 78 double alpha, theta;
79 79
80 memset(s, 0, sizeof(*s)); 80 memset(s, 0, sizeof(*s));
81 n = 1 << nbits; 81 n = 1 << nbits;
82 s->nbits = nbits; 82 s->mdct_bits = nbits;
83 s->n = n; 83 s->mdct_size = n;
84 n4 = n >> 2; 84 n4 = n >> 2;
85 s->tcos = av_malloc(n4 * sizeof(FFTSample)); 85 s->tcos = av_malloc(n4 * sizeof(FFTSample));
86 if (!s->tcos) 86 if (!s->tcos)
87 goto fail; 87 goto fail;
88 s->tsin = av_malloc(n4 * sizeof(FFTSample)); 88 s->tsin = av_malloc(n4 * sizeof(FFTSample));
94 for(i=0;i<n4;i++) { 94 for(i=0;i<n4;i++) {
95 alpha = 2 * M_PI * (i + theta) / n; 95 alpha = 2 * M_PI * (i + theta) / n;
96 s->tcos[i] = -cos(alpha) * scale; 96 s->tcos[i] = -cos(alpha) * scale;
97 s->tsin[i] = -sin(alpha) * scale; 97 s->tsin[i] = -sin(alpha) * scale;
98 } 98 }
99 if (ff_fft_init(&s->fft, s->nbits - 2, inverse) < 0) 99 if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)
100 goto fail; 100 goto fail;
101 return 0; 101 return 0;
102 fail: 102 fail:
103 av_freep(&s->tcos); 103 av_freep(&s->tcos);
104 av_freep(&s->tsin); 104 av_freep(&s->tsin);
120 * Compute the middle half of the inverse MDCT of size N = 2^nbits, 120 * Compute the middle half of the inverse MDCT of size N = 2^nbits,
121 * thus excluding the parts that can be derived by symmetry 121 * thus excluding the parts that can be derived by symmetry
122 * @param output N/2 samples 122 * @param output N/2 samples
123 * @param input N/2 samples 123 * @param input N/2 samples
124 */ 124 */
125 void ff_imdct_half_c(MDCTContext *s, FFTSample *output, const FFTSample *input) 125 void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input)
126 { 126 {
127 int k, n8, n4, n2, n, j; 127 int k, n8, n4, n2, n, j;
128 const uint16_t *revtab = s->fft.revtab; 128 const uint16_t *revtab = s->revtab;
129 const FFTSample *tcos = s->tcos; 129 const FFTSample *tcos = s->tcos;
130 const FFTSample *tsin = s->tsin; 130 const FFTSample *tsin = s->tsin;
131 const FFTSample *in1, *in2; 131 const FFTSample *in1, *in2;
132 FFTComplex *z = (FFTComplex *)output; 132 FFTComplex *z = (FFTComplex *)output;
133 133
134 n = 1 << s->nbits; 134 n = 1 << s->mdct_bits;
135 n2 = n >> 1; 135 n2 = n >> 1;
136 n4 = n >> 2; 136 n4 = n >> 2;
137 n8 = n >> 3; 137 n8 = n >> 3;
138 138
139 /* pre rotation */ 139 /* pre rotation */
143 j=revtab[k]; 143 j=revtab[k];
144 CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]); 144 CMUL(z[j].re, z[j].im, *in2, *in1, tcos[k], tsin[k]);
145 in1 += 2; 145 in1 += 2;
146 in2 -= 2; 146 in2 -= 2;
147 } 147 }
148 ff_fft_calc(&s->fft, z); 148 ff_fft_calc(s, z);
149 149
150 /* post rotation + reordering */ 150 /* post rotation + reordering */
151 for(k = 0; k < n8; k++) { 151 for(k = 0; k < n8; k++) {
152 FFTSample r0, i0, r1, i1; 152 FFTSample r0, i0, r1, i1;
153 CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]); 153 CMUL(r0, i1, z[n8-k-1].im, z[n8-k-1].re, tsin[n8-k-1], tcos[n8-k-1]);
162 /** 162 /**
163 * Compute inverse MDCT of size N = 2^nbits 163 * Compute inverse MDCT of size N = 2^nbits
164 * @param output N samples 164 * @param output N samples
165 * @param input N/2 samples 165 * @param input N/2 samples
166 */ 166 */
167 void ff_imdct_calc_c(MDCTContext *s, FFTSample *output, const FFTSample *input) 167 void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input)
168 { 168 {
169 int k; 169 int k;
170 int n = 1 << s->nbits; 170 int n = 1 << s->mdct_bits;
171 int n2 = n >> 1; 171 int n2 = n >> 1;
172 int n4 = n >> 2; 172 int n4 = n >> 2;
173 173
174 ff_imdct_half_c(s, output+n4, input); 174 ff_imdct_half_c(s, output+n4, input);
175 175
182 /** 182 /**
183 * Compute MDCT of size N = 2^nbits 183 * Compute MDCT of size N = 2^nbits
184 * @param input N samples 184 * @param input N samples
185 * @param out N/2 samples 185 * @param out N/2 samples
186 */ 186 */
187 void ff_mdct_calc_c(MDCTContext *s, FFTSample *out, const FFTSample *input) 187 void ff_mdct_calc_c(FFTContext *s, FFTSample *out, const FFTSample *input)
188 { 188 {
189 int i, j, n, n8, n4, n2, n3; 189 int i, j, n, n8, n4, n2, n3;
190 FFTSample re, im; 190 FFTSample re, im;
191 const uint16_t *revtab = s->fft.revtab; 191 const uint16_t *revtab = s->revtab;
192 const FFTSample *tcos = s->tcos; 192 const FFTSample *tcos = s->tcos;
193 const FFTSample *tsin = s->tsin; 193 const FFTSample *tsin = s->tsin;
194 FFTComplex *x = (FFTComplex *)out; 194 FFTComplex *x = (FFTComplex *)out;
195 195
196 n = 1 << s->nbits; 196 n = 1 << s->mdct_bits;
197 n2 = n >> 1; 197 n2 = n >> 1;
198 n4 = n >> 2; 198 n4 = n >> 2;
199 n8 = n >> 3; 199 n8 = n >> 3;
200 n3 = 3 * n4; 200 n3 = 3 * n4;
201 201
210 im = -(input[n2+2*i] + input[n-1-2*i]); 210 im = -(input[n2+2*i] + input[n-1-2*i]);
211 j = revtab[n8 + i]; 211 j = revtab[n8 + i];
212 CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]); 212 CMUL(x[j].re, x[j].im, re, im, -tcos[n8 + i], tsin[n8 + i]);
213 } 213 }
214 214
215 ff_fft_calc(&s->fft, x); 215 ff_fft_calc(s, x);
216 216
217 /* post rotation */ 217 /* post rotation */
218 for(i=0;i<n8;i++) { 218 for(i=0;i<n8;i++) {
219 FFTSample r0, i0, r1, i1; 219 FFTSample r0, i0, r1, i1;
220 CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]); 220 CMUL(i1, r0, x[n8-i-1].re, x[n8-i-1].im, -tsin[n8-i-1], -tcos[n8-i-1]);
224 x[n8+i ].re = r1; 224 x[n8+i ].re = r1;
225 x[n8+i ].im = i1; 225 x[n8+i ].im = i1;
226 } 226 }
227 } 227 }
228 228
229 av_cold void ff_mdct_end(MDCTContext *s) 229 av_cold void ff_mdct_end(FFTContext *s)
230 { 230 {
231 av_freep(&s->tcos); 231 av_freep(&s->tcos);
232 av_freep(&s->tsin); 232 av_freep(&s->tsin);
233 ff_fft_end(&s->fft); 233 ff_fft_end(s);
234 } 234 }