1 /*****************************************************************************
2 * ac3_downmix.c: ac3 downmix functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
24 #include "int_types.h"
25 #include "ac3_decoder.h"
26 #include "ac3_internal.h"
30 typedef struct prefs_s {
31 u16 use_dolby_surround;
32 u16 dual_mono_channel_select;
35 prefs_t global_prefs = {0,0};
37 /* Pre-scaled downmix coefficients */
38 static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 };
39 static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0 , 0.2071 };
41 /* Downmix into _two_ channels...other downmix modes aren't implemented
42 * to reduce complexity. Realistically, there aren't many machines around
43 * with > 2 channel output anyways */
45 void downmix (ac3dec_t * p_ac3dec, s16 * out_buf)
51 float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
54 if (p_ac3dec->bsi.acmod > 7)
55 intf_ErrMsg( "ac3dec: (downmix) invalid acmod number\n" );
58 /* There are two main cases, with or without Dolby Surround */
59 if (global_prefs.use_dolby_surround) {
60 switch(p_ac3dec->bsi.acmod) {
62 left = p_ac3dec->samples.channel[0];
63 centre = p_ac3dec->samples.channel[1];
64 right = p_ac3dec->samples.channel[2];
65 left_sur = p_ac3dec->samples.channel[3];
66 right_sur = p_ac3dec->samples.channel[4];
68 for (j = 0; j < 256; j++) {
69 right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
70 left_tmp = -1 * right_tmp;
71 right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
72 left_tmp += 0.3204f * *left++ + 0.2265f * *centre++;
74 *(out_buf++) = left_tmp * NORM;
75 *(out_buf++) = right_tmp * NORM;
80 left = p_ac3dec->samples.channel[0];
81 right = p_ac3dec->samples.channel[1];
82 left_sur = p_ac3dec->samples.channel[2];
83 right_sur = p_ac3dec->samples.channel[3];
85 for (j = 0; j < 256; j++) {
86 right_tmp = 0.2265f * *left_sur++ + 0.2265f * *right_sur++;
87 left_tmp = -1 * right_tmp;
88 right_tmp += 0.3204f * *right++;
89 left_tmp += 0.3204f * *left++ ;
91 *(out_buf++) = left_tmp * NORM;
92 *(out_buf++) = right_tmp * NORM;
97 left = p_ac3dec->samples.channel[0];
98 centre = p_ac3dec->samples.channel[1];
99 right = p_ac3dec->samples.channel[2];
101 right_sur = p_ac3dec->samples.channel[3];
103 for (j = 0; j < 256; j++) {
104 right_tmp = 0.2265f * *right_sur++;
105 left_tmp = - right_tmp;
106 right_tmp += 0.3204f * *right++ + 0.2265f * *centre;
107 left_tmp += 0.3204f * *left++ + 0.2265f * *centre++;
109 *(out_buf++) = left_tmp * NORM;
110 *(out_buf++) = right_tmp * NORM;
115 left = p_ac3dec->samples.channel[0];
116 right = p_ac3dec->samples.channel[1];
118 right_sur = p_ac3dec->samples.channel[2];
120 for (j = 0; j < 256; j++) {
121 right_tmp = 0.2265f * *right_sur++;
122 left_tmp = - right_tmp;
123 right_tmp += 0.3204f * *right++;
124 left_tmp += 0.3204f * *left++;
126 *(out_buf++) = left_tmp * NORM;
127 *(out_buf++) = right_tmp * NORM;
132 left = p_ac3dec->samples.channel[0];
133 centre = p_ac3dec->samples.channel[1];
134 right = p_ac3dec->samples.channel[2];
136 for (j = 0; j < 256; j++) {
137 right_tmp = 0.3204f * *right++ + 0.2265f * *centre;
138 left_tmp = 0.3204f * *left++ + 0.2265f * *centre++;
140 *(out_buf++) = left_tmp * NORM;
141 *(out_buf++) = right_tmp * NORM;
146 left = p_ac3dec->samples.channel[0];
147 right = p_ac3dec->samples.channel[1];
149 for (j = 0; j < 256; j++) {
150 *(out_buf++) = *(left++) * NORM;
151 *(out_buf++) = *(right++) * NORM;
157 right = p_ac3dec->samples.channel[0];
159 for (j = 0; j < 256; j++) {
160 right_tmp = 0.7071f * *right++;
162 *(out_buf++) = right_tmp * NORM;
163 *(out_buf++) = right_tmp * NORM;
168 /* Dual mono, output selected by user */
169 right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select];
171 for (j = 0; j < 256; j++) {
172 right_tmp = 0.7071f * *right++;
174 *(out_buf++) = right_tmp * NORM;
175 *(out_buf++) = right_tmp * NORM;
180 /* Non-Dolby surround downmixes */
181 switch(p_ac3dec->bsi.acmod) {
183 left = p_ac3dec->samples.channel[0];
184 centre = p_ac3dec->samples.channel[1];
185 right = p_ac3dec->samples.channel[2];
186 left_sur = p_ac3dec->samples.channel[3];
187 right_sur = p_ac3dec->samples.channel[4];
189 clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
190 slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
192 for (j = 0; j < 256; j++) {
193 right_tmp= 0.4142f * *right++ + clev * *centre + slev * *right_sur++;
194 left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *left_sur++;
196 *(out_buf++) = left_tmp * NORM;
197 *(out_buf++) = right_tmp * NORM;
202 left = p_ac3dec->samples.channel[0];
203 right = p_ac3dec->samples.channel[1];
204 left_sur = p_ac3dec->samples.channel[2];
205 right_sur = p_ac3dec->samples.channel[3];
207 slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
209 for (j = 0; j < 256; j++) {
210 right_tmp= 0.4142f * *right++ + slev * *right_sur++;
211 left_tmp = 0.4142f * *left++ + slev * *left_sur++;
213 *(out_buf++) = left_tmp * NORM;
214 *(out_buf++) = right_tmp * NORM;
219 left = p_ac3dec->samples.channel[0];
220 centre = p_ac3dec->samples.channel[1];
221 right = p_ac3dec->samples.channel[2];
223 right_sur = p_ac3dec->samples.channel[3];
225 clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
226 slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
228 for (j = 0; j < 256; j++) {
229 right_tmp= 0.4142f * *right++ + clev * *centre + slev * *right_sur;
230 left_tmp = 0.4142f * *left++ + clev * *centre++ + slev * *right_sur++;
232 *(out_buf++) = left_tmp * NORM;
233 *(out_buf++) = right_tmp * NORM;
238 left = p_ac3dec->samples.channel[0];
239 right = p_ac3dec->samples.channel[1];
241 right_sur = p_ac3dec->samples.channel[2];
243 slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
245 for (j = 0; j < 256; j++) {
246 right_tmp= 0.4142f * *right++ + slev * *right_sur;
247 left_tmp = 0.4142f * *left++ + slev * *right_sur++;
249 *(out_buf++) = left_tmp * NORM;
250 *(out_buf++) = right_tmp * NORM;
255 left = p_ac3dec->samples.channel[0];
256 centre = p_ac3dec->samples.channel[1];
257 right = p_ac3dec->samples.channel[2];
259 clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
261 for (j = 0; j < 256; j++) {
262 right_tmp= 0.4142f * *right++ + clev * *centre;
263 left_tmp = 0.4142f * *left++ + clev * *centre++;
265 *(out_buf++) = left_tmp * NORM;
266 *(out_buf++) = right_tmp * NORM;
271 left = p_ac3dec->samples.channel[0];
272 right = p_ac3dec->samples.channel[1];
274 for (j = 0; j < 256; j++) {
275 *(out_buf++) = *(left++) * NORM;
276 *(out_buf++) = *(right++) * NORM;
282 right = p_ac3dec->samples.channel[0];
284 for (j = 0; j < 256; j++) {
285 right_tmp = 0.7071f * *right++;
287 *(out_buf++) = right_tmp * NORM;
288 *(out_buf++) = right_tmp * NORM;
293 /* Dual mono, output selected by user */
294 right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select];
296 for (j = 0; j < 256; j++) {
297 right_tmp = 0.7071f * *right++;
299 *(out_buf++) = right_tmp * NORM;
300 *(out_buf++) = right_tmp * NORM;