1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2006-2009 Josh Coalson
3 * Copyright (C) 2011-2022 Xiph.Org Foundation
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * - Neither the name of the Xiph.org Foundation nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #ifdef HAVE_CONFIG_H
34 # include <config.h>
35 #endif
36
37 #include <math.h>
38 #include "share/compat.h"
39 #include "FLAC/assert.h"
40 #include "FLAC/format.h"
41 #include "private/window.h"
42
43 #ifndef FLAC__INTEGER_ONLY_LIBRARY
44
45 #if defined(_MSC_VER)
46 // silence 25 MSVC warnings 'conversion from 'double' to 'float', possible loss of data'
47 #pragma warning ( disable : 4244 )
48 #endif
49
FLAC__window_bartlett(FLAC__real * window,const FLAC__int32 L)50 void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
51 {
52 const FLAC__int32 N = L - 1;
53 FLAC__int32 n;
54
55 if (L & 1) {
56 for (n = 0; n <= N/2; n++)
57 window[n] = 2.0f * n / (float)N;
58 for (; n <= N; n++)
59 window[n] = 2.0f - 2.0f * n / (float)N;
60 }
61 else {
62 for (n = 0; n <= L/2-1; n++)
63 window[n] = 2.0f * n / (float)N;
64 for (; n <= N; n++)
65 window[n] = 2.0f - 2.0f * n / (float)N;
66 }
67 }
68
FLAC__window_bartlett_hann(FLAC__real * window,const FLAC__int32 L)69 void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L)
70 {
71 const FLAC__int32 N = L - 1;
72 FLAC__int32 n;
73
74 for (n = 0; n < L; n++)
75 window[n] = (FLAC__real)(0.62f - 0.48f * fabsf((float)n/(float)N-0.5f) - 0.38f * cosf(2.0f * M_PI * ((float)n/(float)N)));
76 }
77
FLAC__window_blackman(FLAC__real * window,const FLAC__int32 L)78 void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L)
79 {
80 const FLAC__int32 N = L - 1;
81 FLAC__int32 n;
82
83 for (n = 0; n < L; n++)
84 window[n] = (FLAC__real)(0.42f - 0.5f * cosf(2.0f * M_PI * n / N) + 0.08f * cosf(4.0f * M_PI * n / N));
85 }
86
87 /* 4-term -92dB side-lobe */
FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real * window,const FLAC__int32 L)88 void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L)
89 {
90 const FLAC__int32 N = L - 1;
91 FLAC__int32 n;
92
93 for (n = 0; n <= N; n++)
94 window[n] = (FLAC__real)(0.35875f - 0.48829f * cosf(2.0f * M_PI * n / N) + 0.14128f * cosf(4.0f * M_PI * n / N) - 0.01168f * cosf(6.0f * M_PI * n / N));
95 }
96
FLAC__window_connes(FLAC__real * window,const FLAC__int32 L)97 void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L)
98 {
99 const FLAC__int32 N = L - 1;
100 const double N2 = (double)N / 2.;
101 FLAC__int32 n;
102
103 for (n = 0; n <= N; n++) {
104 double k = ((double)n - N2) / N2;
105 k = 1.0f - k * k;
106 window[n] = (FLAC__real)(k * k);
107 }
108 }
109
FLAC__window_flattop(FLAC__real * window,const FLAC__int32 L)110 void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L)
111 {
112 const FLAC__int32 N = L - 1;
113 FLAC__int32 n;
114
115 for (n = 0; n < L; n++)
116 window[n] = (FLAC__real)(0.21557895f - 0.41663158f * cosf(2.0f * M_PI * n / N) + 0.277263158f * cosf(4.0f * M_PI * n / N) - 0.083578947f * cosf(6.0f * M_PI * n / N) + 0.006947368f * cosf(8.0f * M_PI * n / N));
117 }
118
FLAC__window_gauss(FLAC__real * window,const FLAC__int32 L,const FLAC__real stddev)119 void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev)
120 {
121 const FLAC__int32 N = L - 1;
122 const double N2 = (double)N / 2.;
123 FLAC__int32 n;
124
125 if(!(stddev > 0.0f && stddev <= 0.5f))
126 /* stddev is not between 0 and 0.5, might be NaN.
127 * Default to 0.5 */
128 FLAC__window_gauss(window, L, 0.25f);
129 else {
130 for (n = 0; n <= N; n++) {
131 const double k = ((double)n - N2) / (stddev * N2);
132 window[n] = (FLAC__real)exp(-0.5f * k * k);
133 }
134 }
135 }
136
FLAC__window_hamming(FLAC__real * window,const FLAC__int32 L)137 void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L)
138 {
139 const FLAC__int32 N = L - 1;
140 FLAC__int32 n;
141
142 for (n = 0; n < L; n++)
143 window[n] = (FLAC__real)(0.54f - 0.46f * cosf(2.0f * M_PI * n / N));
144 }
145
FLAC__window_hann(FLAC__real * window,const FLAC__int32 L)146 void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L)
147 {
148 const FLAC__int32 N = L - 1;
149 FLAC__int32 n;
150
151 for (n = 0; n < L; n++)
152 window[n] = (FLAC__real)(0.5f - 0.5f * cosf(2.0f * M_PI * n / N));
153 }
154
FLAC__window_kaiser_bessel(FLAC__real * window,const FLAC__int32 L)155 void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L)
156 {
157 const FLAC__int32 N = L - 1;
158 FLAC__int32 n;
159
160 for (n = 0; n < L; n++)
161 window[n] = (FLAC__real)(0.402f - 0.498f * cosf(2.0f * M_PI * n / N) + 0.098f * cosf(4.0f * M_PI * n / N) - 0.001f * cosf(6.0f * M_PI * n / N));
162 }
163
FLAC__window_nuttall(FLAC__real * window,const FLAC__int32 L)164 void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L)
165 {
166 const FLAC__int32 N = L - 1;
167 FLAC__int32 n;
168
169 for (n = 0; n < L; n++)
170 window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cosf(2.0f*M_PI*n/N) + 0.1365995f*cosf(4.0f*M_PI*n/N) - 0.0106411f*cosf(6.0f*M_PI*n/N));
171 }
172
FLAC__window_rectangle(FLAC__real * window,const FLAC__int32 L)173 void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L)
174 {
175 FLAC__int32 n;
176
177 for (n = 0; n < L; n++)
178 window[n] = 1.0f;
179 }
180
FLAC__window_triangle(FLAC__real * window,const FLAC__int32 L)181 void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L)
182 {
183 FLAC__int32 n;
184
185 if (L & 1) {
186 for (n = 1; n <= (L+1)/2; n++)
187 window[n-1] = 2.0f * n / ((float)L + 1.0f);
188 for (; n <= L; n++)
189 window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
190 }
191 else {
192 for (n = 1; n <= L/2; n++)
193 window[n-1] = 2.0f * n / ((float)L + 1.0f);
194 for (; n <= L; n++)
195 window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
196 }
197 }
198
FLAC__window_tukey(FLAC__real * window,const FLAC__int32 L,const FLAC__real p)199 void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p)
200 {
201 if (p <= 0.0)
202 FLAC__window_rectangle(window, L);
203 else if (p >= 1.0)
204 FLAC__window_hann(window, L);
205 else if (!(p > 0.0f && p < 1.0f))
206 /* p is not between 0 and 1, probably NaN.
207 * Default to 0.5 */
208 FLAC__window_tukey(window, L, 0.5f);
209 else {
210 const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1;
211 FLAC__int32 n;
212 /* start with rectangle... */
213 FLAC__window_rectangle(window, L);
214 /* ...replace ends with hann */
215 if (Np > 0) {
216 for (n = 0; n <= Np; n++) {
217 window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * n / Np));
218 window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * (n+Np) / Np));
219 }
220 }
221 }
222 }
223
FLAC__window_partial_tukey(FLAC__real * window,const FLAC__int32 L,const FLAC__real p,const FLAC__real start,const FLAC__real end)224 void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
225 {
226 const FLAC__int32 start_n = (FLAC__int32)(start * L);
227 const FLAC__int32 end_n = (FLAC__int32)(end * L);
228 const FLAC__int32 N = end_n - start_n;
229 FLAC__int32 Np, n, i;
230
231 if (p <= 0.0f)
232 FLAC__window_partial_tukey(window, L, 0.05f, start, end);
233 else if (p >= 1.0f)
234 FLAC__window_partial_tukey(window, L, 0.95f, start, end);
235 else if (!(p > 0.0f && p < 1.0f))
236 /* p is not between 0 and 1, probably NaN.
237 * Default to 0.5 */
238 FLAC__window_partial_tukey(window, L, 0.5f, start, end);
239 else {
240
241 Np = (FLAC__int32)(p / 2.0f * N);
242
243 for (n = 0; n < start_n && n < L; n++)
244 window[n] = 0.0f;
245 for (i = 1; n < (start_n+Np) && n < L; n++, i++)
246 window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Np));
247 for (; n < (end_n-Np) && n < L; n++)
248 window[n] = 1.0f;
249 for (i = Np; n < end_n && n < L; n++, i--)
250 window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Np));
251 for (; n < L; n++)
252 window[n] = 0.0f;
253 }
254 }
255
FLAC__window_punchout_tukey(FLAC__real * window,const FLAC__int32 L,const FLAC__real p,const FLAC__real start,const FLAC__real end)256 void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
257 {
258 const FLAC__int32 start_n = (FLAC__int32)(start * L);
259 const FLAC__int32 end_n = (FLAC__int32)(end * L);
260 FLAC__int32 Ns, Ne, n, i;
261
262 if (p <= 0.0f)
263 FLAC__window_punchout_tukey(window, L, 0.05f, start, end);
264 else if (p >= 1.0f)
265 FLAC__window_punchout_tukey(window, L, 0.95f, start, end);
266 else if (!(p > 0.0f && p < 1.0f))
267 /* p is not between 0 and 1, probably NaN.
268 * Default to 0.5 */
269 FLAC__window_punchout_tukey(window, L, 0.5f, start, end);
270 else {
271
272 Ns = (FLAC__int32)(p / 2.0f * start_n);
273 Ne = (FLAC__int32)(p / 2.0f * (L - end_n));
274
275 for (n = 0, i = 1; n < Ns && n < L; n++, i++)
276 window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ns));
277 for (; n < start_n-Ns && n < L; n++)
278 window[n] = 1.0f;
279 for (i = Ns; n < start_n && n < L; n++, i--)
280 window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ns));
281 for (; n < end_n && n < L; n++)
282 window[n] = 0.0f;
283 for (i = 1; n < end_n+Ne && n < L; n++, i++)
284 window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ne));
285 for (; n < L - (Ne) && n < L; n++)
286 window[n] = 1.0f;
287 for (i = Ne; n < L; n++, i--)
288 window[n] = (FLAC__real)(0.5f - 0.5f * cosf(M_PI * i / Ne));
289 }
290 }
291
FLAC__window_welch(FLAC__real * window,const FLAC__int32 L)292 void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L)
293 {
294 const FLAC__int32 N = L - 1;
295 const double N2 = (double)N / 2.;
296 FLAC__int32 n;
297
298 for (n = 0; n <= N; n++) {
299 const double k = ((double)n - N2) / N2;
300 window[n] = (FLAC__real)(1.0f - k * k);
301 }
302 }
303
304 #if defined(_MSC_VER)
305 #pragma warning ( default : 4244 )
306 #endif
307
308 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
309