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)
运行结果如下:
实验使用到的数据下载链接如下:
https://mp.csdn.net/mp_download/manage/download/UpDetailed
参考文献:语音信号处理实验教程;梁瑞宇、赵力、魏昕(编著)