语音信号的短时频域分析

1、短时傅里叶变换

语音信号是一种典型的非平稳信号,但是其非平稳性是由发音器官的物理运动过程而产生的,此过程与声波振动的速度相比较缓慢,可以假定在10~30ms这样的短时间内是平稳的。傅里叶分析是分析线性系统和平稳信号稳态特性的强有力手段,而短时傅里叶分析,也叫时间依赖傅立叶变换,就是在短时平稳的假定下,用稳态分析方法处理非平稳信号的一种方法。
设语音波形时域信号为x(l)、加窗分帧处理后得到的第n帧语音信号为xn(m),则xn(m)满足下式:

设离散时域采样信号为x(n),n=0,1,…,N-1,其中n为时域采样点序号,N-1是信号长度。然后对信号进行分帧处理,则x(n)表示为xn(m),m=0,1,…,N-1,其中n是帧序号,m是帧同步的时间序号。信号x(n)的短时傅里叶变换为

定义角频率w=2πk/N,则得离散的短时傅里叶变换(DFT),它实际上是Xn(e^(jw))在频域的取样,如下所示:

在语音信号数字处理中,都是采用xn(m)的离散傅里叶变换Xn(k)来替代Xn(e^(jw)),并且可以用高效的快速傅里叶变换(FFT)算法完成由xn(m)至Xn(k)的转换。当然,这时窗长N必须是2的倍数2^L(L是整数)。

2、语谱图表示与实现方法

一般定义|Xn(k)|为x(n)的短时幅度谱估计,而时间处频谱能量密度函数(或功率谱函数)P(n,k)为

则P(n,k)是二维的非负实值函数,并且不难证明它是信号x(n)的短时自相关函数的傅里叶变换。用时间n作为横坐标,k作为纵坐标,将P(n,k)的值表示为灰度级所构成的二维图像就是语谱图。如果通过变换10log10P(n,k)后,得到语谱图就是采用dB进行表示的。将经过变换后的矩阵精细图像和色彩的映射后,就可得到彩色的语谱图。

需要用到的MATLAB函数主要有两个:
1)频谱图显示函数:imagesc(t,f,L)。其中t是时间坐标,f是频率坐标,L则是从功率谱值经伪彩色映射后的彩色电平值,即10log10P(n,k)。
2)伪彩色映射函数:colormap(MAP)。其中MAP是所采用的伪彩色映射矩阵,默认值为JET,即大值为红色,小值为蓝色。可以通过MAP=colormap获得当前的伪彩色映射矩阵,它可以是一个任意行的矩阵,但其必须有且只有三列,并分别表示红色、绿色和蓝色的饱和度。语谱图中的花纹有横杠、乱纹和竖直条等。横杠是与时间轴平行的几条深黑色带纹,它们是共振峰。从横杠对应的频率和宽度可以确定相应的共振峰频率和带宽。在一个语音段的语谱图中,有没有横杠出现是判断它是否是浊音的重要标志。竖直条(又叫冲直条)是语谱图中出现与时间轴垂直的一条窄黑条。每个竖直条相当于一个基音,条纹的起点相当于声门脉冲的起点,条纹之间的距离表示基音周期。条纹越密表示基音频率越高。

分帧后计算每帧对应的时间函数为FrameTimeC代码如下:

function frameTime=FrameTimeC(frameNum,framelen,inc,fs)
% 分帧后计算每帧对应的时间
frameTime=(((1:frameNum)-1)*inc+framelen/2)/fs;

分帧函数enframe代码如下:

function frameout=enframe(x,win,inc)

nx=length(x(:));            % 取数据长度
nwin=length(win);           % 取窗长
if (nwin == 1)              % 判断窗长是否为1,若为1,即表示没有设窗函数
   len = win;               % 是,帧长=win
else
   len = nwin;              % 否,帧长=窗长
end
if (nargin < 3)             % 如果只有两个参数,设帧inc=帧长
   inc = len;
end
nf = fix((nx-len+inc)/inc); % 计算帧数
frameout=zeros(nf,len);            % 初始化
indf= inc*(0:(nf-1)).';     % 设置每帧在x中的位移量位置
inds = (1:len);             % 每帧数据对应1:len
frameout(:) = x(indf(:,ones(1,len))+inds(ones(nf,1),:));   % 对数据分帧
if (nwin > 1)               % 若参数中包括窗函数,把每帧乘以窗函数
    w = win(:)';            % 把win转成行数据
    frameout = frameout .* w(ones(nf,1),:);  % 乘窗函数
end

短时傅里叶变换函数STFFT代码如下:

function d=STFFT(x,win,nfft,inc)
xn=enframe(x,win,inc)';
y=fft(xn,nfft);
d=y(1:(1+nfft/2),:);

案例、读入语音信号数据,得到其语谱图,程序如下:

clear all;
clc; 
close all;

[x,fs]=audioread('C3_3_y.wav');       % 读入数据文件
wlen=256;
nfft=wlen;
win=hanning(wlen);
inc=128;          % 给出帧长和帧移

y=STFFT(x,win,nfft,inc);        %求短时傅里叶变换

fn=size(y,2);                           %帧数

freq=(0:wlen/2)*fs/wlen;                % 计算FFT后的频率刻度

frameTime=FrameTimeC(fn,wlen,inc,fs); % 计算每帧对应的时间
imagesc(frameTime,freq,20*log10(abs(y)+eps)); % 画出Y的图像  
axis xy; ylabel('频率/Hz');xlabel('时间/s');
title('能量谱图');
colormap(jet)

运行结果如下:

语音信号的短时频域分析_第1张图片

实验使用到的数据下载链接如下: 

https://mp.csdn.net/mp_download/manage/download/UpDetailed

参考文献:语音信号处理实验教程;梁瑞宇、赵力、魏昕(编著)

你可能感兴趣的:(语音识别,人工智能)