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