diff options
author | Paul B Mahol <onemda@gmail.com> | 2022-02-19 13:38:56 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2022-02-19 13:45:47 +0100 |
commit | c439c6b191f731e28e5374ecc720a86af1e14308 (patch) | |
tree | e994c9183210474284de421607beb8c18a99643a | |
parent | 1372b30db2d5b4565376a168d7d806c56f3d96f1 (diff) | |
download | ffmpeg-c439c6b191f731e28e5374ecc720a86af1e14308.tar.gz |
avfilter/af_headphone: improve stereo hrir support
Until now, in some cases produced output would be wrong.
-rw-r--r-- | libavfilter/af_headphone.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/libavfilter/af_headphone.c b/libavfilter/af_headphone.c index b2030dbbbb..aea861aa04 100644 --- a/libavfilter/af_headphone.c +++ b/libavfilter/af_headphone.c @@ -82,7 +82,9 @@ typedef struct HeadphoneContext { int ir_len; int eof; } hrir_in[64]; + uint64_t map_channel_layout; uint64_t mapping[64]; + uint8_t hrir_map[64]; } HeadphoneContext; static int parse_channel_name(const char *arg, uint64_t *rchannel) @@ -118,6 +120,7 @@ static void parse_map(AVFilterContext *ctx) s->mapping[s->nb_irs] = out_channel; s->nb_irs++; } + s->map_channel_layout = used_channels; if (s->hrir_fmt == HRIR_MULTI) s->nb_hrir_inputs = 1; @@ -262,7 +265,7 @@ static int headphone_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr, } offset = i * n_fft; - hrtf_offset = hrtf + offset; + hrtf_offset = hrtf + s->hrir_map[i] * n_fft; memset(fft_in, 0, sizeof(AVComplexFloat) * n_fft); @@ -361,6 +364,7 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) struct HeadphoneContext *s = ctx->priv; const int ir_len = s->ir_len; int nb_input_channels = ctx->inputs[0]->channels; + const int nb_hrir_channels = s->nb_hrir_inputs == 1 ? ctx->inputs[1]->channels : s->nb_hrir_inputs * 2; float gain_lin = expf((s->gain - 3 * nb_input_channels) / 20 * M_LN10); AVFrame *frame; int ret = 0; @@ -426,15 +430,15 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) s->temp_src[0] = av_calloc(s->air_len, sizeof(float)); s->temp_src[1] = av_calloc(s->air_len, sizeof(float)); - s->data_ir[0] = av_calloc(nb_input_channels * s->air_len, sizeof(*s->data_ir[0])); - s->data_ir[1] = av_calloc(nb_input_channels * s->air_len, sizeof(*s->data_ir[1])); + s->data_ir[0] = av_calloc(nb_hrir_channels * s->air_len, sizeof(*s->data_ir[0])); + s->data_ir[1] = av_calloc(nb_hrir_channels * s->air_len, sizeof(*s->data_ir[1])); if (!s->data_ir[0] || !s->data_ir[1] || !s->temp_src[0] || !s->temp_src[1]) { ret = AVERROR(ENOMEM); goto fail; } } else { - s->data_hrtf[0] = av_calloc(n_fft, sizeof(*s->data_hrtf[0]) * nb_input_channels); - s->data_hrtf[1] = av_calloc(n_fft, sizeof(*s->data_hrtf[1]) * nb_input_channels); + s->data_hrtf[0] = av_calloc(n_fft, sizeof(*s->data_hrtf[0]) * nb_hrir_channels); + s->data_hrtf[1] = av_calloc(n_fft, sizeof(*s->data_hrtf[1]) * nb_hrir_channels); if (!s->data_hrtf[0] || !s->data_hrtf[1]) { ret = AVERROR(ENOMEM); goto fail; @@ -451,10 +455,12 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) ptr = (float *)frame->extended_data[0]; if (s->hrir_fmt == HRIR_STEREO) { - int idx = av_get_channel_layout_channel_index(inlink->channel_layout, + int idx = av_get_channel_layout_channel_index(s->map_channel_layout, s->mapping[i]); if (idx < 0) continue; + + s->hrir_map[i] = idx; if (s->type == TIME_DOMAIN) { float *data_ir_l = s->data_ir[0] + idx * s->air_len; float *data_ir_r = s->data_ir[1] + idx * s->air_len; @@ -486,6 +492,7 @@ static int convert_coeffs(AVFilterContext *ctx, AVFilterLink *inlink) if (idx < 0) continue; + s->hrir_map[k] = idx; I = k * 2; if (s->type == TIME_DOMAIN) { float *data_ir_l = s->data_ir[0] + idx * s->air_len; |