Tukey window (impl.)

This is the implementation guide for the Tukey window (also known as the tapered cosine window). For theoretical background, including mathematical formula, frequency response, and spectral analysis, see the the article on Tukey window.

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


Direct Implementation

The following function computes the Tukey window value for a given sample index n and total window length N. The Tukey window uses an α (alpha) parameter that controls the proportion of the window that is tapered.


#include <math.h>

/**
 * Compute Tukey window coefficient for a single sample.
 *
 * @param n     Sample index (0 to N-1)
 * @param N     Total window length
 * @param alpha Shape parameter (0 <= alpha <= 1)
 *              alpha = 0 → Rectangular window
 *              alpha = 0.5 → 50% cosine taper
 *              alpha = 1 → Hann window (fully tapered)
 * @return      Window coefficient (0.0 to 1.0)
 */
double tukey_window_sample(int n, int N, double alpha) {
    if (N <= 1) return 1.0;
    if (n < 0 || n >= N) return 0.0;
    
    /* Clamp alpha to [0, 1] */
    if (alpha <= 0.0) return 1.0;
    if (alpha >= 1.0) alpha = 1.0;
    
    double m = (N - 1) / 2.0;
    double r = alpha * m;
    
    if (fabs(n - m) >= r) {
        return 1.0;
    }
    
    double x = (n - m) / r;
    return 0.5 * (1.0 + cos(M_PI * x));
}

Alternative Implementation (Piecewise)

The Tukey window can also be expressed as a piecewise function with three regions: rising cosine taper, flat top, and falling cosine taper.


/**
 * Compute Tukey window using piecewise formula.
 *
 * @param n     Sample index (0 to N-1)
 * @param N     Total window length
 * @param alpha Shape parameter (0 <= alpha <= 1)
 * @return      Window coefficient
 */
double tukey_window_piecewise(int n, int N, double alpha) {
    if (N <= 1) return 1.0;
    if (alpha <= 0.0) return 1.0;
    if (alpha >= 1.0) {
        /* Fully tapered → Hann window */
        return 0.5 - 0.5 * cos(2 * M_PI * n / (N - 1));
    }
    
    double m = (N - 1) / 2.0;
    double r = alpha * m;
    double x = fabs(n - m) - r;
    
    if (fabs(n - m) >= r) {
        return 1.0;
    }
    
    double theta = M_PI * (x / (m - r));
    return 0.5 * (1.0 + cos(theta));
}

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 
#include 

/**
 * Generate full Tukey window array.
 *
 * @param N     Length of the window (number of samples)
 * @param alpha Shape parameter (0 <= alpha <= 1)
 * @param out   Output array of length N (must be pre-allocated)
 */
void tukey_window_array(int N, double alpha, double *out) {
    if (N <= 0) return;
    
    if (N == 1) {
        out[0] = 1.0;
        return;
    }
    
    /* Clamp alpha to [0, 1] */
    if (alpha <= 0.0) {
        for (int i = 0; i < N; i++) out[i] = 1.0;
        return;
    }
    
    if (alpha >= 1.0) {
        /* Fully tapered → Hann window */
        for (int i = 0; i < N; i++) {
            out[i] = 0.5 - 0.5 * cos(2 * M_PI * i / (N - 1));
        }
        return;
    }
    
    double m = (N - 1) / 2.0;
    double r = alpha * m;
    
    for (int i = 0; i < N; i++) {
        if (fabs(i - m) >= r) {
            out[i] = 1.0;
        } else {
            double x = (i - m) / r;
            out[i] = 0.5 * (1.0 + cos(M_PI * x));
        }
    }
}

Usage Example

The following example demonstrates how to apply the Tukey window to a real signal with different alpha values.


#include 
#include 

#define N 64
#define ALPHA 0.5

int main() {
    double window[N];
    double signal[N];
    double windowed[N];
    
    // Generate Tukey window (alpha = 0.5)
    tukey_window_array(N, ALPHA, window);
    
    // Generate test signal (sinusoid)
    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    window      signal      windowed\n");
    for (int i = 0; i < 10; i++) {
        printf("%d    %.6f    %.6f    %.6f\n", 
               i, window[i], signal[i], windowed[i]);
    }
    
    return 0;
}

Expected Output (first 5 samples, N=64, α=0.5)

n    window      signal      windowed
0    0.292893    0.000000    0.000000
1    0.324423    0.647387    0.210034
2    0.356434    0.998351    0.355809
3    0.388726    0.907575    0.352854
4    0.421070    0.460073    0.193726

Implementation Notes

  • Tapered cosine shape: The Tukey window has a flat top (no tapering) and a cosine-shaped rising/falling edges at the ends.
  • Alpha parameter:
    • α = 0.0 → Rectangular window (no taper at all)
    • α = 0.5 → 50% of the window is tapered, 50% is flat
    • α = 1.0 → Hann window (fully tapered)
  • Sidelobe level: Increases with smaller alpha (more rectangular-like).
  • Main lobe width: Decreases with smaller alpha (better resolution).
  • Symmetry: The window is perfectly symmetric: w[n] = w[N-1-n] for all n.
  • Endpoints: For 0 < α < 1, endpoints are < 1. For α = 0, endpoints are 1. For α = 1, endpoints are 0.
  • 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. The values depend on the chosen alpha parameter:


#define N 64
#define ALPHA 0.5

static const double TUKEY_WINDOW[N] = {
    0.292893, 0.324423, 0.356434, 0.388726, 0.421070, /* ... */
    /* Full table would be generated by a script */
};

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

Tukey Window vs Other Windows

The Tukey window's alpha parameter provides continuous control between rectangular and Hann:

α value    Main lobe width    First sidelobe    Shape
0.0        ~0.04              -13 dB            Rectangular
0.25       ~0.05              -20 dB            Slight taper
0.5        ~0.06              -26 dB            Moderate taper
0.75       ~0.07              -30 dB            Heavy taper
1.0        ~0.08              -31 dB            Hann (fully tapered)

Practical Alpha Selection

Common alpha values for different applications:

α       Application
0.2-0.3  Spectral analysis where frequency resolution is critical
0.4-0.6  General purpose – good balance
0.7-0.8  When spectral leakage reduction is more important than resolution
0.9-1.0  When smooth tapering is required (similar to Hann)

See also: The Tukey Window in DSP