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  av_free(pi_wraps);
244  av_free(work);
245  return AVERROR(ENOMEM);
246  }
247 
248  av_rdft_calc(s->rdft, work); /* Cepstral: */
249  UNPACK(work, work_len);
250 
251  for (i = 0; i <= work_len; i += 2) {
252  float angle = atan2f(work[i + 1], work[i]);
253  float detect = 2 * M_PI;
254  float delta = angle - prev_angle2;
255  float adjust = detect * ((delta < -detect * .7f) - (delta > detect * .7f));
256 
257  prev_angle2 = angle;
258  cum_2pi += adjust;
259  angle += cum_2pi;
260  detect = M_PI;
261  delta = angle - prev_angle1;
262  adjust = detect * ((delta < -detect * .7f) - (delta > detect * .7f));
263  prev_angle1 = angle;
264  cum_1pi += fabsf(adjust); /* fabs for when 2pi and 1pi have combined */
265  pi_wraps[i >> 1] = cum_1pi;
266 
267  work[i] = safe_log(sqrtf(SQR(work[i]) + SQR(work[i + 1])));
268  work[i + 1] = 0;
269  }
270 
271  PACK(work, work_len);
272  av_rdft_calc(s->irdft, work);
273 
274  for (i = 0; i < work_len; i++)
275  work[i] *= 2.f / work_len;
276 
277  for (i = 1; i < work_len / 2; i++) { /* Window to reject acausal components */
278  work[i] *= 2;
279  work[i + work_len / 2] = 0;
280  }
281  av_rdft_calc(s->rdft, work);
282 
283  for (i = 2; i < work_len; i += 2) /* Interpolate between linear & min phase */
284  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];
285 
286  work[0] = exp(work[0]);
287  work[1] = exp(work[1]);
288  for (i = 2; i < work_len; i += 2) {
289  float x = expf(work[i]);
290 
291  work[i ] = x * cosf(work[i + 1]);
292  work[i + 1] = x * sinf(work[i + 1]);
293  }
294 
295  av_rdft_calc(s->irdft, work);
296  for (i = 0; i < work_len; i++)
297  work[i] *= 2.f / work_len;
298 
299  /* Find peak pos. */
300  for (i = 0; i <= (int) (pi_wraps[work_len >> 1] / M_PI + .5f); i++) {
301  imp_sum += work[i];
302  if (fabs(imp_sum) > fabs(peak_imp_sum)) {
303  peak_imp_sum = imp_sum;
304  peak = i;
305  }
306  if (work[i] > work[imp_peak]) /* For debug check only */
307  imp_peak = i;
308  }
309 
310  while (peak && fabsf(work[peak - 1]) > fabsf(work[peak]) && (work[peak - 1] * work[peak] > 0)) {
311  peak--;
312  }
313 
314  if (!phase1) {
315  begin = 0;
316  } else if (phase1 == 1) {
317  begin = peak - *len / 2;
318  } else {
319  begin = (.997f - (2 - phase1) * .22f) * *len + .5f;
320  end = (.997f + (0 - phase1) * .22f) * *len + .5f;
321  begin = peak - (begin & ~3);
322  end = peak + 1 + ((end + 3) & ~3);
323  *len = end - begin;
324  *h = av_realloc_f(*h, *len, sizeof(**h));
325  if (!*h) {
326  av_free(pi_wraps);
327  av_free(work);
328  return AVERROR(ENOMEM);
329  }
330  }
331 
332  for (i = 0; i < *len; i++) {
333  (*h)[i] = work[(begin + (phase > 50.f ? *len - 1 - i : i) + work_len) & (work_len - 1)];
334  }
335  *post_len = phase > 50 ? peak - begin : begin + *len - (peak + 1);
336 
337  av_log(s, AV_LOG_DEBUG, "%d nPI=%g peak-sum@%i=%g (val@%i=%g); len=%i post=%i (%g%%)\n",
338  work_len, pi_wraps[work_len >> 1] / M_PI, peak, peak_imp_sum, imp_peak,
339  work[imp_peak], *len, *post_len, 100.f - 100.f * *post_len / (*len - 1));
340 
341  av_free(pi_wraps);
342  av_free(work);
343 
344  return 0;
345 }
346 
347 static int config_output(AVFilterLink *outlink)
348 {
349  AVFilterContext *ctx = outlink->src;
350  SincContext *s = ctx->priv;
351  float Fn = s->sample_rate * .5f;
352  float *h[2];
353  int i, n, post_peak, longer;
354 
355  outlink->sample_rate = s->sample_rate;
356  s->pts = 0;
357 
358  if (s->Fc0 >= Fn || s->Fc1 >= Fn) {
359  av_log(ctx, AV_LOG_ERROR,
360  "filter frequency must be less than %d/2.\n", s->sample_rate);
361  return AVERROR(EINVAL);
362  }
363 
364  h[0] = lpf(Fn, s->Fc0, s->tbw0, &s->num_taps[0], s->att, &s->beta, s->round);
365  h[1] = lpf(Fn, s->Fc1, s->tbw1, &s->num_taps[1], s->att, &s->beta, s->round);
366 
367  if (h[0])
368  invert(h[0], s->num_taps[0]);
369 
370  longer = s->num_taps[1] > s->num_taps[0];
371  n = s->num_taps[longer];
372 
373  if (h[0] && h[1]) {
374  for (i = 0; i < s->num_taps[!longer]; i++)
375  h[longer][i + (n - s->num_taps[!longer]) / 2] += h[!longer][i];
376 
377  if (s->Fc0 < s->Fc1)
378  invert(h[longer], n);
379 
380  av_free(h[!longer]);
381  }
382 
383  if (s->phase != 50.f) {
384  int ret = fir_to_phase(s, &h[longer], &n, &post_peak, s->phase);
385  if (ret < 0)
386  return ret;
387  } else {
388  post_peak = n >> 1;
389  }
390 
391  s->n = 1 << (av_log2(n) + 1);
392  s->rdft_len = 1 << av_log2(n);
393  s->coeffs = av_calloc(s->n, sizeof(*s->coeffs));
394  if (!s->coeffs)
395  return AVERROR(ENOMEM);
396 
397  for (i = 0; i < n; i++)
398  s->coeffs[i] = h[longer][i];
399  av_free(h[longer]);
400 
401  av_rdft_end(s->rdft);
402  av_rdft_end(s->irdft);
403  s->rdft = s->irdft = NULL;
404 
405  return 0;
406 }
407 
409 {
410  SincContext *s = ctx->priv;
411 
412  av_freep(&s->coeffs);
413  av_rdft_end(s->rdft);
414  av_rdft_end(s->irdft);
415  s->rdft = s->irdft = NULL;
416 }
417 
418 static const AVFilterPad sinc_outputs[] = {
419  {
420  .name = "default",
421  .type = AVMEDIA_TYPE_AUDIO,
422  .config_props = config_output,
423  .request_frame = request_frame,
424  },
425  { NULL }
426 };
427 
428 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
429 #define OFFSET(x) offsetof(SincContext, x)
430 
431 static const AVOption sinc_options[] = {
432  { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, AF },
433  { "r", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, AF },
434  { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, AF },
435  { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, AF },
436  { "hp", "set high-pass filter frequency", OFFSET(Fc0), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT_MAX, AF },
437  { "lp", "set low-pass filter frequency", OFFSET(Fc1), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, INT_MAX, AF },
438  { "phase", "set filter phase response", OFFSET(phase), AV_OPT_TYPE_FLOAT, {.dbl=50}, 0, 100, AF },
439  { "beta", "set kaiser window beta", OFFSET(beta), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 256, AF },
440  { "att", "set stop-band attenuation", OFFSET(att), AV_OPT_TYPE_FLOAT, {.dbl=120}, 40, 180, AF },
441  { "round", "enable rounding", OFFSET(round), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF },
442  { "hptaps", "set number of taps for high-pass filter", OFFSET(num_taps[0]), AV_OPT_TYPE_INT, {.i64=0}, 0, 32768, AF },
443  { "lptaps", "set number of taps for low-pass filter", OFFSET(num_taps[1]), AV_OPT_TYPE_INT, {.i64=0}, 0, 32768, AF },
444  { NULL }
445 };
446 
448 
450  .name = "sinc",
451  .description = NULL_IF_CONFIG_SMALL("Generate a sinc kaiser-windowed low-pass, high-pass, band-pass, or band-reject FIR coefficients."),
452  .priv_size = sizeof(SincContext),
453  .priv_class = &sinc_class,
455  .uninit = uninit,
456  .inputs = NULL,
457  .outputs = sinc_outputs,
458 };
static const AVOption sinc_options[]
Definition: asrc_sinc.c:431
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:550
#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:428
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:408
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:1093
#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:569
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:418
#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:347
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:429
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:449
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:557
RDFTContext * irdft
Definition: asrc_sinc.c:43
float * coeffs
Definition: asrc_sinc.c:40
RDFTContext * rdft
Definition: asrc_sinc.c:43