Home | History | Annotate | Download | only in libFLAC
      1 /* libFLAC - Free Lossless Audio Codec library
      2  * Copyright (C) 2006-2009  Josh Coalson
      3  * Copyright (C) 2011-2016  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 
     46 void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L)
     47 {
     48 	const FLAC__int32 N = L - 1;
     49 	FLAC__int32 n;
     50 
     51 	if (L & 1) {
     52 		for (n = 0; n <= N/2; n++)
     53 			window[n] = 2.0f * n / (float)N;
     54 		for (; n <= N; n++)
     55 			window[n] = 2.0f - 2.0f * n / (float)N;
     56 	}
     57 	else {
     58 		for (n = 0; n <= L/2-1; n++)
     59 			window[n] = 2.0f * n / (float)N;
     60 		for (; n <= N; n++)
     61 			window[n] = 2.0f - 2.0f * n / (float)N;
     62 	}
     63 }
     64 
     65 void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L)
     66 {
     67 	const FLAC__int32 N = L - 1;
     68 	FLAC__int32 n;
     69 
     70 	for (n = 0; n < L; n++)
     71 		window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N-0.5f) - 0.38f * cos(2.0f * M_PI * ((float)n/(float)N)));
     72 }
     73 
     74 void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L)
     75 {
     76 	const FLAC__int32 N = L - 1;
     77 	FLAC__int32 n;
     78 
     79 	for (n = 0; n < L; n++)
     80 		window[n] = (FLAC__real)(0.42f - 0.5f * cos(2.0f * M_PI * n / N) + 0.08f * cos(4.0f * M_PI * n / N));
     81 }
     82 
     83 /* 4-term -92dB side-lobe */
     84 void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L)
     85 {
     86 	const FLAC__int32 N = L - 1;
     87 	FLAC__int32 n;
     88 
     89 	for (n = 0; n <= N; n++)
     90 		window[n] = (FLAC__real)(0.35875f - 0.48829f * cos(2.0f * M_PI * n / N) + 0.14128f * cos(4.0f * M_PI * n / N) - 0.01168f * cos(6.0f * M_PI * n / N));
     91 }
     92 
     93 void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L)
     94 {
     95 	const FLAC__int32 N = L - 1;
     96 	const double N2 = (double)N / 2.;
     97 	FLAC__int32 n;
     98 
     99 	for (n = 0; n <= N; n++) {
    100 		double k = ((double)n - N2) / N2;
    101 		k = 1.0f - k * k;
    102 		window[n] = (FLAC__real)(k * k);
    103 	}
    104 }
    105 
    106 void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L)
    107 {
    108 	const FLAC__int32 N = L - 1;
    109 	FLAC__int32 n;
    110 
    111 	for (n = 0; n < L; n++)
    112 		window[n] = (FLAC__real)(1.0f - 1.93f * cos(2.0f * M_PI * n / N) + 1.29f * cos(4.0f * M_PI * n / N) - 0.388f * cos(6.0f * M_PI * n / N) + 0.0322f * cos(8.0f * M_PI * n / N));
    113 }
    114 
    115 void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev)
    116 {
    117 	const FLAC__int32 N = L - 1;
    118 	const double N2 = (double)N / 2.;
    119 	FLAC__int32 n;
    120 
    121 	for (n = 0; n <= N; n++) {
    122 		const double k = ((double)n - N2) / (stddev * N2);
    123 		window[n] = (FLAC__real)exp(-0.5f * k * k);
    124 	}
    125 }
    126 
    127 void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L)
    128 {
    129 	const FLAC__int32 N = L - 1;
    130 	FLAC__int32 n;
    131 
    132 	for (n = 0; n < L; n++)
    133 		window[n] = (FLAC__real)(0.54f - 0.46f * cos(2.0f * M_PI * n / N));
    134 }
    135 
    136 void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L)
    137 {
    138 	const FLAC__int32 N = L - 1;
    139 	FLAC__int32 n;
    140 
    141 	for (n = 0; n < L; n++)
    142 		window[n] = (FLAC__real)(0.5f - 0.5f * cos(2.0f * M_PI * n / N));
    143 }
    144 
    145 void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L)
    146 {
    147 	const FLAC__int32 N = L - 1;
    148 	FLAC__int32 n;
    149 
    150 	for (n = 0; n < L; n++)
    151 		window[n] = (FLAC__real)(0.402f - 0.498f * cos(2.0f * M_PI * n / N) + 0.098f * cos(4.0f * M_PI * n / N) - 0.001f * cos(6.0f * M_PI * n / N));
    152 }
    153 
    154 void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L)
    155 {
    156 	const FLAC__int32 N = L - 1;
    157 	FLAC__int32 n;
    158 
    159 	for (n = 0; n < L; n++)
    160 		window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cos(2.0f*M_PI*n/N) + 0.1365995f*cos(4.0f*M_PI*n/N) - 0.0106411f*cos(6.0f*M_PI*n/N));
    161 }
    162 
    163 void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L)
    164 {
    165 	FLAC__int32 n;
    166 
    167 	for (n = 0; n < L; n++)
    168 		window[n] = 1.0f;
    169 }
    170 
    171 void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L)
    172 {
    173 	FLAC__int32 n;
    174 
    175 	if (L & 1) {
    176 		for (n = 1; n <= (L+1)/2; n++)
    177 			window[n-1] = 2.0f * n / ((float)L + 1.0f);
    178 		for (; n <= L; n++)
    179 			window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
    180 	}
    181 	else {
    182 		for (n = 1; n <= L/2; n++)
    183 			window[n-1] = 2.0f * n / ((float)L + 1.0f);
    184 		for (; n <= L; n++)
    185 			window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f);
    186 	}
    187 }
    188 
    189 void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p)
    190 {
    191 	if (p <= 0.0)
    192 		FLAC__window_rectangle(window, L);
    193 	else if (p >= 1.0)
    194 		FLAC__window_hann(window, L);
    195 	else {
    196 		const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1;
    197 		FLAC__int32 n;
    198 		/* start with rectangle... */
    199 		FLAC__window_rectangle(window, L);
    200 		/* ...replace ends with hann */
    201 		if (Np > 0) {
    202 			for (n = 0; n <= Np; n++) {
    203 				window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * n / Np));
    204 				window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * (n+Np) / Np));
    205 			}
    206 		}
    207 	}
    208 }
    209 
    210 void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
    211 {
    212 	const FLAC__int32 start_n = (FLAC__int32)(start * L);
    213 	const FLAC__int32 end_n = (FLAC__int32)(end * L);
    214 	const FLAC__int32 N = end_n - start_n;
    215 	FLAC__int32 Np, n, i;
    216 
    217 	if (p <= 0.0f)
    218 		FLAC__window_partial_tukey(window, L, 0.05f, start, end);
    219 	else if (p >= 1.0f)
    220 		FLAC__window_partial_tukey(window, L, 0.95f, start, end);
    221 	else {
    222 
    223 		Np = (FLAC__int32)(p / 2.0f * N);
    224 
    225 		for (n = 0; n < start_n && n < L; n++)
    226 			window[n] = 0.0f;
    227 		for (i = 1; n < (start_n+Np) && n < L; n++, i++)
    228 			window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
    229 		for (; n < (end_n-Np) && n < L; n++)
    230 			window[n] = 1.0f;
    231 		for (i = Np; n < end_n && n < L; n++, i--)
    232 			window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np));
    233 		for (; n < L; n++)
    234 			window[n] = 0.0f;
    235 	}
    236 }
    237 
    238 void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end)
    239 {
    240 	const FLAC__int32 start_n = (FLAC__int32)(start * L);
    241 	const FLAC__int32 end_n = (FLAC__int32)(end * L);
    242 	FLAC__int32 Ns, Ne, n, i;
    243 
    244 	if (p <= 0.0f)
    245 		FLAC__window_punchout_tukey(window, L, 0.05f, start, end);
    246 	else if (p >= 1.0f)
    247 		FLAC__window_punchout_tukey(window, L, 0.95f, start, end);
    248 	else {
    249 
    250 		Ns = (FLAC__int32)(p / 2.0f * start_n);
    251 		Ne = (FLAC__int32)(p / 2.0f * (L - end_n));
    252 
    253 		for (n = 0, i = 1; n < Ns && n < L; n++, i++)
    254 			window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
    255 		for (; n < start_n-Ns && n < L; n++)
    256 			window[n] = 1.0f;
    257 		for (i = Ns; n < start_n && n < L; n++, i--)
    258 			window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns));
    259 		for (; n < end_n && n < L; n++)
    260 			window[n] = 0.0f;
    261 		for (i = 1; n < end_n+Ne && n < L; n++, i++)
    262 			window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
    263 		for (; n < L - (Ne) && n < L; n++)
    264 			window[n] = 1.0f;
    265 		for (i = Ne; n < L; n++, i--)
    266 			window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne));
    267 	}
    268 }
    269 
    270 void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L)
    271 {
    272 	const FLAC__int32 N = L - 1;
    273 	const double N2 = (double)N / 2.;
    274 	FLAC__int32 n;
    275 
    276 	for (n = 0; n <= N; n++) {
    277 		const double k = ((double)n - N2) / N2;
    278 		window[n] = (FLAC__real)(1.0f - k * k);
    279 	}
    280 }
    281 
    282 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
    283