FFmpeg
asrc_sinc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008-2009 Rob Sykes <robs@users.sourceforge.net>
3  * Copyright (c) 2017 Paul B Mahol
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/avassert.h"
23 #include "libavutil/opt.h"
24 
25 #include "libavcodec/avfft.h"
26 
27 #include "audio.h"
28 #include "avfilter.h"
29 #include "internal.h"
30 
31 typedef struct SincContext {
32  const AVClass *class;
33 
35  float att, beta, phase, Fc0, Fc1, tbw0, tbw1;
36  int num_taps[2];
37  int round;
38 
39  int n, rdft_len;
40  float *coeffs;
41  int64_t pts;
42 
44 } SincContext;
45 
46 static int request_frame(AVFilterLink *outlink)
47 {
48  AVFilterContext *ctx = outlink->src;
49  SincContext *s = ctx->priv;
50  const float *coeffs = s->coeffs;
51  AVFrame *frame = NULL;
52  int nb_samples;
53 
54  nb_samples = FFMIN(s->nb_samples, s->n - s->pts);
55  if (nb_samples <= 0)
56  return AVERROR_EOF;
57 
58  if (!(frame = ff_get_audio_buffer(outlink, nb_samples)))
59  return AVERROR(ENOMEM);
60 
61  memcpy(frame->data[0], coeffs + s->pts, nb_samples * sizeof(float));
62 
63  frame->pts = s->pts;
64  s->pts += nb_samples;
65 
66  return ff_filter_frame(outlink, frame);
67 }
68 
70 {
71  SincContext *s = ctx->priv;
72  static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 };
73  int sample_rates[] = { s->sample_rate, -1 };
74  static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_FLT,
78  int ret;
79 
80  formats = ff_make_format_list(sample_fmts);
81  if (!formats)
82  return AVERROR(ENOMEM);
83  ret = ff_set_common_formats (ctx, formats);
84  if (ret < 0)
85  return ret;
86 
87  layouts = avfilter_make_format64_list(chlayouts);
88  if (!layouts)
89  return AVERROR(ENOMEM);
90  ret = ff_set_common_channel_layouts(ctx, layouts);
91  if (ret < 0)
92  return ret;
93 
94  formats = ff_make_format_list(sample_rates);
95  if (!formats)
96  return AVERROR(ENOMEM);
97  return ff_set_common_samplerates(ctx, formats);
98 }
99 
100 static float bessel_I_0(float x)
101 {
102  float term = 1, sum = 1, last_sum, x2 = x / 2;
103  int i = 1;
104 
105  do {
106  float y = x2 / i++;
107 
108  last_sum = sum;
109  sum += term *= y * y;
110  } while (sum != last_sum);
111 
112  return sum;
113 }
114 
115 static float *make_lpf(int num_taps, float Fc, float beta, float rho,
116  float scale, int dc_norm)
117 {
118  int i, m = num_taps - 1;
119  float *h = av_calloc(num_taps, sizeof(*h)), sum = 0;
120  float mult = scale / bessel_I_0(beta), mult1 = 1.f / (.5f * m + rho);
121 
122  av_assert0(Fc >= 0 && Fc <= 1);
123 
124  for (i = 0; i <= m / 2; i++) {
125  float z = i - .5f * m, x = z * M_PI, y = z * mult1;
126  h[i] = x ? sinf(Fc * x) / x : Fc;
127  sum += h[i] *= bessel_I_0(beta * sqrtf(1.f - y * y)) * mult;
128  if (m - i != i) {
129  h[m - i] = h[i];
130  sum += h[i];
131  }
132  }
133 
134  for (i = 0; dc_norm && i < num_taps; i++)
135  h[i] *= scale / sum;
136 
137  return h;
138 }
139 
140 static float kaiser_beta(float att, float tr_bw)
141 {
142  if (att >= 60.f) {
143  static const float coefs[][4] = {
144  {-6.784957e-10, 1.02856e-05, 0.1087556, -0.8988365 + .001},
145  {-6.897885e-10, 1.027433e-05, 0.10876, -0.8994658 + .002},
146  {-1.000683e-09, 1.030092e-05, 0.1087677, -0.9007898 + .003},
147  {-3.654474e-10, 1.040631e-05, 0.1087085, -0.8977766 + .006},
148  {8.106988e-09, 6.983091e-06, 0.1091387, -0.9172048 + .015},
149  {9.519571e-09, 7.272678e-06, 0.1090068, -0.9140768 + .025},
150  {-5.626821e-09, 1.342186e-05, 0.1083999, -0.9065452 + .05},
151  {-9.965946e-08, 5.073548e-05, 0.1040967, -0.7672778 + .085},
152  {1.604808e-07, -5.856462e-05, 0.1185998, -1.34824 + .1},
153  {-1.511964e-07, 6.363034e-05, 0.1064627, -0.9876665 + .18},
154  };
155  float realm = logf(tr_bw / .0005f) / logf(2.f);
156  float const *c0 = coefs[av_clip((int)realm, 0, FF_ARRAY_ELEMS(coefs) - 1)];
157  float const *c1 = coefs[av_clip(1 + (int)realm, 0, FF_ARRAY_ELEMS(coefs) - 1)];
158  float b0 = ((c0[0] * att + c0[1]) * att + c0[2]) * att + c0[3];
159  float b1 = ((c1[0] * att + c1[1]) * att + c1[2]) * att + c1[3];
160 
161  return b0 + (b1 - b0) * (realm - (int)realm);
162  }
163  if (att > 50.f)
164  return .1102f * (att - 8.7f);
165  if (att > 20.96f)
166  return .58417f * powf(att - 20.96f, .4f) + .07886f * (att - 20.96f);
167  return 0;
168 }
169 
170 static void kaiser_params(float att, float Fc, float tr_bw, float *beta, int *num_taps)
171 {
172  *beta = *beta < 0.f ? kaiser_beta(att, tr_bw * .5f / Fc): *beta;
173  att = att < 60.f ? (att - 7.95f) / (2.285f * M_PI * 2.f) :
174  ((.0007528358f-1.577737e-05 * *beta) * *beta + 0.6248022f) * *beta + .06186902f;
175  *num_taps = !*num_taps ? ceilf(att/tr_bw + 1) : *num_taps;
176 }
177 
178 static float *lpf(float Fn, float Fc, float tbw, int *num_taps, float att, float *beta, int round)
179 {
180  int n = *num_taps;
181 
182  if ((Fc /= Fn) <= 0.f || Fc >= 1.f) {
183  *num_taps = 0;
184  return NULL;
185  }
186 
187  att = att ? att : 120.f;
188 
189  kaiser_params(att, Fc, (tbw ? tbw / Fn : .05f) * .5f, beta, num_taps);
190 
191  if (!n) {
192  n = *num_taps;
193  *num_taps = av_clip(n, 11, 32767);
194  if (round)
195  *num_taps = 1 + 2 * (int)((int)((*num_taps / 2) * Fc + .5f) / Fc + .5f);
196  }
197 
198  return make_lpf(*num_taps |= 1, Fc, *beta, 0.f, 1.f, 0);
199 }
200 
201 static void invert(float *h, int n)
202 {
203  for (int i = 0; i < n; i++)
204  h[i] = -h[i];
205 
206  h[(n - 1) / 2] += 1;
207 }
208 
209 #define PACK(h, n) h[1] = h[n]
210 #define UNPACK(h, n) h[n] = h[1], h[n + 1] = h[1] = 0;
211 #define SQR(a) ((a) * (a))
212 
213 static float safe_log(float x)
214 {
215  av_assert0(x >= 0);
216  if (x)
217  return logf(x);
218  return -26;
219 }
220 
221 static int fir_to_phase(SincContext *s, float **h, int *len, int *post_len, float phase)
222 {
223  float *pi_wraps, *work, phase1 = (phase > 50.f ? 100.f - phase : phase) / 50.f;
224  int i, work_len, begin, end, imp_peak = 0, peak = 0;
225  float imp_sum = 0, peak_imp_sum = 0;
226  float prev_angle2 = 0, cum_2pi = 0, prev_angle1 = 0, cum_1pi = 0;
227 
228  for (i = *len, work_len = 2 * 2 * 8; i > 1; work_len <<= 1, i >>= 1);
229 
230  work = av_calloc(work_len + 2, sizeof(*work)); /* +2: (UN)PACK */
231  pi_wraps = av_calloc(((work_len + 2) / 2), sizeof(*pi_wraps));
232  if (!work || !pi_wraps)
233  return AVERROR(ENOMEM);
234 
235  memcpy(work, *h, *len * sizeof(*work));
236 
237  av_rdft_end(s->rdft);
238  av_rdft_end(s->irdft);
239  s->rdft = s->irdft = NULL;
240  s->rdft = av_rdft_init(av_log2(work_len), DFT_R2C);
241  s->irdft = av_rdft_init(av_log2(work_len), IDFT_C2R);
242  if (!s->rdft || !s->irdft)
243  return AVERROR(ENOMEM);
244 
245  av_rdft_calc(s->rdft, work); /* Cepstral: */
246  UNPACK(work, work_len);
247 
248  for (i = 0; i <= work_len; i += 2) {
249  float angle = atan2f(work[i + 1], work[i]);
250  float detect = 2 * M_PI;
251  float delta = angle - prev_angle2;
252  float adjust = detect * ((delta < -detect * .7f) - (delta > detect * .7f));
253 
254  prev_angle2 = angle;
255  cum_2pi += adjust;
256  angle += cum_2pi;
257  detect = M_PI;
258  delta = angle - prev_angle1;
259  adjust = detect * ((delta < -detect * .7f) - (delta > detect * .7f));
260  prev_angle1 = angle;
261  cum_1pi += fabsf(adjust); /* fabs for when 2pi and 1pi have combined */
262  pi_wraps[i >> 1] = cum_1pi;
263 
264  work[i] = safe_log(sqrtf(SQR(work[i]) + SQR(work[i + 1])));
265  work[i + 1] = 0;
266  }
267 
268  PACK(work, work_len);
269  av_rdft_calc(s->irdft, work);
270 
271  for (i = 0; i < work_len; i++)
272  work[i] *= 2.f / work_len;
273 
274  for (i = 1; i < work_len / 2; i++) { /* Window to reject acausal components */
275  work[i] *= 2;
276  work[i + work_len / 2] = 0;
277  }
278  av_rdft_calc(s->rdft, work);
279 
280  for (i = 2; i < work_len; i += 2) /* Interpolate between linear & min phase */
281  work[i + 1] = phase1 * i / work_len * pi_wraps[work_len >> 1] + (1 - phase1) * (work[i + 1] + pi_wraps[i >> 1]) - pi_wraps[i >> 1];
282 
283  work[0] = exp(work[0]);
284  work[1] = exp(work[1]);
285  for (i = 2; i < work_len; i += 2) {
286  float x = expf(work[i]);
287 
288  work[i ] = x * cosf(work[i + 1]);
289  work[i + 1] = x * sinf(work[i + 1]);
290  }
291 
292  av_rdft_calc(s->irdft, work);
293  for (i = 0; i < work_len; i++)
294  work[i] *= 2.f / work_len;
295 
296  /* Find peak pos. */
297  for (i = 0; i <= (int) (pi_wraps[work_len >> 1] / M_PI + .5f); i++) {
298  imp_sum += work[i];
299  if (fabs(imp_sum) > fabs(peak_imp_sum)) {
300  peak_imp_sum = imp_sum;
301  peak = i;
302  }
303  if (work[i] > work[imp_peak]) /* For debug check only */
304  imp_peak = i;
305  }
306 
307  while (peak && fabsf(work[peak - 1]) > fabsf(work[peak]) && (work[peak - 1] * work[peak] > 0)) {
308  peak--;
309  }
310 
311  if (!phase1) {
312  begin = 0;
313  } else if (phase1 == 1) {
314  begin = peak - *len / 2;
315  } else {
316  begin = (.997f - (2 - phase1) * .22f) * *len + .5f;
317  end = (.997f + (0 - phase1) * .22f) * *len + .5f;
318  begin = peak - (begin & ~3);
319  end = peak + 1 + ((end + 3) & ~3);
320  *len = end - begin;
321  *h = av_realloc_f(*h, *len, sizeof(**h));
322  if (!*h) {
323  av_free(pi_wraps);
324  av_free(work);
325  return AVERROR(ENOMEM);
326  }
327  }
328 
329  for (i = 0; i < *len; i++) {
330  (*h)[i] = work[(begin + (phase > 50.f ? *len - 1 - i : i) + work_len) & (work_len - 1)];
331  }
332  *post_len = phase > 50 ? peak - begin : begin + *len - (peak + 1);
333 
334  av_log(s, AV_LOG_DEBUG, "%d nPI=%g peak-sum@%i=%g (val@%i=%g); len=%i post=%i (%g%%)\n",
335  work_len, pi_wraps[work_len >> 1] / M_PI, peak, peak_imp_sum, imp_peak,
336  work[imp_peak], *len, *post_len, 100.f - 100.f * *post_len / (*len - 1));
337 
338  av_free(pi_wraps);
339  av_free(work);
340 
341  return 0;
342 }
343 
344 static int config_output(AVFilterLink *outlink)
345 {
346  AVFilterContext *ctx = outlink->src;
347  SincContext *s = ctx->priv;
348  float Fn = s->sample_rate * .5f;
349  float *h[2];
350  int i, n, post_peak, longer;
351 
352  outlink->sample_rate = s->sample_rate;
353  s->pts = 0;
354 
355  if (s->Fc0 >= Fn || s->Fc1 >= Fn) {
356  av_log(ctx, AV_LOG_ERROR,
357  "filter frequency must be less than %d/2.\n", s->sample_rate);
358  return AVERROR(EINVAL);
359  }
360 
361  h[0] = lpf(Fn, s->Fc0, s->tbw0, &s->num_taps[0], s->att, &s->beta, s->round);
362  h[1] = lpf(Fn, s->Fc1, s->tbw1, &s->num_taps[1], s->att, &s->beta, s->round);
363 
364  if (h[0])
365  invert(h[0], s->num_taps[0]);
366 
367  longer = s->num_taps[1] > s->num_taps[0];
368  n = s->num_taps[longer];
369 
370  if (h[0] && h[1]) {
371  for (i = 0; i < s->num_taps[!longer]; i++)
372  h[longer][i + (n - s->num_taps[!longer]) / 2] += h[!longer][i];
373 
374  if (s->Fc0 < s->Fc1)
375  invert(h[longer], n);
376 
377  av_free(h[!longer]);
378  }
379 
380  if (s->phase != 50.f) {
381  int ret = fir_to_phase(s, &h[longer], &n, &post_peak, s->phase);
382  if (ret < 0)
383  return ret;
384  } else {
385  post_peak = n >> 1;
386  }
387 
388  s->n = 1 << (av_log2(n) + 1);
389  s->rdft_len = 1 << av_log2(n);
390  s->coeffs = av_calloc(s->n, sizeof(*s->coeffs));
391  if (!s->coeffs)
392  return AVERROR(ENOMEM);
393 
394  for (i = 0; i < n; i++)
395  s->coeffs[i] = h[longer][i];
396  av_free(h[longer]);
397 
398  av_rdft_end(s->rdft);
399  av_rdft_end(s->irdft);
400  s->rdft = s->irdft = NULL;
401 
402  return 0;
403 }
404 
406 {
407  SincContext *s = ctx->priv;
408 
409  av_freep(&s->coeffs);
410  av_rdft_end(s->rdft);
411  av_rdft_end(s->irdft);
412  s->rdft = s->irdft = NULL;
413 }
414 
415 static const AVFilterPad sinc_outputs[] = {
416  {
417  .name = "default",
418  .type = AVMEDIA_TYPE_AUDIO,
419  .config_props = config_output,
420  .request_frame = request_frame,
421  },
422  { NULL }
423 };
424 
425 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
426 #define OFFSET(x) offsetof(SincContext, x)
427 
428 static const AVOption sinc_options[] = {
429  { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, AF },
430  { "r", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, AF },
431  { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, AF },
432  { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, AF },
433  { "hp", "set high-pass filter frequency", OFFSET(Fc0), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT_MAX, AF },
434  { "lp", "set low-pass filter frequency", OFFSET(Fc1), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT_MAX, AF },
435  { "phase", "set filter phase response", OFFSET(phase), AV_OPT_TYPE_FLOAT, {.dbl=50}, 0, 100, AF },
436  { "beta", "set kaiser window beta", OFFSET(beta), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 256, AF },
437  { "att", "set stop-band attenuation", OFFSET(att), AV_OPT_TYPE_FLOAT, {.dbl=120}, 40, 180, AF },
438  { "round", "enable rounding", OFFSET(round), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF },
439  { "hptaps", "set number of taps for high-pass filter", OFFSET(num_taps[0]), AV_OPT_TYPE_INT, {.i64=0}, 0, 32768, AF },
440  { "lptaps", "set number of taps for low-pass filter", OFFSET(num_taps[1]), AV_OPT_TYPE_INT, {.i64=0}, 0, 32768, AF },
441  { NULL }
442 };
443 
445 
447  .name = "sinc",
448  .description = NULL_IF_CONFIG_SMALL("Generate a sinc kaiser-windowed low-pass, high-pass, band-pass, or band-reject FIR coefficients."),
449  .priv_size = sizeof(SincContext),
450  .priv_class = &sinc_class,
452  .uninit = uninit,
453  .inputs = NULL,
454  .outputs = sinc_outputs,
455 };
static const AVOption sinc_options[]
Definition: asrc_sinc.c:428
static int query_formats(AVFilterContext *ctx)
Definition: asrc_sinc.c:69
#define NULL
Definition: coverity.c:32
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:549
#define av_realloc_f(p, o, n)
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
#define AF
Definition: asrc_sinc.c:425
must be printed separately If there s no standard function for printing the type you the WRITE_1D_FUNC_ARGV macro is a very quick way to create one See libavcodec dv_tablegen c for an example The h file This file should the initialization functions should not do and instead of the variable declarations the generated *_tables h file should be included Since that will be generated in the build the path must be i e not Makefile changes To make the automatic table creation work
Definition: tablegen.txt:45
Main libavfilter public API header.
static av_cold void uninit(AVFilterContext *ctx)
Definition: asrc_sinc.c:405
int av_log2(unsigned v)
Definition: intmath.c:26
static float kaiser_beta(float att, float tr_bw)
Definition: asrc_sinc.c:140
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
static int fir_to_phase(SincContext *s, float **h, int *len, int *post_len, float phase)
Definition: asrc_sinc.c:221
const char * name
Pad name.
Definition: internal.h:60
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
#define av_cold
Definition: attributes.h:82
float delta
AVOptions.
float tbw1
Definition: asrc_sinc.c:35
#define f(width, name)
Definition: cbs_vp9.c:255
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
#define cosf(x)
Definition: libm.h:78
static const uint64_t c1
Definition: murmur3.c:49
#define atan2f(y, x)
Definition: libm.h:45
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
#define expf(x)
Definition: libm.h:283
static void kaiser_params(float att, float Fc, float tr_bw, float *beta, int *num_taps)
Definition: asrc_sinc.c:170
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:568
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
static float bessel_I_0(float x)
Definition: asrc_sinc.c:100
static const AVFilterPad sinc_outputs[]
Definition: asrc_sinc.c:415
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
float beta
Definition: asrc_sinc.c:35
simple assert() macros that are a bit more flexible than ISO C assert().
Definition: avfft.h:73
int8_t exp
Definition: eval.c:72
void av_rdft_calc(RDFTContext *s, FFTSample *data)
#define powf(x, y)
Definition: libm.h:50
#define UNPACK(h, n)
Definition: asrc_sinc.c:210
static int16_t mult(Float11 *f1, Float11 *f2)
Definition: g726.c:55
#define FFMIN(a, b)
Definition: common.h:96
#define PACK(h, n)
Definition: asrc_sinc.c:209
AVFormatContext * ctx
Definition: movenc.c:48
#define SQR(a)
Definition: asrc_sinc.c:211
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
#define s(width, name)
Definition: cbs_vp9.c:257
static void invert(float *h, int n)
Definition: asrc_sinc.c:201
Definition: avfft.h:72
void av_rdft_end(RDFTContext *s)
RDFTContext * av_rdft_init(int nbits, enum RDFTransformType trans)
Set up a real FFT.
float phase
Definition: asrc_sinc.c:35
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
#define FF_ARRAY_ELEMS(a)
A list of supported channel layouts.
Definition: formats.h:85
static int config_output(AVFilterLink *outlink)
Definition: asrc_sinc.c:344
int sample_rate
Definition: asrc_sinc.c:34
float att
Definition: asrc_sinc.c:35
int rdft_len
Definition: asrc_sinc.c:39
#define sinf(x)
Definition: libm.h:419
float tbw0
Definition: asrc_sinc.c:35
AVFilterChannelLayouts * avfilter_make_format64_list(const int64_t *fmts)
Definition: formats.c:303
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AVFILTER_DEFINE_CLASS(sinc)
FFT functions.
static float * make_lpf(int num_taps, float Fc, float beta, float rho, float scale, int dc_norm)
Definition: asrc_sinc.c:115
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
#define OFFSET(x)
Definition: asrc_sinc.c:426
const char * name
Filter name.
Definition: avfilter.h:148
static float * lpf(float Fn, float Fc, float tbw, int *num_taps, float att, float *beta, int round)
Definition: asrc_sinc.c:178
int nb_samples
Definition: asrc_sinc.c:34
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
int64_t pts
Definition: asrc_sinc.c:41
int
sample_rates
float Fc0
Definition: asrc_sinc.c:35
int num_taps[2]
Definition: asrc_sinc.c:36
#define av_free(p)
static float safe_log(float x)
Definition: asrc_sinc.c:213
int len
A list of supported formats for one end of a filter link.
Definition: formats.h:64
AVFilter ff_asrc_sinc
Definition: asrc_sinc.c:446
An instance of a filter.
Definition: avfilter.h:338
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
static int request_frame(AVFilterLink *outlink)
Definition: asrc_sinc.c:46
#define av_freep(p)
#define M_PI
Definition: mathematics.h:52
formats
Definition: signature.h:48
internal API functions
float Fc1
Definition: asrc_sinc.c:35
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#define AV_CH_LAYOUT_MONO
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
RDFTContext * irdft
Definition: asrc_sinc.c:43
float * coeffs
Definition: asrc_sinc.c:40
RDFTContext * rdft
Definition: asrc_sinc.c:43