annotate ffmpeg/libavresample/audio_mix_matrix.c @ 13:844d341cf643 tip

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