利用Matlab对语音信号进行短时分析
用Matlab画出该段语音的时域波形、短时平均能量、短时平均幅度、短时过零率、短时过电平率。
clear;
% 读取语音信号
[y, fs] = audioread('ex2.wav');
% 参数设置
frame_length = 0.025; % 帧长(秒)
frame_shift = 0.01; % 帧移(秒)
over_threshold = 0.02; % 过电平阈值
% 计算帧长和帧移的样本数
frame_length_samples = round(frame_length * fs);
frame_shift_samples = round(frame_shift * fs);
% 计算帧数和总样本数
num_frames = floor((length(y) - frame_length_samples) / frame_shift_samples) + 1;
total_samples = (num_frames - 1) * frame_shift_samples + frame_length_samples;
% 初始化参数数组
energy = zeros(num_frames, 1);
amplitude = zeros(num_frames, 1);
zero_crossing = zeros(num_frames, 1);
over_threshold_ratio = zeros(num_frames, 1);
% 计算短时参数
for i = 1:num_frames
frame_start = (i - 1) * frame_shift_samples + 1;
frame_end = frame_start + frame_length_samples - 1;
frame = y(frame_start:frame_end);
% 计算能量
energy(i) = sum(frame.^2);
% 计算幅度
amplitude(i) = sum(abs(frame));
% 计算过零率
zero_crossing(i) = sum(frame(1:end-1) .* frame(2:end) < 0);
% 计算过电平率
over_threshold_samples = abs(frame) > over_threshold;
consecutive_over_threshold = bwconncomp(over_threshold_samples);
num_consecutive_over_threshold = consecutive_over_threshold.NumObjects;
over_threshold_ratio(i) = num_consecutive_over_threshold / (frame_length_samples / fs*10);
end
% 时间轴(以秒为单位)
time = (0:total_samples-1) / fs;
frame_time = (0:num_frames-1) * frame_shift;
% 绘制图形
figure;
% 绘制时域波形图
subplot(5, 1, 1);
plot(time, y(1:total_samples));
xlabel('时间 (秒)');
ylabel('振幅');
title('时域波形');
% 绘制短时平均能量图
subplot(5, 1, 2);
plot(frame_time, energy);
xlabel('时间 (秒)');
ylabel('能量');
title('短时平均能量');
% 绘制短时平均幅度图
subplot(5, 1, 3);
plot(frame_time, amplitude);
xlabel('时间 (秒)');
ylabel('平均幅度');
title('短时平均幅度');
% 绘制短时过零率图
subplot(5, 1, 4);
plot(frame_time, zero_crossing);
xlabel('时间 (秒)');
ylabel('过零率');
title('短时过零率');
% 绘制短时过电平率图
subplot(5, 1, 5);
plot(frame_time, over_threshold_ratio);
xlabel('时间 (秒)');
ylabel('过电平率');
title('短时过电平率');
- 短时平均能量
浊音段的能量较高。在无声段,短时平均能量接近于0,清音段的短时平均能量亦是如此。但稍微有一点起伏,故观察短时平均能量能有效的找到浊音部分,而清音和无声段需要其他信息判别(有底噪存在无声段可能也有轻微起伏)。
- 短时幅度
很显然,短时平均幅度和短时平均能量的波形很相似,只是大小有所区别(两倍左右)。实质上,这两者刻画的是一个特征即浊音部分能量强、清音和无声段能量弱,可以很明显的看出浊音段。
- 短时平均过零率
过零率可以反映出这段语音信号是否是清音,很明显的观察到过零率有几个波峰,其对应于清音,结合短时能量分析可以确定。由于录音环境比较安静,故噪声影响较小,峰值部分均为清音段。
- 短时过电平率
短时过电平率和短时过零率比较相似,即过零率考察的是语音经过零点而过电平率则是一个特定的电平值。观察图像发现短时过电平率和短时过零率类似也有三个峰能体现出清音部分,同时,无声部分的短时过电平值就几乎为0了。于是就能很清楚的讲清音和浊音区分出来。
参数分析:
结合时域图及四个特征可以很明显的区分出清音、浊音和无声段。下面将对这个三个音段进行分析。
清音段:
清音段发生在刚开始录音的时候的“智”这个字的时候。短时平均能量几乎为0。
短时平均幅度在同一个点有一个比较高的值(较短时能量而言),但对于平均幅度而言这个值比较小,可能与整体录音音量大小相关。
短时过零率的值较高,其峰值能达到169,而浊音段的短时过零率基本上不到20。
短时过电平率的峰值比短时过零率要低,可能和电平值的设置及周期震荡的幅度相关。但也能有效区分清音段。
浊音段:
浊音段比较明显的特点是其能量较高,通过图像可以看到峰值达到52左右。
短时平均幅度的峰值比能量要高,其大小为85左右
短时平均过零率在浊音段均较低,其值比较平稳大概在17附近
短时过电平率相较过零率比较高,且平稳性弱于过零率。但其值相对稳定在35附近。
无声段:
无声段的幅度和能量几乎为0,与课堂理论相符合。
在无声段,短时过零率也存在一个小波峰,此时还未开始发声,其最大值能达到88,推测是由于此时刻有噪声产生。而过电平率则是0,因为此时能量较小,设置一个合理的电平值即可使无声段过电平值为0.
结论:
- 短时能量和短时幅度反映的信息几乎差不多,通过这两个指标可以很清楚的判断出浊音段的语音。其理由如下:浊音段的能量或幅度明显大于其他音频段有很明显的波峰。若环境噪声较小时,也可以通过能量或幅度大致判断出无声段和清音段。
- 清音段可以通过短时过零率和短时过电平率来分辨。这两项指标只有在清音段会出现明显的波峰,而浊音段和无声段则看不到明显波峰,当电平值设置的合适时,无声段的过电平率几乎为0,据此也可以看出浊音段和无声段。
- 综上,通过时域波形和四种特征的综合判断,可以很明显的区分出无声段、浊音段、清音段三种音频信号。清音段大约在0.97~1.03之间,浊音段在1.07~1.2之间,无声段则在0.9以前或3.3之后