FFmpeg
window_func.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 
22 #ifndef AVFILTER_WINDOW_FUNC_H
23 #define AVFILTER_WINDOW_FUNC_H
24 
25 #include <math.h>
26 #include "libavutil/avassert.h"
27 #include "libavutil/common.h"
28 
36 
37 #define WIN_FUNC_OPTION(win_func_opt_name, win_func_offset, flag, default_window_func) \
38  { win_func_opt_name, "set window function", win_func_offset, AV_OPT_TYPE_INT, {.i64 = default_window_func}, 0, NB_WFUNC-1, flag, "win_func" }, \
39  { "rect", "Rectangular", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT}, 0, 0, flag, "win_func" }, \
40  { "bartlett", "Bartlett", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, flag, "win_func" }, \
41  { "hann", "Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, flag, "win_func" }, \
42  { "hanning", "Hanning", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, flag, "win_func" }, \
43  { "hamming", "Hamming", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING}, 0, 0, flag, "win_func" }, \
44  { "blackman", "Blackman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BLACKMAN}, 0, 0, flag, "win_func" }, \
45  { "welch", "Welch", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_WELCH}, 0, 0, flag, "win_func" }, \
46  { "flattop", "Flat-top", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_FLATTOP}, 0, 0, flag, "win_func" }, \
47  { "bharris", "Blackman-Harris", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHARRIS}, 0, 0, flag, "win_func" }, \
48  { "bnuttall", "Blackman-Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BNUTTALL}, 0, 0, flag, "win_func" }, \
49  { "bhann", "Bartlett-Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHANN}, 0, 0, flag, "win_func" }, \
50  { "sine", "Sine", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE}, 0, 0, flag, "win_func" }, \
51  { "nuttall", "Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_NUTTALL}, 0, 0, flag, "win_func" }, \
52  { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_LANCZOS}, 0, 0, flag, "win_func" }, \
53  { "gauss", "Gauss", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_GAUSS}, 0, 0, flag, "win_func" }, \
54  { "tukey", "Tukey", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_TUKEY}, 0, 0, flag, "win_func" }, \
55  { "dolph", "Dolph-Chebyshev", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_DOLPH}, 0, 0, flag, "win_func" }, \
56  { "cauchy", "Cauchy", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_CAUCHY}, 0, 0, flag, "win_func" }, \
57  { "parzen", "Parzen", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_PARZEN}, 0, 0, flag, "win_func" }, \
58  { "poisson", "Poisson", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_POISSON}, 0, 0, flag, "win_func" }, \
59  { "bohman", "Bohman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BOHMAN}, 0, 0, flag, "win_func" }, \
60  { "kaiser", "Kaiser", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_KAISER}, 0, 0, flag, "win_func" }
61 
62 static inline double get_i0(double x)
63 {
64  double y = 1.0, prev = 1.0, i = 1.0;
65 
66  while (fabs(prev) > 1e-20) {
67  double summand = prev * x * x / (4 * i * i);
68  y += summand;
69  prev = summand;
70  i++;
71  }
72 
73  return y;
74 }
75 
76 static inline void generate_window_func(float *lut, int N, int win_func,
77  float *overlap)
78 {
79  int n;
80 
81  switch (win_func) {
82  case WFUNC_RECT:
83  for (n = 0; n < N; n++)
84  lut[n] = 1.;
85  *overlap = 0.;
86  break;
87  case WFUNC_BARTLETT:
88  for (n = 0; n < N; n++)
89  lut[n] = 1.-fabs((n-(N-1)/2.)/((N-1)/2.));
90  *overlap = 0.5;
91  break;
92  case WFUNC_HANNING:
93  for (n = 0; n < N; n++)
94  lut[n] = .5*(1-cos(2*M_PI*n/(N-1)));
95  *overlap = 0.5;
96  break;
97  case WFUNC_HAMMING:
98  for (n = 0; n < N; n++)
99  lut[n] = .54-.46*cos(2*M_PI*n/(N-1));
100  *overlap = 0.5;
101  break;
102  case WFUNC_BLACKMAN:
103  for (n = 0; n < N; n++)
104  lut[n] = .42659-.49656*cos(2*M_PI*n/(N-1))+.076849*cos(4*M_PI*n/(N-1));
105  *overlap = 0.661;
106  break;
107  case WFUNC_WELCH:
108  for (n = 0; n < N; n++)
109  lut[n] = 1.-(n-(N-1)/2.)/((N-1)/2.)*(n-(N-1)/2.)/((N-1)/2.);
110  *overlap = 0.293;
111  break;
112  case WFUNC_FLATTOP:
113  for (n = 0; n < N; n++)
114  lut[n] = 1.-1.985844164102*cos( 2*M_PI*n/(N-1))+1.791176438506*cos( 4*M_PI*n/(N-1))-
115  1.282075284005*cos( 6*M_PI*n/(N-1))+0.667777530266*cos( 8*M_PI*n/(N-1))-
116  0.240160796576*cos(10*M_PI*n/(N-1))+0.056656381764*cos(12*M_PI*n/(N-1))-
117  0.008134974479*cos(14*M_PI*n/(N-1))+0.000624544650*cos(16*M_PI*n/(N-1))-
118  0.000019808998*cos(18*M_PI*n/(N-1))+0.000000132974*cos(20*M_PI*n/(N-1));
119  *overlap = 0.841;
120  break;
121  case WFUNC_BHARRIS:
122  for (n = 0; n < N; n++)
123  lut[n] = 0.35875-0.48829*cos(2*M_PI*n/(N-1))+0.14128*cos(4*M_PI*n/(N-1))-0.01168*cos(6*M_PI*n/(N-1));
124  *overlap = 0.661;
125  break;
126  case WFUNC_BNUTTALL:
127  for (n = 0; n < N; n++)
128  lut[n] = 0.3635819-0.4891775*cos(2*M_PI*n/(N-1))+0.1365995*cos(4*M_PI*n/(N-1))-0.0106411*cos(6*M_PI*n/(N-1));
129  *overlap = 0.661;
130  break;
131  case WFUNC_BHANN:
132  for (n = 0; n < N; n++)
133  lut[n] = 0.62-0.48*fabs(n/(double)(N-1)-.5)-0.38*cos(2*M_PI*n/(N-1));
134  *overlap = 0.5;
135  break;
136  case WFUNC_SINE:
137  for (n = 0; n < N; n++)
138  lut[n] = sin(M_PI*n/(N-1));
139  *overlap = 0.75;
140  break;
141  case WFUNC_NUTTALL:
142  for (n = 0; n < N; n++)
143  lut[n] = 0.355768-0.487396*cos(2*M_PI*n/(N-1))+0.144232*cos(4*M_PI*n/(N-1))-0.012604*cos(6*M_PI*n/(N-1));
144  *overlap = 0.663;
145  break;
146  case WFUNC_LANCZOS:
147  #define SINC(x) (!(x)) ? 1 : sin(M_PI * (x))/(M_PI * (x));
148  for (n = 0; n < N; n++)
149  lut[n] = SINC((2.*n)/(N-1)-1);
150  *overlap = 0.75;
151  break;
152  case WFUNC_GAUSS:
153  #define SQR(x) ((x)*(x))
154  for (n = 0; n < N; n++)
155  lut[n] = exp(-0.5 * SQR((n-(N-1)/2)/(0.4*(N-1)/2.f)));
156  *overlap = 0.75;
157  break;
158  case WFUNC_TUKEY:
159  for (n = 0; n < N; n++) {
160  float M = (N-1)/2.;
161 
162  if (FFABS(n - M) >= 0.3 * M) {
163  lut[n] = 0.5 * (1 + cos((M_PI*(FFABS(n - M) - 0.3 * M))/((1 - 0.3) * M)));
164  } else {
165  lut[n] = 1;
166  }
167  }
168  *overlap = 0.33;
169  break;
170  case WFUNC_DOLPH: {
171  double b = cosh(7.6009022095419887 / (N-1)), sum, t, c, norm = 0;
172  int j;
173  for (c = 1 - 1 / (b*b), n = (N-1) / 2; n >= 0; --n) {
174  for (sum = !n, b = t = j = 1; j <= n && sum != t; b *= (n-j) * (1./j), ++j)
175  t = sum, sum += (b *= c * (N - n - j) * (1./j));
176  sum /= (N - 1 - n), norm = norm ? norm : sum, sum /= norm;
177  lut[n] = sum;
178  lut[N - 1 - n] = sum;
179  }
180  *overlap = 0.5;}
181  break;
182  case WFUNC_CAUCHY:
183  for (n = 0; n < N; n++) {
184  double x = 2 * ((n / (double)(N - 1)) - .5);
185 
186  if (x <= -.5 || x >= .5) {
187  lut[n] = 0;
188  } else {
189  lut[n] = FFMIN(1, fabs(1/(1+4*16*x*x)));
190  }
191  }
192  *overlap = 0.75;
193  break;
194  case WFUNC_PARZEN:
195  for (n = 0; n < N; n++) {
196  double x = 2 * ((n / (double)(N - 1)) - .5);
197 
198  if (x > 0.25 && x <= 0.5) {
199  lut[n] = -2 * powf(-1 + 2 * x, 3);
200  } else if (x >= -.5 && x < -.25) {
201  lut[n] = 2 * powf(1 + 2 * x, 3);
202  } else if (x >= -.25 && x < 0) {
203  lut[n] = 1 - 24 * x * x - 48 * x * x * x;
204  } else if (x >= 0 && x <= .25) {
205  lut[n] = 1 - 24 * x * x + 48 * x * x * x;
206  } else {
207  lut[n] = 0;
208  }
209  }
210  *overlap = 0.75;
211  break;
212  case WFUNC_POISSON:
213  for (n = 0; n < N; n++) {
214  double x = 2 * ((n / (double)(N - 1)) - .5);
215 
216  if (x >= 0 && x <= .5) {
217  lut[n] = exp(-6*x);
218  } else if (x < 0 && x >= -.5) {
219  lut[n] = exp(6*x);
220  } else {
221  lut[n] = 0;
222  }
223  }
224  *overlap = 0.75;
225  break;
226  case WFUNC_BOHMAN:
227  for (n = 0; n < N; n++) {
228  double x = 2 * ((n / (double)(N - 1))) - 1.;
229 
230  lut[n] = (1 - fabs(x)) * cos(M_PI*fabs(x)) + 1./M_PI*sin(M_PI*fabs(x));
231  }
232  *overlap = 0.75;
233  break;
234  case WFUNC_KAISER:
235  for (n = 0; n < N; n++) {
236  double x = 2.0 / (double)(N - 1);
237 
238  lut[n] = get_i0(12. * sqrt(1. - SQR(n * x - 1.))) / get_i0(12.);
239  }
240  *overlap = 0.75;
241  break;
242  default:
243  av_assert0(0);
244  }
245 }
246 
247 #endif /* AVFILTER_WINDOW_FUNC_H */
M
#define M(a, b)
Definition: vp3dsp.c:48
b
#define b
Definition: input.c:41
WFUNC_BNUTTALL
@ WFUNC_BNUTTALL
Definition: window_func.h:31
WFUNC_KAISER
@ WFUNC_KAISER
Definition: window_func.h:34
WFUNC_FLATTOP
@ WFUNC_FLATTOP
Definition: window_func.h:30
WFUNC_HAMMING
@ WFUNC_HAMMING
Definition: window_func.h:29
WFUNC_PARZEN
@ WFUNC_PARZEN
Definition: window_func.h:33
WindowFunc
WindowFunc
Definition: af_firequalizer.c:34
WFUNC_TUKEY
@ WFUNC_TUKEY
Definition: window_func.h:32
WFUNC_BHANN
@ WFUNC_BHANN
Definition: window_func.h:32
avassert.h
WFUNC_DOLPH
@ WFUNC_DOLPH
Definition: window_func.h:33
WFUNC_BHARRIS
@ WFUNC_BHARRIS
Definition: window_func.h:31
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
WFUNC_LANCZOS
@ WFUNC_LANCZOS
Definition: window_func.h:32
WFUNC_RECT
@ WFUNC_RECT
Definition: window_func.h:29
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:64
NB_WFUNC
@ NB_WFUNC
Definition: window_func.h:35
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
double
double
Definition: af_crystalizer.c:132
generate_window_func
static void generate_window_func(float *lut, int N, int win_func, float *overlap)
Definition: window_func.h:76
WFUNC_HANNING
@ WFUNC_HANNING
Definition: window_func.h:29
WFUNC_BARTLETT
@ WFUNC_BARTLETT
Definition: window_func.h:30
WFUNC_BOHMAN
@ WFUNC_BOHMAN
Definition: window_func.h:34
exp
int8_t exp
Definition: eval.c:72
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
f
f
Definition: af_crystalizer.c:122
powf
#define powf(x, y)
Definition: libm.h:50
N
#define N
Definition: af_mcompand.c:53
M_PI
#define M_PI
Definition: mathematics.h:52
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
get_i0
static double get_i0(double x)
Definition: window_func.h:62
WFUNC_SINE
@ WFUNC_SINE
Definition: window_func.h:31
WFUNC_CAUCHY
@ WFUNC_CAUCHY
Definition: window_func.h:33
WFUNC_GAUSS
@ WFUNC_GAUSS
Definition: window_func.h:32
WFUNC_NUTTALL
@ WFUNC_NUTTALL
Definition: window_func.h:31
WFUNC_POISSON
@ WFUNC_POISSON
Definition: window_func.h:33
SQR
#define SQR(x)
SINC
#define SINC(x)
WFUNC_BLACKMAN
@ WFUNC_BLACKMAN
Definition: window_func.h:29
WFUNC_WELCH
@ WFUNC_WELCH
Definition: window_func.h:30