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