1 /* $Id: downmix.c,v 1.15 2005/03/17 19:22:47 stebbins Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.fr/>.
5 It may be used under the terms of the GNU General Public License. */
13 #define LVL_PLUS6DB 2.0
14 #define LVL_PLUS3DB 1.4142135623730951
15 #define LVL_3DB 0.7071067811865476
16 #define LVL_45DB 0.5946035575013605
19 #define LVL_SQRT_1_3 0.577350269
20 #define LVL_SQRT_2_3 0.816496581
22 #define HB_CH_FRONT_LEFT 0x00000001
23 #define HB_CH_FRONT_RIGHT 0x00000002
24 #define HB_CH_FRONT_CENTER 0x00000004
25 #define HB_CH_LOW_FREQUENCY 0x00000008
26 #define HB_CH_BACK_LEFT 0x00000010
27 #define HB_CH_BACK_RIGHT 0x00000020
28 #define HB_CH_BACK_CENTER 0x00000040
29 #define HB_CH_SIDE_LEFT 0x00000080
30 #define HB_CH_SIDE_RIGHT 0x00000100
32 #define HB_CH_SURROUND_MASK 0x000001f0
33 #define HB_CH_MASK 0x000007ff
35 #define HB_CH_DOLBY 0x00000800
36 #define HB_CH_DPLII 0x00001000
38 #define DOWNMIX_MONO 0
39 #define DOWNMIX_STEREO 1
41 #define DOWNMIX_2F1R 3
42 #define DOWNMIX_3F1R 4
43 #define DOWNMIX_2F2R 5
44 #define DOWNMIX_3F2R 6
45 #define DOWNMIX_3F4R 7
46 #define DOWNMIX_DOLBY 8
47 #define DOWNMIX_DPLII 9
48 #define DOWNMIX_NUM_MODES 10
50 #define DOWNMIX_CHANNEL_MASK 0x0f
52 #define DOWNMIX_LFE_FLAG 0x10
53 #define DOWNMIX_FLAGS_MASK 0x10
55 hb_sample_t downmix_matrix[DOWNMIX_NUM_MODES][DOWNMIX_NUM_MODES][8][8] =
60 { { 1, 0, 0, 0, 0, 0, 0, 0 },
61 { 0, 1, 0, 0, 0, 0, 0, 0 },
62 { 0, 0, 0, 0, 0, 0, 0, 0 },
63 { 0, 0, 0, 0, 0, 0, 0, 0 },
64 { 0, 0, 0, 0, 0, 0, 0, 0 },
65 { 0, 0, 0, 0, 0, 0, 0, 0 },
66 { 0, 0, 0, 0, 0, 0, 0, 0 },
67 { 0, 0, 0, 0, 0, 0, 0, 0 } },
69 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
70 { 0, 0, 1, 0, 0, 0, 0, 0 },
71 { 0, 0, 0, 0, 0, 0, 0, 0 },
72 { 0, 0, 0, 0, 0, 0, 0, 0 },
73 { 0, 0, 0, 0, 0, 0, 0, 0 },
74 { 0, 0, 0, 0, 0, 0, 0, 0 },
75 { 0, 0, 0, 0, 0, 0, 0, 0 },
76 { 0, 0, 0, 0, 0, 0, 0, 0 } },
78 { { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
79 { 0, 0, 0, 1, 0, 0, 0, 0 },
80 { 0, 0, 0, 0, 0, 0, 0, 0 },
81 { 0, 0, 0, 0, 0, 0, 0, 0 },
82 { 0, 0, 0, 0, 0, 0, 0, 0 },
83 { 0, 0, 0, 0, 0, 0, 0, 0 },
84 { 0, 0, 0, 0, 0, 0, 0, 0 },
85 { 0, 0, 0, 0, 0, 0, 0, 0 } },
87 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
88 { 0, 0, 0, 1, 0, 0, 0, 0 },
89 { 0, 0, 0, 0, 0, 0, 0, 0 },
90 { 0, 0, 0, 0, 0, 0, 0, 0 },
91 { 0, 0, 0, 0, 0, 0, 0, 0 },
92 { 0, 0, 0, 0, 0, 0, 0, 0 },
93 { 0, 0, 0, 0, 0, 0, 0, 0 },
94 { 0, 0, 0, 0, 0, 0, 0, 0 } },
96 { { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
97 { 0, 0, 0, 0, 1, 0, 0, 0 },
98 { 0, 0, 0, 0, 0, 0, 0, 0 },
99 { 0, 0, 0, 0, 0, 0, 0, 0 },
100 { 0, 0, 0, 0, 0, 0, 0, 0 },
101 { 0, 0, 0, 0, 0, 0, 0, 0 },
102 { 0, 0, 0, 0, 0, 0, 0, 0 },
103 { 0, 0, 0, 0, 0, 0, 0, 0 } },
105 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
106 { 0, 0, 0, 0, 1, 0, 0, 0 },
107 { 0, 0, 0, 0, 0, 0, 0, 0 },
108 { 0, 0, 0, 0, 0, 0, 0, 0 },
109 { 0, 0, 0, 0, 0, 0, 0, 0 },
110 { 0, 0, 0, 0, 0, 0, 0, 0 },
111 { 0, 0, 0, 0, 0, 0, 0, 0 },
112 { 0, 0, 0, 0, 0, 0, 0, 0 } },
114 { { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
115 { 0, 0, 0, 0, 0, 1, 0, 0 },
116 { 0, 0, 0, 0, 0, 0, 0, 0 },
117 { 0, 0, 0, 0, 0, 0, 0, 0 },
118 { 0, 0, 0, 0, 0, 0, 0, 0 },
119 { 0, 0, 0, 0, 0, 0, 0, 0 },
120 { 0, 0, 0, 0, 0, 0, 0, 0 },
121 { 0, 0, 0, 0, 0, 0, 0, 0 } },
123 { { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
124 { 0, 0, 0, 0, 0, 0, 0, 1 },
125 { 0, 0, 0, 0, 0, 0, 0, 0 },
126 { 0, 0, 0, 0, 0, 0, 0, 0 },
127 { 0, 0, 0, 0, 0, 0, 0, 0 },
128 { 0, 0, 0, 0, 0, 0, 0, 0 },
129 { 0, 0, 0, 0, 0, 0, 0, 0 },
130 { 0, 0, 0, 0, 0, 0, 0, 0 } },
132 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
133 { 0, 0, 1, 0, 0, 0, 0, 0 },
134 { 0, 0, 0, 0, 0, 0, 0, 0 },
135 { 0, 0, 0, 0, 0, 0, 0, 0 },
136 { 0, 0, 0, 0, 0, 0, 0, 0 },
137 { 0, 0, 0, 0, 0, 0, 0, 0 },
138 { 0, 0, 0, 0, 0, 0, 0, 0 },
139 { 0, 0, 0, 0, 0, 0, 0, 0 } },
141 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
142 { 0, 0, 1, 0, 0, 0, 0, 0 },
143 { 0, 0, 0, 0, 0, 0, 0, 0 },
144 { 0, 0, 0, 0, 0, 0, 0, 0 },
145 { 0, 0, 0, 0, 0, 0, 0, 0 },
146 { 0, 0, 0, 0, 0, 0, 0, 0 },
147 { 0, 0, 0, 0, 0, 0, 0, 0 },
148 { 0, 0, 0, 0, 0, 0, 0, 0 } },
153 { { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
154 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
155 { 0, 1, 0, 0, 0, 0, 0, 0 },
156 { 0, 0, 0, 0, 0, 0, 0, 0 },
157 { 0, 0, 0, 0, 0, 0, 0, 0 },
158 { 0, 0, 0, 0, 0, 0, 0, 0 },
159 { 0, 0, 0, 0, 0, 0, 0, 0 },
160 { 0, 0, 0, 0, 0, 0, 0, 0 } },
162 { { 1, 0, 0, 0, 0, 0, 0, 0 },
163 { 0, 1, 0, 0, 0, 0, 0, 0 },
164 { 0, 0, 1, 0, 0, 0, 0, 0 },
165 { 0, 0, 0, 0, 0, 0, 0, 0 },
166 { 0, 0, 0, 0, 0, 0, 0, 0 },
167 { 0, 0, 0, 0, 0, 0, 0, 0 },
168 { 0, 0, 0, 0, 0, 0, 0, 0 },
169 { 0, 0, 0, 0, 0, 0, 0, 0 } },
171 { { 0, 1, 0, 0, 0, 0, 0, 0 },
172 { 0, 0, 1, 0, 0, 0, 0, 0 },
173 { 0, 0, 0, 1, 0, 0, 0, 0 },
174 { 0, 0, 0, 0, 0, 0, 0, 0 },
175 { 0, 0, 0, 0, 0, 0, 0, 0 },
176 { 0, 0, 0, 0, 0, 0, 0, 0 },
177 { 0, 0, 0, 0, 0, 0, 0, 0 },
178 { 0, 0, 0, 0, 0, 0, 0, 0 } },
180 { { 1, 0, 0, 0, 0, 0, 0, 0 },
181 { 0, 1, 0, 0, 0, 0, 0, 0 },
182 { 0, 0, 0, 1, 0, 0, 0, 0 },
183 { 0, 0, 0, 0, 0, 0, 0, 0 },
184 { 0, 0, 0, 0, 0, 0, 0, 0 },
185 { 0, 0, 0, 0, 0, 0, 0, 0 },
186 { 0, 0, 0, 0, 0, 0, 0, 0 },
187 { 0, 0, 0, 0, 0, 0, 0, 0 } },
189 { { 0, 1, 0, 0, 0, 0, 0, 0 },
190 { 0, 0, 1, 0, 0, 0, 0, 0 },
191 { 0, 0, 0, 0, 1, 0, 0, 0 },
192 { 0, 0, 0, 0, 0, 0, 0, 0 },
193 { 0, 0, 0, 0, 0, 0, 0, 0 },
194 { 0, 0, 0, 0, 0, 0, 0, 0 },
195 { 0, 0, 0, 0, 0, 0, 0, 0 },
196 { 0, 0, 0, 0, 0, 0, 0, 0 } },
198 { { 1, 0, 0, 0, 0, 0, 0, 0 },
199 { 0, 1, 0, 0, 0, 0, 0, 0 },
200 { 0, 0, 0, 0, 1, 0, 0, 0 },
201 { 0, 0, 0, 0, 0, 0, 0, 0 },
202 { 0, 0, 0, 0, 0, 0, 0, 0 },
203 { 0, 0, 0, 0, 0, 0, 0, 0 },
204 { 0, 0, 0, 0, 0, 0, 0, 0 },
205 { 0, 0, 0, 0, 0, 0, 0, 0 } },
207 { { 0, 1, 0, 0, 0, 0, 0, 0 },
208 { 0, 0, 1, 0, 0, 0, 0, 0 },
209 { 0, 0, 0, 0, 0, 1, 0, 0 },
210 { 0, 0, 0, 0, 0, 0, 0, 0 },
211 { 0, 0, 0, 0, 0, 0, 0, 0 },
212 { 0, 0, 0, 0, 0, 0, 0, 0 },
213 { 0, 0, 0, 0, 0, 0, 0, 0 },
214 { 0, 0, 0, 0, 0, 0, 0, 0 } },
216 { { 0, 1, 0, 0, 0, 0, 0, 0 },
217 { 0, 0, 1, 0, 0, 0, 0, 0 },
218 { 0, 0, 0, 0, 0, 0, 0, 1 },
219 { 0, 0, 0, 0, 0, 0, 0, 0 },
220 { 0, 0, 0, 0, 0, 0, 0, 0 },
221 { 0, 0, 0, 0, 0, 0, 0, 0 },
222 { 0, 0, 0, 0, 0, 0, 0, 0 },
223 { 0, 0, 0, 0, 0, 0, 0, 0 } },
225 { { 1, 0, 0, 0, 0, 0, 0, 0 },
226 { 0, 1, 0, 0, 0, 0, 0, 0 },
227 { 0, 0, 1, 0, 0, 0, 0, 0 },
228 { 0, 0, 0, 0, 0, 0, 0, 0 },
229 { 0, 0, 0, 0, 0, 0, 0, 0 },
230 { 0, 0, 0, 0, 0, 0, 0, 0 },
231 { 0, 0, 0, 0, 0, 0, 0, 0 },
232 { 0, 0, 0, 0, 0, 0, 0, 0 } },
234 { { 1, 0, 0, 0, 0, 0, 0, 0 },
235 { 0, 1, 0, 0, 0, 0, 0, 0 },
236 { 0, 0, 1, 0, 0, 0, 0, 0 },
237 { 0, 0, 0, 0, 0, 0, 0, 0 },
238 { 0, 0, 0, 0, 0, 0, 0, 0 },
239 { 0, 0, 0, 0, 0, 0, 0, 0 },
240 { 0, 0, 0, 0, 0, 0, 0, 0 },
241 { 0, 0, 0, 0, 0, 0, 0, 0 } },
246 { { LVL_PLUS3DB, 0, 0, 0, 0, 0, 0, 0 },
247 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
248 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
249 { 0, 1, 0, 0, 0, 0, 0, 0 },
250 { 0, 0, 0, 0, 0, 0, 0, 0 },
251 { 0, 0, 0, 0, 0, 0, 0, 0 },
252 { 0, 0, 0, 0, 0, 0, 0, 0 },
253 { 0, 0, 0, 0, 0, 0, 0, 0 } },
255 { { 1, 1, 0, 0, 0, 0, 0, 0 },
256 { 1, 0, 0, 0, 0, 0, 0, 0 },
257 { 0, 1, 0, 0, 0, 0, 0, 0 },
258 { 0, 0, 1, 0, 0, 0, 0, 0 },
259 { 0, 0, 0, 0, 0, 0, 0, 0 },
260 { 0, 0, 0, 0, 0, 0, 0, 0 },
261 { 0, 0, 0, 0, 0, 0, 0, 0 },
262 { 0, 0, 0, 0, 0, 0, 0, 0 } },
264 { { 1, 0, 0, 0, 0, 0, 0, 0 },
265 { 0, 1, 0, 0, 0, 0, 0, 0 },
266 { 0, 0, 1, 0, 0, 0, 0, 0 },
267 { 0, 0, 0, 1, 0, 0, 0, 0 },
268 { 0, 0, 0, 0, 0, 0, 0, 0 },
269 { 0, 0, 0, 0, 0, 0, 0, 0 },
270 { 0, 0, 0, 0, 0, 0, 0, 0 },
271 { 0, 0, 0, 0, 0, 0, 0, 0 } },
273 { { 1, 1, 0, 0, 0, 0, 0, 0 },
274 { 1, 0, 0, 0, 0, 0, 0, 0 },
275 { 0, 1, 0, 0, 0, 0, 0, 0 },
276 { 0, 0, 0, 1, 0, 0, 0, 0 },
277 { 0, 0, 0, 0, 0, 0, 0, 0 },
278 { 0, 0, 0, 0, 0, 0, 0, 0 },
279 { 0, 0, 0, 0, 0, 0, 0, 0 },
280 { 0, 0, 0, 0, 0, 0, 0, 0 } },
282 { { 1, 0, 0, 0, 0, 0, 0, 0 },
283 { 0, 1, 0, 0, 0, 0, 0, 0 },
284 { 0, 0, 1, 0, 0, 0, 0, 0 },
285 { 0, 0, 0, 0, 1, 0, 0, 0 },
286 { 0, 0, 0, 0, 0, 0, 0, 0 },
287 { 0, 0, 0, 0, 0, 0, 0, 0 },
288 { 0, 0, 0, 0, 0, 0, 0, 0 },
289 { 0, 0, 0, 0, 0, 0, 0, 0 } },
291 { { 1, 1, 0, 0, 0, 0, 0, 0 },
292 { 1, 0, 0, 0, 0, 0, 0, 0 },
293 { 0, 1, 0, 0, 0, 0, 0, 0 },
294 { 0, 0, 0, 0, 1, 0, 0, 0 },
295 { 0, 0, 0, 0, 0, 0, 0, 0 },
296 { 0, 0, 0, 0, 0, 0, 0, 0 },
297 { 0, 0, 0, 0, 0, 0, 0, 0 },
298 { 0, 0, 0, 0, 0, 0, 0, 0 } },
300 { { 1, 0, 0, 0, 0, 0, 0, 0 },
301 { 0, 1, 0, 0, 0, 0, 0, 0 },
302 { 0, 0, 1, 0, 0, 0, 0, 0 },
303 { 0, 0, 0, 0, 0, 1, 0, 0 },
304 { 0, 0, 0, 0, 0, 0, 0, 0 },
305 { 0, 0, 0, 0, 0, 0, 0, 0 },
306 { 0, 0, 0, 0, 0, 0, 0, 0 },
307 { 0, 0, 0, 0, 0, 0, 0, 0 } },
309 { { 1, 0, 0, 0, 0, 0, 0, 0 },
310 { 0, 1, 0, 0, 0, 0, 0, 0 },
311 { 0, 0, 1, 0, 0, 0, 0, 0 },
312 { 0, 0, 0, 0, 0, 0, 0, 1 },
313 { 0, 0, 0, 0, 0, 0, 0, 0 },
314 { 0, 0, 0, 0, 0, 0, 0, 0 },
315 { 0, 0, 0, 0, 0, 0, 0, 0 },
316 { 0, 0, 0, 0, 0, 0, 0, 0 } },
318 { { 1, 1, 0, 0, 0, 0, 0, 0 },
319 { 1, 0, 0, 0, 0, 0, 0, 0 },
320 { 0, 1, 0, 0, 0, 0, 0, 0 },
321 { 0, 0, 1, 0, 0, 0, 0, 0 },
322 { 0, 0, 0, 0, 0, 0, 0, 0 },
323 { 0, 0, 0, 0, 0, 0, 0, 0 },
324 { 0, 0, 0, 0, 0, 0, 0, 0 },
325 { 0, 0, 0, 0, 0, 0, 0, 0 } },
327 { { 1, 1, 0, 0, 0, 0, 0, 0 },
328 { 1, 0, 0, 0, 0, 0, 0, 0 },
329 { 0, 1, 0, 0, 0, 0, 0, 0 },
330 { 0, 0, 1, 0, 0, 0, 0, 0 },
331 { 0, 0, 0, 0, 0, 0, 0, 0 },
332 { 0, 0, 0, 0, 0, 0, 0, 0 },
333 { 0, 0, 0, 0, 0, 0, 0, 0 },
334 { 0, 0, 0, 0, 0, 0, 0, 0 } },
339 { { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
340 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
341 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
342 { 0, 1, 0, 0, 0, 0, 0, 0 },
343 { 0, 0, 0, 0, 0, 0, 0, 0 },
344 { 0, 0, 0, 0, 0, 0, 0, 0 },
345 { 0, 0, 0, 0, 0, 0, 0, 0 },
346 { 0, 0, 0, 0, 0, 0, 0, 0 } },
348 { { 1, 0, 0, 0, 0, 0, 0, 0 },
349 { 0, 1, 0, 0, 0, 0, 0, 0 },
350 { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
351 { 0, 0, 1, 0, 0, 0, 0, 0 },
352 { 0, 0, 0, 0, 0, 0, 0, 0 },
353 { 0, 0, 0, 0, 0, 0, 0, 0 },
354 { 0, 0, 0, 0, 0, 0, 0, 0 },
355 { 0, 0, 0, 0, 0, 0, 0, 0 } },
357 { { 0, 1, 0, 0, 0, 0, 0, 0 },
358 { 0, 0, 1, 0, 0, 0, 0, 0 },
359 { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
360 { 0, 0, 0, 1, 0, 0, 0, 0 },
361 { 0, 0, 0, 0, 0, 0, 0, 0 },
362 { 0, 0, 0, 0, 0, 0, 0, 0 },
363 { 0, 0, 0, 0, 0, 0, 0, 0 },
364 { 0, 0, 0, 0, 0, 0, 0, 0 } },
366 { { 1, 0, 0, 0, 0, 0, 0, 0 },
367 { 0, 1, 0, 0, 0, 0, 0, 0 },
368 { 0, 0, 1, 0, 0, 0, 0, 0 },
369 { 0, 0, 0, 1, 0, 0, 0, 0 },
370 { 0, 0, 0, 0, 0, 0, 0, 0 },
371 { 0, 0, 0, 0, 0, 0, 0, 0 },
372 { 0, 0, 0, 0, 0, 0, 0, 0 },
373 { 0, 0, 0, 0, 0, 0, 0, 0 } },
375 { { 0, 1, 0, 0, 0, 0, 0, 0 },
376 { 0, 0, 1, 0, 0, 0, 0, 0 },
377 { 0, 0, 0, 1, 0, 0, 0, 0 },
378 { 0, 0, 0, 0, 1, 0, 0, 0 },
379 { 0, 0, 0, 0, 0, 0, 0, 0 },
380 { 0, 0, 0, 0, 0, 0, 0, 0 },
381 { 0, 0, 0, 0, 0, 0, 0, 0 },
382 { 0, 0, 0, 0, 0, 0, 0, 0 } },
384 { { 1, 0, 0, 0, 0, 0, 0, 0 },
385 { 0, 1, 0, 0, 0, 0, 0, 0 },
386 { 0, 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0 },
387 { 0, 0, 0, 0, 1, 0, 0, 0 },
388 { 0, 0, 0, 0, 0, 0, 0, 0 },
389 { 0, 0, 0, 0, 0, 0, 0, 0 },
390 { 0, 0, 0, 0, 0, 0, 0, 0 },
391 { 0, 0, 0, 0, 0, 0, 0, 0 } },
393 { { 0, 1, 0, 0, 0, 0, 0, 0 },
394 { 0, 0, 1, 0, 0, 0, 0, 0 },
395 { 0, 0, 0, LVL_3DB, LVL_3DB, 0, 0, 0 },
396 { 0, 0, 0, 0, 0, 1, 0, 0 },
397 { 0, 0, 0, 0, 0, 0, 0, 0 },
398 { 0, 0, 0, 0, 0, 0, 0, 0 },
399 { 0, 0, 0, 0, 0, 0, 0, 0 },
400 { 0, 0, 0, 0, 0, 0, 0, 0 } },
402 { { 0, 1, 0, 0, 0, 0, 0 , 0 },
403 { 0, 0, 1, 0, 0, 0, 0 , 0 },
404 { 0, 0, 0, 0, 0, LVL_3DB, LVL_3DB, 0 },
405 { 0, 0, 0, 0, 0, 0, 0 , 1 },
406 { 0, 0, 0, 0, 0, 0, 0 , 0 },
407 { 0, 0, 0, 0, 0, 0, 0 , 0 },
408 { 0, 0, 0, 0, 0, 0, 0 , 0 },
409 { 0, 0, 0, 0, 0, 0, 0 , 0 } },
411 { { 1, 0, 0, 0, 0, 0, 0, 0 },
412 { 0, 1, 0, 0, 0, 0, 0, 0 },
413 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
414 { 0, 0, 1, 0, 0, 0, 0, 0 },
415 { 0, 0, 0, 0, 0, 0, 0, 0 },
416 { 0, 0, 0, 0, 0, 0, 0, 0 },
417 { 0, 0, 0, 0, 0, 0, 0, 0 },
418 { 0, 0, 0, 0, 0, 0, 0, 0 } },
420 { { 1, 0, 0, 0, 0, 0, 0, 0 },
421 { 0, 1, 0, 0, 0, 0, 0, 0 },
422 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
423 { 0, 0, 1, 0, 0, 0, 0, 0 },
424 { 0, 0, 0, 0, 0, 0, 0, 0 },
425 { 0, 0, 0, 0, 0, 0, 0, 0 },
426 { 0, 0, 0, 0, 0, 0, 0, 0 },
427 { 0, 0, 0, 0, 0, 0, 0, 0 } },
432 { { LVL_PLUS3DB, 0, 0, 0, 0, 0, 0, 0 },
433 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
434 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
435 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
436 { 0, 1, 0, 0, 0, 0, 0, 0 },
437 { 0, 0, 0, 0, 0, 0, 0, 0 },
438 { 0, 0, 0, 0, 0, 0, 0, 0 },
439 { 0, 0, 0, 0, 0, 0, 0, 0 } },
441 { { 1, 1, 0, 0, 0, 0, 0, 0 },
442 { 1, 0, 0, 0, 0, 0, 0, 0 },
443 { 0, 1, 0, 0, 0, 0, 0, 0 },
444 { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
445 { 0, 0, 1, 0, 0, 0, 0, 0 },
446 { 0, 0, 0, 0, 0, 0, 0, 0 },
447 { 0, 0, 0, 0, 0, 0, 0, 0 },
448 { 0, 0, 0, 0, 0, 0, 0, 0 } },
450 { { 1, 0, 0, 0, 0, 0, 0, 0 },
451 { 0, 1, 0, 0, 0, 0, 0, 0 },
452 { 0, 0, 1, 0, 0, 0, 0, 0 },
453 { 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0 },
454 { 0, 0, 0, 1, 0, 0, 0, 0 },
455 { 0, 0, 0, 0, 0, 0, 0, 0 },
456 { 0, 0, 0, 0, 0, 0, 0, 0 },
457 { 0, 0, 0, 0, 0, 0, 0, 0 } },
459 { { 1, 1, 0, 0, 0, 0, 0, 0 },
460 { 1, 0, 0, 0, 0, 0, 0, 0 },
461 { 0, 1, 0, 0, 0, 0, 0, 0 },
462 { 0, 0, 1, 0, 0, 0, 0, 0 },
463 { 0, 0, 0, 1, 0, 0, 0, 0 },
464 { 0, 0, 0, 0, 0, 0, 0, 0 },
465 { 0, 0, 0, 0, 0, 0, 0, 0 },
466 { 0, 0, 0, 0, 0, 0, 0, 0 } },
468 { { 1, 0, 0, 0, 0, 0, 0, 0 },
469 { 0, 1, 0, 0, 0, 0, 0, 0 },
470 { 0, 0, 1, 0, 0, 0, 0, 0 },
471 { 0, 0, 0, 1, 0, 0, 0, 0 },
472 { 0, 0, 0, 0, 1, 0, 0, 0 },
473 { 0, 0, 0, 0, 0, 0, 0, 0 },
474 { 0, 0, 0, 0, 0, 0, 0, 0 },
475 { 0, 0, 0, 0, 0, 0, 0, 0 } },
477 { { 1, 1, 0, 0, 0, 0, 0, 0 },
478 { 1, 0, 0, 0, 0, 0, 0, 0 },
479 { 0, 1, 0, 0, 0, 0, 0, 0 },
480 { 0, 0, LVL_3DB, LVL_3DB, 0, 0, 0, 0 },
481 { 0, 0, 0, 0, 1, 0, 0, 0 },
482 { 0, 0, 0, 0, 0, 0, 0, 0 },
483 { 0, 0, 0, 0, 0, 0, 0, 0 },
484 { 0, 0, 0, 0, 0, 0, 0, 0 } },
486 { { 1, 0, 0, 0, 0, 0, 0, 0 },
487 { 0, 1, 0, 0, 0, 0, 0, 0 },
488 { 0, 0, 1, 0, 0, 0, 0, 0 },
489 { 0, 0, 0, LVL_3DB, LVL_3DB, 0, 0, 0 },
490 { 0, 0, 0, 0, 0, 1, 0, 0 },
491 { 0, 0, 0, 0, 0, 0, 0, 0 },
492 { 0, 0, 0, 0, 0, 0, 0, 0 },
493 { 0, 0, 0, 0, 0, 0, 0, 0 } },
495 { { 1, 0, 0, 0, 0, 0, 0 , 0 },
496 { 0, 1, 0, 0, 0, 0, 0 , 0 },
497 { 0, 0, 1, 0, 0, 0, 0 , 0 },
498 { 0, 0, 0, 0, 0, LVL_3DB, LVL_3DB, 0 },
499 { 0, 0, 0, 0, 0, 0, 0 , 1 },
500 { 0, 0, 0, 0, 0, 0, 0 , 0 },
501 { 0, 0, 0, 0, 0, 0, 0 , 0 },
502 { 0, 0, 0, 0, 0, 0, 0 , 0 } },
504 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
505 { 1, 0, 0, 0, 0, 0, 0, 0 },
506 { 0, 1, 0, 0, 0, 0, 0, 0 },
507 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
508 { 0, 0, 1, 0, 0, 0, 0, 0 },
509 { 0, 0, 0, 0, 0, 0, 0, 0 },
510 { 0, 0, 0, 0, 0, 0, 0, 0 },
511 { 0, 0, 0, 0, 0, 0, 0, 0 } },
513 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
514 { 1, 0, 0, 0, 0, 0, 0, 0 },
515 { 0, 1, 0, 0, 0, 0, 0, 0 },
516 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
517 { 0, 0, 1, 0, 0, 0, 0, 0 },
518 { 0, 0, 0, 0, 0, 0, 0, 0 },
519 { 0, 0, 0, 0, 0, 0, 0, 0 },
520 { 0, 0, 0, 0, 0, 0, 0, 0 } },
525 { { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
526 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
527 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
528 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
529 { 0, 1, 0, 0, 0, 0, 0, 0 },
530 { 0, 0, 0, 0, 0, 0, 0, 0 },
531 { 0, 0, 0, 0, 0, 0, 0, 0 },
532 { 0, 0, 0, 0, 0, 0, 0, 0 } },
534 { { 1, 0, 0, 0, 0, 0, 0, 0 },
535 { 0, 1, 0, 0, 0, 0, 0, 0 },
536 { 1, 0, 0, 0, 0, 0, 0, 0 },
537 { 0, 1, 0, 0, 0, 0, 0, 0 },
538 { 0, 0, 1, 0, 0, 0, 0, 0 },
539 { 0, 0, 0, 0, 0, 0, 0, 0 },
540 { 0, 0, 0, 0, 0, 0, 0, 0 },
541 { 0, 0, 0, 0, 0, 0, 0, 0 } },
543 { { 0, 1, 0, 0, 0, 0, 0, 0 },
544 { 0, 0, 1, 0, 0, 0, 0, 0 },
545 { 0, 1, 0, 0, 0, 0, 0, 0 },
546 { 0, 0, 1, 0, 0, 0, 0, 0 },
547 { 0, 0, 0, 1, 0, 0, 0, 0 },
548 { 0, 0, 0, 0, 0, 0, 0, 0 },
549 { 0, 0, 0, 0, 0, 0, 0, 0 },
550 { 0, 0, 0, 0, 0, 0, 0, 0 } },
552 { { 1, 0, 0, 0, 0, 0, 0, 0 },
553 { 0, 1, 0, 0, 0, 0, 0, 0 },
554 { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
555 { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
556 { 0, 0, 0, 1, 0, 0, 0, 0 },
557 { 0, 0, 0, 0, 0, 0, 0, 0 },
558 { 0, 0, 0, 0, 0, 0, 0, 0 },
559 { 0, 0, 0, 0, 0, 0, 0, 0 } },
561 { { 0, 1, 0, 0, 0, 0, 0, 0 },
562 { 0, 0, 1, 0, 0, 0, 0, 0 },
563 { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
564 { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
565 { 0, 0, 0, 0, 1, 0, 0, 0 },
566 { 0, 0, 0, 0, 0, 0, 0, 0 },
567 { 0, 0, 0, 0, 0, 0, 0, 0 },
568 { 0, 0, 0, 0, 0, 0, 0, 0 } },
570 { { 1, 0, 0, 0, 0, 0, 0, 0 },
571 { 0, 1, 0, 0, 0, 0, 0, 0 },
572 { 0, 0, 1, 0, 0, 0, 0, 0 },
573 { 0, 0, 0, 1, 0, 0, 0, 0 },
574 { 0, 0, 0, 0, 1, 0, 0, 0 },
575 { 0, 0, 0, 0, 0, 0, 0, 0 },
576 { 0, 0, 0, 0, 0, 0, 0, 0 },
577 { 0, 0, 0, 0, 0, 0, 0, 0 } },
579 { { 0, 1, 0, 0, 0, 0, 0, 0 },
580 { 0, 0, 1, 0, 0, 0, 0, 0 },
581 { 0, 0, 0, 1, 0, 0, 0, 0 },
582 { 0, 0, 0, 0, 1, 0, 0, 0 },
583 { 0, 0, 0, 0, 0, 1, 0, 0 },
584 { 0, 0, 0, 0, 0, 0, 0, 0 },
585 { 0, 0, 0, 0, 0, 0, 0, 0 },
586 { 0, 0, 0, 0, 0, 0, 0, 0 } },
588 { { 0, 1, 0, 0, 0, 0, 0, 0 },
589 { 0, 0, 1, 0, 0, 0, 0, 0 },
590 { 0, 0, 0, 0, 0, 1, 0, 0 },
591 { 0, 0, 0, 0, 0, 0, 1, 0 },
592 { 0, 0, 0, 0, 0, 0, 0, 1 },
593 { 0, 0, 0, 0, 0, 0, 0, 0 },
594 { 0, 0, 0, 0, 0, 0, 0, 0 },
595 { 0, 0, 0, 0, 0, 0, 0, 0 } },
597 { { 1, 0, 0, 0, 0, 0, 0, 0 },
598 { 0, 1, 0, 0, 0, 0, 0, 0 },
599 { -LVL_6DB, LVL_6DB, 0, 0, 0, 0, 0, 0 },
600 { -LVL_6DB, LVL_6DB, 0, 0, 0, 0, 0, 0 },
601 { 0, 0, 1, 0, 0, 0, 0, 0 },
602 { 0, 0, 0, 0, 0, 0, 0, 0 },
603 { 0, 0, 0, 0, 0, 0, 0, 0 },
604 { 0, 0, 0, 0, 0, 0, 0, 0 } },
606 { { 1, 0, 0, 0, 0, 0, 0, 0 },
607 { 0, 1, 0, 0, 0, 0, 0, 0 },
608 { LVL_SQRT_2_3, -LVL_SQRT_1_3, 0, 0, 0, 0, 0, 0 },
609 { -LVL_SQRT_1_3, LVL_SQRT_2_3, 0, 0, 0, 0, 0, 0 },
610 { 0, 0, 1, 0, 0, 0, 0, 0 },
611 { 0, 0, 0, 0, 0, 0, 0, 0 },
612 { 0, 0, 0, 0, 0, 0, 0, 0 },
613 { 0, 0, 0, 0, 0, 0, 0, 0 } },
618 { { LVL_PLUS3DB, 0, 0, 0, 0, 0, 0, 0 },
619 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
620 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
621 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
622 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
623 { 0, 1, 0, 0, 0, 0, 0, 0 },
624 { 0, 0, 0, 0, 0, 0, 0, 0 },
625 { 0, 0, 0, 0, 0, 0, 0, 0 } },
627 { { 1, 1, 0, 0, 0, 0, 0, 0 },
628 { 1, 0, 0, 0, 0, 0, 0, 0 },
629 { 0, 1, 0, 0, 0, 0, 0, 0 },
630 { 1, 0, 0, 0, 0, 0, 0, 0 },
631 { 0, 1, 0, 0, 0, 0, 0, 0 },
632 { 0, 0, 1, 0, 0, 0, 0, 0 },
633 { 0, 0, 0, 0, 0, 0, 0, 0 },
634 { 0, 0, 0, 0, 0, 0, 0, 0 } },
636 { { 1, 0, 0, 0, 0, 0, 0, 0 },
637 { 0, 1, 0, 0, 0, 0, 0, 0 },
638 { 0, 0, 1, 0, 0, 0, 0, 0 },
639 { 0, 1, 0, 0, 0, 0, 0, 0 },
640 { 0, 0, 1, 0, 0, 0, 0, 0 },
641 { 0, 0, 0, 1, 0, 0, 0, 0 },
642 { 0, 0, 0, 0, 0, 0, 0, 0 },
643 { 0, 0, 0, 0, 0, 0, 0, 0 } },
645 { { 1, 1, 0, 0, 0, 0, 0, 0 },
646 { 1, 0, 0, 0, 0, 0, 0, 0 },
647 { 0, 1, 0, 0, 0, 0, 0, 0 },
648 { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
649 { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
650 { 0, 0, 0, 1, 0, 0, 0, 0 },
651 { 0, 0, 0, 0, 0, 0, 0, 0 },
652 { 0, 0, 0, 0, 0, 0, 0, 0 } },
654 { { 1, 0, 0, 0, 0, 0, 0, 0 },
655 { 0, 1, 0, 0, 0, 0, 0, 0 },
656 { 0, 0, 1, 0, 0, 0, 0, 0 },
657 { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
658 { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
659 { 0, 0, 0, 0, 1, 0, 0, 0 },
660 { 0, 0, 0, 0, 0, 0, 0, 0 },
661 { 0, 0, 0, 0, 0, 0, 0, 0 } },
663 { { 1, 1, 0, 0, 0, 0, 0, 0 },
664 { 1, 0, 0, 0, 0, 0, 0, 0 },
665 { 0, 1, 0, 0, 0, 0, 0, 0 },
666 { 0, 0, 1, 0, 0, 0, 0, 0 },
667 { 0, 0, 0, 1, 0, 0, 0, 0 },
668 { 0, 0, 0, 0, 1, 0, 0, 0 },
669 { 0, 0, 0, 0, 0, 0, 0, 0 },
670 { 0, 0, 0, 0, 0, 0, 0, 0 } },
672 { { 1, 0, 0, 0, 0, 0, 0, 0 },
673 { 0, 1, 0, 0, 0, 0, 0, 0 },
674 { 0, 0, 1, 0, 0, 0, 0, 0 },
675 { 0, 0, 0, 1, 0, 0, 0, 0 },
676 { 0, 0, 0, 0, 1, 0, 0, 0 },
677 { 0, 0, 0, 0, 0, 1, 0, 0 },
678 { 0, 0, 0, 0, 0, 0, 0, 0 },
679 { 0, 0, 0, 0, 0, 0, 0, 0 } },
681 { { 1, 0, 0, 0, 0, 0, 0, 0 },
682 { 0, 1, 0, 0, 0, 0, 0, 0 },
683 { 0, 0, 1, 0, 0, 0, 0, 0 },
684 { 0, 0, 0, 0, 0, 1, 0, 0 },
685 { 0, 0, 0, 0, 0, 0, 1, 0 },
686 { 0, 0, 0, 0, 0, 0, 0, 1 },
687 { 0, 0, 0, 0, 0, 0, 0, 0 },
688 { 0, 0, 0, 0, 0, 0, 0, 0 } },
690 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
691 { 1, 0, 0, 0, 0, 0, 0, 0 },
692 { 0, 1, 0, 0, 0, 0, 0, 0 },
693 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
694 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
695 { 0, 0, 1, 0, 0, 0, 0, 0 },
696 { 0, 0, 0, 0, 0, 0, 0, 0 },
697 { 0, 0, 0, 0, 0, 0, 0, 0 } },
699 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
700 { 1, 0, 0, 0, 0, 0, 0, 0 },
701 { 0, 1, 0, 0, 0, 0, 0, 0 },
702 { LVL_SQRT_2_3, -LVL_SQRT_1_3, 0, 0, 0, 0, 0, 0 },
703 { -LVL_SQRT_1_3, LVL_SQRT_2_3, 0, 0, 0, 0, 0, 0 },
704 { 0, 0, 1, 0, 0, 0, 0, 0 },
705 { 0, 0, 0, 0, 0, 0, 0, 0 },
706 { 0, 0, 0, 0, 0, 0, 0, 0 } },
711 { { LVL_PLUS3DB, 0, 0, 0, 0, 0, 0, 0 },
712 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
713 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
714 { LVL_6DB, 0, 0, 0, 0, 0, 0, 0 },
715 { LVL_6DB, 0, 0, 0, 0, 0, 0, 0 },
716 { LVL_6DB, 0, 0, 0, 0, 0, 0, 0 },
717 { LVL_6DB, 0, 0, 0, 0, 0, 0, 0 },
718 { 0, 1, 0, 0, 0, 0, 0, 0 } },
720 { { 1, 1, 0, 0, 0, 0, 0, 0 },
721 { 1, 0, 0, 0, 0, 0, 0, 0 },
722 { 0, 1, 0, 0, 0, 0, 0, 0 },
723 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
724 { 0, LVL_3DB, 0, 0, 0, 0, 0, 0 },
725 { LVL_3DB, 0, 0, 0, 0, 0, 0, 0 },
726 { 0, LVL_3DB, 0, 0, 0, 0, 0, 0 },
727 { 0, 0, 1, 0, 0, 0, 0, 0 } },
729 { { 1, 0, 0, 0, 0, 0, 0, 0 },
730 { 0, 1, 0, 0, 0, 0, 0, 0 },
731 { 0, 0, 1, 0, 0, 0, 0, 0 },
732 { 0, LVL_3DB, 0, 0, 0, 0, 0, 0 },
733 { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
734 { 0, LVL_3DB, 0, 0, 0, 0, 0, 0 },
735 { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
736 { 0, 0, 0, 1, 0, 0, 0, 0 } },
738 { { 1, 1, 0, 0, 0, 0, 0, 0 },
739 { 1, 0, 0, 0, 0, 0, 0, 0 },
740 { 0, 1, 0, 0, 0, 0, 0, 0 },
741 { 0, 0, LVL_6DB, 0, 0, 0, 0, 0 },
742 { 0, 0, LVL_6DB, 0, 0, 0, 0, 0 },
743 { 0, 0, LVL_6DB, 0, 0, 0, 0, 0 },
744 { 0, 0, LVL_6DB, 0, 0, 0, 0, 0 },
745 { 0, 0, 0, 1, 0, 0, 0, 0 } },
747 { { 1, 0, 0, 0, 0, 0, 0, 0 },
748 { 0, 1, 0, 0, 0, 0, 0, 0 },
749 { 0, 0, 1, 0, 0, 0, 0, 0 },
750 { 0, 0, 0, LVL_6DB, 0, 0, 0, 0 },
751 { 0, 0, 0, LVL_6DB, 0, 0, 0, 0 },
752 { 0, 0, 0, LVL_6DB, 0, 0, 0, 0 },
753 { 0, 0, 0, LVL_6DB, 0, 0, 0, 0 },
754 { 0, 0, 0, 0, 1, 0, 0, 0 } },
756 { { 1, 1, 0, 0, 0, 0, 0, 0 },
757 { 1, 0, 0, 0, 0, 0, 0, 0 },
758 { 0, 1, 0, 0, 0, 0, 0, 0 },
759 { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
760 { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
761 { 0, 0, LVL_3DB, 0, 0, 0, 0, 0 },
762 { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
763 { 0, 0, 0, 0, 1, 0, 0, 0 } },
765 { { 1, 0, 0, 0, 0, 0, 0, 0 },
766 { 0, 1, 0, 0, 0, 0, 0, 0 },
767 { 0, 0, 1, 0, 0, 0, 0, 0 },
768 { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
769 { 0, 0, 0, 0, LVL_3DB, 0, 0, 0 },
770 { 0, 0, 0, LVL_3DB, 0, 0, 0, 0 },
771 { 0, 0, 0, 0, LVL_3DB, 0, 0, 0 },
772 { 0, 0, 0, 0, 0, 1, 0, 0 } },
774 { { 1, 0, 0, 0, 0, 0, 0, 0 },
775 { 0, 1, 0, 0, 0, 0, 0, 0 },
776 { 0, 0, 1, 0, 0, 0, 0, 0 },
777 { 0, 0, 0, 1, 0, 0, 0, 0 },
778 { 0, 0, 0, 0, 1, 0, 0, 0 },
779 { 0, 0, 0, 0, 0, 1, 0, 0 },
780 { 0, 0, 0, 0, 0, 0, 1, 0 },
781 { 0, 0, 0, 0, 0, 0, 0, 1 } },
783 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
784 { 1, 0, 0, 0, 0, 0, 0, 0 },
785 { 0, 1, 0, 0, 0, 0, 0, 0 },
786 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
787 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
788 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
789 { -LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
790 { 0, 0, 1, 0, 0, 0, 0, 0 } },
792 { { LVL_3DB, LVL_3DB, 0, 0, 0, 0, 0, 0 },
793 { 1, 0, 0, 0, 0, 0, 0, 0 },
794 { 0, 1, 0, 0, 0, 0, 0, 0 },
795 { LVL_SQRT_2_3*LVL_3DB, -LVL_SQRT_1_3*LVL_3DB, 0, 0, 0, 0, 0, 0 },
796 { -LVL_SQRT_1_3*LVL_3DB, LVL_SQRT_2_3*LVL_3DB, 0, 0, 0, 0, 0, 0 },
797 { LVL_SQRT_2_3*LVL_3DB, -LVL_SQRT_1_3*LVL_3DB, 0, 0, 0, 0, 0, 0 },
798 { -LVL_SQRT_1_3*LVL_3DB, LVL_SQRT_2_3*LVL_3DB, 0, 0, 0, 0, 0, 0 },
799 { 0, 0, 1, 0, 0, 0, 0, 0 } }
803 static int channel_layout_map[DOWNMIX_NUM_MODES] =
806 (HB_CH_FRONT_CENTER),
808 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT),
810 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_FRONT_CENTER),
812 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_BACK_CENTER),
814 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_FRONT_CENTER|HB_CH_BACK_CENTER),
816 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT),
818 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_FRONT_CENTER|HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT),
820 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT|HB_CH_FRONT_CENTER|HB_CH_SIDE_LEFT|
821 HB_CH_SIDE_RIGHT|HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT),
823 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT),
825 (HB_CH_FRONT_LEFT|HB_CH_FRONT_RIGHT)
828 int hb_layout_to_mode(int layout)
831 switch (layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK)
833 case HB_INPUT_CH_LAYOUT_MONO:
836 case HB_INPUT_CH_LAYOUT_STEREO:
837 mode = DOWNMIX_STEREO;
839 case HB_INPUT_CH_LAYOUT_3F:
842 case HB_INPUT_CH_LAYOUT_2F1R:
845 case HB_INPUT_CH_LAYOUT_3F1R:
848 case HB_INPUT_CH_LAYOUT_2F2R:
851 case HB_INPUT_CH_LAYOUT_3F2R:
854 case HB_INPUT_CH_LAYOUT_4F2R:
855 mode = DOWNMIX_3F2R|DOWNMIX_LFE_FLAG;
857 case HB_INPUT_CH_LAYOUT_3F4R:
860 case HB_INPUT_CH_LAYOUT_DOLBY:
861 mode = DOWNMIX_STEREO;
864 mode = DOWNMIX_STEREO;
867 if (layout & HB_INPUT_CH_LAYOUT_DISCRETE_LFE_MASK)
868 mode |= DOWNMIX_LFE_FLAG;
872 int hb_mixdown_to_mode(uint32_t mixdown)
876 case HB_AMIXDOWN_MONO:
878 case HB_AMIXDOWN_STEREO:
879 return DOWNMIX_STEREO;
880 case HB_AMIXDOWN_DOLBY:
881 return DOWNMIX_DOLBY;
882 case HB_AMIXDOWN_DOLBYPLII:
883 return DOWNMIX_DPLII;
884 case HB_AMIXDOWN_6CH:
885 return DOWNMIX_3F2R|DOWNMIX_LFE_FLAG;
887 return DOWNMIX_STEREO;
892 // ffmpeg gives us SMPTE channel layout
893 // We could use this layout and remap channels in encfaac,
894 // but VLC may have problems with remapping, so lets
895 // allow remapping to the default QuickTime order which is:
897 // C L R LS RS Rls Rrs LFE
899 // This arrangement also makes it possible to use half as
900 // many downmix matrices since the matrix with and without
903 // Use hb_layout_remap to accomplish this. For convenience
904 // I've provided the necessary maps.
906 // SMPTE channel layout
909 // DUAL-MONO-LFE L R LFE
913 // STEREO-LFE L R LFE
919 // 3F1-LFE L R C LFE S
921 // 2F2-LFE L R LFE LS RS
923 // 3F2-LFE L R C LFE LS RS
924 // 3F4 L R C Rls Rrs LS RS
925 // 3F4-LFE L R C LFE Rls Rrs LS RS
938 hb_chan_map_t hb_qt_chan_map =
942 { CH_C, CH_LFE, }}, // MONO
945 { CH_L, CH_R, CH_LFE, }}, // STEREO
947 {{ CH_C, CH_L, CH_R, },
948 { CH_C, CH_L, CH_R, CH_LFE, }}, // 3F
950 {{ CH_L, CH_R, CH_CS, },
951 { CH_L, CH_R, CH_CS, CH_LFE, }}, // 2F1R
953 {{ CH_C, CH_L, CH_R, CH_CS, },
954 { CH_C, CH_L, CH_R, CH_CS, CH_LFE, }}, // 3F1R
956 {{ CH_L, CH_R, CH_LS, CH_RS, },
957 { CH_L, CH_R, CH_LS, CH_RS, CH_LFE, }}, // 2F2R
959 {{ CH_C, CH_L, CH_R, CH_LS, CH_RS, },
960 { CH_C, CH_L, CH_R, CH_LS, CH_RS, CH_LFE, }}, // 3F2R
962 {{ CH_C, CH_L, CH_R, CH_LS, CH_RS, CH_Rls, CH_Rrs, },
963 { CH_C, CH_L, CH_R, CH_LS, CH_RS, CH_Rls, CH_Rrs, CH_LFE }}, // 3F4R
966 { CH_L, CH_R, }}, // DOLBY
969 { CH_L, CH_R, }} // DPLII
972 // CH_C CH_L CH_R CH_LS/CS CH_RS CH_Rls CH_Rrs CH_LFE
973 {{ 0, 0, 0, 0, 0, 0, 0, 0 },
974 { 0, 0, 0, 0, 0, 0, 0, 1 }}, // MONO
976 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
977 { 0, 0, 1, 0, 0, 0, 0, 2 }}, // STEREO
979 {{ 0, 1, 2, 0, 0, 0, 0, 0 },
980 { 0, 1, 2, 0, 0, 0, 0, 3 }}, // 3F
982 {{ 0, 0, 1, 2, 0, 0, 0, 0 },
983 { 0, 0, 1, 2, 0, 0, 0, 3 }}, // 2F1R
985 {{ 0, 1, 2, 3, 0, 0, 0, 0 },
986 { 0, 1, 2, 3, 0, 0, 0, 4 }}, // 3F1R
988 {{ 0, 0, 1, 2, 3, 0, 0, 0 },
989 { 0, 0, 1, 2, 3, 0, 0, 4 }}, // 2F2R
991 {{ 0, 1, 2, 3, 4, 0, 0, 0 },
992 { 0, 1, 2, 3, 4, 0, 0, 5 }}, // 3F2R
994 {{ 0, 1, 2, 3, 4, 5, 6, 0 },
995 { 0, 1, 2, 3, 4, 5, 6, 7 }}, // 3F4R
997 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
998 { 0, 0, 1, 0, 0, 0, 0, 0 }}, // DOLBY
1000 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
1001 { 0, 0, 1, 0, 0, 0, 0, 0 }} // DPLII
1005 hb_chan_map_t hb_smpte_chan_map =
1009 { CH_C, CH_LFE, }}, // MONO
1012 { CH_L, CH_R, CH_LFE, }}, // STEREO
1014 {{ CH_L, CH_R, CH_C, },
1015 { CH_L, CH_R, CH_C, CH_LFE, }}, // 3F
1017 {{ CH_L, CH_R, CH_CS, },
1018 { CH_L, CH_R, CH_LFE, CH_CS, }}, // 2F1R
1020 {{ CH_L, CH_R, CH_C, CH_CS, },
1021 { CH_L, CH_R, CH_LFE, CH_CS, }}, // 3F1R
1023 {{ CH_L, CH_R, CH_LS, CH_RS, },
1024 { CH_L, CH_R, CH_LFE, CH_LS, CH_RS, }}, // 2F2R
1026 {{ CH_L, CH_R, CH_C, CH_LS, CH_RS, },
1027 { CH_L, CH_R, CH_C, CH_LFE, CH_LS, CH_RS, }}, // 3F2R
1029 {{ CH_L, CH_R, CH_C, CH_Rls, CH_Rrs, CH_LS, CH_RS },
1030 { CH_L, CH_R, CH_C, CH_LFE, CH_Rls, CH_Rrs, CH_LS, CH_RS }}, // 3F4R
1033 { CH_L, CH_R, }}, // DOLBY
1036 { CH_L, CH_R, }} // DPLII
1039 // CH_C CH_L CH_R CH_LS/CS CH_RS CH_Rls CH_Rrs CH_LFE
1040 {{ 0, 0, 0, 0, 0, 0, 0, 0 },
1041 { 0, 0, 0, 0, 0, 0, 0, 1 }}, // MONO
1043 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
1044 { 0, 0, 1, 0, 0, 0, 0, 2 }}, // STEREO
1046 {{ 2, 0, 1, 0, 0, 0, 0, 0 },
1047 { 2, 0, 1, 0, 0, 0, 0, 3 }}, // 3F
1049 {{ 0, 0, 1, 2, 0, 0, 0, 0 },
1050 { 0, 0, 1, 3, 0, 0, 0, 2 }}, // 2F1R
1052 {{ 2, 0, 1, 3, 0, 0, 0, 0 },
1053 { 2, 0, 1, 4, 0, 0, 0, 3 }}, // 3F1R
1055 {{ 0, 0, 1, 2, 3, 0, 0, 0 },
1056 { 0, 0, 1, 3, 4, 0, 0, 2 }}, // 2F2R
1058 {{ 2, 0, 1, 3, 4, 0, 0, 0 },
1059 { 2, 0, 1, 4, 5, 0, 0, 3 }}, // 3F2R
1061 {{ 2, 0, 1, 5, 6, 3, 4, 0 },
1062 { 2, 0, 1, 6, 7, 4, 5, 3 }}, // 3F4R
1064 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
1065 { 0, 0, 1, 0, 0, 0, 0, 0 }}, // DOLBY
1067 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
1068 { 0, 0, 1, 0, 0, 0, 0, 0 }} // DPLII
1072 hb_chan_map_t hb_ac3_chan_map =
1076 { CH_LFE, CH_C, }}, // MONO
1079 { CH_LFE, CH_L, CH_R, }}, // STEREO
1081 {{ CH_L, CH_C, CH_R, },
1082 { CH_LFE, CH_L, CH_C, CH_R, }}, // 3F
1084 {{ CH_L, CH_R, CH_CS, },
1085 { CH_LFE, CH_L, CH_R, CH_CS, }}, // 2F1R
1087 {{ CH_L, CH_C, CH_R, CH_CS, },
1088 { CH_LFE, CH_L, CH_C, CH_R, CH_CS, }}, // 3F1R
1090 {{ CH_L, CH_R, CH_LS, CH_RS, },
1091 { CH_LFE, CH_L, CH_R, CH_LS, CH_RS, }}, // 2F2R
1093 {{ CH_L, CH_C, CH_R, CH_LS, CH_RS, },
1094 { CH_LFE, CH_L, CH_C, CH_R, CH_LS, CH_RS, }}, // 3F2R
1096 {{ CH_L, CH_C, CH_R, CH_LS, CH_RS, CH_Rls, CH_Rrs, },
1097 { CH_LFE, CH_L, CH_C, CH_R, CH_LS, CH_RS, CH_Rls, CH_Rrs }}, // 3F4R
1100 { CH_L, CH_R, }}, // DOLBY
1103 { CH_L, CH_R, }} // DPLII
1106 // CH_C CH_L CH_R CH_LS/CS CH_RS CH_Rls CH_Rrs CH_LFE
1107 {{ 0, 0, 0, 0, 0, 0, 0, 0 },
1108 { 1, 0, 0, 0, 0, 0, 0, 0 }}, // MONO
1110 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
1111 { 0, 1, 2, 0, 0, 0, 0, 0 }}, // STEREO
1113 {{ 1, 0, 2, 0, 0, 0, 0, 0 },
1114 { 2, 1, 3, 0, 0, 0, 0, 0 }}, // 3F
1116 {{ 0, 0, 1, 2, 0, 0, 0, 0 },
1117 { 0, 1, 2, 3, 0, 0, 0, 0 }}, // 2F1R
1119 {{ 1, 0, 2, 3, 0, 0, 0, 0 },
1120 { 2, 1, 3, 4, 0, 0, 0, 0 }}, // 3F1R
1122 {{ 0, 0, 1, 2, 3, 0, 0, 0 },
1123 { 0, 1, 2, 3, 4, 0, 0, 0 }}, // 2F2R
1125 {{ 1, 0, 2, 3, 4, 0, 0, 0 },
1126 { 2, 1, 3, 4, 5, 0, 0, 0 }}, // 3F2R
1128 {{ 1, 0, 2, 3, 4, 5, 6, 0 },
1129 { 2, 1, 3, 4, 5, 6, 7, 0 }}, // 3F4R
1131 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
1132 { 0, 0, 1, 0, 0, 0, 0, 0 }}, // DOLBY
1134 {{ 0, 0, 1, 0, 0, 0, 0, 0 },
1135 { 0, 0, 1, 0, 0, 0, 0, 0 }} // DPLII
1139 static const uint8_t nchans_tbl[] = {1, 2, 3, 3, 4, 4, 5, 7, 2, 2};
1141 // Takes a set of samples and remaps the channel layout
1142 void hb_layout_remap(
1143 hb_chan_map_t * map_in,
1144 hb_chan_map_t * map_out,
1146 hb_sample_t * samples,
1157 mode = hb_layout_to_mode(layout);
1158 lfe = ((mode & DOWNMIX_LFE_FLAG) != 0);
1159 mode = mode & DOWNMIX_CHANNEL_MASK;
1160 nchans = nchans_tbl[mode] + lfe;
1161 inv_map = map_in->inv_chan_map[mode][lfe];
1162 map = map_out->chan_map[mode][lfe];
1164 for (ii = 0; ii < nsamples; ii++)
1166 for (jj = 0; jj < nchans; jj++)
1168 tmp[jj] = samples[jj];
1170 for (jj = 0; jj < nchans; jj++)
1173 samples[jj] = tmp[inv_map[ord]];
1179 static void matrix_mul(
1185 hb_sample_t (*matrix)[8],
1191 for (nn = 0; nn < nsamples; nn++)
1193 for (ii = 0; ii < nchans_out; ii++)
1196 for (jj = 0; jj < nchans_in; jj++)
1198 val += src[jj] * matrix[jj][ii];
1200 dst[ii] = val + bias;
1207 static void set_level( hb_downmix_t * downmix )
1210 int layout_in, layout_out;
1214 mode_in = downmix->mode_in & ~DOWNMIX_FLAGS_MASK;
1215 mode_out = downmix->mode_out & ~DOWNMIX_FLAGS_MASK;
1217 for (ii = 0; ii < 8; ii++)
1219 for (jj = 0; jj < 8; jj++)
1221 downmix->matrix[ii][jj] *= downmix->level;
1224 if (mode_out >= DOWNMIX_DOLBY)
1227 layout_in = channel_layout_map[mode_in];
1228 layout_out = channel_layout_map[mode_out];
1230 if (layout_in & HB_CH_FRONT_CENTER)
1232 if (!(layout_out & HB_CH_FRONT_CENTER))
1234 for (jj = 0; jj < 8; jj++)
1236 downmix->matrix[downmix->center][jj] *= downmix->clev;
1240 if (layout_in & (HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT|HB_CH_BACK_CENTER|HB_CH_SIDE_LEFT|HB_CH_SIDE_RIGHT))
1242 if (layout_out & (HB_CH_BACK_LEFT|HB_CH_BACK_RIGHT|HB_CH_BACK_CENTER|HB_CH_SIDE_LEFT|HB_CH_SIDE_RIGHT))
1244 // Note, slev only gets set if input has surround, and output has none.
1248 for (jj = 0; jj < 8; jj++)
1250 if ( downmix->left_surround >= 0 )
1251 downmix->matrix[downmix->left_surround][jj] *= downmix->slev;
1252 if ( downmix->right_surround >= 0 )
1253 downmix->matrix[downmix->right_surround][jj] *= downmix->slev;
1254 if ( downmix->rear_left_surround >= 0 )
1255 downmix->matrix[downmix->rear_left_surround][jj] *= downmix->slev;
1256 if ( downmix->rear_right_surround >= 0 )
1257 downmix->matrix[downmix->rear_right_surround][jj] *= downmix->slev;
1261 #define MIXMODE(x,y) (((x)<<4)|(y))
1262 // The downmix operation can result in new sample values that are
1263 // outside the original range of sample values. If you wish to
1264 // guarantee that the levels to not exceed the original range,
1265 // call this function after initializing downmix and setting
1266 // your initial levels.
1268 // Note that this can result in generally lower volume levels
1269 // in the resulting downmixed audio.
1270 void hb_downmix_adjust_level( hb_downmix_t * downmix )
1272 int mode_in, mode_out;
1273 hb_sample_t level = downmix->level;
1274 hb_sample_t clev = downmix->clev;
1275 hb_sample_t slev = downmix->slev;
1277 mode_in = downmix->mode_in & DOWNMIX_CHANNEL_MASK;
1278 mode_out = downmix->mode_out & DOWNMIX_CHANNEL_MASK;
1280 switch MIXMODE(mode_in, mode_out)
1282 case MIXMODE(DOWNMIX_STEREO, DOWNMIX_MONO):
1283 case MIXMODE(DOWNMIX_2F2R, DOWNMIX_2F1R):
1284 case MIXMODE(DOWNMIX_2F2R, DOWNMIX_3F1R):
1285 case MIXMODE(DOWNMIX_3F2R, DOWNMIX_3F1R):
1286 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_3F1R):
1287 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_3F2R):
1289 level /= LVL_PLUS3DB;
1292 case MIXMODE(DOWNMIX_3F, DOWNMIX_MONO):
1293 level /= LVL_PLUS3DB + clev * LVL_PLUS3DB;
1296 case MIXMODE(DOWNMIX_3F2R, DOWNMIX_2F1R):
1297 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_2F1R):
1298 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_2F2R):
1299 if (1 + clev < LVL_PLUS3DB)
1301 case MIXMODE(DOWNMIX_3F, DOWNMIX_STEREO):
1302 case MIXMODE(DOWNMIX_3F, DOWNMIX_2F1R):
1303 case MIXMODE(DOWNMIX_3F, DOWNMIX_2F2R):
1304 case MIXMODE(DOWNMIX_3F, DOWNMIX_DOLBY):
1305 case MIXMODE(DOWNMIX_3F, DOWNMIX_DPLII):
1306 case MIXMODE(DOWNMIX_3F1R, DOWNMIX_2F1R):
1307 case MIXMODE(DOWNMIX_3F1R, DOWNMIX_2F2R):
1308 case MIXMODE(DOWNMIX_3F2R, DOWNMIX_2F2R):
1313 case MIXMODE(DOWNMIX_2F1R, DOWNMIX_MONO):
1314 level /= LVL_PLUS3DB + LVL_3DB * clev;
1317 case MIXMODE(DOWNMIX_2F1R, DOWNMIX_DOLBY):
1318 level /= 1 + LVL_3DB;
1321 case MIXMODE(DOWNMIX_2F1R, DOWNMIX_STEREO):
1322 case MIXMODE(DOWNMIX_2F1R, DOWNMIX_3F):
1323 case MIXMODE(DOWNMIX_3F1R, DOWNMIX_3F):
1324 level /= 1 + LVL_3DB * slev;
1327 case MIXMODE(DOWNMIX_3F1R, DOWNMIX_MONO):
1328 level /= LVL_PLUS3DB + LVL_PLUS3DB * clev + LVL_3DB * slev;
1331 case MIXMODE(DOWNMIX_3F1R, DOWNMIX_STEREO):
1332 level /= 1 + clev + LVL_3DB * slev;
1335 case MIXMODE(DOWNMIX_3F1R, DOWNMIX_DOLBY):
1336 case MIXMODE(DOWNMIX_3F1R, DOWNMIX_DPLII):
1337 case MIXMODE(DOWNMIX_2F2R, DOWNMIX_DOLBY):
1338 level /= 1 + LVL_PLUS3DB;
1341 case MIXMODE(DOWNMIX_2F2R, DOWNMIX_MONO):
1342 level /= LVL_PLUS3DB + LVL_PLUS3DB * slev;
1345 case MIXMODE(DOWNMIX_2F2R, DOWNMIX_STEREO):
1346 case MIXMODE(DOWNMIX_2F2R, DOWNMIX_3F):
1347 case MIXMODE(DOWNMIX_3F2R, DOWNMIX_3F):
1351 case MIXMODE(DOWNMIX_2F2R, DOWNMIX_DPLII):
1352 level /= 1 + LVL_SQRT_1_3 + LVL_SQRT_2_3;
1355 case MIXMODE(DOWNMIX_3F2R, DOWNMIX_MONO):
1356 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_MONO):
1357 level /= LVL_PLUS3DB + LVL_PLUS3DB * clev * LVL_PLUS3DB * slev;
1360 case MIXMODE(DOWNMIX_3F2R, DOWNMIX_STEREO):
1361 level /= 1 + clev + slev;
1364 case MIXMODE(DOWNMIX_3F2R, DOWNMIX_DOLBY):
1365 level /= 1 + 3 * LVL_3DB;
1368 case MIXMODE(DOWNMIX_3F2R, DOWNMIX_DPLII):
1369 level /= 1 + LVL_3DB + LVL_SQRT_1_3 + LVL_SQRT_2_3;
1372 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_STEREO):
1373 level /= 1 + clev + LVL_PLUS3DB * slev;
1376 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_3F):
1377 level /= 1 + LVL_PLUS3DB * slev;
1380 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_DOLBY):
1381 level /= 1 + 5 * LVL_3DB;
1384 case MIXMODE(DOWNMIX_3F4R, DOWNMIX_DPLII):
1385 level /= 1 + LVL_3DB + 2 * LVL_SQRT_1_3 + 2 * LVL_SQRT_2_3;
1388 downmix->level = level;
1389 downmix->matrix_initialized = 0;
1392 void hb_downmix_set_bias( hb_downmix_t * downmix, hb_sample_t bias )
1394 downmix->bias = bias;
1397 // Changes the downmix mode if it needs changing after initialization
1398 static void set_mode( hb_downmix_t * downmix )
1401 int mode_in, mode_out;
1402 hb_sample_t (*matrix)[8];
1404 mode_in = downmix->mode_in & ~DOWNMIX_FLAGS_MASK;
1405 mode_out = downmix->mode_out & ~DOWNMIX_FLAGS_MASK;
1407 matrix = downmix_matrix[mode_in][mode_out];
1409 for (ii = 0; ii < 8; ii++)
1411 for (jj = 0; jj < 8; jj++)
1413 downmix->matrix[ii][jj] = matrix[ii][jj];
1418 // Changes the downmix mode if it needs changing after initialization
1419 int hb_downmix_set_mode( hb_downmix_t * downmix, int layout, int mixdown )
1421 int lfe_in, lfe_out;
1422 int mode_in, mode_out;
1424 if ( downmix == NULL )
1427 mode_in = hb_layout_to_mode(layout);
1428 mode_out = hb_mixdown_to_mode(mixdown);
1429 downmix->mode_in = mode_in;
1430 downmix->mode_out = mode_out;
1432 mode_in = downmix->mode_in & ~DOWNMIX_FLAGS_MASK;
1433 mode_out = downmix->mode_out & ~DOWNMIX_FLAGS_MASK;
1435 if (mode_in >= DOWNMIX_NUM_MODES || mode_out >= DOWNMIX_NUM_MODES)
1438 lfe_in = ((downmix->mode_in & DOWNMIX_LFE_FLAG) != 0);
1439 lfe_out = ((downmix->mode_out & DOWNMIX_LFE_FLAG) != 0);
1441 downmix->nchans_in = nchans_tbl[mode_in] + lfe_in;
1442 downmix->nchans_out = nchans_tbl[mode_out] + lfe_out;
1444 downmix->matrix_initialized = 0;
1448 // Changes the downmix levels if they need changing after initialization
1449 void hb_downmix_set_level( hb_downmix_t * downmix, hb_sample_t clev, hb_sample_t slev, hb_sample_t level )
1451 if ( downmix == NULL )
1454 downmix->clev = clev;
1455 downmix->slev = slev;
1456 downmix->level = level;
1457 downmix->matrix_initialized = 0;
1460 static void set_chan_map( hb_downmix_t * downmix )
1468 hb_sample_t matrix[8][8];
1471 for ( ii = 0; ii < 8; ii++ )
1473 for ( jj = 0; jj < 8; jj++ )
1475 matrix[ii][jj] = downmix->matrix[ii][jj];
1479 // Rearrange the rows to correspond to the input channel order
1480 lfe = ((downmix->mode_in & DOWNMIX_LFE_FLAG) != 0);
1481 mode = downmix->mode_in & DOWNMIX_CHANNEL_MASK;
1482 nchans = nchans_tbl[mode] + lfe;
1483 map = downmix->map_in.chan_map[mode][lfe];
1484 inv_map = hb_qt_chan_map.inv_chan_map[mode][lfe];
1486 downmix->center = -1;
1487 downmix->left_surround = -1;
1488 downmix->right_surround = -1;
1489 downmix->rear_left_surround = -1;
1490 downmix->rear_right_surround = -1;
1491 for ( ii = 0; ii < nchans; ii++ )
1494 int row = inv_map[ord];
1498 downmix->center = ii;
1501 downmix->left_surround = ii;
1504 downmix->right_surround = ii;
1507 downmix->rear_right_surround = ii;
1510 downmix->rear_left_surround = ii;
1513 for ( jj = 0; jj < 8; jj++ )
1515 downmix->matrix[ii][jj] = matrix[row][jj];
1520 for ( ii = 0; ii < 8; ii++ )
1522 for ( jj = 0; jj < 8; jj++ )
1524 matrix[ii][jj] = downmix->matrix[ii][jj];
1528 // Rearrange the columns to correspond to the output channel order
1529 lfe = ((downmix->mode_out & DOWNMIX_LFE_FLAG) != 0);
1530 mode = downmix->mode_out & DOWNMIX_CHANNEL_MASK;
1531 nchans = nchans_tbl[mode] + lfe;
1532 map = downmix->map_out.chan_map[mode][lfe];
1533 inv_map = hb_qt_chan_map.inv_chan_map[mode][lfe];
1534 for ( ii = 0; ii < nchans; ii++ )
1537 int col = inv_map[ord];
1538 for ( jj = 0; jj < 8; jj++ )
1540 downmix->matrix[jj][ii] = matrix[jj][col];
1545 void hb_downmix_set_chan_map(
1546 hb_downmix_t * downmix,
1547 hb_chan_map_t * map_in,
1548 hb_chan_map_t * map_out )
1550 downmix->map_in = *map_in;
1551 downmix->map_out = *map_out;
1552 downmix->matrix_initialized = 0;
1555 hb_downmix_t * hb_downmix_init(int layout, int mixdown)
1557 hb_downmix_t * downmix = calloc(1, sizeof(hb_downmix_t));
1559 if (downmix == NULL)
1561 if ( hb_downmix_set_mode( downmix, layout, mixdown ) < 0 )
1566 // Set some good default values
1567 hb_downmix_set_level( downmix, LVL_3DB, LVL_3DB, 1.0 );
1568 downmix->bias = 0.0;
1569 downmix->matrix_initialized = 0;
1570 // The default input and output channel order is QT
1571 hb_downmix_set_chan_map( downmix, &hb_qt_chan_map, &hb_qt_chan_map );
1575 void hb_downmix_close( hb_downmix_t **downmix )
1577 if (*downmix != NULL)
1582 static void init_matrix( hb_downmix_t * downmix )
1584 if ( !downmix->matrix_initialized )
1586 set_mode( downmix );
1587 set_chan_map( downmix );
1589 downmix->matrix_initialized = 1;
1593 void hb_downmix( hb_downmix_t * downmix, hb_sample_t * dst, hb_sample_t * src, int nsamples)
1595 init_matrix( downmix );
1596 matrix_mul( dst, src, downmix->nchans_out, downmix->nchans_in,
1597 nsamples, downmix->matrix, downmix->bias );
1600 int hb_need_downmix( int layout, int mixdown )
1602 int mode_in, mode_out;
1604 mode_in = hb_layout_to_mode(layout);
1605 mode_out = hb_mixdown_to_mode(mixdown);
1607 return (mode_in != mode_out);