Mercurial > mplayer.hg
annotate libfaad2/mdct.c @ 14410:9b7f3566b603
Playback video with multiple windows.
author | reimar |
---|---|
date | Fri, 07 Jan 2005 11:11:02 +0000 |
parents | 6d50ef45a058 |
children | 2ae5ab4331ca |
rev | line source |
---|---|
10725 | 1 /* |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
12527 | 3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com |
10725 | 4 ** |
5 ** This program is free software; you can redistribute it and/or modify | |
6 ** it under the terms of the GNU General Public License as published by | |
7 ** the Free Software Foundation; either version 2 of the License, or | |
8 ** (at your option) any later version. | |
9 ** | |
10 ** This program is distributed in the hope that it will be useful, | |
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 ** GNU General Public License for more details. | |
14 ** | |
15 ** You should have received a copy of the GNU General Public License | |
16 ** along with this program; if not, write to the Free Software | |
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
18 ** | |
19 ** Any non-GPL usage of this software or parts of this software is strictly | |
20 ** forbidden. | |
21 ** | |
22 ** Commercial non-GPL licensing of this software is possible. | |
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. | |
24 ** | |
12625
d81145997036
More information about modifications to comply more closely with GPL 2a.
diego
parents:
12527
diff
changeset
|
25 ** Initially modified for use with MPlayer by Arpad Gereöffy on 2003/08/30 |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
26 ** $Id: mdct.c,v 1.4 2004/06/23 13:50:51 diego Exp $ |
12625
d81145997036
More information about modifications to comply more closely with GPL 2a.
diego
parents:
12527
diff
changeset
|
27 ** detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
10725 | 28 **/ |
29 | |
30 /* | |
31 * Fast (I)MDCT Implementation using (I)FFT ((Inverse) Fast Fourier Transform) | |
32 * and consists of three steps: pre-(I)FFT complex multiplication, complex | |
33 * (I)FFT, post-(I)FFT complex multiplication, | |
34 * | |
35 * As described in: | |
36 * P. Duhamel, Y. Mahieux, and J.P. Petit, "A Fast Algorithm for the | |
37 * Implementation of Filter Banks Based on 'Time Domain Aliasing | |
38 * Cancellation’," IEEE Proc. on ICASSP‘91, 1991, pp. 2209-2212. | |
39 * | |
40 * | |
41 * As of April 6th 2002 completely rewritten. | |
42 * This (I)MDCT can now be used for any data size n, where n is divisible by 8. | |
43 * | |
44 */ | |
45 | |
46 #include "common.h" | |
47 #include "structs.h" | |
48 | |
49 #include <stdlib.h> | |
50 #ifdef _WIN32_WCE | |
51 #define assert(x) | |
52 #else | |
53 #include <assert.h> | |
54 #endif | |
55 | |
56 #include "cfft.h" | |
57 #include "mdct.h" | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
58 #include "mdct_tab.h" |
10725 | 59 |
60 | |
61 mdct_info *faad_mdct_init(uint16_t N) | |
62 { | |
12527 | 63 mdct_info *mdct = (mdct_info*)faad_malloc(sizeof(mdct_info)); |
10725 | 64 |
65 assert(N % 8 == 0); | |
66 | |
67 mdct->N = N; | |
68 | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
69 /* NOTE: For "small framelengths" in FIXED_POINT the coefficients need to be |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
70 * scaled by sqrt("(nearest power of 2) > N" / N) */ |
10725 | 71 |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
72 /* RE(mdct->sincos[k]) = scale*(real_t)(cos(2.0*M_PI*(k+1./8.) / (real_t)N)); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
73 * IM(mdct->sincos[k]) = scale*(real_t)(sin(2.0*M_PI*(k+1./8.) / (real_t)N)); */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
74 /* scale is 1 for fixed point, sqrt(N) for floating point */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
75 switch (N) |
10725 | 76 { |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
77 case 2048: mdct->sincos = (complex_t*)mdct_tab_2048; break; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
78 case 256: mdct->sincos = (complex_t*)mdct_tab_256; break; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
79 #ifdef LD_DEC |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
80 case 1024: mdct->sincos = (complex_t*)mdct_tab_1024; break; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
81 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
82 #ifdef ALLOW_SMALL_FRAMELENGTH |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
83 case 1920: mdct->sincos = (complex_t*)mdct_tab_1920; break; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
84 case 240: mdct->sincos = (complex_t*)mdct_tab_240; break; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
85 #ifdef LD_DEC |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
86 case 960: mdct->sincos = (complex_t*)mdct_tab_960; break; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
87 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
88 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
89 #ifdef SSR_DEC |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
90 case 512: mdct->sincos = (complex_t*)mdct_tab_512; break; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
91 case 64: mdct->sincos = (complex_t*)mdct_tab_64; break; |
10989 | 92 #endif |
10725 | 93 } |
94 | |
95 /* initialise fft */ | |
96 mdct->cfft = cffti(N/4); | |
97 | |
12527 | 98 #ifdef PROFILE |
99 mdct->cycles = 0; | |
100 mdct->fft_cycles = 0; | |
101 #endif | |
102 | |
10725 | 103 return mdct; |
104 } | |
105 | |
106 void faad_mdct_end(mdct_info *mdct) | |
107 { | |
108 if (mdct != NULL) | |
109 { | |
12527 | 110 #ifdef PROFILE |
111 printf("MDCT[%.4d]: %I64d cycles\n", mdct->N, mdct->cycles); | |
112 printf("CFFT[%.4d]: %I64d cycles\n", mdct->N/4, mdct->fft_cycles); | |
113 #endif | |
114 | |
10725 | 115 cfftu(mdct->cfft); |
116 | |
12527 | 117 faad_free(mdct); |
10725 | 118 } |
119 } | |
120 | |
121 void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out) | |
122 { | |
123 uint16_t k; | |
124 | |
125 complex_t x; | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
126 #ifdef ALLOW_SMALL_FRAMELENGTH |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
127 #ifdef FIXED_POINT |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
128 real_t scale, b_scale = 0; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
129 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
130 #endif |
12527 | 131 ALIGN complex_t Z1[512]; |
132 complex_t *sincos = mdct->sincos; | |
133 | |
134 uint16_t N = mdct->N; | |
135 uint16_t N2 = N >> 1; | |
136 uint16_t N4 = N >> 2; | |
137 uint16_t N8 = N >> 3; | |
138 | |
139 #ifdef PROFILE | |
140 int64_t count1, count2 = faad_get_ts(); | |
141 #endif | |
142 | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
143 #ifdef ALLOW_SMALL_FRAMELENGTH |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
144 #ifdef FIXED_POINT |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
145 /* detect non-power of 2 */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
146 if (N & (N-1)) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
147 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
148 /* adjust scale for non-power of 2 MDCT */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
149 /* 2048/1920 */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
150 b_scale = 1; |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
151 scale = COEF_CONST(1.0666666666666667); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
152 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
153 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
154 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
155 |
12527 | 156 /* pre-IFFT complex multiplication */ |
157 for (k = 0; k < N4; k++) | |
158 { | |
159 ComplexMult(&IM(Z1[k]), &RE(Z1[k]), | |
160 X_in[2*k], X_in[N2 - 1 - 2*k], RE(sincos[k]), IM(sincos[k])); | |
161 } | |
162 | |
163 #ifdef PROFILE | |
164 count1 = faad_get_ts(); | |
165 #endif | |
166 | |
167 /* complex IFFT, any non-scaling FFT can be used here */ | |
168 cfftb(mdct->cfft, Z1); | |
169 | |
170 #ifdef PROFILE | |
171 count1 = faad_get_ts() - count1; | |
172 #endif | |
173 | |
174 /* post-IFFT complex multiplication */ | |
175 for (k = 0; k < N4; k++) | |
176 { | |
177 RE(x) = RE(Z1[k]); | |
178 IM(x) = IM(Z1[k]); | |
179 ComplexMult(&IM(Z1[k]), &RE(Z1[k]), | |
180 IM(x), RE(x), RE(sincos[k]), IM(sincos[k])); | |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
181 |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
182 #ifdef ALLOW_SMALL_FRAMELENGTH |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
183 #ifdef FIXED_POINT |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
184 /* non-power of 2 MDCT scaling */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
185 if (b_scale) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
186 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
187 RE(Z1[k]) = MUL_C(RE(Z1[k]), scale); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
188 IM(Z1[k]) = MUL_C(IM(Z1[k]), scale); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
189 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
190 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
191 #endif |
12527 | 192 } |
193 | |
194 /* reordering */ | |
195 for (k = 0; k < N8; k+=2) | |
196 { | |
197 X_out[ 2*k] = IM(Z1[N8 + k]); | |
198 X_out[ 2 + 2*k] = IM(Z1[N8 + 1 + k]); | |
199 | |
200 X_out[ 1 + 2*k] = -RE(Z1[N8 - 1 - k]); | |
201 X_out[ 3 + 2*k] = -RE(Z1[N8 - 2 - k]); | |
202 | |
203 X_out[N4 + 2*k] = RE(Z1[ k]); | |
204 X_out[N4 + + 2 + 2*k] = RE(Z1[ 1 + k]); | |
205 | |
206 X_out[N4 + 1 + 2*k] = -IM(Z1[N4 - 1 - k]); | |
207 X_out[N4 + 3 + 2*k] = -IM(Z1[N4 - 2 - k]); | |
208 | |
209 X_out[N2 + 2*k] = RE(Z1[N8 + k]); | |
210 X_out[N2 + + 2 + 2*k] = RE(Z1[N8 + 1 + k]); | |
211 | |
212 X_out[N2 + 1 + 2*k] = -IM(Z1[N8 - 1 - k]); | |
213 X_out[N2 + 3 + 2*k] = -IM(Z1[N8 - 2 - k]); | |
214 | |
215 X_out[N2 + N4 + 2*k] = -IM(Z1[ k]); | |
216 X_out[N2 + N4 + 2 + 2*k] = -IM(Z1[ 1 + k]); | |
217 | |
218 X_out[N2 + N4 + 1 + 2*k] = RE(Z1[N4 - 1 - k]); | |
219 X_out[N2 + N4 + 3 + 2*k] = RE(Z1[N4 - 2 - k]); | |
220 } | |
221 | |
222 #ifdef PROFILE | |
223 count2 = faad_get_ts() - count2; | |
224 mdct->fft_cycles += count1; | |
225 mdct->cycles += (count2 - count1); | |
226 #endif | |
227 } | |
228 | |
10725 | 229 #ifdef LTP_DEC |
230 void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out) | |
231 { | |
232 uint16_t k; | |
233 | |
234 complex_t x; | |
12527 | 235 ALIGN complex_t Z1[512]; |
10725 | 236 complex_t *sincos = mdct->sincos; |
237 | |
238 uint16_t N = mdct->N; | |
239 uint16_t N2 = N >> 1; | |
240 uint16_t N4 = N >> 2; | |
241 uint16_t N8 = N >> 3; | |
242 | |
12527 | 243 #ifndef FIXED_POINT |
10725 | 244 real_t scale = REAL_CONST(N); |
12527 | 245 #else |
246 real_t scale = REAL_CONST(4.0/N); | |
247 #endif | |
10725 | 248 |
13453
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
249 #ifdef ALLOW_SMALL_FRAMELENGTH |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
250 #ifdef FIXED_POINT |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
251 /* detect non-power of 2 */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
252 if (N & (N-1)) |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
253 { |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
254 /* adjust scale for non-power of 2 MDCT */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
255 /* *= sqrt(2048/1920) */ |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
256 scale = MUL_C(scale, COEF_CONST(1.0327955589886444)); |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
257 } |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
258 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
259 #endif |
6d50ef45a058
Update FAAD to a 2.1 beta CVS snapshot from 2004.07.12.
diego
parents:
12625
diff
changeset
|
260 |
10725 | 261 /* pre-FFT complex multiplication */ |
262 for (k = 0; k < N8; k++) | |
263 { | |
264 uint16_t n = k << 1; | |
265 RE(x) = X_in[N - N4 - 1 - n] + X_in[N - N4 + n]; | |
266 IM(x) = X_in[ N4 + n] - X_in[ N4 - 1 - n]; | |
267 | |
12527 | 268 ComplexMult(&RE(Z1[k]), &IM(Z1[k]), |
269 RE(x), IM(x), RE(sincos[k]), IM(sincos[k])); | |
270 | |
271 RE(Z1[k]) = MUL_R(RE(Z1[k]), scale); | |
272 IM(Z1[k]) = MUL_R(IM(Z1[k]), scale); | |
10725 | 273 |
274 RE(x) = X_in[N2 - 1 - n] - X_in[ n]; | |
275 IM(x) = X_in[N2 + n] + X_in[N - 1 - n]; | |
276 | |
12527 | 277 ComplexMult(&RE(Z1[k + N8]), &IM(Z1[k + N8]), |
278 RE(x), IM(x), RE(sincos[k + N8]), IM(sincos[k + N8])); | |
279 | |
280 RE(Z1[k + N8]) = MUL_R(RE(Z1[k + N8]), scale); | |
281 IM(Z1[k + N8]) = MUL_R(IM(Z1[k + N8]), scale); | |
10725 | 282 } |
283 | |
10989 | 284 /* complex FFT, any non-scaling FFT can be used here */ |
10725 | 285 cfftf(mdct->cfft, Z1); |
286 | |
287 /* post-FFT complex multiplication */ | |
288 for (k = 0; k < N4; k++) | |
289 { | |
290 uint16_t n = k << 1; | |
12527 | 291 ComplexMult(&RE(x), &IM(x), |
292 RE(Z1[k]), IM(Z1[k]), RE(sincos[k]), IM(sincos[k])); | |
10725 | 293 |
12527 | 294 X_out[ n] = -RE(x); |
295 X_out[N2 - 1 - n] = IM(x); | |
296 X_out[N2 + n] = -IM(x); | |
297 X_out[N - 1 - n] = RE(x); | |
10725 | 298 } |
299 } | |
300 #endif |