自相关函数法基音周期提取(matlab版)
来源:互联网 发布:淘宝刷枪是真的吗 编辑:程序博客网 时间:2024/04/30 17:53
1、引言
人在发浊音时,气流通过声门使声带产生张弛振荡式振动,产生一股准周期脉冲气流,这一气流激励声道就产生浊音,又称有声语音,它携带着语音中的大部分能量。这种声带振动的频率称为基频,相应的周期就称为基音周期( Pitch) ,它由声带逐渐开启到面积最大(约占基音周期的50% )、逐渐关闭到完全闭合(约占基音周期的35% )、完全闭合(约占基音周期的15% )三部分组成。
当今主流的基音周期检测技术主要有时域的自相关法、频域的倒谱法、时频结合的小波变换分析方法以及在其基础上的衍生算法。本文所采用的方法是自相关法
2.设计思路
(1)自相关函数
对于离散的语音信号x(n),它的自相关函数定义为:
R(k)=Σx(n)x(n-k),
如果信号x(n))具有周期性,那么它的自相关函数也具有周期性,而且周期与信号x(n)的周期性相同。自相关函数提供了一种获取周期信号周期的方法。在周期信号周期的整数倍上,它的自相关函数可以达到最大值,因此可以不考虑起始时间,而从自相关函数的第一个最大值的位置估计出信号的基音周期,这使自相关函数成为信号基音周期估计的一种工具。
(2)短时自相关函数
语音信号是非平稳的信号,所以对信号的处理都使用短时自相关函数。短时自相关函数是在信号的第N个样本点附近用短时窗截取一段信号,做自相关计算所得的结果
Rm(k)=Σx(n)x(n-k)
式中,n表示窗函数是从第n点开始加入。
3、程序代码
function pitch
x=wavread('E:\luyin\wkxp.wav');%读取声音文件
figure(1);
stem(x,'.'); %显示声音信号的波形
n=160; %取20ms的声音片段,即160个样点
for m=1:length(x)/n; %对每一帧求短时自相关函数
for k=1:n;
Rm(k)=0;
for i=(k+1):n;
Rm(k)=Rm(k)+x(i+(m-1)*n)*x(i-k+(m-1)*n);
end
end
p=Rm(10:n); %防止误判,去掉前边10个数值较大的点
[Rmax,N(m)]=max(p); %读取第一个自相关函数的最大点
end %补回前边去掉的10个点
N=N+10;
T=N/8; %算出对应的周期
figure(2);stem(T,'.');axis([0 length(T) 0 10]);
xlabel('帧数(n)');ylabel('周期(ms)');title('各帧基音周期');
T1= medfilt1(T,5); %去除野点
figure(3);stem(T1,'.');axis([0 length(T1) 0 10]);
xlabel('帧数(n)');ylabel('周期(ms)');title('各帧基音周期');
4、运行结果与分析
(1)
运行
x=wavread('E:\luyin\wkxp.wav');%读取声音文件
figure(1);
stem(x,'.'); %显示声音信号的波形
得到的波形如下
图 1
原来的声音文件时长为t=5s,采样率为8kHZ。故总共有5*8k=40000个采样点(如图所示)。
图中的三个波形分别对应a,o,e
(2)
运行
n=160; %取20ms的声音片段,即160个样点
for m=1:length(x)/n; %对每一帧求短时自相关函数
for k=1:n;
Rm(k)=0;
for i=(k+1):n;
Rm(k)=Rm(k)+x(i+(m-1)*n)*x(i-k+(m-1)*n);
end
end
p=Rm(10:n); %防止误判,去掉前边10个数值较大的点
[Rmax,N(m)]=max(p); %读取第一个自相关函数的最大点
end %补回前边去掉的10个点
N=N+10;
T=N/8; %算出对应的周期
figure(2);stem(T,'.');axis([0 length(T) 0 10]);
xlabel('帧数(n)');ylabel('周期(ms)');title('各帧基音周期');
得到的结果为:
图 2
由第一步可知40000个样点,一共有250帧(每帧160个样点),对应着图中的横坐标
由图中可以看出基音周期大约为7ms.但是图中存在太多的野点,为此,需要对此进行进一步的处理,即去除野点
(3)去除野点
运行
T1= medfilt1(T,5); %去除野点
figure(3);stem(T1,'.');axis([0 length(T1) 0 10]);
xlabel('帧数(n)');ylabel('周期(ms)');title('各帧基音周期');
运行结果如下
图 3
5、设计中遇到的问题与心得
(1)设计中遇到的问题:
由于每一帧做短时自相关时,Rm(k)开始的几个点的值比第一个周期的峰值还大,因此无法正常提取出第一个峰值对应的点。开始程序的运行结果如下:
图 4
于是经过和同学讨论之后决定舍弃Rm开始几个值较大的点,于是运行结果就正常了
图 5
(2)心得体验:
短时自相关函数法基音检测的主要原理是通过比较原始信号和它移位后的信号之间的类似性来确定基音周期,如果移位距离等于基音周期,那么两个信号具有最大类似性。基于自相关函数的算法是基音周期估计的常用方法,特别适用于噪声环境下的基音提取。自相关函数在基音周期处表现为峰值,相邻两个峰值之间的间隔即为一个基音周期。
但是短时自相关函数法也存在以下缺点:
①倍频现象
通常情况下,基波分量往往不是最强的分量,丰富的谐波成分使语音信号的波形变得非常复杂,给基音检测带来了困难,经常发生基频估计结果为其实际基音频率的二次倍频或二次分频的情况。加之还有清浊混杂等情况,使基音检测成为一大难题。
如图5 ( a)是一帧语音信号,图4 ( b)是这帧语音信号的自相关函数,可以看出自相关函数在基音周期处表现为峰值,这些峰值点之间的间隔的平均值就是基音周期,如图6 ( b)所示可以看出自相关函数检测出的基音周期是原始信号基音周期的一半,这是由于谐波峰值点(箭头所示)的影响,这就是上述缺点中所说的倍频现象。
图 6
图 7
②运算量大,效率低下
无论是对随机的语音信号还是对离散的信号进行处理,只要是使用自相关函数对信号进行周期估计,必然涉及大量的乘法运算。虽然经过实验证明,自相关函数法是一种简单而且有效的方法,但是大量的乘法运算严重影响算法的效率。然而从估计基音周期的角度看,短时自相关函数所包含的信息许多是多余的,真正能反映基音周期性的只是少数几个峰,而其余的大多数峰都是由于声道的谐振特性引起的。为此,可以用三电平削波法来突现反映基音周期的信息,同时压缩与共无关的信息。三电平法具体的方法就不在此详细说明了。
- 自相关函数法基音周期提取(matlab版)
- 语音学习笔记1------matlab实现自相关函数法基音周期提取
- 基于自相关的基音周期检测算法实现
- 互相关法提取基音
- 基音周期估计
- matlab中自相关函数
- pitch提取一(自相关函数法)
- 使用自相关函数的纹理图像周期计算
- Matlab 自相关检测 :自相关函数xcorr
- Matlab的自相关函数xcorr
- Matlab的autocorr自相关函数
- g723源码分析-(五)-基音周期补充
- 音频信号处理——基音周期
- MATLAB计算自相关函数和互相关函数
- matlab中的xcorr 自相关函数(转)
- 时间序列分析的matlab自相关函数autocorr
- g729源码分析-3-基音周期搜索(上)
- g729源码分析-4-基音周期搜索(中)
- Android Listview下拉刷新数据
- c# 判断字符串数字
- uva 165 - Stamps
- plsql连接远程oracle数据库配置
- ALL与max 何时等价
- 自相关函数法基音周期提取(matlab版)
- 网络安全需靠法治 法国以法净化网络
- 【整理】struct device的初始化
- 发送一副图到浏览器的(socket 传送 file)
- VC如何改变编辑框的背景颜色方法
- Linux 下的内存管理[转载]
- 借助易宝实现Java版网上在线支付
- c++builder中截获TPanel的窗口信息(其他控件类似)
- c++ string