]> git.sesse.net Git - vlc/blob - plugins/imdct/ac3_imdct_common.c
* Added error checking in pthread wrapper ; as a result, intf_msg.h must
[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.4 2001/11/28 15:08:05 massiot 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 /* MODULE_NAME defined in Makefile together with -DBUILTIN */
26 #ifdef BUILTIN
27 #   include "modules_inner.h"
28 #else
29 #   define _M( foo ) foo
30 #endif
31
32 /*****************************************************************************
33  * Preamble
34  *****************************************************************************/
35 #include "defs.h"
36
37 #include <string.h>                                              /* memcpy() */
38
39 #include <math.h>
40 #include <stdio.h>
41
42 #include "config.h"
43 #include "common.h"
44
45 #include "ac3_imdct.h"
46 #include "ac3_retables.h"
47
48 #ifndef M_PI
49 #   define M_PI 3.14159265358979323846
50 #endif
51
52 void _M( fft_64p )  ( complex_t *x );
53
54 void _M( imdct_do_256 ) (imdct_t * p_imdct, float data[],float delay[])
55 {
56     int i, j, k;
57     int p, q;
58
59     float tmp_a_i;
60     float tmp_a_r;
61
62     float *data_ptr;
63     float *delay_ptr;
64     float *window_ptr;
65
66     complex_t *buf1, *buf2;
67
68     buf1 = &p_imdct->buf[0];
69     buf2 = &p_imdct->buf[64];
70
71     /* Pre IFFT complex multiply plus IFFT complex conjugate */
72     for (k=0; k<64; k++) { 
73         /* X1[k] = X[2*k]
74          * X2[k] = X[2*k+1]    */
75
76         j = pm64[k];
77         p = 2 * (128-2*j-1);
78         q = 2 * (2 * j);
79
80         /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
81         buf1[k].real =        data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
82         buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
83         /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
84         buf2[k].real =        data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
85         buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
86     }
87
88     _M( fft_64p ) ( &buf1[0] );
89     _M( fft_64p ) ( &buf2[0] );
90
91     /* Post IFFT complex multiply */
92     for( i=0; i < 64; i++) {
93         tmp_a_r =  buf1[i].real;
94         tmp_a_i = -buf1[i].imag;
95         buf1[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
96         buf1[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[i]);
97         tmp_a_r =  buf2[i].real;
98         tmp_a_i = -buf2[i].imag;
99         buf2[i].real = (tmp_a_r * p_imdct->xcos2[i]) - (tmp_a_i * p_imdct->xsin2[i]);
100         buf2[i].imag = (tmp_a_r * p_imdct->xsin2[i]) + (tmp_a_i * p_imdct->xcos2[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++ = -buf1[i].imag     * *window_ptr++ + *delay_ptr++;
110         *data_ptr++ = buf1[64-i-1].real * *window_ptr++ + *delay_ptr++;
111     }
112
113     for(i=0; i< 64; i++) {
114         *data_ptr++ = -buf1[i].real     * *window_ptr++ + *delay_ptr++;
115         *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
116     }
117     
118     delay_ptr = delay;
119
120     for(i=0; i< 64; i++) {
121         *delay_ptr++ = -buf2[i].real      * *--window_ptr;
122         *delay_ptr++ =  buf2[64-i-1].imag * *--window_ptr;
123     }
124
125     for(i=0; i< 64; i++) {
126         *delay_ptr++ =  buf2[i].imag      * *--window_ptr;
127         *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
128     }
129 }
130
131
132 void _M( imdct_do_256_nol ) (imdct_t * p_imdct, float data[], float delay[])
133 {
134     int i, j, k;
135     int p, q;
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     complex_t *buf1, *buf2;
145
146     buf1 = &p_imdct->buf[0];
147     buf2 = &p_imdct->buf[64];
148
149     /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
150     for(k=0; k<64; k++) {
151         /* X1[k] = X[2*k]
152         * X2[k] = X[2*k+1] */
153         j = pm64[k];
154         p = 2 * (128-2*j-1);
155         q = 2 * (2 * j);
156
157         /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
158         buf1[k].real =        data[p] * p_imdct->xcos2[j] - data[q] * p_imdct->xsin2[j];
159         buf1[k].imag = -1.0f*(data[q] * p_imdct->xcos2[j] + data[p] * p_imdct->xsin2[j]);
160         /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
161         buf2[k].real =        data[p + 1] * p_imdct->xcos2[j] - data[q + 1] * p_imdct->xsin2[j];
162         buf2[k].imag = -1.0f*(data[q + 1] * p_imdct->xcos2[j] + data[p + 1] * p_imdct->xsin2[j]);
163     }
164
165     _M( fft_64p ) ( &buf1[0] );
166     _M( fft_64p ) ( &buf2[0] );
167
168     /* Post IFFT complex multiply */
169     for( i=0; i < 64; i++) {
170         /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
171         tmp_a_r =  buf1[i].real;
172         tmp_a_i = -buf1[i].imag;
173         buf1[i].real =(tmp_a_r * p_imdct->xcos2[i])  -  (tmp_a_i  * p_imdct->xsin2[i]);
174         buf1[i].imag =(tmp_a_r * p_imdct->xsin2[i])  +  (tmp_a_i  * p_imdct->xcos2[i]);
175         /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
176         tmp_a_r =  buf2[i].real;
177         tmp_a_i = -buf2[i].imag;
178         buf2[i].real =(tmp_a_r * p_imdct->xcos2[i])  -  (tmp_a_i  * p_imdct->xsin2[i]);
179         buf2[i].imag =(tmp_a_r * p_imdct->xsin2[i])  +  (tmp_a_i  * p_imdct->xcos2[i]);
180     }
181       
182     data_ptr = data;
183     delay_ptr = delay;
184     window_ptr = window;
185
186     /* Window and convert to real valued signal, no overlap */
187     for(i=0; i< 64; i++) {
188         *data_ptr++ = -buf1[i].imag     * *window_ptr++;
189         *data_ptr++ = buf1[64-i-1].real * *window_ptr++;
190     }
191
192     for(i=0; i< 64; i++) {
193         *data_ptr++ = -buf1[i].real     * *window_ptr++ + *delay_ptr++;
194         *data_ptr++ = buf1[64-i-1].imag * *window_ptr++ + *delay_ptr++;
195     }
196
197     delay_ptr = delay;
198
199     for(i=0; i< 64; i++) {
200         *delay_ptr++ = -buf2[i].real      * *--window_ptr;
201         *delay_ptr++ =  buf2[64-i-1].imag * *--window_ptr;
202     }
203
204     for(i=0; i< 64; i++) {
205         *delay_ptr++ =  buf2[i].imag      * *--window_ptr;
206         *delay_ptr++ = -buf2[64-i-1].real * *--window_ptr;
207     }
208 }