1 /*****************************************************************************
2 * ac3_imdct_c.c: ac3 DCT
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
5 * $Id: ac3_imdct_c.c,v 1.3 2001/05/14 15:58:04 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 *****************************************************************************/
27 #include <string.h> /* memcpy() */
37 #include "stream_control.h"
38 #include "input_ext-dec.h"
40 #include "ac3_decoder.h"
41 #include "ac3_imdct_c.h"
44 # define M_PI 3.14159265358979323846
47 void fft_64p_c (complex_t *x);
48 void fft_128p_c (complex_t *x);
50 static float window[] = {
51 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
52 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
53 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
54 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
55 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
56 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
57 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
58 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
59 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
60 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
61 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
62 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
63 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
64 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
65 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
66 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
67 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
68 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
69 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
70 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
71 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
72 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
73 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
74 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
75 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
76 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
77 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
78 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
79 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
80 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
81 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
82 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
85 static const int pm128[128] =
87 0, 16, 32, 48, 64, 80, 96, 112, 8, 40, 72, 104, 24, 56, 88, 120,
88 4, 20, 36, 52, 68, 84, 100, 116, 12, 28, 44, 60, 76, 92, 108, 124,
89 2, 18, 34, 50, 66, 82, 98, 114, 10, 42, 74, 106, 26, 58, 90, 122,
90 6, 22, 38, 54, 70, 86, 102, 118, 14, 46, 78, 110, 30, 62, 94, 126,
91 1, 17, 33, 49, 65, 81, 97, 113, 9, 41, 73, 105, 25, 57, 89, 121,
92 5, 21, 37, 53, 69, 85, 101, 117, 13, 29, 45, 61, 77, 93, 109, 125,
93 3, 19, 35, 51, 67, 83, 99, 115, 11, 43, 75, 107, 27, 59, 91, 123,
94 7, 23, 39, 55, 71, 87, 103, 119, 15, 31, 47, 63, 79, 95, 111, 127
97 static const int pm64[64] =
99 0, 8, 16, 24, 32, 40, 48, 56,
100 4, 20, 36, 52, 12, 28, 44, 60,
101 2, 10, 18, 26, 34, 42, 50, 58,
102 6, 14, 22, 30, 38, 46, 54, 62,
103 1, 9, 17, 25, 33, 41, 49, 57,
104 5, 21, 37, 53, 13, 29, 45, 61,
105 3, 11, 19, 27, 35, 43, 51, 59,
106 7, 23, 39, 55, 15, 31, 47, 63
109 int imdct_init_c (imdct_t * p_imdct)
112 float scale = 181.019;
114 p_imdct->imdct_do_512 = imdct_do_512_c;
115 p_imdct->imdct_do_512_nol = imdct_do_512_nol_c;
116 p_imdct->fft_64p = fft_64p_c;
118 /* Twiddle factors to turn IFFT into IMDCT */
120 for (i=0; i < 128; i++) {
121 p_imdct->xcos1[i] = cos(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
122 p_imdct->xsin1[i] = sin(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
128 void imdct_do_256 (imdct_t * p_imdct, float data[],float delay[])
140 complex_t *buf1, *buf2;
142 buf1 = &p_imdct->buf[0];
143 buf2 = &p_imdct->buf[64];
145 /* Pre IFFT complex multiply plus IFFT complex conjugate */
146 for (k=0; k<64; k++) {
148 * X2[k] = X[2*k+1] */
154 /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
155 buf1[k].real = data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
156 buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
157 /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
158 buf2[k].real = data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
159 buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
162 p_imdct->fft_64p(&buf1[0]);
163 p_imdct->fft_64p(&buf2[0]);
165 /* Post IFFT complex multiply */
166 for( i=0; i < 64; i++) {
167 tmp_a_r = buf1[i].real;
168 tmp_a_i = -buf1[i].imag;
169 buf1[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
170 buf1[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
171 tmp_a_r = buf2[i].real;
172 tmp_a_i = -buf2[i].imag;
173 buf2[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
174 buf2[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
181 /* Window and convert to real valued signal */
182 for(i=0; i< 64; i++) {
183 *data_ptr++ = -buf1[i].imag * *window_ptr++ + *delay_ptr++;
184 *data_ptr++ = buf1[64-i-1].real * *window_ptr++ + *delay_ptr++;
187 for(i=0; i< 64; i++) {
188 *data_ptr++ = -buf1[i].real * *window_ptr++ + *delay_ptr++;
189 *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
194 for(i=0; i< 64; i++) {
195 *delay_ptr++ = -buf2[i].real * *--window_ptr;
196 *delay_ptr++ = buf2[64-i-1].imag * *--window_ptr;
199 for(i=0; i< 64; i++) {
200 *delay_ptr++ = buf2[i].imag * *--window_ptr;
201 *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
206 void imdct_do_256_nol (imdct_t * p_imdct, float data[], float delay[])
218 complex_t *buf1, *buf2;
220 buf1 = &p_imdct->buf[0];
221 buf2 = &p_imdct->buf[64];
223 /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
224 for(k=0; k<64; k++) {
226 * X2[k] = X[2*k+1] */
231 /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
232 buf1[k].real = data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
233 buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
234 /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
235 buf2[k].real = data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
236 buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
239 p_imdct->fft_64p(&buf1[0]);
240 p_imdct->fft_64p(&buf2[0]);
242 /* Post IFFT complex multiply */
243 for( i=0; i < 64; i++) {
244 /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
245 tmp_a_r = buf1[i].real;
246 tmp_a_i = -buf1[i].imag;
247 buf1[i].real =(tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
248 buf1[i].imag =(tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
249 /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
250 tmp_a_r = buf2[i].real;
251 tmp_a_i = -buf2[i].imag;
252 buf2[i].real =(tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
253 buf2[i].imag =(tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
260 /* Window and convert to real valued signal, no overlap */
261 for(i=0; i< 64; i++) {
262 *data_ptr++ = -buf1[i].imag * *window_ptr++;
263 *data_ptr++ = buf1[64-i-1].real * *window_ptr++;
266 for(i=0; i< 64; i++) {
267 *data_ptr++ = -buf1[i].real * *window_ptr++ + *delay_ptr++;
268 *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
273 for(i=0; i< 64; i++) {
274 *delay_ptr++ = -buf2[i].real * *--window_ptr;
275 *delay_ptr++ = buf2[64-i-1].imag * *--window_ptr;
278 for(i=0; i< 64; i++) {
279 *delay_ptr++ = buf2[i].imag * *--window_ptr;
280 *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
284 void imdct_do_512_c (imdct_t * p_imdct, float data[], float delay[])
287 float tmp_a_r, tmp_a_i;
292 /* 512 IMDCT with source and dest data in 'data'
293 * Pre IFFT complex multiply plus IFFT complex conjugate */
295 for( i=0; i < 128; i++) {
297 /* a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
298 * c = data[2*j] * xcos1[j];
299 * b = data[256-2*j-1] * xsin1[j];
300 * buf1[i].real = a - b + c;
301 * buf1[i].imag = b + c; */
302 p_imdct->buf[i].real = (data[256-2*j-1] * p_imdct->xcos1[j]) - (data[2*j] * p_imdct->xsin1[j]);
303 p_imdct->buf[i].imag = -1.0 * (data[2*j] * p_imdct->xcos1[j] + data[256-2*j-1] * p_imdct->xsin1[j]);
306 fft_128p_c (&p_imdct->buf[0]);
308 /* Post IFFT complex multiply plus IFFT complex conjugate */
309 for (i=0; i < 128; i++) {
310 tmp_a_r = p_imdct->buf[i].real;
311 tmp_a_i = p_imdct->buf[i].imag;
312 /* a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
313 * b = tmp_a_r * xsin1[j];
314 * c = tmp_a_i * xcos1[j];
315 * buf[j].real = a - b + c;
316 * buf[j].imag = b + c; */
317 p_imdct->buf[i].real =(tmp_a_r * p_imdct->xcos1[i]) + (tmp_a_i * p_imdct->xsin1[i]);
318 p_imdct->buf[i].imag =(tmp_a_r * p_imdct->xsin1[i]) - (tmp_a_i * p_imdct->xcos1[i]);
325 /* Window and convert to real valued signal */
326 for (i=0; i< 64; i++) {
327 *data_ptr++ = -p_imdct->buf[64+i].imag * *window_ptr++ + *delay_ptr++;
328 *data_ptr++ = p_imdct->buf[64-i-1].real * *window_ptr++ + *delay_ptr++;
331 for(i=0; i< 64; i++) {
332 *data_ptr++ = -p_imdct->buf[i].real * *window_ptr++ + *delay_ptr++;
333 *data_ptr++ = p_imdct->buf[128-i-1].imag * *window_ptr++ + *delay_ptr++;
336 /* The trailing edge of the window goes into the delay line */
339 for(i=0; i< 64; i++) {
340 *delay_ptr++ = -p_imdct->buf[64+i].real * *--window_ptr;
341 *delay_ptr++ = p_imdct->buf[64-i-1].imag * *--window_ptr;
344 for(i=0; i<64; i++) {
345 *delay_ptr++ = p_imdct->buf[i].imag * *--window_ptr;
346 *delay_ptr++ = -p_imdct->buf[128-i-1].real * *--window_ptr;
351 void imdct_do_512_nol_c (imdct_t * p_imdct, float data[], float delay[])
362 /* 512 IMDCT with source and dest data in 'data'
363 * Pre IFFT complex multiply plus IFFT cmplx conjugate */
365 for( i=0; i < 128; i++) {
366 /* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) */
368 /* a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
369 * c = data[2*j] * xcos1[j];
370 * b = data[256-2*j-1] * xsin1[j];
371 * buf1[i].real = a - b + c;
372 * buf1[i].imag = b + c; */
373 p_imdct->buf[i].real = (data[256-2*j-1] * p_imdct->xcos1[j]) - (data[2*j] * p_imdct->xsin1[j]);
374 p_imdct->buf[i].imag = -1.0 * (data[2*j] * p_imdct->xcos1[j] + data[256-2*j-1] * p_imdct->xsin1[j]);
377 fft_128p_c (&p_imdct->buf[0]);
379 /* Post IFFT complex multiply plus IFFT complex conjugate*/
380 for (i=0; i < 128; i++) {
381 /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ;
383 tmp_a_r = p_imdct->buf[i].real;
384 tmp_a_i = p_imdct->buf[i].imag;
385 /* a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
386 * b = tmp_a_r * xsin1[j];
387 * c = tmp_a_i * xcos1[j];
388 * buf[j].real = a - b + c;
389 * buf[j].imag = b + c; */
390 p_imdct->buf[i].real =(tmp_a_r * p_imdct->xcos1[i]) + (tmp_a_i * p_imdct->xsin1[i]);
391 p_imdct->buf[i].imag =(tmp_a_r * p_imdct->xsin1[i]) - (tmp_a_i * p_imdct->xcos1[i]);
398 /* Window and convert to real valued signal, no overlap here*/
399 for (i=0; i< 64; i++) {
400 *data_ptr++ = -p_imdct->buf[64+i].imag * *window_ptr++;
401 *data_ptr++ = p_imdct->buf[64-i-1].real * *window_ptr++;
404 for(i=0; i< 64; i++) {
405 *data_ptr++ = -p_imdct->buf[i].real * *window_ptr++;
406 *data_ptr++ = p_imdct->buf[128-i-1].imag * *window_ptr++;
409 /* The trailing edge of the window goes into the delay line */
412 for(i=0; i< 64; i++) {
413 *delay_ptr++ = -p_imdct->buf[64+i].real * *--window_ptr;
414 *delay_ptr++ = p_imdct->buf[64-i-1].imag * *--window_ptr;
417 for(i=0; i<64; i++) {
418 *delay_ptr++ = p_imdct->buf[i].imag * *--window_ptr;
419 *delay_ptr++ = -p_imdct->buf[128-i-1].real * *--window_ptr;