2019-11-19 22:10:10 tengfei0973 阅读数 75
  1. 矩形窗
    w(n)={10nL10w(n)=\begin{cases}1 \qquad 0 \le n \le L-1\\\\ 0 \qquad 其他\end{cases}
  2. 汉明窗
    w(n)={0.540.46cos[2πn/(L1)]0nL10w(n)=\begin{cases}0.54-0.46cos[2\pi n/(L-1)] \qquad 0 \le n \le L-1 \\\\ 0 \qquad 其他\end{cases}
  3. 汉宁窗
    w(n)={0.5{1cos[2πn/(L1)]}0nL10w(n)=\begin{cases}0.5\{1-cos[2\pi n/(L-1)]\} \qquad 0 \le n \le L-1 \\\\ 0 \qquad 其他\end{cases}
clear all;clc;close all;
w = linspace(-pi,pi,4096);
%=========================
%矩形窗的频率响应图    
%=========================
wn1 = rectwin(51)   %矩形窗
h1 = freqz(wn1,1,w);
subplot(3,1,1);
plot(w/pi,20*log10(abs(h1/max(h1)))); %以归一化频率为横坐标
axis([-1 1 -100 0]); 
xlabel('归一化频率 /\pi');  
ylabel('20log_{10}|W(e^{j\omega})| /dB');  
title('矩形窗的傅里叶变换');

%=========================
%汉明窗的频率响应图    
%=========================
wn2 = hamming(51) %汉明窗
h2 = freqz(wn2,1,w);
subplot(3,1,2);
plot(w/pi,20*log10(abs(h2/max(h2)))); %以归一化频率为横坐标
axis([-1 1 -100 0]);
xlabel('归一化频率 /\pi'); 
ylabel('20log_{10}|W(e^{j\omega})| /dB');  
title('汉明窗的傅里叶变换');

%=========================
%汉宁窗的频率响应图   
%=========================
wn3 = hanning(51)  
h3 = freqz(wn3,1,w); 
subplot(3,1,3);
plot(w/pi,20*log10(abs(h3/max(h3))));  %以归一化频率为横坐标
axis([-1 1 -100 0]); 
xlabel('归一化频率 /\pi');  
ylabel('20log_{10}|W(e^{j\omega})| /dB');  
title('汉宁窗的傅里叶变换');

在这里插入图片描述

2017-07-15 22:21:01 u010212101 阅读数 4738

I、预备知识:

1)帧:简单说,有一段语音信号,分成很小的一段一段的等长的信号,这其中一段就是一帧。—通常一秒取约33帧到100帧,也就是说一帧大约时长为1s/100-1s/33。(如下图为一段语音数字信号)
这里写图片描述
2)信号预处理:
a. 在对一段语音数字信号进行预加重数字滤波处理后,紧接着需要将信号分成一帧一帧,为了保证帧与帧之间平滑过渡,往往允许帧与帧之间有重合,(如下图所示)
这里写图片描述
这里写图片描述
b. 分帧就会导致频谱泄露的问题,为了应对这些问题,大牛老师们提出了使用窗口函数进行分帧(也称之为截断),好了,终于绕到窗口函数了,说到窗口函数,那就很多了,汉明窗就是一个典型的例子。
c. 有了窗口函数,就可愉快地对信号进行分帧处理了,新的信号可以用右边这个公式表示了:S(n) = s(n)*w(n)
3)余弦函数:y = cos(x),(如下图)
这里写图片描述


II、汉明窗–公式如下

这里写图片描述

III、原理

   其原理可以说就是通过余弦函数的特性得到的,举个栗子,以下是原始信号经过加窗处理的之后结果:

—观察余弦函数,是不是能看出点什么来?嗯,就是这个道理。
这里写图片描述
这里写图片描述

参考资料:

[1]. 基于嵌入式的关键词组识别系统的设计与实现
[2].矩形窗和汉明窗分辨率说明  --百度文库
[3].窗函数  --百度百科
[4]. 短时傅里叶变换及其应用  --百度文库
2018-07-28 20:50:49 zlyong0018 阅读数 1350

    笔者学识有限。 本博客旨在对mitre_sfr核心代码进行简单注解, 详细内容读者仁者见仁智者见智。

    SFR算法对ESF曲线进行差分得到LSF;

    给LSF加上汉明窗, 降低干扰;

    对加窗后的LSF曲线进行DFT, 得到SFR。

 

