]> git.sesse.net Git - vlc/blob - src/ac3_decoder/ac3_imdct.c
c52006b21f14c8310115355897494711e0b873ab
[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.19 2001/05/14 15:58:04 reno 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
43 #include "ac3_imdct_c.h"                                     /* imdct_init_c */
44 #include "ac3_imdct_sse.h"                                 /* imdct_init_sse */
45
46 #include "tests.h"                                                /* TestCPU */
47
48 #ifndef M_PI
49 #   define M_PI 3.14159265358979323846
50 #endif
51
52
53 void imdct_init(imdct_t * p_imdct)
54 {
55         int i;
56         float scale = 181.019;
57 #if 0
58         if ( TestCPU (CPU_CAPABILITY_SSE) )
59     {
60         imdct_init_sse (p_imdct);
61     }
62     else
63 #endif
64     {
65         imdct_init_c (p_imdct);
66     }
67
68         /* More twiddle factors to turn IFFT into IMDCT */
69         for (i=0; i < 64; i++) {
70                 p_imdct->xcos2[i] = cos(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
71                 p_imdct->xsin2[i] = sin(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
72         }
73 }
74
75 void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
76 {
77         int   i;
78         int   doable = 0;
79         float *center=NULL, *left, *right, *left_sur, *right_sur;
80         float *delay_left, *delay_right;
81         float *delay1_left, *delay1_right, *delay1_center, *delay1_sr, *delay1_sl;
82         float right_tmp, left_tmp;
83         void (*do_imdct)(imdct_t * p_imdct, float data[], float delay[]);
84
85         /* test if dm in frequency is doable */
86         if (!(doable = p_ac3dec->audblk.blksw[0]))
87     {
88                 do_imdct = p_ac3dec->imdct.imdct_do_512;
89     }
90         else
91     {
92                 do_imdct = imdct_do_256; /* There is only a C function */
93     }
94
95         /* downmix in the frequency domain if all the channels
96          * use the same imdct */
97         for (i=0; i < p_ac3dec->bsi.nfchans; i++)
98     {
99                 if (doable != p_ac3dec->audblk.blksw[i])
100         {
101                         do_imdct = NULL;
102                         break;
103                 }
104         }
105
106     if (do_imdct)
107     {
108                 /* dowmix first and imdct */
109         switch(p_ac3dec->bsi.acmod)
110         {
111                 case 7:         /* 3/2 */
112                         p_ac3dec->downmix.downmix_3f_2r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
113                         break;
114                 case 6:         /* 2/2 */
115                         p_ac3dec->downmix.downmix_2f_2r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
116                         break;
117                 case 5:         /* 3/1 */
118                         p_ac3dec->downmix.downmix_3f_1r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
119                         break;
120                 case 4:         /* 2/1 */
121                         p_ac3dec->downmix.downmix_2f_1r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
122                         break;
123                 case 3:         /* 3/0 */
124                         p_ac3dec->downmix.downmix_3f_0r_to_2ch (p_ac3dec->samples[0], &p_ac3dec->dm_par);
125                         break;
126                 case 2:
127                         break;
128                 default:        /* 1/0 */
129 //                      if (p_ac3dec->bsi.acmod == 1)
130                                 center = p_ac3dec->samples[0];
131 //                      else if (p_ac3dec->bsi.acmod == 0)
132 //                  center = samples[ac3_config.dual_mono_ch_sel];
133                 do_imdct(&p_ac3dec->imdct, center, p_ac3dec->imdct.delay[0]); /* no downmix*/
134     
135                         p_ac3dec->downmix.stream_sample_1ch_to_s16 (buffer, center);
136
137                     return;
138                 break;
139         }
140
141                 do_imdct (&p_ac3dec->imdct, p_ac3dec->samples[0], p_ac3dec->imdct.delay[0]);
142                 do_imdct (&p_ac3dec->imdct, p_ac3dec->samples[1], p_ac3dec->imdct.delay[1]);
143                 p_ac3dec->downmix.stream_sample_2ch_to_s16(buffer, p_ac3dec->samples[0], p_ac3dec->samples[1]);
144
145         } else {
146         /* imdct and then downmix
147                  * delay and samples should be saved and mixed
148                  * fprintf(stderr, "time domain downmix\n"); */
149                 for (i=0; i<p_ac3dec->bsi.nfchans; i++)
150         {
151                         if (p_ac3dec->audblk.blksw[i])
152                 /* There is only a C function */
153                                 imdct_do_256_nol (&p_ac3dec->imdct, p_ac3dec->samples[i], p_ac3dec->imdct.delay1[i]);
154                         else
155                                 p_ac3dec->imdct.imdct_do_512_nol (&p_ac3dec->imdct, p_ac3dec->samples[i], p_ac3dec->imdct.delay1[i]);
156                 }
157
158                 /* mix the sample, overlap */
159                 switch(p_ac3dec->bsi.acmod)
160         {
161                 case 7:         /* 3/2 */
162                         left = p_ac3dec->samples[0];
163                         center = p_ac3dec->samples[1];
164                         right = p_ac3dec->samples[2];
165                         left_sur = p_ac3dec->samples[3];
166                         right_sur = p_ac3dec->samples[4];
167                         delay_left = p_ac3dec->imdct.delay[0];
168                         delay_right = p_ac3dec->imdct.delay[1];
169                         delay1_left = p_ac3dec->imdct.delay1[0];
170                         delay1_center = p_ac3dec->imdct.delay1[1];
171                         delay1_right = p_ac3dec->imdct.delay1[2];
172                 delay1_sl = p_ac3dec->imdct.delay1[3];
173                         delay1_sr = p_ac3dec->imdct.delay1[4];
174     
175                         for (i = 0; i < 256; i++) {
176                                 left_tmp = p_ac3dec->dm_par.unit * *left++  + p_ac3dec->dm_par.clev * *center  + p_ac3dec->dm_par.slev * *left_sur++;
177                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *right_sur++;
178                                 *buffer++ = (s16)(left_tmp + *delay_left);
179                                 *buffer++ = (s16)(right_tmp + *delay_right);
180                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++  + p_ac3dec->dm_par.clev * *delay1_center  + p_ac3dec->dm_par.slev * *delay1_sl++;
181                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *delay1_sr++;
182                         }
183                         break;
184                 case 6:         /* 2/2 */
185                         left = p_ac3dec->samples[0];
186                         right = p_ac3dec->samples[1];
187                         left_sur = p_ac3dec->samples[2];
188                         right_sur = p_ac3dec->samples[3];
189                         delay_left = p_ac3dec->imdct.delay[0];
190                         delay_right = p_ac3dec->imdct.delay[1];
191                         delay1_left = p_ac3dec->imdct.delay1[0];
192                         delay1_right = p_ac3dec->imdct.delay1[1];
193                         delay1_sl = p_ac3dec->imdct.delay1[2];
194                         delay1_sr = p_ac3dec->imdct.delay1[3];
195     
196                         for (i = 0; i < 256; i++) {
197                                 left_tmp = p_ac3dec->dm_par.unit * *left++  + p_ac3dec->dm_par.slev * *left_sur++;
198                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.slev * *right_sur++;
199                                 *buffer++ = (s16)(left_tmp + *delay_left);
200                                 *buffer++ = (s16)(right_tmp + *delay_right);
201                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++  + p_ac3dec->dm_par.slev * *delay1_sl++;
202                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.slev * *delay1_sr++;
203                         }
204                         break;
205                 case 5:         /* 3/1 */
206                         left = p_ac3dec->samples[0];
207                         center = p_ac3dec->samples[1];
208                         right = p_ac3dec->samples[2];
209                         right_sur = p_ac3dec->samples[3];
210                         delay_left = p_ac3dec->imdct.delay[0];
211                         delay_right = p_ac3dec->imdct.delay[1];
212                         delay1_left = p_ac3dec->imdct.delay1[0];
213                         delay1_center = p_ac3dec->imdct.delay1[1];
214                         delay1_right = p_ac3dec->imdct.delay1[2];
215                         delay1_sl = p_ac3dec->imdct.delay1[3];
216     
217                         for (i = 0; i < 256; i++) {
218                                 left_tmp = p_ac3dec->dm_par.unit * *left++  + p_ac3dec->dm_par.clev * *center  - p_ac3dec->dm_par.slev * *right_sur;
219                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *right_sur++;
220                                 *buffer++ = (s16)(left_tmp + *delay_left);
221                                 *buffer++ = (s16)(right_tmp + *delay_right);
222                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++  + p_ac3dec->dm_par.clev * *delay1_center  + p_ac3dec->dm_par.slev * *delay1_sl;
223                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++ + p_ac3dec->dm_par.slev * *delay1_sl++;
224                         }
225                         break;
226                 case 4:         /* 2/1 */
227                         left = p_ac3dec->samples[0];
228                         right = p_ac3dec->samples[1];
229                         right_sur = p_ac3dec->samples[2];
230                         delay_left = p_ac3dec->imdct.delay[0];
231                         delay_right = p_ac3dec->imdct.delay[1];
232                         delay1_left = p_ac3dec->imdct.delay1[0];
233                         delay1_right = p_ac3dec->imdct.delay1[1];
234                         delay1_sl = p_ac3dec->imdct.delay1[2];
235     
236                         for (i = 0; i < 256; i++) {
237                                 left_tmp = p_ac3dec->dm_par.unit * *left++ - p_ac3dec->dm_par.slev * *right_sur;
238                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.slev * *right_sur++;
239                                 *buffer++ = (s16)(left_tmp + *delay_left);
240                                 *buffer++ = (s16)(right_tmp + *delay_right);
241                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++ + p_ac3dec->dm_par.slev * *delay1_sl;
242                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.slev * *delay1_sl++;
243                         }
244                         break;
245                 case 3:         /* 3/0 */
246                         left = p_ac3dec->samples[0];
247                         center = p_ac3dec->samples[1];
248                         right = p_ac3dec->samples[2];
249                         delay_left = p_ac3dec->imdct.delay[0];
250                         delay_right = p_ac3dec->imdct.delay[1];
251                         delay1_left = p_ac3dec->imdct.delay1[0];
252                         delay1_center = p_ac3dec->imdct.delay1[1];
253                         delay1_right = p_ac3dec->imdct.delay1[2];
254
255                         for (i = 0; i < 256; i++) {
256                                 left_tmp = p_ac3dec->dm_par.unit * *left++  + p_ac3dec->dm_par.clev * *center;
257                                 right_tmp= p_ac3dec->dm_par.unit * *right++ + p_ac3dec->dm_par.clev * *center++;
258                                 *buffer++ = (s16)(left_tmp + *delay_left);
259                                 *buffer++ = (s16)(right_tmp + *delay_right);
260                                 *delay_left++ = p_ac3dec->dm_par.unit * *delay1_left++  + p_ac3dec->dm_par.clev * *delay1_center;
261                                 *delay_right++ = p_ac3dec->dm_par.unit * *delay1_right++ + p_ac3dec->dm_par.clev * *center++;
262                         }
263                         break;
264                 case 2:         /* copy to output */
265                         for (i = 0; i < 256; i++) {
266                                 *buffer++ = (s16)p_ac3dec->samples[0][i];
267                                 *buffer++ = (s16)p_ac3dec->samples[1][i];
268                         }
269                         break;
270                 }
271         }
272 }