On Sat, Jan 16, 2016 at 09:09:21PM +0100, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol <[email protected]> [...] > +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
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list [email protected] http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