/*****************************************************************************/
/* This has been modified from Annex A, to more closely match Annex D and 
   reduce finite difference errors.  Now allows either [-1 1] derivative
   (when separation = 0) or [-1/2 0 1/2] derivative (when separation=1)

   Inputs:   len          length of ESF array
             AveEdge      array of ESF values
             separation   type of derivative 
	                    0 = [-1 1]
			    1 = [-1/2 0 1/2]

   Outputs:  AveTmp       array of original ESF values
             AveEdge      array of derivative (LSF) values
             centroid     centroid of the derivative 
*/
// 计算ESF的差分图像LSF, 并计算LSF的质心
void calculate_derivative(unsigned int len, double *AveTmp, double *AveEdge,
			  double *centroid,int separation)
{
  unsigned long i;
  double dt, dt1;

  dt = 0.0;
  dt1 = 0.0;

  for (i=0; i< len; i++) 
    AveTmp[i] = AveEdge[i];

  for (i=1; i< len-separation; i++) {
    /* Not wasting time with division by 2 since constant factors don't 
       change SFR computation */
    AveEdge[i] = (AveTmp[i+separation]-AveTmp[i-1]);  
    if (separation == 1)
      AveEdge[i] /= 2.0;
    dt += AveEdge[i] * (double)i;
    dt1 += AveEdge[i];
  }

  *centroid = dt/dt1;

  AveEdge[0] = AveEdge[1];
  if (separation == 1) AveEdge[len-1] = AveEdge[len-2];
}

 

/*****************************************************************************/
void apply_hamming_window(  unsigned short alpha,
			    unsigned int oldlen,
			  unsigned short newxwidth,
			  double *AveEdge, long *pcnt2)
{
  long i,j,k, begin, end, edge_offset;
  double sfrc;

  /* Shift the AvgEdge[i] vector to centre the lsf in the transform window */
  // 将LSF的最大值移到中心位置, 两边由于移动造成的空位由0补齐
  edge_offset = (*pcnt2) - (oldlen/2);
  if (edge_offset != 0) {
    if (edge_offset < 0 ) {
      for (i=oldlen-1; i > -edge_offset-1; i--) 
		  AveEdge[i] = (AveEdge[i+edge_offset]);
      for (i=0; i < -edge_offset; i++) 
		  AveEdge[i] = 0.00; /* last operation */
    } else {
      for (i=0; i < oldlen-edge_offset; i++) 
		  AveEdge[i] = (AveEdge[i+edge_offset]);
      for (i=oldlen-edge_offset; i < oldlen; i++) 
		  AveEdge[i] = 0.00;
    }
  }
  /* Multiply the LSF data by a Hamming window of width NEWXWIDTH*alpha */
  // 在当前上下文中, 下面这段代码应该不会起任何作用, 不知道为什么会有这么复杂而冗余的逻辑
  begin = (oldlen/2)-(newxwidth*alpha/2);
  if (begin < 0) begin = 0;
  end = (oldlen/2)+(newxwidth*alpha/2);
  if (end > oldlen )  end = oldlen;
  for (i=0; i< begin; i++) 
    AveEdge[i] = 0.0;
  for (i=end; i< oldlen; i++) 
    AveEdge[i] = 0.0;

  // 给begin和end之间的数据加上汉明窗
  // 汉明窗 W(n,α ) = (1 -α ) - α cos(2*PI*n/(N-1)) ,(0≤n≤N-1)
  // 一般情况下,α取0.46
  // 下面计算方法等于窗发生了平移(故符号发生了变化), 结果是一样的
  for (i=begin,j = -newxwidth*alpha/2; i < end; i++,j++) {
    sfrc = 0.54 + 0.46*cos( (M_PI*(double)j)/(newxwidth*alpha/2) );
    AveEdge[i] = (AveEdge[i])*sfrc; 
  }

  // 将有效数据平移到起始位置
  // 在当前上下文中, 下面这段代码应该不会起任何作用, 不知道为什么会有这么复杂而冗余的逻辑
  if (begin != 0) /* Shift LSF to begin at index 0 (rather than begin) */
    for (k=0, i=begin; k<newxwidth*alpha; i++,k++) 
      AveEdge[k] = AveEdge[i];

}

 

