]> git.sesse.net Git - vlc/blob - src/ac3_decoder/ac3_imdct.c
* Fixed a few warnings with gcc 3.0.
[vlc] / src / ac3_decoder / ac3_imdct.c
1 /*****************************************************************************
2  * ac3_imdct.c: ac3 DCT
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: ac3_imdct.c,v 1.18 2001/05/06 04:32:02 sam Exp $
6  *
7  * Authors: Michel Kaempf <maxx@via.ecp.fr>
8  *          Aaron Holtzman <aholtzma@engr.uvic.ca>
9  *          Renaud Dartus <reno@videolan.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 #include "defs.h"
27
28 #include <string.h>                                              /* memcpy() */
29
30 #include <math.h>
31 #include <stdio.h>
32
33 #include "config.h"
34 #include "common.h"
35 #include "threads.h"
36 #include "mtime.h"
37
38 #include "stream_control.h"
39 #include "input_ext-dec.h"
40
41 #include "ac3_decoder.h"
42 #include "ac3_internal.h"
43
44 #include "ac3_downmix.h"
45 #include "ac3_imdct_c.h"
46 #if 0
47 #include "ac3_imdct_kni.h"
48 #endif
49
50 #include "tests.h"
51
52 #ifndef M_PI
53 #   define M_PI 3.14159265358979323846
54 #endif
55
56
57 void imdct_init(imdct_t * p_imdct)
58 {
59         int i;
60         float scale = 255.99609372;
61
62 #if 0
63         if ( TestCPU (CPU_CAPABILITY_MMX) )
64     {
65         imdct_init_kni (p_imdct);
66     } else 
67 #endif
68     {
69         imdct_init_c (p_imdct);
70     }
71
72         /* More twiddle factors to turn IFFT into IMDCT */
73         for (i=0; i < 64; i++) {
74                 p_imdct->xcos2[i] = cos(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
75                 p_imdct->xsin2[i] = sin(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
76         }
77 }
78
79 void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
80 {
81         int   i;
82         int   doable = 0;
83         float *center=NULL, *left, *right, *left_sur, *right_sur;
84         float *delay_left, *delay_right;
85         float *delay1_left, *delay1_right, *delay1_center, *delay1_sr, *delay1_sl;
86         float right_tmp, left_tmp;
87         void (*do_imdct)(imdct_t * p_imdct, float data[], float delay[]);
88
89         /* test if dm in frequency is doable */
90         if (!(doable = p_ac3dec->audblk.blksw[0]))
91     {
92                 do_imdct = p_ac3dec->imdct.imdct_do_512;
93     }
94         else
95     {
96                 do_imdct = imdct_do_256; /* There is only a C function */
97     }
98
99         /* downmix in the frequency domain if all the channels
100          * use the same imdct */
101         for (i=0; i < p_ac3dec->bsi.nfchans; i++)
102     {
103                 if (doable != p_ac3dec->audblk.blksw[i])
104         {
105                         do_imdct = NULL;
106                         break;
107                 }
108         }
109
110     if (do_imdct)
111     {
112                 /* dowmix first and imdct */
113         switch(p_ac3dec->bsi.acmod)
114         {
115                 case 7:         /* 3/2 */
116                         p_ac3dec->downmix.downmix_3f_2r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
117                         break;
118                 case 6:         /* 2/2 */
119                         p_ac3dec->downmix.downmix_2f_2r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
120                         break;
121                 case 5:         /* 3/1 */
122                         p_ac3dec->downmix.downmix_3f_1r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
123                         break;
124                 case 4:         /* 2/1 */
125                         p_ac3dec->downmix.downmix_2f_1r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
126                         break;
127                 case 3:         /* 3/0 */
128                         p_ac3dec->downmix.downmix_3f_0r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
129                         break;
130                 case 2:
131                         break;
132                 default:        /* 1/0 */
133 //                      if (p_ac3dec->bsi.acmod == 1)
134                                 center = p_ac3dec->samples[0];
135 //                      else if (p_ac3dec->bsi.acmod == 0)
136 //                  center = samples[ac3_config.dual_mono_ch_sel];
137                 do_imdct(&p_ac3dec->imdct, center, p_ac3dec->imdct.delay[0]); /* no downmix*/
138     
139                         p_ac3dec->downmix.stream_sample_1ch_to_s16 (buffer, center);
140
141                     return;
142                 break;
143         }
144
145                 do_imdct (&p_ac3dec->imdct, p_ac3dec->samples[0], p_ac3dec->imdct.delay[0]);
146                 do_imdct (&p_ac3dec->imdct, p_ac3dec->samples[1], p_ac3dec->imdct.delay[1]);
147                 p_ac3dec->downmix.stream_sample_2ch_to_s16(buffer, p_ac3dec->samples[0], p_ac3dec->samples[1]);
148
149         } else {
150         /* imdct and then downmix
151                  * delay and samples should be saved and mixed
152                  * fprintf(stderr, "time domain downmix\n"); */
153                 for (i=0; i<p_ac3dec->bsi.nfchans; i++)
154         {
155                         if (p_ac3dec->audblk.blksw[i])
156                 /* There is only a C function */
157                                 imdct_do_256_nol (&p_ac3dec->imdct, p_ac3dec->samples[i], p_ac3dec->imdct.delay1[i]);
158                         else
159                                 p_ac3dec->imdct.imdct_do_512_nol (&p_ac3dec->imdct, p_ac3dec->samples[i], p_ac3dec->imdct.delay1[i]);
160                 }
161
162                 /* mix the sample, overlap */
163                 switch(p_ac3dec->bsi.acmod)
164         {
165                 case 7:         /* 3/2 */
166                         left = p_ac3dec->samples[0];
167                         center = p_ac3dec->samples[1];
168                         right = p_ac3dec->samples[2];
169                         left_sur = p_ac3dec->samples[3];
170                         right_sur = p_ac3dec->samples[4];
171                         delay_left = p_ac3dec->imdct.delay[0];
172                         delay_right = p_ac3dec->imdct.delay[1];
173                         delay1_left = p_ac3dec->imdct.delay1[0];
174                         delay1_center = p_ac3dec->imdct.delay1[1];
175                         delay1_right = p_ac3dec->imdct.delay1[2];
176                 delay1_sl = p_ac3dec->imdct.delay1[3];
177                         delay1_sr = p_ac3dec->imdct.delay1[4];
178     
179                         for (i = 0; i < 256; i++) {
180                                 left_tmp = p_ac3dec->dm_par.unit * *left++  + p_ac3dec->dm_par.clev * *center  + p_ac3dec->dm_par.slev * *left_sur++;
181                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *right_sur++;
182                                 *buffer++ = (s16)(left_tmp + *delay_left);
183                                 *buffer++ = (s16)(right_tmp + *delay_right);
184                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++  + p_ac3dec->dm_par.clev * *delay1_center  + p_ac3dec->dm_par.slev * *delay1_sl++;
185                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *delay1_sr++;
186                         }
187                         break;
188                 case 6:         /* 2/2 */
189                         left = p_ac3dec->samples[0];
190                         right = p_ac3dec->samples[1];
191                         left_sur = p_ac3dec->samples[2];
192                         right_sur = p_ac3dec->samples[3];
193                         delay_left = p_ac3dec->imdct.delay[0];
194                         delay_right = p_ac3dec->imdct.delay[1];
195                         delay1_left = p_ac3dec->imdct.delay1[0];
196                         delay1_right = p_ac3dec->imdct.delay1[1];
197                         delay1_sl = p_ac3dec->imdct.delay1[2];
198                         delay1_sr = p_ac3dec->imdct.delay1[3];
199     
200                         for (i = 0; i < 256; i++) {
201                                 left_tmp = p_ac3dec->dm_par.unit * *left++  + p_ac3dec->dm_par.slev * *left_sur++;
202                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.slev * *right_sur++;
203                                 *buffer++ = (s16)(left_tmp + *delay_left);
204                                 *buffer++ = (s16)(right_tmp + *delay_right);
205                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++  + p_ac3dec->dm_par.slev * *delay1_sl++;
206                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.slev * *delay1_sr++;
207                         }
208                         break;
209                 case 5:         /* 3/1 */
210                         left = p_ac3dec->samples[0];
211                         center = p_ac3dec->samples[1];
212                         right = p_ac3dec->samples[2];
213                         right_sur = p_ac3dec->samples[3];
214                         delay_left = p_ac3dec->imdct.delay[0];
215                         delay_right = p_ac3dec->imdct.delay[1];
216                         delay1_left = p_ac3dec->imdct.delay1[0];
217                         delay1_center = p_ac3dec->imdct.delay1[1];
218                         delay1_right = p_ac3dec->imdct.delay1[2];
219                         delay1_sl = p_ac3dec->imdct.delay1[3];
220     
221                         for (i = 0; i < 256; i++) {
222                                 left_tmp = p_ac3dec->dm_par.unit * *left++  + p_ac3dec->dm_par.clev * *center  - p_ac3dec->dm_par.slev * *right_sur;
223                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *right_sur++;
224                                 *buffer++ = (s16)(left_tmp + *delay_left);
225                                 *buffer++ = (s16)(right_tmp + *delay_right);
226                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++  + p_ac3dec->dm_par.clev * *delay1_center  + p_ac3dec->dm_par.slev * *delay1_sl;
227                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *delay1_sl++;
228                         }
229                         break;
230                 case 4:         /* 2/1 */
231                         left = p_ac3dec->samples[0];
232                         right = p_ac3dec->samples[1];
233                         right_sur = p_ac3dec->samples[2];
234                         delay_left = p_ac3dec->imdct.delay[0];
235                         delay_right = p_ac3dec->imdct.delay[1];
236                         delay1_left = p_ac3dec->imdct.delay1[0];
237                         delay1_right = p_ac3dec->imdct.delay1[1];
238                         delay1_sl = p_ac3dec->imdct.delay1[2];
239     
240                         for (i = 0; i < 256; i++) {
241                                 left_tmp = p_ac3dec->dm_par.unit * *left++ - p_ac3dec->dm_par.slev * *right_sur;
242                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.slev * *right_sur++;
243                                 *buffer++ = (s16)(left_tmp + *delay_left);
244                                 *buffer++ = (s16)(right_tmp + *delay_right);
245                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++ + p_ac3dec->dm_par.slev * *delay1_sl;
246                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.slev * *delay1_sl++;
247                         }
248                         break;
249                 case 3:         /* 3/0 */
250                         left = p_ac3dec->samples[0];
251                         center = p_ac3dec->samples[1];
252                         right = p_ac3dec->samples[2];
253                         delay_left = p_ac3dec->imdct.delay[0];
254                         delay_right = p_ac3dec->imdct.delay[1];
255                         delay1_left = p_ac3dec->imdct.delay1[0];
256                         delay1_center = p_ac3dec->imdct.delay1[1];
257                         delay1_right = p_ac3dec->imdct.delay1[2];
258
259                         for (i = 0; i < 256; i++) {
260                                 left_tmp = p_ac3dec->dm_par.unit * *left++  + p_ac3dec->dm_par.clev * *center;
261                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++;
262                                 *buffer++ = (s16)(left_tmp + *delay_left);
263                                 *buffer++ = (s16)(right_tmp + *delay_right);
264                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++  + p_ac3dec->dm_par.clev * *delay1_center;
265                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++;
266                         }
267                         break;
268                 case 2:         /* copy to output */
269                         for (i = 0; i < 256; i++) {
270                                 *buffer++ = (s16)p_ac3dec->samples[0][i];
271                                 *buffer++ = (s16)p_ac3dec->samples[1][i];
272                         }
273                         break;
274                 }
275         }
276 }