# Is the DCT prone to spectral leakage like the DFT?

My understanding is that the DCT assumes the input to be an even periodic signal.
This avoids the discontinuity that can occur in the periodic extension assumed by the DFT (see image).
Does this lack of discontinuity prevent spectral leakage from occurring in the DCT?
If so, why are input signals still often windowed prior to DCT?

Thanks

• my goodness this is a refreshingly good question. someone give this guy some points. – robert bristow-johnson Sep 13 '20 at 6:57

A window function other than rectangular can be applied to suppress sidelobes also with the discrete cosine transform (DCT). Window functions are also sometimes used together with some flavors of DCT as a lapped transform, with pre and post windowing providing some protection against reflection artifacts arising from processing (such as quantization) of the DCT data.

Here is tested to multiply a real sinusoidal input by 1) a rectangular window or 2) a Hamming window, before DCT analysis. The tested inputs are cosines with different phase shifts. Phase shifts that are multiples of 90 degrees give identical results in the magnitude of DCT. Each plot shows the magnitude of DFT in decibel scale for multiple different fractional offsets of the sinusoid frequency from a DCT bin frequency, in units of bin width. Octave's dct was used for the calculations.

## DCT of cosine with 0 degree phase shift:

Rectangular window:

Hamming window:

## DCT of cosine with +45 degree phase shift:

Rectangular window:

Hamming window:

## DCT of cosine with -45 degree phase shift:

Rectangular window:

Hamming window:

Note that depending on the phase of the real sinusoid, its DCT, and DCT of the sinusoid multiplied by a window function, will be more or less spiky, which is another phenomenon than the window's much lower sidelobes.

Octave source:

pkg load signal;
phase = 2*pi/8; # Phase shift of the cosine
N = 256; # Sequence length
M = 8; # Number of fractional shifts that are in range 0..1 of DCT bin width
n = [0:N-1]'; # Zero-based index
omega = 2*pi*(0.25 + 0.5*[0:M]/M + 0.5*round(N/M)*[0:M]); # Cosine frequency
x = 2*real(exp(i*(n.*omega/N + phase))); # Cosine with phase shift
plot(n/(M*round(N/M)), 20*log10(abs(dct(x)/sqrt(N))));
xlim([0, 1]);
ylim([-60, 0]);
title(["rectangular window, cosine phase shift = " num2str(360*phase/(2*pi)) " deg"]);
xlabel("bin (not labeled), for each peak: fractional offset of cosine from bin center");
ylabel("|DCT(x)[k]| (dB)");

y = x .* hamming(N);
plot(n/(M*round(N/M)), 20*log10(abs(dct(y)/sqrt(N))));
xlim([0, 1]);
ylim([-60, 0]);
title(["Hamming window, cosine phase shift = " num2str(360*phase/(2*pi)) " deg"]);
xlabel("k (not labeled); for each peak: fractional offset of cosine from bin center");
ylabel("|DCT(x)[k]| (dB)");