This is the implementation guide for the Hann window. For theoretical background, including mathematical formula, frequency response, and spectral analysis, see the the article on Hann window.
All code examples are written in C for maximum performance and portability.
Direct Implementation
The following function computes the Hann window value for a given sample index n and total window length N. The window is symmetric and tapers smoothly to zero at both ends.
#include <math.h>
/**
* Compute Hann window coefficient for a single sample.
*
* @param n Sample index (0 to N-1)
* @param N Total window length
* @return Window coefficient (0.0 to 1.0)
*/
double hann_window_sample(int n, int N) {
if (N <= 1) return 1.0;
if (n < 0 || n >= N) return 0.0;
return 0.5 - 0.5 * cos(2 * M_PI * n / (N - 1));
}
Full Array Implementation
For better performance when the entire window is needed, the following function fills a pre-allocated array with all coefficients at once.
#include <math.h>
#include <stdlib.h>
/**
* Generate full Hann window array.
*
* @param N Length of the window (number of samples)
* @param out Output array of length N (must be pre-allocated)
*/
void hann_window_array(int N, double *out) {
if (N <= 0) return;
if (N == 1) {
out[0] = 1.0;
return;
}
for (int i = 0; i < N; i++) {
out[i] = 0.5 - 0.5 * cos(2 * M_PI * i / (N - 1));
}
}
Usage Example
The following example demonstrates how to apply the Hann window to a real signal.
#include <stdio.h>
#include <math.h>
#define N 512
int main() {
double window[N];
double signal[N];
double windowed[N];
// Generate Hann window
hann_window_array(N, window);
// Generate test signal (sinusoid with non-integer period)
for (int i = 0; i < N; i++) {
signal[i] = sin(2 * M_PI * i / 9.5);
}
// Apply window to signal
for (int i = 0; i < N; i++) {
windowed[i] = signal[i] * window[i];
}
// Print first 10 samples
printf("n\twindow\tsignal\t\twindowed\n");
for (int i = 0; i < 10; i++) {
printf("%d\t%.6f\t%.6f\t%.6f\n",
i, window[i], signal[i], windowed[i]);
}
return 0;
}
Expected Output (first 5 samples)
n window signal windowed
0 0.000000 0.000000 0.000000
1 0.000148 0.647387 0.000096
2 0.000589 0.998351 0.000588
3 0.001322 0.907575 0.001200
4 0.002342 0.460073 0.001078
Implementation Notes
- Numerical stability: The formula uses
cos(2πn/(N-1)), which ensures the first sample (n=0) and last sample (n=N-1) are exactly zero. - Symmetry: The window is perfectly symmetric:
w[n] = w[N-1-n]for all n. - Edge case N=1: The only coefficient is 1.0.
- Precomputation: For real-time applications, precompute the window once and reuse it for multiple signal blocks.
Alternative: Precomputed Lookup Table
For embedded systems or when speed is critical, precompute the window at compile time:
#define N 512
static const double HANN_WINDOW[N] = {
0.000000, 0.000148, 0.000589, 0.001322, 0.002342, /* ... */
/* Full table would be generated by a script */
};
// Usage
for (int i = 0; i < N; i++) {
windowed[i] = signal[i] * HANN_WINDOW[i];
}
See also:The Hann Window in DSP