数字信号处理-大实验1.3
MATLAB仿真实验目录
- 验证实验:常见离散信号产生和实现
- 验证实验:离散系统的时域分析
- 应用实验:语音信号的基音周期(频率)测定
说明:(1)本文是DSP大实验1的最后一篇,主要讲解效果更优的倒谱法的原理和代码实现,难度大于1.2,不明白欢迎格物,有问题欢迎交流。
(2)工具函数在1.2中,如果想要复现,需要自行编写。
目录
三、语音信号的基音周期(频率)测定
3.3 实验原理
倒谱法
3.4 实验代码
3.5 实验结果
3.5.2 倒谱法(初步预处理/完全预处理)
3.5.3 不同人、不同音素、不同声调
实验心得
参考文献
三、语音信号的基音周期(频率)测定
3.3 实验原理
倒谱法
Figure 5 倒谱与共振峰求解方法[2],0.08门限需要根据实际情况调整,笔者设置的是0.05
在“计算基音周期pitch”环节,实际上是通过在搜索序列里得到的索引号+Lower_N(搜索下限/偏置量),结合采样率fs得到的。
倒谱法的优势:将时域卷积的两个信号x1[n]*x2[n]->x’[1]+x2’[n](’表示和初始信号有关联但不同的信号,具体是幅频曲线取完对数-IDFT得到的实偶信号序列),可以区分出浊音(周期性明显)和清音(周期性极弱),和预处理环节去除静音部分的操作有些相似,计算出的基音周期和频率较为准确;
倒谱法的劣势:运算时间通常较长,准确度和性能对于预处理环节均较为依赖;经过预处理之后,准确度和性能可以大幅提升。
3.4 实验代码
(实)倒谱法与共振峰绘制实现:
function [Ts,Fs]=pitch_transform(s,window_t,overlap_t,fs,fl,fh);
% 倒谱法(实偶数据帧/数据帧较短时可压缩一半的运算量;支持相对更长的数据帧)function [Ts,Fs,u_Fs]=pitch_transform(s,window_t,overlap_t,fs,fl,fh,divides)% 奇数个点,便于后续搜索最大值时确立索引window_width=round(window_t*fs/1000)+mod(round(window_t*fs/1000)+1,2);overlap_width=round(overlap_t*fs/1000)+mod(round(overlap_t*fs/1000)+1,2);% divides=round(divides/(window_width-overlap_width));count5=1;for i=1:length(divides)divides(i)=max(round(divides(i)/(window_width-overlap_width)),1);if divides(i)>floor((length(s)-window_width)/(window_width-overlap_width))+1count5=i-1;break;endendif count5~=1divides=divides(1:count5);enddivides=unique(divides);Lower_N=floor(fs/fh);Higher_N=floor(fs/fl);if Higher_N>(window_width-1)/2Higher_N=floor(window_width-1)/2;endTs=zeros(1,floor((length(s)-window_width)/(window_width-overlap_width))+1);Fs=zeros(1,floor((length(s)-window_width)/(window_width-overlap_width))+1);formants=zeros(floor((length(s)-window_width)/(window_width-overlap_width))+1,fix((window_width+1)/2));% figure();for i=1:window_width-overlap_width:length(s)-window_width+1-mod(length(s)-window_width+1,window_width-overlap_width)logS=log(abs(fft(s(i:i+window_width-1).*(hamming(window_width).')))+eps);even_pitch=ifft(logS);even_pitch(floor(length(even_pitch)/2)+1+Lower_N:floor(length(even_pitch)/2)+1+Higher_N);[max_v,max_ind]=find_average_peak(even_pitch(floor(length(even_pitch)/2)+1+Lower_N:floor(length(even_pitch)/2)+1+Higher_N),fs);if max_v>=0.025% period in milisecondsTs(floor(i/(window_width-overlap_width))+1)=(Lower_N+round(max_ind))/fs*1000;% frequency in HzFs(floor(i/(window_width-overlap_width))+1)=fs/(Lower_N+round(max_ind));endtemp=Formants(even_pitch,fs);formants(floor(i/(window_width-overlap_width))+1,:)=temp(:);enddivides(end)Ts=Ts(1:divides(length(divides)));Fs=Fs(1:divides(length(divides)));formants=formants(1:length(Ts),:);divides=divides(1:length(divides)-1);Ts_marks=zeros(1,length(divides));Fs_marks=zeros(1,length(divides));for i=1:length(divides)Ts_marks(i)=Ts(divides(i));Fs_marks(i)=Fs(divides(i));endfigure();subplot(2,1,1);plot(0:(window_width-overlap_width)/fs*1000:(length(Ts)-1)*(window_width-overlap_width)/fs*1000,Ts,'b', ...divides*(window_width-overlap_width)/fs*1000,Ts_marks,'o','MarkerFaceColor','r');title('Basic Period-Pitch Method');xlabel('t(ms)');ylabel('Basic Period(ms)');subplot(2,1,2);plot(0:(window_width-overlap_width)/fs*1000:(length(Fs)-1)*(window_width-overlap_width)/fs*1000,Fs,'cyan', ...divides*(window_width-overlap_width)/fs*1000,Fs_marks,'o','MarkerFaceColor','magenta');title('Basic Frequency-Pitch Method');xlabel('t(ms)');ylabel('Basic Frequency(Hz)');aug_divides=[1 divides length(Ts)];u_Fs=zeros(1,length(divides)+1);for i=1:length(divides)+1u_Fs(i)=mean(Fs(aug_divides(i):aug_divides(i+1)));endfigure();x=0:(window_width-overlap_width)/fs*1000:(length(Ts)-1)*(window_width-overlap_width)/fs*1000;y=0:(fs/window_width):(fs/2-fs/window_width/2);[X,Y]=meshgrid(x,y);mesh(X.',Y.',formants);colorbar;xlabel('t(ms)');ylabel('f(Hz)');zlabel('i(dB)')end
主函数编写:可根据自己的需求调用以上函数(组合)。
3.5 实验结果
3.5.2 倒谱法(初步预处理/完全预处理)
Figure 13 预处理× “生活就像海洋,只有意志坚强的人才能到达彼岸”√ 倒谱法√ 短时基音周期和基因频率 |
Figure 14 预处理√ “生活就像海洋,只有意志坚强的人才能到达彼岸”√ 倒谱法√ 短时基音周期和基音频率 |
通过Figure13和Figure14的对比,可见完全的音频预处理,对于倒谱法基音频率测定影响很大,主要体现在:
- 初步预处理+倒谱法测定得到的基音频率和周期同步为0(初始化设置)的短时数据帧很多,因此完全预处理+倒谱法具有更高的鲁棒性;
- 初步预处理+倒谱法测得的单个音素四声调平均基音频率(基线)在150Hz左右,实际测量157.6318Hz;而完全预处理+倒谱法测得的平均基音频率在250Hz左右,实际测量为279.8385Hz;我在专业音高测量软件中录制a的四个声调,得出平均基因频率大概是288Hz,虽然内容不同,但也说明初步预处理会导致基音频率测量严重偏低,而完全预处理+倒谱法具有更高的准确性。
Figure 15 a中文元音音素的四个声调,平均在C3/D3交界处,按照算术平均计算等于288Hz,MATLAB 倒谱法平均基音频率为256.6982Hz |
对于第1个缺陷,主要原因是低频分量和无音区间没有去除;
对于第2个缺陷,是关键的涉及实验核心的基音周期计算问题,主要原因如下。
Figure 16 初步预处理-倒谱实偶信号搜索区间,峰与谷差异过小,不能仅仅通过左右点数进行选择
Figure 17 完全预处理-倒谱实偶信号搜索区间(按照筛选规则,有5个尖峰符合条件,算术平均求取基音周期“索引号”)
Figure 18 完全预处理-单个数据帧的共振峰曲线(横轴单位10kHz,定义域0-24kHz;纵轴单位dB,表示相对声强)
Figure 19 预处理× “生活就像海洋,只有意志坚强的人才能到达彼岸”√ 运算效率↓ 时间-共振峰曲面
Figure 20 预处理√ “生活就像海洋,只有意志坚强的人才能到达彼岸”√ 运算效率↑ 时间-共振峰曲面
共振峰可以反映我们语音的基频信号和更高频率的K次谐波之间的相对强弱关系,也说明我们说话的时候,声音一般都是由具有相同基频的多个谐波构成的。
Figure 21 倒谱法用于检测音素(字符)个数(o的四个声调)
3.5.3 不同人、不同音素、不同声调
对应实验要求(1)-(4),收集了笔者和笔者的一位同学的音频样本,进行基音频率的测算(单位:赫兹)。使用可视化展示的音素发音区间自动切割方法分离不同音素发音区间,就可以得到同一元素不同声调的平均基音频率,同时节约了数据集构建成本,不需要每个元素每种声调分开录制保存,具体笔者尝试了四种方式(见3.4数据预处理函数体代码)。
- 作者(男):
1声 2声 3声 4声
a 275.6334 270.0315 244.3738 267.6659 264.0111
o 276.9702 293.9123 278.0272 266.9471 280.0617
e 276.3741 288.8473 276.9304 275.4824 279.9025
(2)同学(女):
1声 2声 3声 4声
a 281.4283 297.0079 281.6180 269.4950 282.3802
o 268.0011 291.9784 286.1182 277.2853 280.8530
e 264.9855 294.9584 290.2603 281.8556 282.5470
同一个人对于不同的元音音素4种声调平均差异不大,推测笔者录制a的音频时平均发音不是很自然;
同一个人同一种音素的不同声调,笔者是2声基音频率最高,1声和3声接近(a无效),4一般而言最低,也和具体的音素有较大关联;同学是a:2 1/3 4,o和e:2 3 4 1。
不同人的基音频率也有一定的偏差,比如女同学一般比男同学基音频率更高,由于样本量较小,具备偶然性。
实验心得
通过这次实验,我认知到语音信号处理是一门博大精深的工程学科,不仅仅涉及信号与系统、数字信号处理等系统的分析理论,更涉及在工程应用中的各种实际问题,更重要的是,我明白了“没有一种办法是万能的,是完美的”这个道理。
比如第三个测算基音周期的子实验中,理论上提供了通过短时信号(数据帧)自相关(实际上是帧选取+相关系数)计算基音周期的方法,然而实际过程中需要考虑信号干扰、短时信号能量或幅度、语种和说话内容、语音录述人的性别年龄音高等等:比如针对信号在录制时产生的干扰,在仿真时就需要对信号进行带通滤波的处理;针对单个元音或者辅音的发声无音区间、音素与音素之间、整段文字与整段文字之间的低频小幅值信号“干扰”,可能需要引入信号幅度的去均值化、归一化,并进行信号的去小幅值处理;而针对不同的语音内容,参数也要进行手动或者自动的适应调整。
知识方面,我了解到基音周期的提取对于语音压缩、语音合成、语音识别的重要性;了解到主要的三种处理思路——波形的直接形态学估计法(并行处理、数据减少)、相关运算方法(包括短时自相关ACF、平均幅值差分AMDF法)、变换域方法(小波变换、Hilbert-Huang变换、倒谱法)。基本掌握了ACF方法、倒谱法的理论基础和实践方法。
我还明白了“抓大放小”和“反思”在任何工程和学习中的重要性,比如这次仿真实验的ACF方法采用理想带通滤波器,既受到滤波器类型的约束,又受到通带上下限选取的影响,导致在测算基音周期时,频谱能量密度分布在低频段仍有较大比重,基音周期过大;后面我通过引入大窗口长度参数,既减少了运算时间,提升了运算速度,又在一定程度上提升了计算的准确性。
再比如,通过研究如何编写自动分割音素(字符)区间的算法,可以有效减少数据集制备方面的人力消耗,提升系统性能。
参考文献
[1] 阿沉. MATLAB语音信号分析与合成(第二版)》:第8章 基音周期的估算方法
[EB/OL]. https://zhuanlan.zhihu.com/p/510455250, 2022-05-12/2025-5-11.
[2] Eudmonia. Matlab实现倒谱法 求 基音频率和共振峰[EB/OL]. Matlab实现倒谱法 求 基音频率和共振峰_倒谱怎么反应基频-CSDN博客, 2022-04-17/2025-05-13.