int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix, int stride) { int in_channels, out_channels, i, o; if (avr->am) return ff_audio_mix_set_matrix(avr->am, matrix, stride); in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout); out_channels = av_get_channel_layout_nb_channels(avr->out_channel_layout); if ( in_channels <= 0 || in_channels > AVRESAMPLE_MAX_CHANNELS || out_channels <= 0 || out_channels > AVRESAMPLE_MAX_CHANNELS) { av_log(avr, AV_LOG_ERROR, "Invalid channel layouts\n"); return AVERROR(EINVAL); } if (avr->mix_matrix) av_freep(&avr->mix_matrix); avr->mix_matrix = av_malloc(in_channels * out_channels * sizeof(*avr->mix_matrix)); if (!avr->mix_matrix) return AVERROR(ENOMEM); for (o = 0; o < out_channels; o++) for (i = 0; i < in_channels; i++) avr->mix_matrix[o * in_channels + i] = matrix[o * stride + i]; return 0; }
AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr) { AudioMix *am; int ret; am = av_mallocz(sizeof(*am)); if (!am) return NULL; am->avr = avr; if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P && avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP) { av_log(avr, AV_LOG_ERROR, "Unsupported internal format for " "mixing: %s\n", av_get_sample_fmt_name(avr->internal_sample_fmt)); goto error; } am->fmt = avr->internal_sample_fmt; am->coeff_type = avr->mix_coeff_type; am->in_layout = avr->in_channel_layout; am->out_layout = avr->out_channel_layout; am->in_channels = avr->in_channels; am->out_channels = avr->out_channels; /* build matrix if the user did not already set one */ if (avr->mix_matrix) { ret = ff_audio_mix_set_matrix(am, avr->mix_matrix, avr->in_channels); if (ret < 0) goto error; av_freep(&avr->mix_matrix); } else { double *matrix_dbl = av_mallocz(avr->out_channels * avr->in_channels * sizeof(*matrix_dbl)); if (!matrix_dbl) goto error; ret = avresample_build_matrix(avr->in_channel_layout, avr->out_channel_layout, avr->center_mix_level, avr->surround_mix_level, avr->lfe_mix_level, avr->normalize_mix_level, matrix_dbl, avr->in_channels, avr->matrix_encoding); if (ret < 0) { av_free(matrix_dbl); goto error; } ret = ff_audio_mix_set_matrix(am, matrix_dbl, avr->in_channels); if (ret < 0) { av_log(avr, AV_LOG_ERROR, "error setting mix matrix\n"); av_free(matrix_dbl); goto error; } av_free(matrix_dbl); } return am; error: av_free(am); return NULL; }
AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr) { AudioMix *am; int ret; am = av_mallocz(sizeof(*am)); if (!am) return NULL; am->avr = avr; if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P && avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP) { av_log(avr, AV_LOG_ERROR, "Unsupported internal format for " "mixing: %s\n", av_get_sample_fmt_name(avr->internal_sample_fmt)); goto error; } am->fmt = avr->internal_sample_fmt; am->coeff_type = avr->mix_coeff_type; am->in_layout = avr->in_channel_layout; am->out_layout = avr->out_channel_layout; am->in_channels = avr->in_channels; am->out_channels = avr->out_channels; /* build matrix if the user did not already set one */ if (avr->mix_matrix) { ret = ff_audio_mix_set_matrix(am, avr->mix_matrix, avr->in_channels); if (ret < 0) goto error; av_freep(&avr->mix_matrix); } else { int i, j; char in_layout_name[128]; char out_layout_name[128]; double *matrix_dbl = av_mallocz(avr->out_channels * avr->in_channels * sizeof(*matrix_dbl)); if (!matrix_dbl) goto error; ret = avresample_build_matrix(avr->in_channel_layout, avr->out_channel_layout, avr->center_mix_level, avr->surround_mix_level, avr->lfe_mix_level, avr->normalize_mix_level, matrix_dbl, avr->in_channels, avr->matrix_encoding); if (ret < 0) { av_free(matrix_dbl); goto error; } av_get_channel_layout_string(in_layout_name, sizeof(in_layout_name), avr->in_channels, avr->in_channel_layout); av_get_channel_layout_string(out_layout_name, sizeof(out_layout_name), avr->out_channels, avr->out_channel_layout); av_log(avr, AV_LOG_DEBUG, "audio_mix: %s to %s\n", in_layout_name, out_layout_name); for (i = 0; i < avr->out_channels; i++) { for (j = 0; j < avr->in_channels; j++) { av_log(avr, AV_LOG_DEBUG, " %0.3f ", matrix_dbl[i * avr->in_channels + j]); } av_log(avr, AV_LOG_DEBUG, "\n"); } ret = ff_audio_mix_set_matrix(am, matrix_dbl, avr->in_channels); if (ret < 0) { av_free(matrix_dbl); goto error; } av_free(matrix_dbl); } return am; error: av_free(am); return NULL; }