/*****************************************************************************/
/* This is the DFT magnitude code                                            */
unsigned short ftwos(long number, double dx, double *lsf, 
		     long ns, double ds, double *sfr)
{
  double a, b, twopi, g;
  long i,j;

  //                n-1              k
  // DFT ==> X[k] = Σ  x[n]e^(-j2π - n)
  //                n=0              N

  twopi = 2.0 * M_PI;
  for (j = 0; j < ns; j++){
    g = twopi * dx * ds * (double)j;
    for (i = 0, a = 0, b = 0; i < number; i++) { 
      a += lsf[i] * cos(g * (double)(i));
      b += lsf[i] * sin(g * (double)(i)); 
    }
    sfr[j] = sqrt(a * a + b * b); 
  }
  return 0;
}

 

2017-06-21 21:08:58 gxiaoyaya 阅读数 10267

为什么要加汉明窗?什么叫加窗?

 在信号处理中,可以说加窗处理是一个必经的过程,因为我们的计算机只能处理有限长度的信号,因此原始信号X(t)要以T(采样时间)截断,即有限化,成为XT(t)后再进一步处理,这个过程序就是加窗处理,但什么时候用什么窗呢?这时我们就要对所需用到的函数窗做一定的了解。在平时,我们用得最多的是矩形窗,这个也很容易理解,好像我们屋子里的窗口一样,透过窗口我们可以看到外面的世界,但在如果我们理窗口远一些的话,我们的看到的范围将减少,越远就越小。实际的信号处理过程中,我们用的矩形窗,但矩形窗在边缘处将信号突然截断,窗外时域信息全部消失,导致在频域增加了频率分量的现象,即频谱泄漏。避免泄漏的最佳方法是满足整周期采样条件,但实际中是不可能做到的。对于非整周期采样的情况,必须考虑如何减少加窗时造成的泄漏误差,主要的措施是使用合理的加窗函数,使信号截断的锐角钝化,从而使频谱的扩散减到最少。

    首先介绍一下为什么要用函数窗:函数窗的主要用于对截断处的不连续变化进行平滑,减少泄漏。此外,加窗处理还有很多其它的原因,如减少噪声干扰、限定测试的持续时间、从频率接近的信号中分离出幅值不同的信号……

常见的几种窗的基本指标:

 

一个窗是否合适:窗谱主瓣宽度就尽可能的窄,且能量集中在主瓣内,以获得较陡的过渡带;窗谱旁瓣与主瓣相比应尽可能的小,旁瓣能量衰减要快,以利于增加阻带衰耗。

汉明窗就是信号窗口的一种,在matlab中执行命令,画出plot(hamming(100))的图如下:


 

它主要部分的形状像sin(x)在0到pi区间的形状,而其余部分都是0.这样的函数乘上其他任何一个函数f,f只有一部分有非零值。

 

为什么汉明窗这样取呢?因为之后我们会对汉明窗中的数据进行FFT,它假设一个窗内的信号是代表一个周期的信号。(也就是说窗的左端和右端应该大致能连在一起)而通常一小段音频数据没有明显的周期性,加上汉明窗后,数据形状就有点周期的感觉了。

 

因为加上汉明窗,只有中间的数据体现出来了,两边的数据信息丢失了,所以等会移窗的时候,只会移1/3或1/2窗,这样被前一帧或二帧丢失的数据又重新得到了体现。

 

简单的说汉明窗就是个函数,它的形状像窗,所以类似的函数都叫做窗函数。希望你能明白。

 

2.加Hanmming窗的作用

现在在看G.723.1,对语音编码刚入门,

发现在对信号进行LPC分析前,对信号乘以一个Hamming 窗,

