static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; ShowFreqsContext *s = ctx->priv; AVFrame *fin = NULL; int ret = 0; av_audio_fifo_write(s->fifo, (void **)in->extended_data, in->nb_samples); while (av_audio_fifo_size(s->fifo) >= s->win_size) { fin = ff_get_audio_buffer(inlink, s->win_size); if (!fin) { ret = AVERROR(ENOMEM); goto fail; } fin->pts = s->pts; s->pts += s->skip_samples; ret = av_audio_fifo_peek(s->fifo, (void **)fin->extended_data, s->win_size); if (ret < 0) goto fail; ret = plot_freqs(inlink, fin); av_frame_free(&fin); av_audio_fifo_drain(s->fifo, s->skip_samples); if (ret < 0) goto fail; } fail: av_frame_free(&fin); av_frame_free(&in); return ret; }
static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; AudioSurroundContext *s = ctx->priv; av_audio_fifo_write(s->fifo, (void **)in->extended_data, in->nb_samples); if (s->pts == AV_NOPTS_VALUE) s->pts = in->pts; av_frame_free(&in); while (av_audio_fifo_size(s->fifo) >= s->buf_size) { AVFrame *out; int ret; ret = av_audio_fifo_peek(s->fifo, (void **)s->input->extended_data, s->buf_size); if (ret < 0) return ret; ctx->internal->execute(ctx, fft_channel, NULL, NULL, inlink->channels); s->filter(ctx); out = ff_get_audio_buffer(outlink, s->hop_size); if (!out) return AVERROR(ENOMEM); ctx->internal->execute(ctx, ifft_channel, out, NULL, outlink->channels); out->pts = s->pts; if (s->pts != AV_NOPTS_VALUE) s->pts += av_rescale_q(out->nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base); av_audio_fifo_drain(s->fifo, s->hop_size); ret = ff_filter_frame(outlink, out); if (ret < 0) return ret; } return 0; }
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. / s->win_scale; 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) { if (!in) { 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_NBBINS] = window_size / 2; 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 fr, fi; values[VAR_BIN] = n; fr = av_expr_eval(s->real[ch], values, s); fi = av_expr_eval(s->imag[ch], values, s); fft_data[n].re *= fr; fft_data[n].im *= fi; } 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; } start += s->hop_size; end = j; } s->start = start; s->end = end; if (start >= window_size) { float *dst, *buf; start -= window_size; end -= window_size; s->start = start; s->end = end; out = ff_get_audio_buffer(outlink, window_size); if (!out) { ret = AVERROR(ENOMEM); break; } out->pts = s->pts; s->pts += window_size; for (ch = 0; ch < inlink->channels; ch++) { dst = (float *)out->extended_data[ch]; buf = (float *)s->buffer->extended_data[ch]; for (n = 0; n < window_size; n++) { dst[n] = buf[n] * (1 - s->overlap); } memmove(buf, buf + window_size, window_size * 4); } ret = ff_filter_frame(outlink, out); if (ret < 0) break; } av_audio_fifo_drain(s->fifo, s->hop_size); } av_frame_free(&in); return ret; }