]> git.sesse.net Git - vlc/blob - src/ac3_decoder/ac3_downmix.c
ce138c6eb0ed0b23332e133e5b189350a8aff673
[vlc] / src / ac3_decoder / ac3_downmix.c
1 #include "int_types.h"
2 #include "ac3_decoder.h"
3 #include "ac3_internal.h"
4
5 #define NORM 16384
6
7 typedef struct prefs_s {
8     u16 use_dolby_surround;
9     u16 dual_mono_channel_select;
10 } prefs_t;
11
12 prefs_t global_prefs = {0,0};
13
14 /* Pre-scaled downmix coefficients */
15 static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 };
16 static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0   , 0.2071 };
17
18 /* Downmix into _two_ channels...other downmix modes aren't implemented
19  * to reduce complexity. Realistically, there aren't many machines around
20  * with > 2 channel output anyways */
21
22 void downmix (ac3dec_t * p_ac3dec, s16 * out_buf)
23 {
24     int j;
25     float right_tmp;
26     float left_tmp;
27     float clev,slev;
28     float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
29
30     /*
31     if (p_ac3dec->bsi.acmod > 7)
32         dprintf("(downmix) invalid acmod number\n");
33     */
34
35     /* There are two main cases, with or without Dolby Surround */
36     if (global_prefs.use_dolby_surround) {
37         switch(p_ac3dec->bsi.acmod) {
38         case 7: /* 3/2 */
39             left      = p_ac3dec->samples.channel[0];
40             centre    = p_ac3dec->samples.channel[1];
41             right     = p_ac3dec->samples.channel[2];
42             left_sur  = p_ac3dec->samples.channel[3];
43             right_sur = p_ac3dec->samples.channel[4];
44
45             for (j = 0; j < 256; j++) {
46                 right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
47                 left_tmp  = -1 * right_tmp;
48                 right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
49                 left_tmp  += 0.3204f * *left++  + 0.2265f * *centre++;
50
51                 *(out_buf++) = left_tmp * NORM;
52                 *(out_buf++) = right_tmp * NORM;
53             }
54             break;
55
56         case 6: /* 2/2 */
57             left      = p_ac3dec->samples.channel[0];
58             right     = p_ac3dec->samples.channel[1];
59             left_sur  = p_ac3dec->samples.channel[2];
60             right_sur = p_ac3dec->samples.channel[3];
61
62             for (j = 0; j < 256; j++) {
63                 right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
64                 left_tmp  = -1 * right_tmp;
65                 right_tmp += 0.3204f * *right++;
66                 left_tmp  += 0.3204f * *left++ ;
67
68                 *(out_buf++) = left_tmp * NORM;
69                 *(out_buf++) = right_tmp * NORM;
70             }
71             break;
72
73         case 5: /* 3/1 */
74             left      = p_ac3dec->samples.channel[0];
75             centre    = p_ac3dec->samples.channel[1];
76             right     = p_ac3dec->samples.channel[2];
77             /* Mono surround */
78             right_sur = p_ac3dec->samples.channel[3];
79
80             for (j = 0; j < 256; j++) {
81                 right_tmp =  0.2265f * *right_sur++;
82                 left_tmp  = - right_tmp;
83                 right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
84                 left_tmp  += 0.3204f * *left++  + 0.2265f * *centre++;
85
86                 *(out_buf++) = left_tmp * NORM;
87                 *(out_buf++) = right_tmp * NORM;
88             }
89             break;
90
91         case 4: /* 2/1 */
92             left      = p_ac3dec->samples.channel[0];
93             right     = p_ac3dec->samples.channel[1];
94             /* Mono surround */
95             right_sur = p_ac3dec->samples.channel[2];
96
97             for (j = 0; j < 256; j++) {
98                 right_tmp =  0.2265f * *right_sur++;
99                 left_tmp  = - right_tmp;
100                 right_tmp += 0.3204f * *right++;
101                 left_tmp  += 0.3204f * *left++;
102
103                 *(out_buf++) = left_tmp * NORM;
104                 *(out_buf++) = right_tmp * NORM;
105             }
106             break;
107
108         case 3: /* 3/0 */
109             left      = p_ac3dec->samples.channel[0];
110             centre    = p_ac3dec->samples.channel[1];
111             right     = p_ac3dec->samples.channel[2];
112
113             for (j = 0; j < 256; j++) {
114                 right_tmp = 0.3204f * *right++ + 0.2265f * *centre;
115                 left_tmp  = 0.3204f * *left++  + 0.2265f * *centre++;
116
117                 *(out_buf++) = left_tmp * NORM;
118                 *(out_buf++) = right_tmp * NORM;
119             }
120             break;
121
122         case 2: /* 2/0 */
123             left = p_ac3dec->samples.channel[0];
124             right = p_ac3dec->samples.channel[1];
125
126             for (j = 0; j < 256; j++) {
127                 *(out_buf++) = *(left++) * NORM;
128                 *(out_buf++) = *(right++) * NORM;
129             }
130             break;
131
132         case 1: /* 1/0 */
133             /* Mono program! */
134             right = p_ac3dec->samples.channel[0];
135
136             for (j = 0; j < 256; j++) {
137                 right_tmp = 0.7071f * *right++;
138
139                 *(out_buf++) = right_tmp * NORM;
140                 *(out_buf++) = right_tmp * NORM;
141             }
142             break;
143
144         case 0: /* 1+1 */
145             /* Dual mono, output selected by user */
146             right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select];
147
148             for (j = 0; j < 256; j++) {
149                 right_tmp = 0.7071f * *right++;
150
151                 *(out_buf++) = right_tmp * NORM;
152                 *(out_buf++) = right_tmp * NORM;
153             }
154             break;
155         }
156     } else {
157         /* Non-Dolby surround downmixes */
158         switch(p_ac3dec->bsi.acmod) {
159         case 7: /* 3/2 */
160             left      = p_ac3dec->samples.channel[0];
161             centre    = p_ac3dec->samples.channel[1];
162             right     = p_ac3dec->samples.channel[2];
163             left_sur  = p_ac3dec->samples.channel[3];
164             right_sur = p_ac3dec->samples.channel[4];
165
166             clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
167             slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
168
169             for (j = 0; j < 256; j++) {
170                 right_tmp= 0.4142f * *right++ + clev * *centre   + slev * *right_sur++;
171                 left_tmp = 0.4142f * *left++  + clev * *centre++ + slev * *left_sur++;
172
173                 *(out_buf++) = left_tmp * NORM;
174                 *(out_buf++) = right_tmp * NORM;
175             }
176             break;
177
178         case 6: /* 2/2 */
179             left      = p_ac3dec->samples.channel[0];
180             right     = p_ac3dec->samples.channel[1];
181             left_sur  = p_ac3dec->samples.channel[2];
182             right_sur = p_ac3dec->samples.channel[3];
183
184             slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
185
186             for (j = 0; j < 256; j++) {
187                 right_tmp= 0.4142f * *right++ + slev * *right_sur++;
188                 left_tmp = 0.4142f * *left++  + slev * *left_sur++;
189
190                 *(out_buf++) = left_tmp * NORM;
191                 *(out_buf++) = right_tmp * NORM;
192             }
193             break;
194
195         case 5: /* 3/1 */
196             left      = p_ac3dec->samples.channel[0];
197             centre    = p_ac3dec->samples.channel[1];
198             right     = p_ac3dec->samples.channel[2];
199             /* Mono surround */
200             right_sur = p_ac3dec->samples.channel[3];
201
202             clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
203             slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
204             
205             for (j = 0; j < 256; j++) {
206                 right_tmp= 0.4142f * *right++ + clev * *centre   + slev * *right_sur;
207                 left_tmp = 0.4142f * *left++  + clev * *centre++ + slev * *right_sur++;
208
209                 *(out_buf++) = left_tmp * NORM;
210                 *(out_buf++) = right_tmp * NORM;
211             }
212             break;
213
214         case 4: /* 2/1 */
215             left      = p_ac3dec->samples.channel[0];
216             right     = p_ac3dec->samples.channel[1];
217             /* Mono surround */
218             right_sur = p_ac3dec->samples.channel[2];
219
220             slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
221
222             for (j = 0; j < 256; j++) {
223                 right_tmp= 0.4142f * *right++ + slev * *right_sur;
224                 left_tmp = 0.4142f * *left++  + slev * *right_sur++;
225
226                 *(out_buf++) = left_tmp * NORM;
227                 *(out_buf++) = right_tmp * NORM;
228             }
229             break;
230
231         case 3: /* 3/0 */
232             left      = p_ac3dec->samples.channel[0];
233             centre    = p_ac3dec->samples.channel[1];
234             right     = p_ac3dec->samples.channel[2];
235
236             clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
237
238             for (j = 0; j < 256; j++) {
239                 right_tmp= 0.4142f * *right++ + clev * *centre;
240                 left_tmp = 0.4142f * *left++  + clev * *centre++;
241
242                 *(out_buf++) = left_tmp * NORM;
243                 *(out_buf++) = right_tmp * NORM;
244             }
245             break;
246
247         case 2: /* 2/0 */
248             left = p_ac3dec->samples.channel[0];
249             right = p_ac3dec->samples.channel[1];
250
251             for (j = 0; j < 256; j++) {
252                 *(out_buf++) = *(left++) * NORM;
253                 *(out_buf++) = *(right++) * NORM;
254             }
255             break;
256
257         case 1: /* 1/0 */
258             /* Mono program! */
259             right = p_ac3dec->samples.channel[0];
260
261             for (j = 0; j < 256; j++) {
262                 right_tmp = 0.7071f * *right++;
263
264                 *(out_buf++) = right_tmp * NORM;
265                 *(out_buf++) = right_tmp * NORM;
266             }
267             break;
268
269         case 0: /* 1+1 */
270             /* Dual mono, output selected by user */
271             right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select];
272
273             for (j = 0; j < 256; j++) {
274                 right_tmp = 0.7071f * *right++;
275
276                 *(out_buf++) = right_tmp * NORM;
277                 *(out_buf++) = right_tmp * NORM;
278             }
279             break;
280         }
281     }
282 }