00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdint.h>
00023
00024 #include "libavutil/common.h"
00025 #include "libavutil/libm.h"
00026 #include "libavutil/samplefmt.h"
00027 #include "avresample.h"
00028 #include "internal.h"
00029 #include "audio_data.h"
00030 #include "audio_mix.h"
00031
00032
00033 #define FRONT_LEFT 0
00034 #define FRONT_RIGHT 1
00035 #define FRONT_CENTER 2
00036 #define LOW_FREQUENCY 3
00037 #define BACK_LEFT 4
00038 #define BACK_RIGHT 5
00039 #define FRONT_LEFT_OF_CENTER 6
00040 #define FRONT_RIGHT_OF_CENTER 7
00041 #define BACK_CENTER 8
00042 #define SIDE_LEFT 9
00043 #define SIDE_RIGHT 10
00044 #define TOP_CENTER 11
00045 #define TOP_FRONT_LEFT 12
00046 #define TOP_FRONT_CENTER 13
00047 #define TOP_FRONT_RIGHT 14
00048 #define TOP_BACK_LEFT 15
00049 #define TOP_BACK_CENTER 16
00050 #define TOP_BACK_RIGHT 17
00051 #define STEREO_LEFT 29
00052 #define STEREO_RIGHT 30
00053 #define WIDE_LEFT 31
00054 #define WIDE_RIGHT 32
00055 #define SURROUND_DIRECT_LEFT 33
00056 #define SURROUND_DIRECT_RIGHT 34
00057 #define LOW_FREQUENCY_2 35
00058
00059 #define SQRT3_2 1.22474487139158904909
00060
00061 static av_always_inline int even(uint64_t layout)
00062 {
00063 return (!layout || (layout & (layout - 1)));
00064 }
00065
00066 static int sane_layout(uint64_t layout)
00067 {
00068
00069 if (!(layout & AV_CH_LAYOUT_SURROUND))
00070 return 0;
00071
00072
00073 if (!even(layout & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)) ||
00074 !even(layout & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)) ||
00075 !even(layout & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)) ||
00076 !even(layout & (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)) ||
00077 !even(layout & (AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT)) ||
00078 !even(layout & (AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT)) ||
00079 !even(layout & (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT)) ||
00080 !even(layout & (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT)) ||
00081 !even(layout & (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)))
00082 return 0;
00083
00084 return 1;
00085 }
00086
00087 int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout,
00088 double center_mix_level, double surround_mix_level,
00089 double lfe_mix_level, int normalize,
00090 double *matrix_out, int stride,
00091 enum AVMatrixEncoding matrix_encoding)
00092 {
00093 int i, j, out_i, out_j;
00094 double matrix[64][64] = {{0}};
00095 int64_t unaccounted;
00096 double maxcoef = 0;
00097 int in_channels, out_channels;
00098
00099 if ((out_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX) {
00100 out_layout = AV_CH_LAYOUT_STEREO;
00101 }
00102
00103 unaccounted = in_layout & ~out_layout;
00104
00105 in_channels = av_get_channel_layout_nb_channels( in_layout);
00106 out_channels = av_get_channel_layout_nb_channels(out_layout);
00107
00108 memset(matrix_out, 0, out_channels * stride * sizeof(*matrix_out));
00109
00110
00111 if (!in_layout || in_channels > AVRESAMPLE_MAX_CHANNELS)
00112 return AVERROR(EINVAL);
00113 if (!out_layout || out_channels > AVRESAMPLE_MAX_CHANNELS)
00114 return AVERROR(EINVAL);
00115
00116
00117 if (!sane_layout(in_layout) || !sane_layout(out_layout))
00118 return AVERROR_PATCHWELCOME;
00119
00120
00121 for (i = 0; i < 64; i++) {
00122 if (in_layout & out_layout & (1ULL << i))
00123 matrix[i][i] = 1.0;
00124 }
00125
00126
00127 if (unaccounted & AV_CH_FRONT_CENTER) {
00128 if ((out_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) {
00129 matrix[FRONT_LEFT ][FRONT_CENTER] += M_SQRT1_2;
00130 matrix[FRONT_RIGHT][FRONT_CENTER] += M_SQRT1_2;
00131 } else
00132 return AVERROR_PATCHWELCOME;
00133 }
00134
00135 if (unaccounted & AV_CH_LAYOUT_STEREO) {
00136 if (out_layout & AV_CH_FRONT_CENTER) {
00137 matrix[FRONT_CENTER][FRONT_LEFT ] += M_SQRT1_2;
00138 matrix[FRONT_CENTER][FRONT_RIGHT] += M_SQRT1_2;
00139
00140 if (in_layout & AV_CH_FRONT_CENTER)
00141 matrix[FRONT_CENTER][FRONT_CENTER] = center_mix_level * M_SQRT2;
00142 } else
00143 return AVERROR_PATCHWELCOME;
00144 }
00145
00146 if (unaccounted & AV_CH_BACK_CENTER) {
00147 if (out_layout & AV_CH_BACK_LEFT) {
00148 matrix[BACK_LEFT ][BACK_CENTER] += M_SQRT1_2;
00149 matrix[BACK_RIGHT][BACK_CENTER] += M_SQRT1_2;
00150 } else if (out_layout & AV_CH_SIDE_LEFT) {
00151 matrix[SIDE_LEFT ][BACK_CENTER] += M_SQRT1_2;
00152 matrix[SIDE_RIGHT][BACK_CENTER] += M_SQRT1_2;
00153 } else if (out_layout & AV_CH_FRONT_LEFT) {
00154 if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
00155 matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
00156 if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
00157 matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
00158 matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
00159 } else {
00160 matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
00161 matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
00162 }
00163 } else {
00164 matrix[FRONT_LEFT ][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
00165 matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
00166 }
00167 } else if (out_layout & AV_CH_FRONT_CENTER) {
00168 matrix[FRONT_CENTER][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
00169 } else
00170 return AVERROR_PATCHWELCOME;
00171 }
00172
00173 if (unaccounted & AV_CH_BACK_LEFT) {
00174 if (out_layout & AV_CH_BACK_CENTER) {
00175 matrix[BACK_CENTER][BACK_LEFT ] += M_SQRT1_2;
00176 matrix[BACK_CENTER][BACK_RIGHT] += M_SQRT1_2;
00177 } else if (out_layout & AV_CH_SIDE_LEFT) {
00178
00179
00180 if (in_layout & AV_CH_SIDE_LEFT) {
00181 matrix[SIDE_LEFT ][BACK_LEFT ] += M_SQRT1_2;
00182 matrix[SIDE_RIGHT][BACK_RIGHT] += M_SQRT1_2;
00183 } else {
00184 matrix[SIDE_LEFT ][BACK_LEFT ] += 1.0;
00185 matrix[SIDE_RIGHT][BACK_RIGHT] += 1.0;
00186 }
00187 } else if (out_layout & AV_CH_FRONT_LEFT) {
00188 if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
00189 matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
00190 matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
00191 matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
00192 matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
00193 } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
00194 matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
00195 matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
00196 matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
00197 matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
00198 } else {
00199 matrix[FRONT_LEFT ][BACK_LEFT ] += surround_mix_level;
00200 matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
00201 }
00202 } else if (out_layout & AV_CH_FRONT_CENTER) {
00203 matrix[FRONT_CENTER][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
00204 matrix[FRONT_CENTER][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
00205 } else
00206 return AVERROR_PATCHWELCOME;
00207 }
00208
00209 if (unaccounted & AV_CH_SIDE_LEFT) {
00210 if (out_layout & AV_CH_BACK_LEFT) {
00211
00212
00213 if (in_layout & AV_CH_BACK_LEFT) {
00214 matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2;
00215 matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2;
00216 } else {
00217 matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
00218 matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
00219 }
00220 } else if (out_layout & AV_CH_BACK_CENTER) {
00221 matrix[BACK_CENTER][SIDE_LEFT ] += M_SQRT1_2;
00222 matrix[BACK_CENTER][SIDE_RIGHT] += M_SQRT1_2;
00223 } else if (out_layout & AV_CH_FRONT_LEFT) {
00224 if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
00225 matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
00226 matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
00227 matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
00228 matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
00229 } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
00230 matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
00231 matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
00232 matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
00233 matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
00234 } else {
00235 matrix[FRONT_LEFT ][SIDE_LEFT ] += surround_mix_level;
00236 matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
00237 }
00238 } else if (out_layout & AV_CH_FRONT_CENTER) {
00239 matrix[FRONT_CENTER][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
00240 matrix[FRONT_CENTER][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
00241 } else
00242 return AVERROR_PATCHWELCOME;
00243 }
00244
00245 if (unaccounted & AV_CH_FRONT_LEFT_OF_CENTER) {
00246 if (out_layout & AV_CH_FRONT_LEFT) {
00247 matrix[FRONT_LEFT ][FRONT_LEFT_OF_CENTER ] += 1.0;
00248 matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER] += 1.0;
00249 } else if (out_layout & AV_CH_FRONT_CENTER) {
00250 matrix[FRONT_CENTER][FRONT_LEFT_OF_CENTER ] += M_SQRT1_2;
00251 matrix[FRONT_CENTER][FRONT_RIGHT_OF_CENTER] += M_SQRT1_2;
00252 } else
00253 return AVERROR_PATCHWELCOME;
00254 }
00255
00256 if (unaccounted & AV_CH_LOW_FREQUENCY) {
00257 if (out_layout & AV_CH_FRONT_CENTER) {
00258 matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level;
00259 } else if (out_layout & AV_CH_FRONT_LEFT) {
00260 matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
00261 matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
00262 } else
00263 return AVERROR_PATCHWELCOME;
00264 }
00265
00266
00267
00268 for (out_i = i = 0; out_i < out_channels && i < 64; i++) {
00269 double sum = 0;
00270 for (out_j = j = 0; out_j < in_channels && j < 64; j++) {
00271 matrix_out[out_i * stride + out_j] = matrix[i][j];
00272 sum += fabs(matrix[i][j]);
00273 if (in_layout & (1ULL << j))
00274 out_j++;
00275 }
00276 maxcoef = FFMAX(maxcoef, sum);
00277 if (out_layout & (1ULL << i))
00278 out_i++;
00279 }
00280
00281
00282 if (normalize && maxcoef > 1.0) {
00283 for (i = 0; i < out_channels; i++)
00284 for (j = 0; j < in_channels; j++)
00285 matrix_out[i * stride + j] /= maxcoef;
00286 }
00287
00288 return 0;
00289 }
00290
00291 int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
00292 int stride)
00293 {
00294 int in_channels, out_channels, i, o;
00295
00296 in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
00297 out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
00298
00299 if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS ||
00300 out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
00301 av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
00302 return AVERROR(EINVAL);
00303 }
00304
00305 switch (avr->mix_coeff_type) {
00306 case AV_MIX_COEFF_TYPE_Q8:
00307 if (!avr->am->matrix_q8[0]) {
00308 av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
00309 return AVERROR(EINVAL);
00310 }
00311 for (o = 0; o < out_channels; o++)
00312 for (i = 0; i < in_channels; i++)
00313 matrix[o * stride + i] = avr->am->matrix_q8[o][i] / 256.0;
00314 break;
00315 case AV_MIX_COEFF_TYPE_Q15:
00316 if (!avr->am->matrix_q15[0]) {
00317 av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
00318 return AVERROR(EINVAL);
00319 }
00320 for (o = 0; o < out_channels; o++)
00321 for (i = 0; i < in_channels; i++)
00322 matrix[o * stride + i] = avr->am->matrix_q15[o][i] / 32768.0;
00323 break;
00324 case AV_MIX_COEFF_TYPE_FLT:
00325 if (!avr->am->matrix_flt[0]) {
00326 av_log(avr, AV_LOG_ERROR, "matrix is not set\n");
00327 return AVERROR(EINVAL);
00328 }
00329 for (o = 0; o < out_channels; o++)
00330 for (i = 0; i < in_channels; i++)
00331 matrix[o * stride + i] = avr->am->matrix_flt[o][i];
00332 break;
00333 default:
00334 av_log(avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
00335 return AVERROR(EINVAL);
00336 }
00337
00338 return 0;
00339 }
00340
00341 int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
00342 int stride)
00343 {
00344 int in_channels, out_channels, i, o;
00345
00346 in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
00347 out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout);
00348
00349 if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS ||
00350 out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) {
00351 av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n");
00352 return AVERROR(EINVAL);
00353 }
00354
00355 if (avr->am->matrix) {
00356 av_free(avr->am->matrix[0]);
00357 avr->am->matrix = NULL;
00358 }
00359
00360 #define CONVERT_MATRIX(type, expr) \
00361 avr->am->matrix_## type[0] = av_mallocz(out_channels * in_channels * \
00362 sizeof(*avr->am->matrix_## type[0])); \
00363 if (!avr->am->matrix_## type[0]) \
00364 return AVERROR(ENOMEM); \
00365 for (o = 0; o < out_channels; o++) { \
00366 if (o > 0) \
00367 avr->am->matrix_## type[o] = avr->am->matrix_## type[o - 1] + \
00368 in_channels; \
00369 for (i = 0; i < in_channels; i++) { \
00370 double v = matrix[o * stride + i]; \
00371 avr->am->matrix_## type[o][i] = expr; \
00372 } \
00373 } \
00374 avr->am->matrix = (void **)avr->am->matrix_## type;
00375
00376 switch (avr->mix_coeff_type) {
00377 case AV_MIX_COEFF_TYPE_Q8:
00378 CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
00379 break;
00380 case AV_MIX_COEFF_TYPE_Q15:
00381 CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
00382 break;
00383 case AV_MIX_COEFF_TYPE_FLT:
00384 CONVERT_MATRIX(flt, v)
00385 break;
00386 default:
00387 av_log(avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
00388 return AVERROR(EINVAL);
00389 }
00390
00391
00392
00393
00394
00395 avr->am->in_layout = avr->in_channel_layout;
00396 avr->am->out_layout = avr->out_channel_layout;
00397 avr->am->in_channels = in_channels;
00398 avr->am->out_channels = out_channels;
00399
00400 return 0;
00401 }