Прямоугольное окно длины M имеет частотную характеристику sin(ω*M/2)/sin(ω/2)
, которая равна нулю, когда ω = 2*π*k/M
, для k ≠ 0. Для ДПФ длины N, где ω = 2*π*n/N
, есть нули в n = k * N/M
.Отношение N / M не обязательно является целым числом.Например, если N = 40 и M = 32, то в DFT появятся нулевые значения, кратные 1,25, но в DFT появятся только целочисленные кратные значения, которые в данном случае равны 5, 10, 15 и 20.
Вот график 1024-точечного ДПФ прямоугольного окна с 32 точками:
M = 32
N = 1024
w = ones(M)
W = rfft(w, N)
K = N/M
nulls = abs(W[K::K])
plot(abs(W))
plot(r_[K:N/2+1:K], nulls, 'ro')
xticks(r_[:512:64])
grid(); axis('tight')
Обратите внимание на нули в каждом N / M = 32 бункеров,Если N = M (т. Е. Длина окна равна длине ДПФ), то во всех бинах будут нулевые значения, кроме n = 0.
Когда вы умножаете окно на сигнал, соответствующая операция в частотной областикруговая свертка спектра окна со спектром сигнала.Например, DTFT синусоиды представляет собой взвешенную дельта-функцию (т.е. импульс с бесконечной высотой, бесконечно малым расширением и конечной площадью), расположенный на положительной и отрицательной частоте синусоиды.Свертывание спектра с дельта-функцией просто смещает его к местоположению дельты и масштабирует по весу дельты.Поэтому, когда вы умножаете окно на синусоиду в области выборки, частотная характеристика окна масштабируется и сдвигается на частоту синусоиды.
Существует несколько сценариев для изучения длины прямоугольного окна.Сначала давайте рассмотрим случай, когда длина окна является целым кратным периода синусоиды, например, прямоугольное окно косинуса с 32 выборками с периодом 32/8 = 4 выборки:
x1 = cos(2*pi*8*r_[:32]/32) # ω0 = 8π/16, bin 8/32 * 1024 = 256
X1 = rfft(x1 * w, 1024)
plot(abs(X1))
xticks(r_[:513:64])
grid(); axis('tight')
Как и прежде, есть значения NULL при значениях, кратных N / M = 32. Но спектр окна был смещен в корзину 256 синусоиды и масштабирован по ее величине, которая на 0,5 делится между положительной частотойи отрицательная частота (я только строю положительные частоты).Если бы длина DFT была 32, нули были бы выстроены в линию в каждом бункере, подсказывая появление , что нет утечки.Но этот вводящий в заблуждение вид является только функцией длины ДПФ.Если вы добавите в оконный сигнал нули (как указано выше), вы увидите синусоидальный отклик на частотах между нулями.
Теперь давайте рассмотрим случай, когда длина окна не является целым числомкратный периоду синусоиды, например, косинус с угловой частотой 7,5 / 16 (период 64 выборки):
x2 = cos(2*pi*15*r_[:32]/64) # ω0 = 7.5π/16, bin 15/64 * 1024 = 240
X2 = rfft(x2 * w, 1024)
plot(abs(X2))
xticks(r_[-16:513:64])
grid(); axis('tight')
Расположение центральной ячейки нетбольше на целое число, кратное 32, но смещено вдвое к бину 240. Итак, давайте посмотрим, как будет выглядеть соответствующий 32-точечный ДПФ (выводя прямоугольное окно из 32 точек).Я вычислю и нарисую 32-точечное ДПФ x2 [n], а также наложу 32-кратную десятичную копию 1024-точечного ДПФ:
X2_32 = rfft(x2, 32)
X2_sample = X2[::32]
stem(r_[:17],abs(X2_32))
plot(abs(X2_sample), 'rs') # red squares
grid(); axis([0,16,0,11])
Как выКак видно на предыдущем графике, нулевые значения больше не выровнены с кратными 32, поэтому величина 32-точечного ДПФ не равна нулю в каждом бине.В 32-точечном DFT нулевые значения окна по-прежнему расположены через каждые N / M = 32/32 = 1 бин, но, поскольку ω0 = 7.5π / 16, центр находится в «bin» 7.5, что устанавливает нули в 0.5, 1.5и т. д., поэтому они отсутствуют в 32-точечном DFT.
Общее сообщение состоит в том, что спектральная утечка оконного сигнала всегда присутствует , но может быть замаскирована в DFT, еслиСпектр сигнала, длина окна и длина DFT объединяются в едином правильном порядке, чтобы выровнять нули.Кроме того, вы должны просто игнорировать эти артефакты DFT и сконцентрироваться на DTFT вашего сигнала (т. Е. Заполнить нулями пробу DTFT с более высоким разрешением, чтобы вы могли четко изучить утечку).
Спектральная утечка, вызванная свертыванием со спектром окна, всегда будет существовать, поэтому искусство изготовления окон особой формы так важно.Спектр каждого типа окна был адаптирован для конкретной задачи, такой как динамический диапазон или чувствительность.
Вот пример, сравнивающий выходные данные прямоугольного окна с окном Хемминга:
from pylab import *
import wave
fs = 44100
M = 4096
N = 16384
# load a sample of guitar playing an open string 6
# with a fundamental frequency of 82.4 Hz
g = fromstring(wave.open('dist_gtr_6.wav').readframes(-1),
dtype='int16')
L = len(g)/4
g_t = g[L:L+M]
g_t = g_t / float64(max(abs(g_t)))
# compute the response with rectangular vs Hamming window
g_rect = rfft(g_t, N)
g_hamm = rfft(g_t * hamming(M), N)
def make_plot():
fmax = int(82.4 * 4.5 / fs * N) # 4 harmonics
subplot(211); title('Rectangular Window')
plot(abs(g_rect[:fmax])); grid(); axis('tight')
subplot(212); title('Hamming Window')
plot(abs(g_hamm[:fmax])); grid(); axis('tight')
if __name__ == "__main__":
make_plot()