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 
61 static inline void generate_window_func(float *lut, int N, int win_func,
62  float *overlap)
63 {
64  int n;
65 
66  switch (win_func) {
67  case WFUNC_RECT:
68  for (n = 0; n < N; n++)
69  lut[n] = 1.;
70  *overlap = 0.;
71  break;
72  case WFUNC_BARTLETT:
73  for (n = 0; n < N; n++)
74  lut[n] = 1.-fabs((n-(N-1)/2.)/((N-1)/2.));
75  *overlap = 0.5;
76  break;
77  case WFUNC_HANNING:
78  for (n = 0; n < N; n++)
79  lut[n] = .5*(1-cos(2*M_PI*n/(N-1)));
80  *overlap = 0.5;
81  break;
82  case WFUNC_HAMMING:
83  for (n = 0; n < N; n++)
84  lut[n] = .54-.46*cos(2*M_PI*n/(N-1));
85  *overlap = 0.5;
86  break;
87  case WFUNC_BLACKMAN:
88  for (n = 0; n < N; n++)
89  lut[n] = .42659-.49656*cos(2*M_PI*n/(N-1))+.076849*cos(4*M_PI*n/(N-1));
90  *overlap = 0.661;
91  break;
92  case WFUNC_WELCH:
93  for (n = 0; n < N; n++)
94  lut[n] = 1.-(n-(N-1)/2.)/((N-1)/2.)*(n-(N-1)/2.)/((N-1)/2.);
95  *overlap = 0.293;
96  break;
97  case WFUNC_FLATTOP:
98  for (n = 0; n < N; n++)
99  lut[n] = 1.-1.985844164102*cos( 2*M_PI*n/(N-1))+1.791176438506*cos( 4*M_PI*n/(N-1))-
100  1.282075284005*cos( 6*M_PI*n/(N-1))+0.667777530266*cos( 8*M_PI*n/(N-1))-
101  0.240160796576*cos(10*M_PI*n/(N-1))+0.056656381764*cos(12*M_PI*n/(N-1))-
102  0.008134974479*cos(14*M_PI*n/(N-1))+0.000624544650*cos(16*M_PI*n/(N-1))-
103  0.000019808998*cos(18*M_PI*n/(N-1))+0.000000132974*cos(20*M_PI*n/(N-1));
104  *overlap = 0.841;
105  break;
106  case WFUNC_BHARRIS:
107  for (n = 0; n < N; n++)
108  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));
109  *overlap = 0.661;
110  break;
111  case WFUNC_BNUTTALL:
112  for (n = 0; n < N; n++)
113  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));
114  *overlap = 0.661;
115  break;
116  case WFUNC_BHANN:
117  for (n = 0; n < N; n++)
118  lut[n] = 0.62-0.48*fabs(n/(double)(N-1)-.5)-0.38*cos(2*M_PI*n/(N-1));
119  *overlap = 0.5;
120  break;
121  case WFUNC_SINE:
122  for (n = 0; n < N; n++)
123  lut[n] = sin(M_PI*n/(N-1));
124  *overlap = 0.75;
125  break;
126  case WFUNC_NUTTALL:
127  for (n = 0; n < N; n++)
128  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));
129  *overlap = 0.663;
130  break;
131  case WFUNC_LANCZOS:
132  #define SINC(x) (!(x)) ? 1 : sin(M_PI * (x))/(M_PI * (x));
133  for (n = 0; n < N; n++)
134  lut[n] = SINC((2.*n)/(N-1)-1);
135  *overlap = 0.75;
136  break;
137  case WFUNC_GAUSS:
138  #define SQR(x) ((x)*(x))
139  for (n = 0; n < N; n++)
140  lut[n] = exp(-0.5 * SQR((n-(N-1)/2)/(0.4*(N-1)/2.f)));
141  *overlap = 0.75;
142  break;
143  case WFUNC_TUKEY:
144  for (n = 0; n < N; n++) {
145  float M = (N-1)/2.;
146 
147  if (FFABS(n - M) >= 0.3 * M) {
148  lut[n] = 0.5 * (1 + cos((M_PI*(FFABS(n - M) - 0.3 * M))/((1 - 0.3) * M)));
149  } else {
150  lut[n] = 1;
151  }
152  }
153  *overlap = 0.33;
154  break;
155  case WFUNC_DOLPH: {
156  double b = cosh(7.6009022095419887 / (N-1)), sum, t, c, norm = 0;
157  int j;
158  for (c = 1 - 1 / (b*b), n = (N-1) / 2; n >= 0; --n) {
159  for (sum = !n, b = t = j = 1; j <= n && sum != t; b *= (n-j) * (1./j), ++j)
160  t = sum, sum += (b *= c * (N - n - j) * (1./j));
161  sum /= (N - 1 - n), norm = norm ? norm : sum, sum /= norm;
162  lut[n] = sum;
163  lut[N - 1 - n] = sum;
164  }
165  *overlap = 0.5;}
166  break;
167  case WFUNC_CAUCHY:
168  for (n = 0; n < N; n++) {
169  double x = 2 * ((n / (double)(N - 1)) - .5);
170 
171  if (x <= -.5 || x >= .5) {
172  lut[n] = 0;
173  } else {
174  lut[n] = FFMIN(1, fabs(1/(1+4*16*x*x)));
175  }
176  }
177  *overlap = 0.75;
178  break;
179  case WFUNC_PARZEN:
180  for (n = 0; n < N; n++) {
181  double x = 2 * ((n / (double)(N - 1)) - .5);
182 
183  if (x > 0.25 && x <= 0.5) {
184  lut[n] = -2 * powf(-1 + 2 * x, 3);
185  } else if (x >= -.5 && x < -.25) {
186  lut[n] = 2 * powf(1 + 2 * x, 3);
187  } else if (x >= -.25 && x < 0) {
188  lut[n] = 1 - 24 * x * x - 48 * x * x * x;
189  } else if (x >= 0 && x <= .25) {
190  lut[n] = 1 - 24 * x * x + 48 * x * x * x;
191  } else {
192  lut[n] = 0;
193  }
194  }
195  *overlap = 0.75;
196  break;
197  case WFUNC_POISSON:
198  for (n = 0; n < N; n++) {
199  double x = 2 * ((n / (double)(N - 1)) - .5);
200 
201  if (x >= 0 && x <= .5) {
202  lut[n] = exp(-6*x);
203  } else if (x < 0 && x >= -.5) {
204  lut[n] = exp(6*x);
205  } else {
206  lut[n] = 0;
207  }
208  }
209  *overlap = 0.75;
210  break;
211  case WFUNC_BOHMAN:
212  for (n = 0; n < N; n++) {
213  double x = 2 * ((n / (double)(N - 1))) - 1.;
214 
215  lut[n] = (1 - fabs(x)) * cos(M_PI*fabs(x)) + 1./M_PI*sin(M_PI*fabs(x));
216  }
217  *overlap = 0.75;
218  break;
219  default:
220  av_assert0(0);
221  }
222 }
223 
224 #endif /* AVFILTER_WINDOW_FUNC_H */
M
#define M(a, b)
Definition: vp3dsp.c:48
b
#define b
Definition: input.c:34
WFUNC_BNUTTALL
@ WFUNC_BNUTTALL
Definition: window_func.h:31
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:33
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:61
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
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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