72 #define OFFSET(x) offsetof(SpectrumSynthContext, x)
73 #define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
74 #define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
162 "Magnitude and Phase sizes differ (%dx%d vs %dx%d).\n",
164 ctx->inputs[1]->w,
ctx->inputs[1]->h);
166 }
else if (
av_cmp_q(time_base,
ctx->inputs[1]->time_base) != 0) {
168 "Magnitude and Phase time bases differ (%d/%d vs %d/%d).\n",
169 time_base.
num, time_base.
den,
170 ctx->inputs[1]->time_base.num,
171 ctx->inputs[1]->time_base.den);
173 }
else if (
av_cmp_q(frame_rate,
ctx->inputs[1]->frame_rate) != 0) {
175 "Magnitude and Phase framerates differ (%d/%d vs %d/%d).\n",
176 frame_rate.
num, frame_rate.
den,
177 ctx->inputs[1]->frame_rate.num,
178 ctx->inputs[1]->frame_rate.den);
185 for (fft_bits = 1; 1 << fft_bits < 2 *
s->size; fft_bits++);
187 s->win_size = 1 << fft_bits;
188 s->nb_freq = 1 << (fft_bits - 1);
193 "The window size might be too high.\n");
196 s->fft_data =
av_calloc(
s->channels,
sizeof(*
s->fft_data));
199 for (ch = 0; ch <
s->channels; ch++) {
200 s->fft_data[ch] =
av_calloc(
s->win_size,
sizeof(**
s->fft_data));
201 if (!
s->fft_data[ch])
211 sizeof(*
s->window_func_lut));
212 if (!
s->window_func_lut)
216 s->overlap = overlap;
217 s->hop_size = (1 -
s->overlap) *
s->win_size;
219 factor +=
s->window_func_lut[
i] *
s->window_func_lut[
i];
221 s->factor = (
factor /
s->win_size) /
FFMAX(1 / (1 -
s->overlap) - 1, 1);
227 int x,
int y,
int f,
int ch)
229 const int m_linesize =
s->magnitude->linesize[0];
230 const int p_linesize =
s->phase->linesize[0];
231 const uint16_t *m = (uint16_t *)(
s->magnitude->data[0] + y * m_linesize);
232 const uint16_t *p = (uint16_t *)(
s->phase->data[0] + y * p_linesize);
233 float magnitude, phase;
237 magnitude = m[x] / (double)UINT16_MAX;
240 magnitude =
ff_exp10(((m[x] / (
double)UINT16_MAX) - 1.) * 6.);
245 phase = ((p[x] / (double)UINT16_MAX) * 2. - 1.) *
M_PI;
247 s->fft_data[ch][
f].re = magnitude * cos(phase);
248 s->fft_data[ch][
f].im = magnitude * sin(phase);
252 int x,
int y,
int f,
int ch)
254 const int m_linesize =
s->magnitude->linesize[0];
255 const int p_linesize =
s->phase->linesize[0];
256 const uint8_t *m = (
uint8_t *)(
s->magnitude->data[0] + y * m_linesize);
258 float magnitude, phase;
262 magnitude = m[x] / (double)UINT8_MAX;
265 magnitude =
ff_exp10(((m[x] / (
double)UINT8_MAX) - 1.) * 6.);
270 phase = ((p[x] / (double)UINT8_MAX) * 2. - 1.) *
M_PI;
272 s->fft_data[ch][
f].re = magnitude * cos(phase);
273 s->fft_data[ch][
f].im = magnitude * sin(phase);
280 int start =
h * (
s->channels - ch) - 1;
281 int end =
h * (
s->channels - ch - 1);
284 switch (
s->orientation) {
289 for (y = start,
f = 0; y >= end; y--,
f++) {
296 for (y = start,
f = 0; y >= end; y--,
f++) {
306 for (y = end,
f = 0; y <= start; y++,
f++) {
313 for (y = end,
f = 0; y <= start; y++,
f++) {
325 const int h =
s->size;
326 int nb =
s->win_size;
329 for (ch = 0; ch <
s->channels; ch++) {
332 for (y =
h; y <=
s->nb_freq; y++) {
333 s->fft_data[ch][y].re = 0;
334 s->fft_data[ch][y].im = 0;
337 for (y =
s->nb_freq + 1,
f =
s->nb_freq - 1; y < nb; y++,
f--) {
338 s->fft_data[ch][y].re =
s->fft_data[ch][
f].re;
339 s->fft_data[ch][y].im = -
s->fft_data[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_data[ch][
i].re;
369 for (;
i <
s->win_size;
i++, j++) {
370 buf[j] =
s->fft_data[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++) {
504 for (
i = 0;
i <
s->channels;
i++)
533 .
name =
"spectrumsynth",
541 .priv_class = &spectrumsynth_class,
static enum AVSampleFormat sample_fmts[]
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
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.
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.
audio channel layout utility functions
internal math functions header
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
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.
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
static int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
av_cold void av_fft_end(FFTContext *s)
#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.
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
AVSampleFormat
Audio sample formats.
@ AV_SAMPLE_FMT_FLTP
float, planar
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
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.
AVFilterFormatsConfig incfg
Lists of supported formats / etc.
AVFilterFormatsConfig outcfg
Lists of supported formats / etc.
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.
const char * name
Pad name.
const char * name
Filter name.
This structure describes decoded (raw) audio or video data.
Rational number (pair of numerator and denominator).
float * window_func_lut
Window function LUT.
int fft_bits
number of bits (FFT window size = 1<<fft_bits)
FFTContext * fft
Fast Fourier Transform context.
FFTComplex ** fft_data
bins holder for each (displayed) channels
#define av_realloc_f(p, o, n)
static void synth_window(AVFilterContext *ctx, int x)
static int try_push_frame(AVFilterContext *ctx, int x)
AVFilter ff_vaf_spectrumsynth
static int query_formats(AVFilterContext *ctx)
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 activate(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
AVFILTER_DEFINE_CLASS(spectrumsynth)
static int config_output(AVFilterLink *outlink)
static const AVFilterPad spectrumsynth_outputs[]
static const int factor[16]
static void generate_window_func(float *lut, int N, int win_func, float *overlap)