[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