乘法是:信号直接乘以一个HammingWindowTable中的值,这个加窗有什么作用?

如果是限制带宽的话, 在时域应对信号应做卷积的, 不明白,请赐教

 

因为要处理的是无限长序列中的一段,所以必须对这段序列加窗采集出来。

 

典型的窗口大小是25ms,帧移是10ms。汉明窗函数为

            W(n,α ) = (1 -α ) - α cos(2*PI*n/(N-1)),0≦n≦N-1

    一般情况下,α取0.46 。

谁能解释一下这个函数吗?我实在是不理解,谢谢.

 

由于直接对信号(加矩形窗)截断会产生频率泄露,为了改善频率泄露的情况,加非矩形窗,一般都是加汉明窗,因为汉明窗的幅频特性是旁瓣衰减较大,主瓣峰值与第一个旁瓣峰值衰减可达40db。

 

举例:

a=wavread('jiasiqi.wav');   %将音频信号jiasiqi.wav读入
subplot(2,1,1),                  %分配画布,一幅图上共两个图,这是第一个
plot(a);title('original signal');  %画出原始信号,即前面这个音频信号的原始波形
grid                                    %添加网格线
N=256;                               %设置短时傅里叶变换的长度,同时也是汉明窗的长度
h=hamming(N);                   %设置汉明窗
for m=1:N                       %用汉明窗截取信号,长度为N,主要是为了减少截断引起的栅栏效应等
b(m)=a(m)*h(m)
end
y=20*log(abs(fft(b)))           %做傅里叶变换,取其模值,即幅频特性,然后用分贝(dB)表示
subplot(2,1,2)                     %分配画布,第二副图
plot(y);title('短时谱');            %画出短时谱
grid                                        %添加网格线



2019-06-02 15:22:12 qq_33472146 阅读数 234

首先,hamming()函数的作用是返回一个L点的对称海明窗列向量w。
语音信号一般在10ms到30ms之间,我们可以把它看成是平稳的。为了处理语音信号,我们要对语音信号进行加窗,也就是一次仅处理窗中的数据。因为实际的语音信号是很长的,我们不能也不必对非常长的数据进行一次性处理。明智的解决办法就是每次取一段数据,进行分析,然后再取下一段数据,再进行分析。

怎么仅取一段数据呢?
一种方式就是构造一个函数。这个函数在某一区间有非零值,而在其余区间皆为0。汉明窗就是这样的一种函数。它主要部分的形状像sin(x)在0到pi区间的形状,而其余部分都是0。这样的函数乘上其他任何一个函数f,f只有一部分有非零值。

为什么汉明窗这样取呢?

因为之后我们会对汉明窗中的数据进行FFT(快速傅里叶变化),它假设一个窗内的信号是代表一个周期的信号。(也就是说窗的左端和右端应该大致能连在一起)而通常一小段音频数据没有明显的周期性,加上汉明窗后,数据形状就有点周期的感觉了。

因为加上汉明窗,只有中间的数据体现出来了,两边的数据信息丢失了,所以等会移窗的时候,只会移1/3或1/2窗,这样被前一帧或二帧丢失的数据又重新得到了体现。

简单的说汉明窗就是个函数,它的形状像窗,所以类似的函数都叫做窗函数。

加Hanmming窗的作用

在对信号进行LPC分析前,对信号乘以一个Hamming 窗。乘法是:信号直接乘以一个HammingWindowTable中的值。如果是限制带宽的话, 在时域应对信号应做卷积的。
因为要处理的是无限长序列中的一段,所以必须对这段序列加窗采集出来。
汉明窗函数为
W(n,α ) = (1 -α ) - α cos(2PIn/(N-1)),0≦n≦N-1
一般情况下,α取0.46

由于直接对信号(加矩形窗)截断会产生频率泄露,为了改善频率泄露的情况,加非矩形窗,一般都是加汉明窗,因为汉明窗的幅频特性是旁瓣衰减较大,主瓣峰值与第一个旁瓣峰值衰减可达40db。

汉宁窗的性质

阅读数 32080

没有更多推荐了,返回首页