语音信号处理中的“窗函数”
# -*- coding:utf-8 -*-
# Author:凌逆战 | Never
# Date: 2023/1/1
"""
绘制 窗函数和对应的频率响应
"""
import numpy as np
from numpy.fft import rfft
import matplotlib.pyplot as plt
window_len = 60
# frequency response
def frequency_response(window, window_len=window_len, NFFT=2048):
A = rfft(window, NFFT) / (window_len / 2) # (513,)
mag = np.abs(A)
freq = np.linspace(0, 0.5, len(A))
# 忽略警告
with np.errstate(divide='ignore', invalid='ignore'):
response = 20 * np.log10(mag)
response = np.clip(response, -150, 150)
return freq, response
def Rectangle_windows(win_length):
# 矩形窗
return np.ones((win_length))
def Voibis_windows(win_length):
""" Voibis_windows窗函数,RNNoise使用的是它,它满足Princen-Bradley准则。
:param x:
:param win_length: 窗长
:return:
"""
x = np.arange(0, win_length)
return np.sin((np.pi / 2) * np.sin((np.pi * x) / win_length) ** 2)
def sqrt_hanning_windows(win_length, mode="periodic"):
# symmetric: 对称窗,主要用于滤波器的设计
# periodic: 周期窗,常用于频谱分析
if mode == "symmetric":
haning_window = np.hanning(win_length)
sqrt_haning_window = np.sqrt(haning_window)
elif mode == "periodic":
haning_window = np.hanning(win_length+1)
sqrt_haning_window = np.sqrt(haning_window)
sqrt_haning_window = sqrt_haning_window[0:-1].astype('float32')
return sqrt_haning_window
Rectangle_windows = Rectangle_windows(window_len)
hanning_window = np.hanning(M=window_len)
print(np.argmax(hanning_window))
sqrt_hanning_windows = sqrt_hanning_windows(window_len)
hamming_window = np.hamming(M=window_len)
Voibis_windows = Voibis_windows(window_len)
blackman_window = np.blackman(M=window_len)
bartlett_window = np.bartlett(M=window_len)
kaiser_window = np.kaiser(M=window_len, beta=14)
plt.figure()
plt.plot(Rectangle_windows, label="Rectangle")
plt.plot(hanning_window, label="hanning")
plt.plot(sqrt_hanning_windows, label="sqrt_hanning")
plt.plot(hamming_window, label="hamming")
plt.plot(Voibis_windows, label="Voibis")
plt.plot(blackman_window, label="blackman")
plt.plot(bartlett_window, label="bartlett")
plt.plot(kaiser_window, label="kaiser")
plt.legend()
plt.tight_layout()
plt.show()
freq, Rectangle_FreqResp = frequency_response(Rectangle_windows, window_len)
freq, hanning_FreqResp = frequency_response(hanning_window, window_len)
freq, sqrt_hanning_FreqResp = frequency_response(sqrt_hanning_windows, window_len)
freq, hamming_FreqResp = frequency_response(hamming_window, window_len)
freq, Voibis_FreqResp = frequency_response(Voibis_windows, window_len)
freq, blackman_FreqResp = frequency_response(blackman_window, window_len)
freq, bartlett_FreqResp = frequency_response(bartlett_window, window_len)
freq, kaiser_FreqRespw = frequency_response(kaiser_window, window_len)
plt.figure()
plt.title("Frequency response")
plt.plot(freq, Rectangle_FreqResp, label="Rectangle")
plt.plot(freq, hanning_FreqResp, label="hanning")
plt.plot(freq, sqrt_hanning_FreqResp, label="sqrt_hanning")
plt.plot(freq, hamming_FreqResp, label="hamming")
plt.plot(freq, Voibis_FreqResp, label="Voibis")
plt.plot(freq, blackman_FreqResp, label="blackman")
plt.plot(freq, bartlett_FreqResp, label="bartlett")
plt.plot(freq, kaiser_FreqRespw, label="kaiser")
plt.ylabel("Magnitude [dB]")
plt.xlabel("Normalized frequency [cycles per sample]")
plt.legend()
plt.tight_layout()
plt.show()