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