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