Hamming, Blackman, and Blackman-Harris
Python. This is my implementation for some of windows used in audio applications. I chose Hamming, Blackman, and Blackman-Harris window functions. Instead of using FFT pack, I directly applied DFT since the DFT size is not too big. I scaled the amplitude for a better view. In the figure, we see their main-lobe width and side-lobes. The main lobe and the highest side lobe are important for us. I chose the small window and DFT sizes (64 and 512).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
import numpy as np import matplotlib.pyplot as plt def WindowFreqResponses(M = 64, N = 512): #Window and DFT sizes have to be even #HAMMING WINDOW nh = np.arange(-M/2, M/2) w1 = 0.54 + 0.46 * np.cos(2 * np.pi * nh / M) #BLACKMAN WINDOW nb = np.arange(0, M) w2 = 0.42 - 0.5 *np.cos(2 * np.pi * nb / M) + 0.08 * np.cos(4 * np.pi * nb / M) #BLACKMAN-HARRIS nbh = np.arange(-M/2, M/2) w3 = np.zeros(M) coefficient = [0.35875, 0.48829, 0.14128, 0.01168] for i in range(0, 4): w3 += coefficient[i] * np.cos(2 * np.pi * i * nbh / M) w3 = w3 / M #Taking DFT and plotting for each window plt.subplot(131) DFT(w1, M, N) plt.title('Hamming') plt.ylabel('amplitude (dB)') plt.subplot(132) DFT(w2, M, N) plt.title('Blackman') plt.xlabel('bins') plt.subplot(133) DFT(w3, M, N) plt.title('Blackman-Harris') plt.show() return def DFT(w, M, N): hWindow = int(M/2) #Half of window size fftbuffer = np.zeros(N) #Zero-padding fftbuffer[:hWindow] = w[hWindow:] fftbuffer[N-hWindow:] = w[:hWindow] #DFT Calculation X = np.array([]) for k in range(N): s = np.exp(-1j * 2 * np.pi * k * np.arange(N)/ N) X = np.append(X, sum(fftbuffer*s)) mX = abs(X) #Amplitude mX[mX<np.finfo(float).eps] = np.finfo(float).eps #For machine epsilon mXdb = 20*np.log10(mX) #Amplitude in dB hDFT = int(N/2) #Half of DFT size scaledmX = np.zeros(N) #For a better view scaledmX[:hDFT] = mXdb[hDFT:] scaledmX[hDFT:] = mXdb[:hDFT] plt.plot(np.arange(-N/2,N/2)/float(N)*M, scaledmX - max(scaledmX), 'b') plt.axis([-15, 15, -100, 0]) return ### WindowFreqResponses() |
The results are (approximately):
Hamming: Main lobe width is 4 bins and side-lobe level is -42.7 dB.
Blackman: Main lobe width is 6 bins and side-lobe level is -58.2 dB.
Blackman-Harris: Main lobe width is 8 bins and side-lobe level is -92 dB.
References:
[1] Mathematics of the Discrete Fourier Transform, Julius O. Smith III [2] FFT Bin Interpolation, Ted Knowlton [3] Windows, Matlab Documentation