2 * Copyright (C) 2011 Michael Niedermayer (michaelni@gmx.at)
3 * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "libavutil/common.h"
25 #include "libavutil/libm.h"
26 #include "libavutil/samplefmt.h"
27 #include "avresample.h"
29 #include "audio_data.h"
30 #include "audio_mix.h"
32 /* channel positions */
35 #define FRONT_CENTER 2
36 #define LOW_FREQUENCY 3
39 #define FRONT_LEFT_OF_CENTER 6
40 #define FRONT_RIGHT_OF_CENTER 7
45 #define TOP_FRONT_LEFT 12
46 #define TOP_FRONT_CENTER 13
47 #define TOP_FRONT_RIGHT 14
48 #define TOP_BACK_LEFT 15
49 #define TOP_BACK_CENTER 16
50 #define TOP_BACK_RIGHT 17
51 #define STEREO_LEFT 29
52 #define STEREO_RIGHT 30
55 #define SURROUND_DIRECT_LEFT 33
56 #define SURROUND_DIRECT_RIGHT 34
57 #define LOW_FREQUENCY_2 35
59 #define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
61 static av_always_inline
int even(uint64_t layout
)
63 return (!layout
|| !!(layout
& (layout
- 1)));
66 static int sane_layout(uint64_t layout
)
68 /* check that there is at least 1 front speaker */
69 if (!(layout
& AV_CH_LAYOUT_SURROUND
))
72 /* check for left/right symmetry */
73 if (!even(layout
& (AV_CH_FRONT_LEFT
| AV_CH_FRONT_RIGHT
)) ||
74 !even(layout
& (AV_CH_SIDE_LEFT
| AV_CH_SIDE_RIGHT
)) ||
75 !even(layout
& (AV_CH_BACK_LEFT
| AV_CH_BACK_RIGHT
)) ||
76 !even(layout
& (AV_CH_FRONT_LEFT_OF_CENTER
| AV_CH_FRONT_RIGHT_OF_CENTER
)) ||
77 !even(layout
& (AV_CH_TOP_FRONT_LEFT
| AV_CH_TOP_FRONT_RIGHT
)) ||
78 !even(layout
& (AV_CH_TOP_BACK_LEFT
| AV_CH_TOP_BACK_RIGHT
)) ||
79 !even(layout
& (AV_CH_STEREO_LEFT
| AV_CH_STEREO_RIGHT
)) ||
80 !even(layout
& (AV_CH_WIDE_LEFT
| AV_CH_WIDE_RIGHT
)) ||
81 !even(layout
& (AV_CH_SURROUND_DIRECT_LEFT
| AV_CH_SURROUND_DIRECT_RIGHT
)))
87 int avresample_build_matrix(uint64_t in_layout
, uint64_t out_layout
,
88 double center_mix_level
, double surround_mix_level
,
89 double lfe_mix_level
, int normalize
,
90 double *matrix_out
, int stride
,
91 enum AVMatrixEncoding matrix_encoding
)
93 int i
, j
, out_i
, out_j
;
94 double matrix
[64][64] = {{0}};
97 int in_channels
, out_channels
;
99 if ((out_layout
& AV_CH_LAYOUT_STEREO_DOWNMIX
) == AV_CH_LAYOUT_STEREO_DOWNMIX
) {
100 out_layout
= AV_CH_LAYOUT_STEREO
;
103 unaccounted
= in_layout
& ~out_layout
;
105 in_channels
= av_get_channel_layout_nb_channels( in_layout
);
106 out_channels
= av_get_channel_layout_nb_channels(out_layout
);
108 memset(matrix_out
, 0, out_channels
* stride
* sizeof(*matrix_out
));
110 /* check if layouts are supported */
111 if (!in_layout
|| in_channels
> AVRESAMPLE_MAX_CHANNELS
)
112 return AVERROR(EINVAL
);
113 if (!out_layout
|| out_channels
> AVRESAMPLE_MAX_CHANNELS
)
114 return AVERROR(EINVAL
);
116 /* check if layouts are unbalanced or abnormal */
117 if (!sane_layout(in_layout
) || !sane_layout(out_layout
))
118 return AVERROR_PATCHWELCOME
;
120 /* route matching input/output channels */
121 for (i
= 0; i
< 64; i
++) {
122 if (in_layout
& out_layout
& (1ULL << i
))
126 /* mix front center to front left/right */
127 if (unaccounted
& AV_CH_FRONT_CENTER
) {
128 if ((out_layout
& AV_CH_LAYOUT_STEREO
) == AV_CH_LAYOUT_STEREO
) {
129 if ((in_layout
& AV_CH_LAYOUT_STEREO
) == AV_CH_LAYOUT_STEREO
) {
130 matrix
[FRONT_LEFT
][FRONT_CENTER
] += center_mix_level
;
131 matrix
[FRONT_RIGHT
][FRONT_CENTER
] += center_mix_level
;
133 matrix
[FRONT_LEFT
][FRONT_CENTER
] += M_SQRT1_2
;
134 matrix
[FRONT_RIGHT
][FRONT_CENTER
] += M_SQRT1_2
;
137 return AVERROR_PATCHWELCOME
;
139 /* mix front left/right to center */
140 if (unaccounted
& AV_CH_LAYOUT_STEREO
) {
141 if (out_layout
& AV_CH_FRONT_CENTER
) {
142 matrix
[FRONT_CENTER
][FRONT_LEFT
] += M_SQRT1_2
;
143 matrix
[FRONT_CENTER
][FRONT_RIGHT
] += M_SQRT1_2
;
144 /* mix left/right/center to center */
145 if (in_layout
& AV_CH_FRONT_CENTER
)
146 matrix
[FRONT_CENTER
][FRONT_CENTER
] = center_mix_level
* M_SQRT2
;
148 return AVERROR_PATCHWELCOME
;
150 /* mix back center to back, side, or front */
151 if (unaccounted
& AV_CH_BACK_CENTER
) {
152 if (out_layout
& AV_CH_BACK_LEFT
) {
153 matrix
[BACK_LEFT
][BACK_CENTER
] += M_SQRT1_2
;
154 matrix
[BACK_RIGHT
][BACK_CENTER
] += M_SQRT1_2
;
155 } else if (out_layout
& AV_CH_SIDE_LEFT
) {
156 matrix
[SIDE_LEFT
][BACK_CENTER
] += M_SQRT1_2
;
157 matrix
[SIDE_RIGHT
][BACK_CENTER
] += M_SQRT1_2
;
158 } else if (out_layout
& AV_CH_FRONT_LEFT
) {
159 if (matrix_encoding
== AV_MATRIX_ENCODING_DOLBY
||
160 matrix_encoding
== AV_MATRIX_ENCODING_DPLII
) {
161 if (unaccounted
& (AV_CH_BACK_LEFT
| AV_CH_SIDE_LEFT
)) {
162 matrix
[FRONT_LEFT
][BACK_CENTER
] -= surround_mix_level
* M_SQRT1_2
;
163 matrix
[FRONT_RIGHT
][BACK_CENTER
] += surround_mix_level
* M_SQRT1_2
;
165 matrix
[FRONT_LEFT
][BACK_CENTER
] -= surround_mix_level
;
166 matrix
[FRONT_RIGHT
][BACK_CENTER
] += surround_mix_level
;
169 matrix
[FRONT_LEFT
][BACK_CENTER
] += surround_mix_level
* M_SQRT1_2
;
170 matrix
[FRONT_RIGHT
][BACK_CENTER
] += surround_mix_level
* M_SQRT1_2
;
172 } else if (out_layout
& AV_CH_FRONT_CENTER
) {
173 matrix
[FRONT_CENTER
][BACK_CENTER
] += surround_mix_level
* M_SQRT1_2
;
175 return AVERROR_PATCHWELCOME
;
177 /* mix back left/right to back center, side, or front */
178 if (unaccounted
& AV_CH_BACK_LEFT
) {
179 if (out_layout
& AV_CH_BACK_CENTER
) {
180 matrix
[BACK_CENTER
][BACK_LEFT
] += M_SQRT1_2
;
181 matrix
[BACK_CENTER
][BACK_RIGHT
] += M_SQRT1_2
;
182 } else if (out_layout
& AV_CH_SIDE_LEFT
) {
183 /* if side channels do not exist in the input, just copy back
184 channels to side channels, otherwise mix back into side */
185 if (in_layout
& AV_CH_SIDE_LEFT
) {
186 matrix
[SIDE_LEFT
][BACK_LEFT
] += M_SQRT1_2
;
187 matrix
[SIDE_RIGHT
][BACK_RIGHT
] += M_SQRT1_2
;
189 matrix
[SIDE_LEFT
][BACK_LEFT
] += 1.0;
190 matrix
[SIDE_RIGHT
][BACK_RIGHT
] += 1.0;
192 } else if (out_layout
& AV_CH_FRONT_LEFT
) {
193 if (matrix_encoding
== AV_MATRIX_ENCODING_DOLBY
) {
194 matrix
[FRONT_LEFT
][BACK_LEFT
] -= surround_mix_level
* M_SQRT1_2
;
195 matrix
[FRONT_LEFT
][BACK_RIGHT
] -= surround_mix_level
* M_SQRT1_2
;
196 matrix
[FRONT_RIGHT
][BACK_LEFT
] += surround_mix_level
* M_SQRT1_2
;
197 matrix
[FRONT_RIGHT
][BACK_RIGHT
] += surround_mix_level
* M_SQRT1_2
;
198 } else if (matrix_encoding
== AV_MATRIX_ENCODING_DPLII
) {
199 matrix
[FRONT_LEFT
][BACK_LEFT
] -= surround_mix_level
* SQRT3_2
;
200 matrix
[FRONT_LEFT
][BACK_RIGHT
] -= surround_mix_level
* M_SQRT1_2
;
201 matrix
[FRONT_RIGHT
][BACK_LEFT
] += surround_mix_level
* M_SQRT1_2
;
202 matrix
[FRONT_RIGHT
][BACK_RIGHT
] += surround_mix_level
* SQRT3_2
;
204 matrix
[FRONT_LEFT
][BACK_LEFT
] += surround_mix_level
;
205 matrix
[FRONT_RIGHT
][BACK_RIGHT
] += surround_mix_level
;
207 } else if (out_layout
& AV_CH_FRONT_CENTER
) {
208 matrix
[FRONT_CENTER
][BACK_LEFT
] += surround_mix_level
* M_SQRT1_2
;
209 matrix
[FRONT_CENTER
][BACK_RIGHT
] += surround_mix_level
* M_SQRT1_2
;
211 return AVERROR_PATCHWELCOME
;
213 /* mix side left/right into back or front */
214 if (unaccounted
& AV_CH_SIDE_LEFT
) {
215 if (out_layout
& AV_CH_BACK_LEFT
) {
216 /* if back channels do not exist in the input, just copy side
217 channels to back channels, otherwise mix side into back */
218 if (in_layout
& AV_CH_BACK_LEFT
) {
219 matrix
[BACK_LEFT
][SIDE_LEFT
] += M_SQRT1_2
;
220 matrix
[BACK_RIGHT
][SIDE_RIGHT
] += M_SQRT1_2
;
222 matrix
[BACK_LEFT
][SIDE_LEFT
] += 1.0;
223 matrix
[BACK_RIGHT
][SIDE_RIGHT
] += 1.0;
225 } else if (out_layout
& AV_CH_BACK_CENTER
) {
226 matrix
[BACK_CENTER
][SIDE_LEFT
] += M_SQRT1_2
;
227 matrix
[BACK_CENTER
][SIDE_RIGHT
] += M_SQRT1_2
;
228 } else if (out_layout
& AV_CH_FRONT_LEFT
) {
229 if (matrix_encoding
== AV_MATRIX_ENCODING_DOLBY
) {
230 matrix
[FRONT_LEFT
][SIDE_LEFT
] -= surround_mix_level
* M_SQRT1_2
;
231 matrix
[FRONT_LEFT
][SIDE_RIGHT
] -= surround_mix_level
* M_SQRT1_2
;
232 matrix
[FRONT_RIGHT
][SIDE_LEFT
] += surround_mix_level
* M_SQRT1_2
;
233 matrix
[FRONT_RIGHT
][SIDE_RIGHT
] += surround_mix_level
* M_SQRT1_2
;
234 } else if (matrix_encoding
== AV_MATRIX_ENCODING_DPLII
) {
235 matrix
[FRONT_LEFT
][SIDE_LEFT
] -= surround_mix_level
* SQRT3_2
;
236 matrix
[FRONT_LEFT
][SIDE_RIGHT
] -= surround_mix_level
* M_SQRT1_2
;
237 matrix
[FRONT_RIGHT
][SIDE_LEFT
] += surround_mix_level
* M_SQRT1_2
;
238 matrix
[FRONT_RIGHT
][SIDE_RIGHT
] += surround_mix_level
* SQRT3_2
;
240 matrix
[FRONT_LEFT
][SIDE_LEFT
] += surround_mix_level
;
241 matrix
[FRONT_RIGHT
][SIDE_RIGHT
] += surround_mix_level
;
243 } else if (out_layout
& AV_CH_FRONT_CENTER
) {
244 matrix
[FRONT_CENTER
][SIDE_LEFT
] += surround_mix_level
* M_SQRT1_2
;
245 matrix
[FRONT_CENTER
][SIDE_RIGHT
] += surround_mix_level
* M_SQRT1_2
;
247 return AVERROR_PATCHWELCOME
;
249 /* mix left-of-center/right-of-center into front left/right or center */
250 if (unaccounted
& AV_CH_FRONT_LEFT_OF_CENTER
) {
251 if (out_layout
& AV_CH_FRONT_LEFT
) {
252 matrix
[FRONT_LEFT
][FRONT_LEFT_OF_CENTER
] += 1.0;
253 matrix
[FRONT_RIGHT
][FRONT_RIGHT_OF_CENTER
] += 1.0;
254 } else if (out_layout
& AV_CH_FRONT_CENTER
) {
255 matrix
[FRONT_CENTER
][FRONT_LEFT_OF_CENTER
] += M_SQRT1_2
;
256 matrix
[FRONT_CENTER
][FRONT_RIGHT_OF_CENTER
] += M_SQRT1_2
;
258 return AVERROR_PATCHWELCOME
;
260 /* mix LFE into front left/right or center */
261 if (unaccounted
& AV_CH_LOW_FREQUENCY
) {
262 if (out_layout
& AV_CH_FRONT_CENTER
) {
263 matrix
[FRONT_CENTER
][LOW_FREQUENCY
] += lfe_mix_level
;
264 } else if (out_layout
& AV_CH_FRONT_LEFT
) {
265 matrix
[FRONT_LEFT
][LOW_FREQUENCY
] += lfe_mix_level
* M_SQRT1_2
;
266 matrix
[FRONT_RIGHT
][LOW_FREQUENCY
] += lfe_mix_level
* M_SQRT1_2
;
268 return AVERROR_PATCHWELCOME
;
271 /* transfer internal matrix to output matrix and calculate maximum
272 per-channel coefficient sum */
273 for (out_i
= i
= 0; out_i
< out_channels
&& i
< 64; i
++) {
275 for (out_j
= j
= 0; out_j
< in_channels
&& j
< 64; j
++) {
276 matrix_out
[out_i
* stride
+ out_j
] = matrix
[i
][j
];
277 sum
+= fabs(matrix
[i
][j
]);
278 if (in_layout
& (1ULL << j
))
281 maxcoef
= FFMAX(maxcoef
, sum
);
282 if (out_layout
& (1ULL << i
))
287 if (normalize
&& maxcoef
> 1.0) {
288 for (i
= 0; i
< out_channels
; i
++)
289 for (j
= 0; j
< in_channels
; j
++)
290 matrix_out
[i
* stride
+ j
] /= maxcoef
;