用功率谱来识别声音怎么做啊?
我用matlab,得到一个声音的功率谱,如下,想用来识别,但是不知道里面怎么提取出特征参数,得到功率谱怎么做识别的。很急啊,还有不到十天就要交论文初稿了。
/////////////////////////matlab命令:
>> =myrecord('1','2',11025,2);%b是经过归一化和端点检测后的声音数据
>> =mypsd(b);%pxx得到功率谱
>> subplot(211);
>> plot(b);
>> xlabel('声音数据');
>> subplot(212);
>> plot(pxx);
>> xlabel('功率谱');
///////////////////////////myrecord函数:
function [ newWav, valueWav ] = myrecord( filename1, filename2, fs, sec)
%录音并提取可用的声音部分。
%newWav:目标声音的数据;filename:要存储的文件名
%录音部分
channels = 1;
newWav = wavrecord(sec*fs,fs,channels,'double');
%端点检测部分
valueWav =newWav / max(abs(newWav));%各个采样点的幅度归一化到1
%%常数设置
FrameLen = 240;
FrameInc = 80;
amp1 = 10;%确定进入声音段的最低能量门限
zcr1 = 10;%确定进入声音段的过零率
amp2 = 2;%可能处在声音段时的最低能量门限
zcr2 = 5;%可能处在声音段时的过零率
delta = 0.02;%检测过零率时用到的阈值
minsilence = 3;%能表示处于静音段的最少持续静音帧数
minlen = 4;%能表示处于声音段的最少持续声音帧数
status = 0;%检查时用到的状态记号,0表示静音,1表示可能处于声音段,2表示正处于声音片段,3表示声音结束
count = 0;%持续声音段的总帧数
silence = 0;%持续静音段的总帧数
%%计算过零率
tmp1 = enframe(valueWav(1:length(valueWav)-1), FrameLen, FrameInc);
tmp2 = enframe(valueWav(2:length(valueWav)) , FrameLen, FrameInc);
signs = (tmp1.*tmp2)<0;%两点的符号不一样,即穿过零
diffs = (tmp1 -tmp2)>delta;%两点之间的差值超过阈值
zcr = sum(signs.*diffs, 2);%检测上面两个条件都符合
%%计算短时能量,过程是先预加重,然后分帧,再计算幅值绝对值的和
amp = sum(abs(enframe(filter(, 1, valueWav), FrameLen, FrameInc)), 2);
%%调整能量门限
amp1 = min(amp1, max(amp)/4);%用于确定是声音帧
amp2 = min(amp2, max(amp)/8);%用于确定超过静音帧门限
%%开始端点检测
startFrame = 0;
endFrame = 0;
status = 0;
for n=1:length(zcr)%一帧一帧检查
switch status
case {0,1}
if amp(n) > amp1 | zcr(n) > zcr1%确定进入声音段
startFrame = max(n-count-1,1);%得到声音开始的第一帧
status = 2;
silence = 0;
count = count + 1;
elseif amp(n) > amp2 | zcr(n) > zcr2%可能处于声音段
status = 1;
count = count + 1;
else%处在静音状态
status = 0;
count = 0;
end
case 2,
if amp(n) > amp2 | zcr(n) > zcr2%保持在声音段
count = count + 1;
else%声音将要结束,因为没有维持能量或过零率
silence = silence+1;
if silence < minsilence%静音不够长,声音还没有结束
count = count + 1;
elseif count < minlen % 声音不够长,认为之前检测到的是噪声(特别是当噪声的过零率或短时能量很高时,这个检测可以减少误判)
status = 0;
silence = 0;
count = 0;
else%声音结束
status = 3;
end
end
case 3,
break;
end
end
count = count-silence/2;
endFrame = startFrame + count -1;%得到声音结束帧
%声音数据存储部分
valueWav = valueWav(startFrame*FrameInc : endFrame*FrameInc, : );
wavwrite(newWav, filename1);
wavwrite(valueWav,filename2);
/////////////////////////////mypsd函数:
function [ pxx, f ] = mypsd( wavData )
%用周期图法得到功率谱
%pxx:结果功率谱图;wavData:声音数据
nfft=1024;
fs=22050;
window=hamming(length(wavData));
=periodogram(wavData,window,nfft,fs);
/////////////////////////最后帖图是用一个陶瓷杯子的杯盖敲杯身的结果图
页:
[1]