[FFmpeg-devel] [PATCH] avfilter: add arbitrary audio FIR filter

Paul B Mahol onemda at gmail.com
Mon May 1 11:32:12 EEST 2017


On 5/1/17, Muhammad Faiz <mfcc64 at gmail.com> wrote:
> On Mon, May 1, 2017 at 5:02 AM, Paul B Mahol <onemda at gmail.com> wrote:

[...]

>> +
>> +        for (ch = 0; ch < s->nb_channels; ch++) {
>> +            dst = (float *)out->extended_data[ch];
>> +            buf = (float *)s->buffer->extended_data[ch];
>> +
>> +            for (n = 0; n < s->fft_length; n++)
>> +                dst[n] = buf[n];
>> +            memmove(buf, buf + s->fft_length, s->fft_length * 4);
>> +        }
>
> Is this overlap-save?
>

Yes.

>
>
>> +
>> +        ret = ff_filter_frame(outlink, out);
>> +    }
>> +
>> +    av_audio_fifo_drain(s->fifo[0], s->hop_size);
>> +    av_frame_free(&s->in[0]);
>> +
>> +    return ret;
>> +}
>> +
>> +static int convert_coeffs(AVFilterContext *ctx)
>> +{
>> +    FIRContext *s = ctx->priv;
>> +    int ch, n;
>> +
>> +    s->nb_taps = av_audio_fifo_size(s->fifo[1]);
>> +    if (s->nb_taps > 131072) {
>> +        av_log(ctx, AV_LOG_ERROR, "Too big number of taps: %d >
>> 131072.\n", s->nb_taps);
>> +        return AVERROR(EINVAL);
>> +    }
>> +
>> +    for (n = 1; (1 << n) < s->nb_taps; n++);
>> +    s->n = n;
>> +    s->fft_length = 1 << s->n;
>> +
>> +    for (ch = 0; ch < ctx->inputs[0]->channels; ch++) {
>> +        s->fft_data[ch] = av_calloc(s->fft_length,
>> sizeof(**s->fft_data));
>> +        if (!s->fft_data[ch])
>> +            return AVERROR(ENOMEM);
>> +    }
>> +
>> +    for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
>> +        s->fft_coef[ch] = av_calloc(s->fft_length,
>> sizeof(**s->fft_coef));
>> +        if (!s->fft_coef[ch])
>> +            return AVERROR(ENOMEM);
>> +    }
>> +
>> +    s->hop_size = s->nb_taps / 4;
>
> In theory, hop_size should be <= fft_length - nb_taps + 1

Fixed.

>
>
>
>> +    if (s->hop_size <= 0) {
>> +        av_log(ctx, AV_LOG_ERROR, "Too small number of taps: %d < 4.\n",
>> s->nb_taps);
>> +        return AVERROR(EINVAL);
>> +    }
>> +
>> +    s->buffer = ff_get_audio_buffer(ctx->inputs[0], s->fft_length * 2);
>> +    if (!s->buffer)
>> +        return AVERROR(ENOMEM);
>> +
>> +    s->fft  = av_fft_init(s->n, 0);
>> +    s->ifft = av_fft_init(s->n, 1);
>> +    if (!s->fft || !s->ifft)
>> +        return AVERROR(ENOMEM);
>> +
>> +    s->in[1] = ff_get_audio_buffer(ctx->inputs[1], s->nb_taps);
>> +    if (!s->in[1])
>> +        return AVERROR(ENOMEM);
>> +
>> +    av_audio_fifo_read(s->fifo[1], (void **)s->in[1]->data, s->nb_taps);
>> +    for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
>> +        FFTComplex *fft_coef = s->fft_coef[ch];
>> +        const float *re = (const float *)s->in[1]->extended_data[0 +
>> !s->one2many * ch];
>> +        const float *im = (const float *)s->in[1]->extended_data[1 +
>> !s->one2many * ch];
>
> What is the meaning of imaginary coeffs in time domain?

Removed.


See new patch.


More information about the ffmpeg-devel mailing list