[FFmpeg-devel] [PATCH] avfilter: add afftfilter

Michael Niedermayer michael at niedermayer.cc
Mon Jan 18 11:53:17 CET 2016


On Sat, Jan 16, 2016 at 09:09:21PM +0100, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
[...]
> +static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
> +{
> +    AVFilterContext *ctx = inlink->dst;
> +    AVFilterLink *outlink = ctx->outputs[0];
> +    AFFTFiltContext *s = ctx->priv;
> +    const int window_size = s->window_size;
> +    const float f = 1. / window_size;
> +    double values[VAR_VARS_NB];
> +    AVFrame *out, *in = NULL;
> +    int ch, n, ret, i, j, k;
> +    int start = s->start, end = s->end;
> +
> +    av_audio_fifo_write(s->fifo, (void **)frame->extended_data, frame->nb_samples);
> +    av_frame_free(&frame);
> +
> +    while (av_audio_fifo_size(s->fifo) >= window_size) {
> +        in = ff_get_audio_buffer(outlink, window_size);
> +        if (!in)
> +            return AVERROR(ENOMEM);
> +
> +        ret = av_audio_fifo_peek(s->fifo, (void **)in->extended_data, window_size);
> +        if (ret < 0)
> +            break;
> +
> +        for (ch = 0; ch < inlink->channels; ch++) {
> +            const float *src = (float *)in->extended_data[ch];
> +            FFTComplex *fft_data = s->fft_data[ch];
> +
> +            for (n = 0; n < in->nb_samples; n++) {
> +                fft_data[n].re = src[n] * s->window_func_lut[n];
> +                fft_data[n].im = 0;
> +            }
> +
> +            for (; n < window_size; n++) {
> +                fft_data[n].re = 0;
> +                fft_data[n].im = 0;
> +            }
> +        }
> +
> +        values[VAR_PTS]         = s->pts;
> +        values[VAR_SAMPLE_RATE] = inlink->sample_rate;
> +        values[VAR_CHANNELS]    = inlink->channels;
> +
> +        for (ch = 0; ch < inlink->channels; ch++) {
> +            FFTComplex *fft_data = s->fft_data[ch];
> +            float *buf = (float *)s->buffer->extended_data[ch];
> +            int x;
> +
> +            values[VAR_CHANNEL] = ch;
> +
> +            av_fft_permute(s->fft, fft_data);
> +            av_fft_calc(s->fft, fft_data);
> +
> +            for (n = 0; n < window_size / 2; n++) {
> +                float ff;
> +
> +                values[VAR_BIN] = n;
> +
> +                ff = av_expr_eval(s->expr[ch], values, s);
> +                fft_data[n].re *= ff;
> +                fft_data[n].im *= ff;

if you use a complex valued FFT then allowing complex values from the
user somehow could make sense
maybe a real / imag expr


> +            }
> +
> +            for (n = window_size / 2 + 1, x = window_size / 2 - 1; n < window_size; n++, x--) {
> +                fft_data[n].re =  fft_data[x].re;
> +                fft_data[n].im = -fft_data[x].im;
> +            }
> +
> +            av_fft_permute(s->ifft, fft_data);
> +            av_fft_calc(s->ifft, fft_data);
> +
> +            start = s->start;
> +            end = s->end;
> +            k = end;

> +            for (i = 0, j = start; j < k && i < window_size; i++, j++) {
> +                buf[j] += s->fft_data[ch][i].re * f;
> +            }
> +
> +            for (; i < window_size; i++, j++) {
> +                buf[j] = s->fft_data[ch][i].re * f;
> +            }

rescaling by a constant can likely be merged into something
(window or expr based coeffs)

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The bravest are surely those who have the clearest vision
of what is before them, glory and danger alike, and yet
notwithstanding go out to meet it. -- Thucydides
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20160118/393746bc/attachment.sig>


More information about the ffmpeg-devel mailing list