|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?我要加入
x
我用matlab,得到一个声音的功率谱,如下,想用来识别,但是不知道里面怎么提取出特征参数,得到功率谱怎么做识别的。
很急啊,还有不到十天就要交论文初稿了。
/////////////////////////matlab命令:
>> [a,b]=myrecord('1','2',11025,2); %b是经过归一化和端点检测后的声音数据
>> [pxx,f]=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 -0.9375], 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));
[pxx,f]=periodogram(wavData,window,nfft,fs);
/////////////////////////最后帖图是用一个陶瓷杯子的杯盖敲杯身的结果图 |
-
用一个陶瓷杯子的杯盖敲杯身的结果图
|