]> git.sesse.net Git - vlc/blob - plugins/imdct/ac3_imdct_c.c
Fixed numerous bugs with the Altivec IDCT (still not compiling).
[vlc] / plugins / imdct / ac3_imdct_c.c
1 /*****************************************************************************
2  * ac3_imdct_c.c: ac3 DCT in C
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: ac3_imdct_c.c,v 1.2 2001/05/16 14:51:29 reno 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 #define MODULE_NAME imdct
26 #include "modules_inner.h"
27
28 /*****************************************************************************
29  * Preamble
30  *****************************************************************************/
31 #include "defs.h"
32
33 #include <string.h>                                              /* memcpy() */
34
35 #include <math.h>
36 #include <stdio.h>
37
38 #include "config.h"
39 #include "common.h"
40 #include "threads.h"
41 #include "mtime.h"
42
43 #include "ac3_imdct.h"
44 #include "ac3_imdct_common.h"
45 #include "ac3_retables.h"
46
47 #ifndef M_PI
48 #   define M_PI 3.14159265358979323846
49 #endif
50
51 void _M( fft_64p )  ( complex_t *x );
52 void _M( fft_128p ) ( complex_t *x );
53
54 void _M( imdct_init ) (imdct_t * p_imdct)
55 {
56     int i;
57     float scale = 181.019;
58
59     /* Twiddle factors to turn IFFT into IMDCT */
60     for (i=0; i < 128; i++) {
61         p_imdct->xcos1[i] = cos(2.0f * M_PI * (8*i+1)/(8*N)) * scale; 
62         p_imdct->xsin1[i] = sin(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
63     }
64 }
65
66 void _M( imdct_do_512 ) (imdct_t * p_imdct, float data[], float delay[])
67 {
68     int i, j;
69     float tmp_a_r, tmp_a_i;
70     float *data_ptr;
71     float *delay_ptr;
72     float *window_ptr;
73
74     /* 512 IMDCT with source and dest data in 'data'
75      * Pre IFFT complex multiply plus IFFT complex conjugate */
76
77     for( i=0; i < 128; i++) {
78         j = pm128[i];
79         /* a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
80          * c = data[2*j] * xcos1[j];
81          * b = data[256-2*j-1] * xsin1[j];
82          * buf1[i].real = a - b + c;
83          * buf1[i].imag = b + c; */
84         p_imdct->buf[i].real = (data[256-2*j-1] * p_imdct->xcos1[j]) - (data[2*j] * p_imdct->xsin1[j]);
85         p_imdct->buf[i].imag = -1.0 * (data[2*j] * p_imdct->xcos1[j] + data[256-2*j-1] * p_imdct->xsin1[j]);
86     }
87
88     _M( fft_128p ) ( &p_imdct->buf[0] );
89
90     /* Post IFFT complex multiply  plus IFFT complex conjugate */
91     for (i=0; i < 128; i++) {
92         tmp_a_r = p_imdct->buf[i].real;
93         tmp_a_i = p_imdct->buf[i].imag;
94         /* a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
95          * b = tmp_a_r * xsin1[j];
96          * c = tmp_a_i * xcos1[j];
97          * buf[j].real = a - b + c;
98          * buf[j].imag = b + c; */
99         p_imdct->buf[i].real =(tmp_a_r * p_imdct->xcos1[i])  +  (tmp_a_i  * p_imdct->xsin1[i]);
100         p_imdct->buf[i].imag =(tmp_a_r * p_imdct->xsin1[i])  -  (tmp_a_i  * p_imdct->xcos1[i]);
101     }
102
103     data_ptr = data;
104     delay_ptr = delay;
105     window_ptr = window;
106
107     /* Window and convert to real valued signal */
108     for (i=0; i< 64; i++) {
109         *data_ptr++ = -p_imdct->buf[64+i].imag  * *window_ptr++ + *delay_ptr++;
110         *data_ptr++ = p_imdct->buf[64-i-1].real * *window_ptr++ + *delay_ptr++;
111     }
112
113     for(i=0; i< 64; i++) {
114         *data_ptr++ = -p_imdct->buf[i].real      * *window_ptr++ + *delay_ptr++;
115         *data_ptr++ = p_imdct->buf[128-i-1].imag * *window_ptr++ + *delay_ptr++;
116     }
117
118     /* The trailing edge of the window goes into the delay line */
119     delay_ptr = delay;
120
121     for(i=0; i< 64; i++) {
122         *delay_ptr++ = -p_imdct->buf[64+i].real   * *--window_ptr;
123         *delay_ptr++ =  p_imdct->buf[64-i-1].imag * *--window_ptr;
124     }
125
126     for(i=0; i<64; i++) {
127         *delay_ptr++ =  p_imdct->buf[i].imag       * *--window_ptr;
128         *delay_ptr++ = -p_imdct->buf[128-i-1].real * *--window_ptr;
129     }
130 }
131
132
133 void _M( imdct_do_512_nol ) (imdct_t * p_imdct, float data[], float delay[])
134 {
135     int i, j;
136
137     float tmp_a_i;
138     float tmp_a_r;
139
140     float *data_ptr;
141     float *delay_ptr;
142     float *window_ptr;
143
144     /* 512 IMDCT with source and dest data in 'data'
145      * Pre IFFT complex multiply plus IFFT cmplx conjugate */
146
147     for( i=0; i < 128; i++) {
148         /* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) */
149         j = pm128[i];
150         /* a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
151          * c = data[2*j] * xcos1[j];
152          * b = data[256-2*j-1] * xsin1[j];
153          * buf1[i].real = a - b + c;
154          * buf1[i].imag = b + c; */
155         p_imdct->buf[i].real = (data[256-2*j-1] * p_imdct->xcos1[j]) - (data[2*j] * p_imdct->xsin1[j]);
156         p_imdct->buf[i].imag = -1.0 * (data[2*j] * p_imdct->xcos1[j] + data[256-2*j-1] * p_imdct->xsin1[j]);
157     }
158        
159     _M( fft_128p ) ( &p_imdct->buf[0] );
160
161     /* Post IFFT complex multiply  plus IFFT complex conjugate*/
162     for (i=0; i < 128; i++) {
163         /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ;
164          * int j1 = i; */
165         tmp_a_r = p_imdct->buf[i].real;
166         tmp_a_i = p_imdct->buf[i].imag;
167         /* a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
168          * b = tmp_a_r * xsin1[j];
169          * c = tmp_a_i * xcos1[j];
170          * buf[j].real = a - b + c;
171          * buf[j].imag = b + c; */
172         p_imdct->buf[i].real =(tmp_a_r * p_imdct->xcos1[i]) + (tmp_a_i  * p_imdct->xsin1[i]);
173         p_imdct->buf[i].imag =(tmp_a_r * p_imdct->xsin1[i]) - (tmp_a_i  * p_imdct->xcos1[i]);
174     }
175        
176     data_ptr = data;
177     delay_ptr = delay;
178     window_ptr = window;
179
180     /* Window and convert to real valued signal, no overlap here*/
181     for (i=0; i< 64; i++) { 
182         *data_ptr++ = -p_imdct->buf[64+i].imag  * *window_ptr++; 
183         *data_ptr++ = p_imdct->buf[64-i-1].real * *window_ptr++; 
184     }
185
186     for(i=0; i< 64; i++) { 
187         *data_ptr++ = -p_imdct->buf[i].real      * *window_ptr++; 
188         *data_ptr++ = p_imdct->buf[128-i-1].imag * *window_ptr++; 
189     }
190        
191     /* The trailing edge of the window goes into the delay line */
192     delay_ptr = delay;
193
194     for(i=0; i< 64; i++) { 
195         *delay_ptr++ = -p_imdct->buf[64+i].real   * *--window_ptr; 
196         *delay_ptr++ =  p_imdct->buf[64-i-1].imag * *--window_ptr; 
197     }
198
199     for(i=0; i<64; i++) {
200         *delay_ptr++ =  p_imdct->buf[i].imag       * *--window_ptr; 
201         *delay_ptr++ = -p_imdct->buf[128-i-1].real * *--window_ptr; 
202     }
203 }
204