71#define OFFSET(x) offsetof(SpectrumSynthContext, x)
72#define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
73#define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
76 {
"sample_rate",
"set sample rate",
OFFSET(sample_rate),
AV_OPT_TYPE_INT, {.i64 = 44100}, 15, INT_MAX,
A },
156 "Magnitude and Phase sizes differ (%dx%d vs %dx%d).\n",
158 ctx->inputs[1]->w,
ctx->inputs[1]->h);
160 }
else if (
av_cmp_q(time_base,
ctx->inputs[1]->time_base) != 0) {
162 "Magnitude and Phase time bases differ (%d/%d vs %d/%d).\n",
163 time_base.
num, time_base.
den,
164 ctx->inputs[1]->time_base.num,
165 ctx->inputs[1]->time_base.den);
169 "Magnitude and Phase framerates differ (%d/%d vs %d/%d).\n",
170 frame_rate.
num, frame_rate.
den,
179 s->win_size =
s->size * 2;
180 s->nb_freq =
s->size;
185 "The window size might be too high.\n");
192 s->fft_out =
av_calloc(
s->channels,
sizeof(*
s->fft_out));
196 for (ch = 0; ch <
s->channels; ch++) {
212 sizeof(*
s->window_func_lut));
213 if (!
s->window_func_lut)
217 s->overlap = overlap;
218 s->hop_size = (1 -
s->overlap) *
s->win_size;
219 for (
factor = 0,
i = 0;
i <
s->win_size;
i++) {
220 factor +=
s->window_func_lut[
i] *
s->window_func_lut[
i];
222 s->factor = (
factor /
s->win_size) /
FFMAX(1 / (1 -
s->overlap) - 1, 1);
228 int x,
int y,
int f,
int ch)
230 const int m_linesize =
s->magnitude->linesize[0];
231 const int p_linesize =
s->phase->linesize[0];
232 const uint16_t *m = (uint16_t *)(
s->magnitude->data[0] + y * m_linesize);
233 const uint16_t *p = (uint16_t *)(
s->phase->data[0] + y * p_linesize);
234 float magnitude, phase;
238 magnitude = m[x] / (
double)UINT16_MAX;
241 magnitude =
ff_exp10(((m[x] / (
double)UINT16_MAX) - 1.) * 6.);
246 phase = ((p[x] / (
double)UINT16_MAX) * 2. - 1.) *
M_PI;
248 s->fft_in[ch][
f].re = magnitude * cos(phase);
249 s->fft_in[ch][
f].im = magnitude * sin(phase);
253 int x,
int y,
int f,
int ch)
255 const int m_linesize =
s->magnitude->linesize[0];
256 const int p_linesize =
s->phase->linesize[0];
257 const uint8_t *m = (uint8_t *)(
s->magnitude->data[0] + y * m_linesize);
258 const uint8_t *p = (uint8_t *)(
s->phase->data[0] + y * p_linesize);
259 float magnitude, phase;
263 magnitude = m[x] / (
double)UINT8_MAX;
266 magnitude =
ff_exp10(((m[x] / (
double)UINT8_MAX) - 1.) * 6.);
271 phase = ((p[x] / (
double)UINT8_MAX) * 2. - 1.) *
M_PI;
273 s->fft_in[ch][
f].re = magnitude * cos(phase);
274 s->fft_in[ch][
f].im = magnitude * sin(phase);
281 int start =
h * (
s->channels - ch) - 1;
282 int end =
h * (
s->channels - ch - 1);
285 switch (
s->orientation) {
290 for (y = start,
f = 0; y >= end; y--,
f++) {
297 for (y = start,
f = 0; y >= end; y--,
f++) {
307 for (y = end,
f = 0; y <= start; y++,
f++) {
314 for (y = end,
f = 0; y <= start; y++,
f++) {
326 const int h =
s->size;
327 int nb =
s->win_size;
330 for (ch = 0; ch <
s->channels; ch++) {
333 for (y =
h; y <=
s->nb_freq; y++) {
334 s->fft_in[ch][y].re = 0;
335 s->fft_in[ch][y].im = 0;
338 for (y =
s->nb_freq + 1,
f =
s->nb_freq - 1; y < nb; y++,
f--) {
339 s->fft_in[ch][y].re =
s->fft_in[ch][
f].re;
340 s->fft_in[ch][y].im = -
s->fft_in[ch][
f].im;
351 const float factor =
s->factor;
358 for (ch = 0; ch <
s->channels; ch++) {
359 float *buf = (
float *)
s->buffer->extended_data[ch];
365 for (
i = 0, j = start; j < k &&
i <
s->win_size;
i++, j++) {
366 buf[j] +=
s->fft_out[ch][
i].re;
369 for (;
i <
s->win_size;
i++, j++) {
370 buf[j] =
s->fft_out[ch][
i].re;
373 start +=
s->hop_size;
376 if (start >=
s->win_size) {
377 start -=
s->win_size;
380 if (ch ==
s->channels - 1) {
392 s->pts +=
s->win_size;
393 for (
c = 0;
c <
s->channels;
c++) {
394 dst = (
float *)
out->extended_data[
c];
395 buf = (
float *)
s->buffer->extended_data[
c];
397 for (n = 0; n <
s->win_size; n++) {
400 memmove(buf, buf +
s->win_size,
s->win_size * 4);
421 if (!(
s->magnitude &&
s->phase))
424 switch (
s->sliding) {
428 if (
s->xpos >=
s->xend)
432 s->xpos =
s->xend - 1;
440 for (x = 0; x <
s->xend; x++) {
458 AVFrame **staging[2] = { &
s->magnitude, &
s->phase };
464 for (
i = 0;
i < 2;
i++) {
476 for (
i = 0;
i < 2;
i++) {
485 for (
i = 0;
i < 2;
i++) {
506 for (
i = 0;
i <
s->channels;
i++)
510 for (
i = 0;
i <
s->channels;
i++)
538 .p.name =
"spectrumsynth",
540 .p.priv_class = &spectrumsynth_class,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static enum AVSampleFormat sample_fmts[]
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
const FFFilter ff_vaf_spectrumsynth
static AVFormatContext * ctx
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
void ff_inlink_set_status(AVFilterLink *link, int status)
Set the status on an input link.
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
static const uint16_t channel_layouts[7]
static const int sample_rates[]
internal math functions header
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
AVSampleFormat
Audio sample formats.
@ AV_SAMPLE_FMT_FLTP
float, planar
static void scale(int *out, const int *in, const int w, const int h, const int shift)
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
static FilterLink * ff_filter_link(AVFilterLink *link)
#define AVFILTER_DEFINE_CLASS(fname)
#define FILTER_QUERY_FUNC2(func)
static const int factor[16]
size_t av_cpu_max_align(void)
Get the maximum data alignment that may be required by FFmpeg.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
#define AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_YUV444P16
Describe the class of an AVClass context structure.
A list of supported channel layouts.
A link between two filters.
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
int sample_rate
samples per second
int format
agreed upon media format
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
Rational number (pair of numerator and denominator).
Link properties exposed to filter code, but not external callers.
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable.
float * window_func_lut
Window function LUT.
AVTXContext * fft
Fast Fourier Transform context.
AVComplexFloat ** fft_in
bins holder for each (displayed) channels
AVComplexFloat ** fft_out
bins holder for each (displayed) channels
#define av_realloc_f(p, o, n)
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
@ AV_TX_FLOAT_FFT
Standard complex to complex FFT with sample data type of AVComplexFloat, AVComplexDouble or AVComplex...
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
static void synth_window(AVFilterContext *ctx, int x)
static int try_push_frame(AVFilterContext *ctx, int x)
static int try_push_frames(AVFilterContext *ctx)
static const AVOption spectrumsynth_options[]
static void read8_fft_bin(SpectrumSynthContext *s, int x, int y, int f, int ch)
static const AVFilterPad spectrumsynth_inputs[]
static void read16_fft_bin(SpectrumSynthContext *s, int x, int y, int f, int ch)
static void read_fft_data(AVFilterContext *ctx, int x, int h, int ch)
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static int activate(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
static int config_output(AVFilterLink *outlink)
static const AVFilterPad spectrumsynth_outputs[]
#define WIN_FUNC_OPTION(win_func_opt_name, win_func_offset, flag, default_window_func)
static void generate_window_func(float *lut, int N, int win_func, float *overlap)