]> git.sesse.net Git - vlc/blob - plugins/imdct/ac3_imdct_common.c
Some heavy changes today:
[vlc] / plugins / imdct / ac3_imdct_common.c
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.6 2001/12/30 07:09:55 sam Exp $
6  *
7  * Authors: Renaud Dartus <reno@videolan.org>
8  *          Aaron Holtzman <aholtzma@engr.uvic.ca>
9  *
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.
14  * 
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.
19  *
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  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <math.h>
29 #include <stdio.h>
30
31 #include <videolan/vlc.h>
32
33 #include "ac3_imdct.h"
34 #include "ac3_retables.h"
35
36 #ifndef M_PI
37 #   define M_PI 3.14159265358979323846
38 #endif
39
40 void _M( fft_64p )  ( complex_t *x );
41
42 void _M( imdct_do_256 ) (imdct_t * p_imdct, float data[],float delay[])
43 {
44     int i, j, k;
45     int p, q;
46
47     float tmp_a_i;
48     float tmp_a_r;
49
50     float *data_ptr;
51     float *delay_ptr;
52     float *window_ptr;
53
54     complex_t *buf1, *buf2;
55
56     buf1 = &p_imdct->buf[0];
57     buf2 = &p_imdct->buf[64];
58
59     /* Pre IFFT complex multiply plus IFFT complex conjugate */
60     for (k=0; k<64; k++) { 
61         /* X1[k] = X[2*k]
62          * X2[k] = X[2*k+1]    */
63
64         j = pm64[k];
65         p = 2 * (128-2*j-1);
66         q = 2 * (2 * j);
67
68         /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
69         buf1[k].real =        data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
70         buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
71         /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
72         buf2[k].real =        data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
73         buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
74     }
75
76     _M( fft_64p ) ( &buf1[0] );
77     _M( fft_64p ) ( &buf2[0] );
78
79     /* Post IFFT complex multiply */
80     for( i=0; i < 64; i++) {
81         tmp_a_r =  buf1[i].real;
82         tmp_a_i = -buf1[i].imag;
83         buf1[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
84         buf1[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
85         tmp_a_r =  buf2[i].real;
86         tmp_a_i = -buf2[i].imag;
87         buf2[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
88         buf2[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
89     }
90     
91     data_ptr = data;
92     delay_ptr = delay;
93     window_ptr = window;
94
95     /* Window and convert to real valued signal */
96     for(i=0; i< 64; i++) { 
97         *data_ptr++ = -buf1[i].imag     * *window_ptr++ + *delay_ptr++;
98         *data_ptr++ = buf1[64-i-1].real * *window_ptr++ + *delay_ptr++;
99     }
100
101     for(i=0; i< 64; i++) {
102         *data_ptr++ = -buf1[i].real     * *window_ptr++ + *delay_ptr++;
103         *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
104     }
105     
106     delay_ptr = delay;
107
108     for(i=0; i< 64; i++) {
109         *delay_ptr++ = -buf2[i].real      * *--window_ptr;
110         *delay_ptr++ =  buf2[64-i-1].imag * *--window_ptr;
111     }
112
113     for(i=0; i< 64; i++) {
114         *delay_ptr++ =  buf2[i].imag      * *--window_ptr;
115         *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
116     }
117 }
118
119
120 void _M( imdct_do_256_nol ) (imdct_t * p_imdct, float data[], float delay[])
121 {
122     int i, j, k;
123     int p, q;
124
125     float tmp_a_i;
126     float tmp_a_r;
127
128     float *data_ptr;
129     float *delay_ptr;
130     float *window_ptr;
131
132     complex_t *buf1, *buf2;
133
134     buf1 = &p_imdct->buf[0];
135     buf2 = &p_imdct->buf[64];
136
137     /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
138     for(k=0; k<64; k++) {
139         /* X1[k] = X[2*k]
140         * X2[k] = X[2*k+1] */
141         j = pm64[k];
142         p = 2 * (128-2*j-1);
143         q = 2 * (2 * j);
144
145         /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
146         buf1[k].real =        data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
147         buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
148         /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
149         buf2[k].real =        data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
150         buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
151     }
152
153     _M( fft_64p ) ( &buf1[0] );
154     _M( fft_64p ) ( &buf2[0] );
155
156     /* Post IFFT complex multiply */
157     for( i=0; i < 64; i++) {
158         /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
159         tmp_a_r =  buf1[i].real;
160         tmp_a_i = -buf1[i].imag;
161         buf1[i].real =(tmp_a_r * p_imdct->xcos2[i])  -  (tmp_a_i  * p_imdct->xsin2[i]);
162         buf1[i].imag =(tmp_a_r * p_imdct->xsin2[i])  +  (tmp_a_i  * p_imdct->xcos2[i]);
163         /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
164         tmp_a_r =  buf2[i].real;
165         tmp_a_i = -buf2[i].imag;
166         buf2[i].real =(tmp_a_r * p_imdct->xcos2[i])  -  (tmp_a_i  * p_imdct->xsin2[i]);
167         buf2[i].imag =(tmp_a_r * p_imdct->xsin2[i])  +  (tmp_a_i  * p_imdct->xcos2[i]);
168     }
169       
170     data_ptr = data;
171     delay_ptr = delay;
172     window_ptr = window;
173
174     /* Window and convert to real valued signal, no overlap */
175     for(i=0; i< 64; i++) {
176         *data_ptr++ = -buf1[i].imag     * *window_ptr++;
177         *data_ptr++ = buf1[64-i-1].real * *window_ptr++;
178     }
179
180     for(i=0; i< 64; i++) {
181         *data_ptr++ = -buf1[i].real     * *window_ptr++ + *delay_ptr++;
182         *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
183     }
184
185     delay_ptr = delay;
186
187     for(i=0; i< 64; i++) {
188         *delay_ptr++ = -buf2[i].real      * *--window_ptr;
189         *delay_ptr++ =  buf2[64-i-1].imag * *--window_ptr;
190     }
191
192     for(i=0; i< 64; i++) {
193         *delay_ptr++ =  buf2[i].imag      * *--window_ptr;
194         *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
195     }
196 }