| 1 | /* |
| 2 | * Copyright (C) 2011 Michael Niedermayer (michaelni@gmx.at) |
| 3 | * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com> |
| 4 | * |
| 5 | * This file is part of FFmpeg. |
| 6 | * |
| 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. |
| 11 | * |
| 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. |
| 16 | * |
| 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 |
| 20 | */ |
| 21 | |
| 22 | #include <stdint.h> |
| 23 | |
| 24 | #include "libavutil/common.h" |
| 25 | #include "libavutil/libm.h" |
| 26 | #include "libavutil/samplefmt.h" |
| 27 | #include "avresample.h" |
| 28 | #include "internal.h" |
| 29 | #include "audio_data.h" |
| 30 | #include "audio_mix.h" |
| 31 | |
| 32 | /* channel positions */ |
| 33 | #define FRONT_LEFT 0 |
| 34 | #define FRONT_RIGHT 1 |
| 35 | #define FRONT_CENTER 2 |
| 36 | #define LOW_FREQUENCY 3 |
| 37 | #define BACK_LEFT 4 |
| 38 | #define BACK_RIGHT 5 |
| 39 | #define FRONT_LEFT_OF_CENTER 6 |
| 40 | #define FRONT_RIGHT_OF_CENTER 7 |
| 41 | #define BACK_CENTER 8 |
| 42 | #define SIDE_LEFT 9 |
| 43 | #define SIDE_RIGHT 10 |
| 44 | #define TOP_CENTER 11 |
| 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 |
| 53 | #define WIDE_LEFT 31 |
| 54 | #define WIDE_RIGHT 32 |
| 55 | #define SURROUND_DIRECT_LEFT 33 |
| 56 | #define SURROUND_DIRECT_RIGHT 34 |
| 57 | #define LOW_FREQUENCY_2 35 |
| 58 | |
| 59 | #define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */ |
| 60 | |
| 61 | static av_always_inline int even(uint64_t layout) |
| 62 | { |
| 63 | return (!layout || !!(layout & (layout - 1))); |
| 64 | } |
| 65 | |
| 66 | static int sane_layout(uint64_t layout) |
| 67 | { |
| 68 | /* check that there is at least 1 front speaker */ |
| 69 | if (!(layout & AV_CH_LAYOUT_SURROUND)) |
| 70 | return 0; |
| 71 | |
| 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))) |
| 82 | return 0; |
| 83 | |
| 84 | return 1; |
| 85 | } |
| 86 | |
| 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) |
| 92 | { |
| 93 | int i, j, out_i, out_j; |
| 94 | double matrix[64][64] = {{0}}; |
| 95 | int64_t unaccounted; |
| 96 | double maxcoef = 0; |
| 97 | int in_channels, out_channels; |
| 98 | |
| 99 | if ((out_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX) { |
| 100 | out_layout = AV_CH_LAYOUT_STEREO; |
| 101 | } |
| 102 | |
| 103 | unaccounted = in_layout & ~out_layout; |
| 104 | |
| 105 | in_channels = av_get_channel_layout_nb_channels( in_layout); |
| 106 | out_channels = av_get_channel_layout_nb_channels(out_layout); |
| 107 | |
| 108 | memset(matrix_out, 0, out_channels * stride * sizeof(*matrix_out)); |
| 109 | |
| 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); |
| 115 | |
| 116 | /* check if layouts are unbalanced or abnormal */ |
| 117 | if (!sane_layout(in_layout) || !sane_layout(out_layout)) |
| 118 | return AVERROR_PATCHWELCOME; |
| 119 | |
| 120 | /* route matching input/output channels */ |
| 121 | for (i = 0; i < 64; i++) { |
| 122 | if (in_layout & out_layout & (1ULL << i)) |
| 123 | matrix[i][i] = 1.0; |
| 124 | } |
| 125 | |
| 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; |
| 132 | } else { |
| 133 | matrix[FRONT_LEFT ][FRONT_CENTER] += M_SQRT1_2; |
| 134 | matrix[FRONT_RIGHT][FRONT_CENTER] += M_SQRT1_2; |
| 135 | } |
| 136 | } else |
| 137 | return AVERROR_PATCHWELCOME; |
| 138 | } |
| 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; |
| 147 | } else |
| 148 | return AVERROR_PATCHWELCOME; |
| 149 | } |
| 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; |
| 164 | } else { |
| 165 | matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level; |
| 166 | matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level; |
| 167 | } |
| 168 | } else { |
| 169 | matrix[FRONT_LEFT ][BACK_CENTER] += surround_mix_level * M_SQRT1_2; |
| 170 | matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2; |
| 171 | } |
| 172 | } else if (out_layout & AV_CH_FRONT_CENTER) { |
| 173 | matrix[FRONT_CENTER][BACK_CENTER] += surround_mix_level * M_SQRT1_2; |
| 174 | } else |
| 175 | return AVERROR_PATCHWELCOME; |
| 176 | } |
| 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; |
| 188 | } else { |
| 189 | matrix[SIDE_LEFT ][BACK_LEFT ] += 1.0; |
| 190 | matrix[SIDE_RIGHT][BACK_RIGHT] += 1.0; |
| 191 | } |
| 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; |
| 203 | } else { |
| 204 | matrix[FRONT_LEFT ][BACK_LEFT ] += surround_mix_level; |
| 205 | matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level; |
| 206 | } |
| 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; |
| 210 | } else |
| 211 | return AVERROR_PATCHWELCOME; |
| 212 | } |
| 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; |
| 221 | } else { |
| 222 | matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0; |
| 223 | matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0; |
| 224 | } |
| 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; |
| 239 | } else { |
| 240 | matrix[FRONT_LEFT ][SIDE_LEFT ] += surround_mix_level; |
| 241 | matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level; |
| 242 | } |
| 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; |
| 246 | } else |
| 247 | return AVERROR_PATCHWELCOME; |
| 248 | } |
| 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; |
| 257 | } else |
| 258 | return AVERROR_PATCHWELCOME; |
| 259 | } |
| 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; |
| 267 | } else |
| 268 | return AVERROR_PATCHWELCOME; |
| 269 | } |
| 270 | |
| 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++) { |
| 274 | double sum = 0; |
| 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)) |
| 279 | out_j++; |
| 280 | } |
| 281 | maxcoef = FFMAX(maxcoef, sum); |
| 282 | if (out_layout & (1ULL << i)) |
| 283 | out_i++; |
| 284 | } |
| 285 | |
| 286 | /* normalize */ |
| 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; |
| 291 | } |
| 292 | |
| 293 | return 0; |
| 294 | } |