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