2 #include "ac3_decoder.h"
3 #include "ac3_internal.h"
7 typedef struct prefs_s {
8 u16 use_dolby_surround;
9 u16 dual_mono_channel_select;
12 prefs_t global_prefs = {0,0};
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 };
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 */
22 void downmix (ac3dec_t * p_ac3dec, s16 * out_buf)
28 float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
31 if (p_ac3dec->bsi.acmod > 7)
32 dprintf("(downmix) invalid acmod number\n");
35 /* There are two main cases, with or without Dolby Surround */
36 if (global_prefs.use_dolby_surround) {
37 switch(p_ac3dec->bsi.acmod) {
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];
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++;
51 *(out_buf++) = left_tmp * NORM;
52 *(out_buf++) = right_tmp * NORM;
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];
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++ ;
68 *(out_buf++) = left_tmp * NORM;
69 *(out_buf++) = right_tmp * NORM;
74 left = p_ac3dec->samples.channel[0];
75 centre = p_ac3dec->samples.channel[1];
76 right = p_ac3dec->samples.channel[2];
78 right_sur = p_ac3dec->samples.channel[3];
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++;
86 *(out_buf++) = left_tmp * NORM;
87 *(out_buf++) = right_tmp * NORM;
92 left = p_ac3dec->samples.channel[0];
93 right = p_ac3dec->samples.channel[1];
95 right_sur = p_ac3dec->samples.channel[2];
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++;
103 *(out_buf++) = left_tmp * NORM;
104 *(out_buf++) = right_tmp * NORM;
109 left = p_ac3dec->samples.channel[0];
110 centre = p_ac3dec->samples.channel[1];
111 right = p_ac3dec->samples.channel[2];
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++;
117 *(out_buf++) = left_tmp * NORM;
118 *(out_buf++) = right_tmp * NORM;
123 left = p_ac3dec->samples.channel[0];
124 right = p_ac3dec->samples.channel[1];
126 for (j = 0; j < 256; j++) {
127 *(out_buf++) = *(left++) * NORM;
128 *(out_buf++) = *(right++) * NORM;
134 right = p_ac3dec->samples.channel[0];
136 for (j = 0; j < 256; j++) {
137 right_tmp = 0.7071f * *right++;
139 *(out_buf++) = right_tmp * NORM;
140 *(out_buf++) = right_tmp * NORM;
145 /* Dual mono, output selected by user */
146 right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select];
148 for (j = 0; j < 256; j++) {
149 right_tmp = 0.7071f * *right++;
151 *(out_buf++) = right_tmp * NORM;
152 *(out_buf++) = right_tmp * NORM;
157 /* Non-Dolby surround downmixes */
158 switch(p_ac3dec->bsi.acmod) {
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];
166 clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
167 slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
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++;
173 *(out_buf++) = left_tmp * NORM;
174 *(out_buf++) = right_tmp * NORM;
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];
184 slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
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++;
190 *(out_buf++) = left_tmp * NORM;
191 *(out_buf++) = right_tmp * NORM;
196 left = p_ac3dec->samples.channel[0];
197 centre = p_ac3dec->samples.channel[1];
198 right = p_ac3dec->samples.channel[2];
200 right_sur = p_ac3dec->samples.channel[3];
202 clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
203 slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
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++;
209 *(out_buf++) = left_tmp * NORM;
210 *(out_buf++) = right_tmp * NORM;
215 left = p_ac3dec->samples.channel[0];
216 right = p_ac3dec->samples.channel[1];
218 right_sur = p_ac3dec->samples.channel[2];
220 slev = smixlev_lut[p_ac3dec->bsi.surmixlev];
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++;
226 *(out_buf++) = left_tmp * NORM;
227 *(out_buf++) = right_tmp * NORM;
232 left = p_ac3dec->samples.channel[0];
233 centre = p_ac3dec->samples.channel[1];
234 right = p_ac3dec->samples.channel[2];
236 clev = cmixlev_lut[p_ac3dec->bsi.cmixlev];
238 for (j = 0; j < 256; j++) {
239 right_tmp= 0.4142f * *right++ + clev * *centre;
240 left_tmp = 0.4142f * *left++ + clev * *centre++;
242 *(out_buf++) = left_tmp * NORM;
243 *(out_buf++) = right_tmp * NORM;
248 left = p_ac3dec->samples.channel[0];
249 right = p_ac3dec->samples.channel[1];
251 for (j = 0; j < 256; j++) {
252 *(out_buf++) = *(left++) * NORM;
253 *(out_buf++) = *(right++) * NORM;
259 right = p_ac3dec->samples.channel[0];
261 for (j = 0; j < 256; j++) {
262 right_tmp = 0.7071f * *right++;
264 *(out_buf++) = right_tmp * NORM;
265 *(out_buf++) = right_tmp * NORM;
270 /* Dual mono, output selected by user */
271 right = p_ac3dec->samples.channel[global_prefs.dual_mono_channel_select];
273 for (j = 0; j < 256; j++) {
274 right_tmp = 0.7071f * *right++;
276 *(out_buf++) = right_tmp * NORM;
277 *(out_buf++) = right_tmp * NORM;