1 /*****************************************************************************
2 * ac3_imdct_c.c: ac3 DCT
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
5 * $Id: ac3_imdct_c.c,v 1.1 2001/04/30 21:04:20 reno Exp $
7 * Authors: Renaud Dartus <reno@videolan.org>
8 * Aaron Holtzman <aholtzma@engr.uvic.ca>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
35 #include "stream_control.h"
36 #include "input_ext-dec.h"
38 #include "ac3_decoder.h"
39 #include "ac3_internal.h"
41 void fft_64p_c (complex_t *x);
42 void fft_128p_c (complex_t *x);
43 void imdct_do_512_c (imdct_t * p_imdct, float data[], float delay[]);
44 void imdct_do_512_nol_c (imdct_t * p_imdct, float data[], float delay[]);
47 static float window[] = {
48 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
49 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
50 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
51 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
52 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
53 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
54 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
55 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
56 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
57 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
58 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
59 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
60 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
61 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
62 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
63 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
64 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
65 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
66 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
67 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
68 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
69 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
70 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
71 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
72 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
73 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
74 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
75 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
76 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
77 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
78 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
79 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
82 static const int pm128[128] =
84 0, 16, 32, 48, 64, 80, 96, 112, 8, 40, 72, 104, 24, 56, 88, 120,
85 4, 20, 36, 52, 68, 84, 100, 116, 12, 28, 44, 60, 76, 92, 108, 124,
86 2, 18, 34, 50, 66, 82, 98, 114, 10, 42, 74, 106, 26, 58, 90, 122,
87 6, 22, 38, 54, 70, 86, 102, 118, 14, 46, 78, 110, 30, 62, 94, 126,
88 1, 17, 33, 49, 65, 81, 97, 113, 9, 41, 73, 105, 25, 57, 89, 121,
89 5, 21, 37, 53, 69, 85, 101, 117, 13, 29, 45, 61, 77, 93, 109, 125,
90 3, 19, 35, 51, 67, 83, 99, 115, 11, 43, 75, 107, 27, 59, 91, 123,
91 7, 23, 39, 55, 71, 87, 103, 119, 15, 31, 47, 63, 79, 95, 111, 127
94 static const int pm64[64] =
96 0, 8, 16, 24, 32, 40, 48, 56,
97 4, 20, 36, 52, 12, 28, 44, 60,
98 2, 10, 18, 26, 34, 42, 50, 58,
99 6, 14, 22, 30, 38, 46, 54, 62,
100 1, 9, 17, 25, 33, 41, 49, 57,
101 5, 21, 37, 53, 13, 29, 45, 61,
102 3, 11, 19, 27, 35, 43, 51, 59,
103 7, 23, 39, 55, 15, 31, 47, 63
106 int imdct_init_c (imdct_t * p_imdct)
109 float scale = 255.99609372;
111 p_imdct->imdct_do_512 = imdct_do_512_c;
112 p_imdct->imdct_do_512_nol = imdct_do_512_nol_c;
113 p_imdct->fft_64p = fft_64p_c;
115 /* Twiddle factors to turn IFFT into IMDCT */
117 for (i=0; i < 128; i++) {
118 p_imdct->xcos1[i] = cos(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
119 p_imdct->xsin1[i] = sin(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
125 void imdct_do_256 (imdct_t * p_imdct, float data[],float delay[])
137 complex_t *buf1, *buf2;
139 buf1 = &p_imdct->buf[0];
140 buf2 = &p_imdct->buf[64];
142 /* Pre IFFT complex multiply plus IFFT complex conjugate */
143 for (k=0; k<64; k++) {
145 * X2[k] = X[2*k+1] */
151 /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
152 buf1[k].real = data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
153 buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
154 /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
155 buf2[k].real = data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
156 buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
159 p_imdct->fft_64p(&buf1[0]);
160 p_imdct->fft_64p(&buf2[0]);
162 /* Post IFFT complex multiply */
163 for( i=0; i < 64; i++) {
164 tmp_a_r = buf1[i].real;
165 tmp_a_i = -buf1[i].imag;
166 buf1[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
167 buf1[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
168 tmp_a_r = buf2[i].real;
169 tmp_a_i = -buf2[i].imag;
170 buf2[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
171 buf2[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
178 /* Window and convert to real valued signal */
179 for(i=0; i< 64; i++) {
180 *data_ptr++ = -buf1[i].imag * *window_ptr++ + *delay_ptr++;
181 *data_ptr++ = buf1[64-i-1].real * *window_ptr++ + *delay_ptr++;
184 for(i=0; i< 64; i++) {
185 *data_ptr++ = -buf1[i].real * *window_ptr++ + *delay_ptr++;
186 *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
191 for(i=0; i< 64; i++) {
192 *delay_ptr++ = -buf2[i].real * *--window_ptr;
193 *delay_ptr++ = buf2[64-i-1].imag * *--window_ptr;
196 for(i=0; i< 64; i++) {
197 *delay_ptr++ = buf2[i].imag * *--window_ptr;
198 *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
203 void imdct_do_256_nol (imdct_t * p_imdct, float data[], float delay[])
215 complex_t *buf1, *buf2;
217 buf1 = &p_imdct->buf[0];
218 buf2 = &p_imdct->buf[64];
220 /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
221 for(k=0; k<64; k++) {
223 * X2[k] = X[2*k+1] */
228 /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
229 buf1[k].real = data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
230 buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
231 /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
232 buf2[k].real = data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
233 buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
236 p_imdct->fft_64p(&buf1[0]);
237 p_imdct->fft_64p(&buf2[0]);
239 /* Post IFFT complex multiply */
240 for( i=0; i < 64; i++) {
241 /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
242 tmp_a_r = buf1[i].real;
243 tmp_a_i = -buf1[i].imag;
244 buf1[i].real =(tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
245 buf1[i].imag =(tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
246 /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
247 tmp_a_r = buf2[i].real;
248 tmp_a_i = -buf2[i].imag;
249 buf2[i].real =(tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
250 buf2[i].imag =(tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
257 /* Window and convert to real valued signal, no overlap */
258 for(i=0; i< 64; i++) {
259 *data_ptr++ = -buf1[i].imag * *window_ptr++;
260 *data_ptr++ = buf1[64-i-1].real * *window_ptr++;
263 for(i=0; i< 64; i++) {
264 *data_ptr++ = -buf1[i].real * *window_ptr++ + *delay_ptr++;
265 *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
270 for(i=0; i< 64; i++) {
271 *delay_ptr++ = -buf2[i].real * *--window_ptr;
272 *delay_ptr++ = buf2[64-i-1].imag * *--window_ptr;
275 for(i=0; i< 64; i++) {
276 *delay_ptr++ = buf2[i].imag * *--window_ptr;
277 *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
281 void imdct_do_512_c (imdct_t * p_imdct, float data[], float delay[])
284 float tmp_a_r, tmp_a_i;
289 /* 512 IMDCT with source and dest data in 'data'
290 * Pre IFFT complex multiply plus IFFT complex conjugate */
292 for( i=0; i < 128; i++) {
294 /* a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
295 * c = data[2*j] * xcos1[j];
296 * b = data[256-2*j-1] * xsin1[j];
297 * buf1[i].real = a - b + c;
298 * buf1[i].imag = b + c; */
299 p_imdct->buf[i].real = (data[256-2*j-1] * p_imdct->xcos1[j]) - (data[2*j] * p_imdct->xsin1[j]);
300 p_imdct->buf[i].imag = -1.0 * (data[2*j] * p_imdct->xcos1[j] + data[256-2*j-1] * p_imdct->xsin1[j]);
303 fft_128p_c (&p_imdct->buf[0]);
305 /* Post IFFT complex multiply plus IFFT complex conjugate */
306 for (i=0; i < 128; i++) {
307 tmp_a_r = p_imdct->buf[i].real;
308 tmp_a_i = p_imdct->buf[i].imag;
309 /* a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
310 * b = tmp_a_r * xsin1[j];
311 * c = tmp_a_i * xcos1[j];
312 * buf[j].real = a - b + c;
313 * buf[j].imag = b + c; */
314 p_imdct->buf[i].real =(tmp_a_r * p_imdct->xcos1[i]) + (tmp_a_i * p_imdct->xsin1[i]);
315 p_imdct->buf[i].imag =(tmp_a_r * p_imdct->xsin1[i]) - (tmp_a_i * p_imdct->xcos1[i]);
322 /* Window and convert to real valued signal */
323 for (i=0; i< 64; i++) {
324 *data_ptr++ = -p_imdct->buf[64+i].imag * *window_ptr++ + *delay_ptr++;
325 *data_ptr++ = p_imdct->buf[64-i-1].real * *window_ptr++ + *delay_ptr++;
328 for(i=0; i< 64; i++) {
329 *data_ptr++ = -p_imdct->buf[i].real * *window_ptr++ + *delay_ptr++;
330 *data_ptr++ = p_imdct->buf[128-i-1].imag * *window_ptr++ + *delay_ptr++;
333 /* The trailing edge of the window goes into the delay line */
336 for(i=0; i< 64; i++) {
337 *delay_ptr++ = -p_imdct->buf[64+i].real * *--window_ptr;
338 *delay_ptr++ = p_imdct->buf[64-i-1].imag * *--window_ptr;
341 for(i=0; i<64; i++) {
342 *delay_ptr++ = p_imdct->buf[i].imag * *--window_ptr;
343 *delay_ptr++ = -p_imdct->buf[128-i-1].real * *--window_ptr;
348 void imdct_do_512_nol_c (imdct_t * p_imdct, float data[], float delay[])
359 /* 512 IMDCT with source and dest data in 'data'
360 * Pre IFFT complex multiply plus IFFT cmplx conjugate */
362 for( i=0; i < 128; i++) {
363 /* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) */
365 /* a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
366 * c = data[2*j] * xcos1[j];
367 * b = data[256-2*j-1] * xsin1[j];
368 * buf1[i].real = a - b + c;
369 * buf1[i].imag = b + c; */
370 p_imdct->buf[i].real = (data[256-2*j-1] * p_imdct->xcos1[j]) - (data[2*j] * p_imdct->xsin1[j]);
371 p_imdct->buf[i].imag = -1.0 * (data[2*j] * p_imdct->xcos1[j] + data[256-2*j-1] * p_imdct->xsin1[j]);
374 fft_128p_c (&p_imdct->buf[0]);
376 /* Post IFFT complex multiply plus IFFT complex conjugate*/
377 for (i=0; i < 128; i++) {
378 /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ;
380 tmp_a_r = p_imdct->buf[i].real;
381 tmp_a_i = p_imdct->buf[i].imag;
382 /* a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
383 * b = tmp_a_r * xsin1[j];
384 * c = tmp_a_i * xcos1[j];
385 * buf[j].real = a - b + c;
386 * buf[j].imag = b + c; */
387 p_imdct->buf[i].real =(tmp_a_r * p_imdct->xcos1[i]) + (tmp_a_i * p_imdct->xsin1[i]);
388 p_imdct->buf[i].imag =(tmp_a_r * p_imdct->xsin1[i]) - (tmp_a_i * p_imdct->xcos1[i]);
395 /* Window and convert to real valued signal, no overlap here*/
396 for (i=0; i< 64; i++) {
397 *data_ptr++ = -p_imdct->buf[64+i].imag * *window_ptr++;
398 *data_ptr++ = p_imdct->buf[64-i-1].real * *window_ptr++;
401 for(i=0; i< 64; i++) {
402 *data_ptr++ = -p_imdct->buf[i].real * *window_ptr++;
403 *data_ptr++ = p_imdct->buf[128-i-1].imag * *window_ptr++;
406 /* The trailing edge of the window goes into the delay line */
409 for(i=0; i< 64; i++) {
410 *delay_ptr++ = -p_imdct->buf[64+i].real * *--window_ptr;
411 *delay_ptr++ = p_imdct->buf[64-i-1].imag * *--window_ptr;
414 for(i=0; i<64; i++) {
415 *delay_ptr++ = p_imdct->buf[i].imag * *--window_ptr;
416 *delay_ptr++ = -p_imdct->buf[128-i-1].real * *--window_ptr;