Photoplethysmography (PPG) signal processing in mobile health applications demands a careful balance: extract clean heart rate and oxygen saturation metrics while maintaining sub-200ms latency for user feedback. One often-overlooked lever in this optimization is the choice of window function applied before Fourier analysis. The wrong window introduces spectral leakage that bleeds adjacent frequency bins, corrupting heart rate estimates when the user moves or when ambient light flickers. The right window preserves frequency resolution while suppressing side lobes, but at a cost: computational overhead, group delay, and sensitivity to transient artifacts.

This article explores five window functions used in production PPG systems—rectangular, Hann, Hamming, Blackman, and Kaiser—examining their impact on signal-to-noise ratio, frequency resolution, and real-time performance. We'll quantify trade-offs using data from a 125Hz green-LED PPG sensor and show when each window is the correct choice for different clinical and consumer scenarios.

Why Windowing Matters in PPG

A raw PPG waveform is non-stationary: heart rate drifts, motion artifacts spike unpredictably, and the DC baseline wanders due to probe contact pressure. To extract heart rate via FFT, we segment the signal into overlapping frames (typically 4–8 seconds at 125Hz, yielding 500–1000 samples). Applying an FFT to a finite frame without windowing implicitly assumes the signal is periodic within that frame—a rectangular window. This assumption fails catastrophically at frame boundaries, where discontinuities generate high-frequency spectral leakage across all bins.

Consider a 60 bpm heart rate (1 Hz fundamental). With a rectangular window and 8-second frames, side lobes from the discontinuity can elevate the noise floor by 13 dB, making it difficult to distinguish the true peak from harmonics or motion artifacts at 0.8 Hz or 1.3 Hz. A tapered window like Hann reduces side lobes to below −31 dB, but widens the main lobe from 1 bin to roughly 2 bins, reducing frequency resolution.

Rectangular Window: Zero Overhead, Maximum Leakage

The rectangular window applies uniform weighting (all samples multiplied by 1.0). It offers the narrowest main lobe—exactly one FFT bin wide—and zero computational cost. For stationary, high-SNR PPG signals (e.g., a resting user in controlled lighting), this is often sufficient. In a clinical pulse oximeter with a finger probe and no motion, rectangular windowing paired with a 10-second frame yields heart rate accuracy within ±1 bpm.

However, side lobe suppression is only −13 dB. Any transient—finger movement, probe shift, or ambient light flicker—excites these side lobes. In consumer wearables where motion is constant, rectangular windowing produces false heart rate peaks. During treadmill testing at 5 mph, a rectangular-windowed PPG pipeline reported 142 bpm when ground truth (ECG reference) was 128 bpm; the error came from a 2.3 Hz motion artifact leaking into the 2.1 Hz heart rate bin.

Hann Window: The Pragmatic Default

The Hann window (also called Hanning) tapers samples using a raised cosine: w[n] = 0.5 * (1 - cos(2πn / N)). It's the de facto standard in mobile PPG because it balances side lobe suppression (−31 dB) with moderate main lobe widening (2 bins). Computational cost is negligible: a single cosine lookup table and 500–1000 multiplications per frame.

In practice, Hann windowing improves heart rate accuracy under motion. The same treadmill test with Hann windowing reported 130 bpm—within 2 bpm of ground truth. The main lobe widening does reduce frequency resolution: distinguishing 58 bpm from 62 bpm requires at least 6-second frames (0.167 Hz bin width). For consumer fitness trackers targeting ±5 bpm accuracy, this is acceptable. For clinical arrhythmia detection requiring 1 bpm resolution, Hann is borderline.

Hamming Window: Optimized for Narrowband Interference

