1 /*****************************************************************************
2 * ac3_imdct_common.c: common ac3 DCT functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
5 * $Id: ac3_imdct_common.c,v 1.1 2001/05/15 16:19:42 sam 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 *****************************************************************************/
25 /* MODULE_NAME defined in Makefile together with -DBUILTIN */
27 # include "modules_inner.h"
29 # define _M( foo ) foo
32 /*****************************************************************************
34 *****************************************************************************/
37 #include <string.h> /* memcpy() */
47 #include "ac3_imdct.h"
50 # define M_PI 3.14159265358979323846
53 static float window[] = {
54 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
55 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
56 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
57 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
58 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
59 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
60 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
61 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
62 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
63 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
64 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
65 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
66 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
67 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
68 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
69 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
70 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
71 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
72 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
73 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
74 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
75 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
76 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
77 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
78 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
79 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
80 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
81 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
82 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
83 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
84 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
85 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
88 static const int pm128[128] =
90 0, 16, 32, 48, 64, 80, 96, 112, 8, 40, 72, 104, 24, 56, 88, 120,
91 4, 20, 36, 52, 68, 84, 100, 116, 12, 28, 44, 60, 76, 92, 108, 124,
92 2, 18, 34, 50, 66, 82, 98, 114, 10, 42, 74, 106, 26, 58, 90, 122,
93 6, 22, 38, 54, 70, 86, 102, 118, 14, 46, 78, 110, 30, 62, 94, 126,
94 1, 17, 33, 49, 65, 81, 97, 113, 9, 41, 73, 105, 25, 57, 89, 121,
95 5, 21, 37, 53, 69, 85, 101, 117, 13, 29, 45, 61, 77, 93, 109, 125,
96 3, 19, 35, 51, 67, 83, 99, 115, 11, 43, 75, 107, 27, 59, 91, 123,
97 7, 23, 39, 55, 71, 87, 103, 119, 15, 31, 47, 63, 79, 95, 111, 127
100 static const int pm64[64] =
102 0, 8, 16, 24, 32, 40, 48, 56,
103 4, 20, 36, 52, 12, 28, 44, 60,
104 2, 10, 18, 26, 34, 42, 50, 58,
105 6, 14, 22, 30, 38, 46, 54, 62,
106 1, 9, 17, 25, 33, 41, 49, 57,
107 5, 21, 37, 53, 13, 29, 45, 61,
108 3, 11, 19, 27, 35, 43, 51, 59,
109 7, 23, 39, 55, 15, 31, 47, 63
112 void _M( imdct_do_256 ) (imdct_t * p_imdct, float data[],float delay[])
124 complex_t *buf1, *buf2;
126 buf1 = &p_imdct->buf[0];
127 buf2 = &p_imdct->buf[64];
129 /* Pre IFFT complex multiply plus IFFT complex conjugate */
130 for (k=0; k<64; k++) {
132 * X2[k] = X[2*k+1] */
138 /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
139 buf1[k].real = data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
140 buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
141 /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
142 buf2[k].real = data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
143 buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
146 _M( fft_64p ) ( &buf1[0] );
147 _M( fft_64p ) ( &buf2[0] );
149 /* Post IFFT complex multiply */
150 for( i=0; i < 64; i++) {
151 tmp_a_r = buf1[i].real;
152 tmp_a_i = -buf1[i].imag;
153 buf1[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
154 buf1[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
155 tmp_a_r = buf2[i].real;
156 tmp_a_i = -buf2[i].imag;
157 buf2[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
158 buf2[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
165 /* Window and convert to real valued signal */
166 for(i=0; i< 64; i++) {
167 *data_ptr++ = -buf1[i].imag * *window_ptr++ + *delay_ptr++;
168 *data_ptr++ = buf1[64-i-1].real * *window_ptr++ + *delay_ptr++;
171 for(i=0; i< 64; i++) {
172 *data_ptr++ = -buf1[i].real * *window_ptr++ + *delay_ptr++;
173 *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
178 for(i=0; i< 64; i++) {
179 *delay_ptr++ = -buf2[i].real * *--window_ptr;
180 *delay_ptr++ = buf2[64-i-1].imag * *--window_ptr;
183 for(i=0; i< 64; i++) {
184 *delay_ptr++ = buf2[i].imag * *--window_ptr;
185 *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
190 void _M( imdct_do_256_nol ) (imdct_t * p_imdct, float data[], float delay[])
202 complex_t *buf1, *buf2;
204 buf1 = &p_imdct->buf[0];
205 buf2 = &p_imdct->buf[64];
207 /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
208 for(k=0; k<64; k++) {
210 * X2[k] = X[2*k+1] */
215 /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
216 buf1[k].real = data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
217 buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
218 /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
219 buf2[k].real = data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
220 buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
223 _M( fft_64p ) ( &buf1[0] );
224 _M( fft_64p ) ( &buf2[0] );
226 /* Post IFFT complex multiply */
227 for( i=0; i < 64; i++) {
228 /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
229 tmp_a_r = buf1[i].real;
230 tmp_a_i = -buf1[i].imag;
231 buf1[i].real =(tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
232 buf1[i].imag =(tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
233 /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
234 tmp_a_r = buf2[i].real;
235 tmp_a_i = -buf2[i].imag;
236 buf2[i].real =(tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
237 buf2[i].imag =(tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
244 /* Window and convert to real valued signal, no overlap */
245 for(i=0; i< 64; i++) {
246 *data_ptr++ = -buf1[i].imag * *window_ptr++;
247 *data_ptr++ = buf1[64-i-1].real * *window_ptr++;
250 for(i=0; i< 64; i++) {
251 *data_ptr++ = -buf1[i].real * *window_ptr++ + *delay_ptr++;
252 *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
257 for(i=0; i< 64; i++) {
258 *delay_ptr++ = -buf2[i].real * *--window_ptr;
259 *delay_ptr++ = buf2[64-i-1].imag * *--window_ptr;
262 for(i=0; i< 64; i++) {
263 *delay_ptr++ = buf2[i].imag * *--window_ptr;
264 *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;