]> git.sesse.net Git - vlc/blob - plugins/ac3_adec/ac3_imdct.c
* COMPLETE CVS BREAKAGE !! The MAIN branch is going to be a playground
[vlc] / plugins / ac3_adec / ac3_imdct.c
1 /*****************************************************************************
2  * ac3_imdct.c: ac3 DCT
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: ac3_imdct.c,v 1.5 2001/12/09 17:01:36 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 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include "defs.h"
30
31 #include <string.h>                                              /* memcpy() */
32
33 #include <math.h>
34 #include <stdio.h>
35
36 #include "common.h"
37 #include "intf_msg.h"
38 #include "threads.h"
39 #include "mtime.h"
40
41 #include "modules.h"
42 #include "modules_export.h"
43
44 #include "stream_control.h"
45 #include "input_ext-dec.h"
46
47 #include "ac3_imdct.h"
48 #include "ac3_downmix.h"
49 #include "ac3_decoder.h"
50
51 #ifndef M_PI
52 #   define M_PI 3.14159265358979323846
53 #endif
54
55 void imdct_init(imdct_t * p_imdct)
56 {
57     int i;
58     float scale = 181.019;
59
60     p_imdct->pf_imdct_init( p_imdct );
61
62     /* More twiddle factors to turn IFFT into IMDCT */
63     for (i=0; i < 64; i++) {
64         p_imdct->xcos2[i] = cos(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
65         p_imdct->xsin2[i] = sin(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
66     }
67 }
68
69 void imdct (ac3dec_t * p_ac3dec, s16 * buffer)
70 {
71     int   i;
72     int   doable = 0;
73     float *center=NULL, *left, *right, *left_sur, *right_sur;
74     float *delay_left, *delay_right;
75     float *delay1_left, *delay1_right, *delay1_center, *delay1_sr, *delay1_sl;
76     float right_tmp, left_tmp;
77     void (*do_imdct)(imdct_t * p_imdct, float data[], float delay[]);
78
79     /* test if dm in frequency is doable */
80     if (!(doable = p_ac3dec->audblk.blksw[0]))
81     {
82         do_imdct = p_ac3dec->imdct->pf_imdct_512;
83     }
84     else
85     {
86         do_imdct = p_ac3dec->imdct->pf_imdct_256;
87     }
88
89     /* downmix in the frequency domain if all the channels
90      * use the same imdct */
91     for (i=0; i < p_ac3dec->bsi.nfchans; i++)
92     {
93         if (doable != p_ac3dec->audblk.blksw[i])
94         {
95             do_imdct = NULL;
96             break;
97         }
98     }
99
100     if (do_imdct)
101     {
102         /* dowmix first and imdct */
103         switch(p_ac3dec->bsi.acmod)
104         {
105             case 7:        /* 3/2 */
106                 p_ac3dec->downmix.pf_downmix_3f_2r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
107                 break;
108             case 6:        /* 2/2 */
109                 p_ac3dec->downmix.pf_downmix_2f_2r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
110                 break;
111             case 5:        /* 3/1 */
112                 p_ac3dec->downmix.pf_downmix_3f_1r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
113                 break;
114             case 4:        /* 2/1 */
115                 p_ac3dec->downmix.pf_downmix_2f_1r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
116                 break;
117             case 3:        /* 3/0 */
118                 p_ac3dec->downmix.pf_downmix_3f_0r_to_2ch (p_ac3dec->samples, &p_ac3dec->dm_par);
119                 break;
120             case 2:
121                 break;
122             default:    /* 1/0 */
123 //                if (p_ac3dec->bsi.acmod == 1)
124                     center = p_ac3dec->samples;
125 //                else if (p_ac3dec->bsi.acmod == 0)
126 //                  center = samples[ac3_config.dual_mono_ch_sel];
127                 do_imdct(p_ac3dec->imdct, center, p_ac3dec->imdct->delay); /* no downmix*/
128     
129                 p_ac3dec->downmix.pf_stream_sample_1ch_to_s16 (buffer, center);
130
131                 return;
132                 break;
133         }
134
135         do_imdct (p_ac3dec->imdct, p_ac3dec->samples, p_ac3dec->imdct->delay);
136         do_imdct (p_ac3dec->imdct, p_ac3dec->samples+256, p_ac3dec->imdct->delay+256);
137         p_ac3dec->downmix.pf_stream_sample_2ch_to_s16(buffer, p_ac3dec->samples, p_ac3dec->samples+256);
138
139     } else {
140         /* imdct and then downmix
141          * delay and samples should be saved and mixed
142          * fprintf(stderr, "time domain downmix\n"); */
143         for (i=0; i<p_ac3dec->bsi.nfchans; i++)
144         {
145             if (p_ac3dec->audblk.blksw[i])
146             {
147                 /* There is only a C function */
148                 p_ac3dec->imdct->pf_imdct_256_nol( p_ac3dec->imdct,
149                      p_ac3dec->samples+256*i, p_ac3dec->imdct->delay1+256*i );
150             }
151             else
152             {
153                 p_ac3dec->imdct->pf_imdct_512_nol( p_ac3dec->imdct,
154                      p_ac3dec->samples+256*i, p_ac3dec->imdct->delay1+256*i );
155             }
156         }
157
158         /* mix the sample, overlap */
159         switch(p_ac3dec->bsi.acmod)
160         {
161             case 7:        /* 3/2 */
162                 left = p_ac3dec->samples;
163                 center = p_ac3dec->samples+256;
164                 right = p_ac3dec->samples+2*256;
165                 left_sur = p_ac3dec->samples+3*256;
166                 right_sur = p_ac3dec->samples+4*256;
167                 delay_left = p_ac3dec->imdct->delay;
168                 delay_right = p_ac3dec->imdct->delay+256;
169                 delay1_left = p_ac3dec->imdct->delay1;
170                 delay1_center = p_ac3dec->imdct->delay1+256;
171                 delay1_right = p_ac3dec->imdct->delay1+2*256;
172                 delay1_sl = p_ac3dec->imdct->delay1+3*256;
173                 delay1_sr = p_ac3dec->imdct->delay1+4*256;
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;
186                 right = p_ac3dec->samples+256;
187                 left_sur = p_ac3dec->samples+2*256;
188                 right_sur = p_ac3dec->samples+3*256;
189                 delay_left = p_ac3dec->imdct->delay;
190                 delay_right = p_ac3dec->imdct->delay+256;
191                 delay1_left = p_ac3dec->imdct->delay1;
192                 delay1_right = p_ac3dec->imdct->delay1+256;
193                 delay1_sl = p_ac3dec->imdct->delay1+2*256;
194                 delay1_sr = p_ac3dec->imdct->delay1+3*256;
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;
207                 center = p_ac3dec->samples+256;
208                 right = p_ac3dec->samples+2*256;
209                 right_sur = p_ac3dec->samples+3*256;
210                 delay_left = p_ac3dec->imdct->delay;
211                 delay_right = p_ac3dec->imdct->delay+256;
212                 delay1_left = p_ac3dec->imdct->delay1;
213                 delay1_center = p_ac3dec->imdct->delay1+256;
214                 delay1_right = p_ac3dec->imdct->delay1+2*256;
215                 delay1_sl = p_ac3dec->imdct->delay1+3*256;
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;
228                 right = p_ac3dec->samples+256;
229                 right_sur = p_ac3dec->samples+2*256;
230                 delay_left = p_ac3dec->imdct->delay;
231                 delay_right = p_ac3dec->imdct->delay+256;
232                 delay1_left = p_ac3dec->imdct->delay1;
233                 delay1_right = p_ac3dec->imdct->delay1+256;
234                 delay1_sl = p_ac3dec->imdct->delay1+2*256;
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;
247                 center = p_ac3dec->samples+256;
248                 right = p_ac3dec->samples+2*256;
249                 delay_left = p_ac3dec->imdct->delay;
250                 delay_right = p_ac3dec->imdct->delay+256;
251                 delay1_left = p_ac3dec->imdct->delay1;
252                 delay1_center = p_ac3dec->imdct->delay1+256;
253                 delay1_right = p_ac3dec->imdct->delay1+2*256;
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+i);
267                     *buffer++ = (s16) *(p_ac3dec->samples+256+i);
268                 }
269                 break;
270         }
271     }
272 }