Hamming window (impl.)

This is the implementation guide for the Hamming window. For theoretical background, including mathematical formula, frequency response, and spectral analysis, see the the article on Hamming window.

All code examples are written in C for maximum performance and portability.


Direct Implementation

The following function computes the Hamming window value for a given sample index n and total window length N. The window is symmetric and tapers smoothly to near zero at both ends (unlike Hann, the endpoints are not zero).


#include <math.h>

/**
 * Compute Hamming 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 hamming_window_sample(int n, int N) {
    if (N <= 1) return 1.0;
    if (n < 0 || n >= N) return 0.0;
    
    const double a0 = 0.54;
    const double a1 = 0.46;
    
    return a0 - a1 * 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 Hamming window array.
 *
 * @param N     Length of the window (number of samples)
 * @param out   Output array of length N (must be pre-allocated)
 */
void hamming_window_array(int N, double *out) {
    if (N <= 0) return;
    
    if (N == 1) {
        out[0] = 1.0;
        return;
    }
    
    const double a0 = 0.54;
    const double a1 = 0.46;
    
    for (int i = 0; i < N; i++) {
        out[i] = a0 - a1 * cos(2 * M_PI * i / (N - 1));
    }
}

Usage Example

The following example demonstrates how to apply the Hamming 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 Hamming window
    hamming_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.080000	0.000000	0.000000
1	0.080145	0.647387	0.051888
2	0.080578	0.998351	0.080465
3	0.081295	0.907575	0.073792
4	0.082287	0.460073	0.037850

Implementation Notes

  • Coefficients: The Hamming window uses a0 = 0.54 and a1 = 0.46, which minimises the first sidelobe level to approximately -41 dB.
  • Non-zero endpoints: Unlike the Hann window, the Hamming window does not taper to zero. The values at n=0 and n=N-1 are 0.08, not zero. This is intentional and helps reduce the first sidelobe.
  • 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 HAMMING_WINDOW[N] = {
    0.080000, 0.080145, 0.080578, 0.081295, 0.082287, /* ... */
    /* Full table would be generated by a script */
};

// Usage
for (int i = 0; i < N; i++) {
    windowed[i] = signal[i] * HAMMING_WINDOW[i];
}

See also: The Hamming Window in DSP