matlab提取语音信号特征

原谅我上课走神了,,结果用了更多的时间去补偿自己上课浪费的时间。。。
以后课前一定做好预习,课后及时做好反馈,整个下来其实花的时间也不是很多,归根结底还是自己tcl

基本要求

  1. 录音,自己读5个数字0-4,然后录下来转成单声道的wav文件

  2. 求基音
    基音的求法可以比较简单,就是通过加w=20ms,160个样点的汉明窗,然后计算出短时自相关函数,取最大值就是基音的频率

  3. 通过LP,求预测增益,画出数字0的预测增益

m4a转wav格式

matlab

[y,fs] = audioread('5num.m4a');
audiowrite('5num.wav', y(:,1), 8000)

这样就转成了wav格式的文件

当然我比较偷懒,本来双声道应该是要做一点处理再变成单声道的,但是为了方便就直接变好了

求基音频率

这里当然我是不知道写代码的,所以用了别人的代码,下面好好分析一下:

说实话我有点晕不知道应该是怎么说比较好

栗1

x = audioread('5num.wav');
figure(1);
stem(x, '.');

n=160; %每一帧160个样点

for m=1:length(x)/n;%帧的个数
    for k=1:n;%一帧有160个点
        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(30:n);
    [Rmax,N(m)]=max(p);
end

首先读入音频,然后分帧,每一帧是160个样点,取出每一帧来,通过

        for i=(k+1):n;
            Rm(k)=Rm(k)+x(i+(m-1)*n)*x(i-k+(m-1)*n);
        end

这是公式,计算出短时自相关函数
同时之后求出其中的最大值及其索引存起来

这样画出的其实就是基音频率了

figure(2);
stem(T,'.');
axis([0 length(T) 0 20]);
xlabel('frame(n)');
ylabel('period(ms)');
title('');

fig1如下:

matlab提取语音信号特征_第1张图片

fig2如下:
matlab提取语音信号特征_第2张图片

当然之后还可以做一次中值滤波

T1=medfilt1(T,5); % 中值滤波函数
figure(3);
stem(T1,'.');
axis([0 length(T1) 0 20]);
xlabel('frame(n)');
ylabel('period(ms)');

matlab提取语音信号特征_第3张图片
这样得到的其实就是基音频率了

栗2

我在这个链接这里也找到了代码,效果如下

matlab提取语音信号特征_第4张图片
整理的代码如下所示:

%%
[x, fs] = audioread('5num.wav');
frame_length = 30
frame_overlap = 20
nsample = round(frame_length  * fs / 1000); % 转换 ms 到 point
noverlap = round(frame_overlap * fs / 1000); % 转换 ms 到 point
N = length(x);
pos = 1;
i = 1;
while (pos+nsample < N)
    frame = x(pos:pos+nsample-1);
    frame_length = length(frame);
    %      加窗
    window = hanning(frame_length);
    frame = window.*frame;
    frame = frame - mean(frame); % 去除中值
    R(:,i) = xcorr(frame, fs, 'coeff');
%     R(:,i) = spCorrelum(frame, fs);
     % 搜2ms (=500Hz)到20ms (=50Hz)内的最大值
    F0(i) = spPitchCorr(R(:,i), fs);
    r = R(:,i);
     % 搜2ms (=500Hz)到20ms (=50Hz)内的最大值
     ms2=floor(fs/500); % 2ms
     ms20=floor(fs/50); % 20ms
     % 反应真实信号
     r = r(floor(length(r)/2):end);
     [maxi,idx]=max(r(ms2:ms20));
     f0 = fs/(ms2+idx-1);
    pos = pos + (nsample - noverlap);
    i = i + 1;
end
%  求出对应的横坐标 帧长nsample 重叠 noverlap,如果noverlap为0那么就是直接每隔nsample取值
 T = (round(nsample/2):(nsample-noverlap):N-1-round(nsample/2))/fs;

% 画出波形
subplot(2,1,1);
t = (0:N-1)/fs;
 plot(t, x);
%     plot(x);
legend('Waveform');
xlabel('Time (s)');
ylabel('Amplitude');
xlim([t(1) t(end)]);

% 画出 F0跟踪
subplot(2,1,2);
plot(T,F0);
legend('pitch track');
xlabel('Time (s)');
ylabel('Frequency (Hz)');
xlim([t(1) t(end)]);

但是为什么得到的图是倒过来的呢??。。

求预测增益

[y,fs] = audioread(input);
%设置帧长20ms
wlen=160;inc=40;%inc为帧移
win=hamming(wlen);%给出汉明窗
N=length(y);%信号长度
X=enframe(y,win,inc);%分帧
%frame=X(850:851,:);
figure;
subplot(211);plot(X);xlabel('帧');ylabel('分帧加窗后的矩阵');

加窗之后可以看到如下:

matlab提取语音信号特征_第5张图片
然后问题来了,我分帧之后怎么求出频率呢。

或者说这幅图又代表了什么呢?

局部放大之后可以看到

matlab提取语音信号特征_第6张图片

可以看到我读0的时候的帧大概是第520帧

可以单独提取出来

%[x,fs]=audioread(input);
n=160;%一帧的样点数
p0=40;%帧重叠的部分
x1=buffer(y,n,p0);
m=521;%第几帧
y1=x1((m-1)*n+1:m*n);%选出一个帧的数据
%p=10;%
subplot(212);plot(y1);xlabel('520帧');ylabel('分帧加窗后的矩阵');

matlab提取语音信号特征_第7张图片

但是这幅图又代表什么呢emmm

之后开始计算预测系数

ar=lpc(y1,10);%预测系数
est_x=filter([0 -ar(2:end)],1,y1);%估计信号
e=y1-est_x;%预测误差

以及:

%%求预测增益
%计算残差能量
En=zeros(1,160);
for i=1:160
   u=e(i);%取出一样点
   u2=u.*u;%求出能量
   En(i)=sum(u2);%对每一样点累加求和
end

%计算原始能量
En1=zeros(1,160);
for i=1:160
   u=y1(i);%取出一样点
   u2=u.*u;%求出能量
   En1(i)=sum(u2);%对每一样点累加求和
end
CA=zeros(1,160);
for i=1:160
   en1=En1(i);%取出一样点
   en=En(i);
   CA(i)=abs(en1)/abs(en);
end

matlab提取语音信号特征_第8张图片

matlab提取语音信号特征_第9张图片

你可能感兴趣的:(多媒体,matlab)