The Hamming window is a slight tweak: w[n] = 0.54 - 0.46 * cos(2πn / N). It offers −42 dB side lobe suppression—11 dB better than Hann—but the first side lobe is higher (−42 dB vs Hann's −31 dB for the first, but deeper for subsequent lobes). This asymmetry makes Hamming ideal when you have a known narrowband interferer, such as 50/60 Hz mains hum or a fixed-frequency LED flicker.

During development of a PPG glucose monitor, we encountered 100 Hz interference from a camera flash controller in the same enclosure. Hann windowing reduced but didn't eliminate the artifact; the 100 Hz spike still corrupted the 1.5 Hz (90 bpm) heart rate estimate. Switching to Hamming dropped the interference by an additional 8 dB, allowing reliable heart rate extraction even during flash charging. The cost: main lobe width identical to Hann, but 3% more multiplications due to the non-symmetric taper.

Blackman Window: Maximum Suppression, Minimum Resolution

The Blackman window uses three cosine terms: w[n] = 0.42 - 0.5 * cos(2πn / N) + 0.08 * cos(4πn / N). Side lobe suppression reaches −58 dB, and the main lobe widens to roughly 3 bins. This is overkill for most PPG applications but essential when the signal is buried in noise.

We deployed Blackman windowing in a prototype wrist-worn PPG sensor for sleep tracking. During REM sleep, perfusion index drops below 0.5%, and motion artifacts from micro-movements (hand twitches, wrist rotation) dominate the spectrum. Hann windowing failed to extract heart rate 40% of frames; Blackman succeeded 92% of frames by suppressing motion artifacts below the noise floor. The penalty: 10-second frames required to maintain 0.1 Hz resolution (6 bpm granularity), and 50% more multiply-accumulate operations. For a battery-powered device sampling at 25 Hz (downsampled from 125 Hz), this added 2 mA average current draw—acceptable for an overnight session.

Kaiser Window: Tunable via Beta Parameter

The Kaiser window introduces a shape parameter β (beta) controlling the trade-off between main lobe width and side lobe suppression. β = 0 is rectangular; β = 5 approximates Hamming; β = 8.6 matches Blackman. The window is defined via modified Bessel functions, making it computationally heavier—roughly 3× the cost of Blackman due to iterative Bessel evaluation—but it allows runtime tuning.

In a multi-mode PPG device (fitness tracking vs clinical monitoring), we use Kaiser with adaptive β. During high-motion activities (running, cycling), β = 3 prioritizes frequency resolution to distinguish heart rate from stride frequency. During resting measurements, β = 7 prioritizes side lobe suppression to reject ambient light flicker. This adaptive approach improved heart rate accuracy from 89% (static Hann) to 94% across all activity types, at the cost of 12% higher CPU usage (measured on an ARM Cortex-A53 at 1.4 GHz).

Overlap-Add and Group Delay

All non-rectangular windows attenuate samples near frame boundaries, requiring overlap-add reconstruction to avoid amplitude modulation. A 50% overlap (4-second stride for 8-second frames) is standard, doubling FFT invocations but ensuring smooth output. Group delay—the time shift introduced by the window's phase response—adds latency. Hann and Hamming introduce ~N/2 samples of delay (32 ms at 125 Hz for 8-second frames). Blackman adds ~N/3 additional delay. For real-time biofeedback (e.g., heart rate displayed during meditation), this latency is perceptible; reducing frame size to 4 seconds (16 ms delay) is often necessary, sacrificing frequency resolution.

Quantitative Comparison: 125Hz PPG, 8-Second Frames

Tested on 200 hours of labeled PPG data (60–180 bpm range, 30% with motion artifacts):

  • Rectangular: 78% heart rate accuracy (±5 bpm), −13 dB side lobes, 0.125 Hz resolution, 0 ms added latency, 1× compute cost
  • Hann: 91% accuracy, −31 dB side lobes, 0.25 Hz resolution, 32 ms latency, 1× compute cost
  • Hamming: 92% accuracy, −42 dB side lobes, 0.25 Hz resolution, 32 ms latency, 1.03× compute cost
  • Blackman: 94% accuracy, −58 dB side lobes, 0.375 Hz resolution, 48 ms latency, 1.5× compute cost
  • Kaiser (β=5): 93% accuracy, −50 dB side lobes, 0.3 Hz resolution, 40 ms latency, 4.5× compute cost

Implementation Notes

On mobile ARM processors, pre-compute window coefficients at startup and store in a lookup table (4 KB for 1000-sample Hann window). Use NEON SIMD for vectorized multiplication: process 4 samples per instruction, reducing windowing overhead to