%%
%语音采集
R = audiorecorder(16000, 16, 1);
%创建一个保存音频信息的对象,采样为16000Hz,用16bits存储,1即单声道。
recordblocking(R, 3); %开始录制,此时对着麦克风说话即可。
myspeech = getaudiodata(R)'; %得到以矩阵形式存储的刚录制的音频信号。
figure(1);
plot(myspeech); %画出波形
title('speech');
xlabel('时间t');
ylabel('幅值');
wavwrite(myspeech,16000,16,'语音');%保存语音
%%
%预加重
signal=wavread('myspeech.wav');%读取语音
figure(2);
subplot(211)
plot(signal, 'b');%画出预加重前的语音时域图
xlabel('时间t');
ylabel('幅值');
hold on
n = size(signal, 1);%求出语音大小
signalpress = zeros(1,n);%初始化用来存储预加重语音的矩阵
for i = 2 : n
signalpress(i) = signal(i) - 0.95 * signal(i-1);%预加重公式
end
plot(signalpress,'r'); title('signal After pre-emphasis时域');%画出预加重后的语音时域图
subplot(212)
plot(abs(fft(signal)), 'b');%画出预加重前的语音频域图
xlabel('频率f');
ylabel('幅值');
hold on
plot(abs(fft(signalpress)), 'r');title('signal After pre-emphasis频域');%画出预加重后的语音频域图
wavwrite(signalpress,16000,16,'signalpress');
%%
%海明窗的设置
x = wavread('signalpress.wav');
figure(3);
subplot(221)
plot(x); title('signalpress');
wa=3*16000; %3秒语音的总采样点
llframe=25*16;%每一帧的采样点
step=10*16; %帧与帧之间相差的采样点
numframe=floor((wa-llframe)/step)+1; %确定总的帧数
window=hamming(llframe);%函数直接调用设置海明窗
for i=1:llframe %通过公式实现来设置海明窗
window(i) = 0.54-0.46*cos(2*pi*i/(llframe - 1));
end
subplot(222)
plot(window); %画出设置好的海明窗
title('Generalized Hamming Window');
%%
%分帧
x1=zeros(numframe,llframe);%共有numframe帧,每帧长度为llframe
for i=1:numframe
n1=(i-1)*step+1;
n2=(i-1)*step+llframe;
t=1;
for j=n1:n2
x1(i,t)=x(j);%矩阵的一行存储语音信号的一帧
t=t+1;
end
end
%%
%加窗
x2=zeros(numframe,llframe);
for i=1:numframe
n1=(i-1)*step+1;
n2=(i-1)*step+llframe;
u=1;
for j=n1:n2 %对每一帧进行加窗,即每一帧的400个采样点与长度为400个采样点的海明窗相乘
x2(i, u)=x1(i, u)*window(j+1-n1);
u=u+1;
end
end
x2_show=zeros(1,numframe*llframe);
t=1;
for i=1:numframe
for j=1:400
x2_show(t)=x2(i,j); %将[numframe llframe]矩阵中的数据以[1 numframe*llframe]矩阵形式存储
t=t+1;
end
end
subplot(223) %画出分帧加窗后的语音信号
plot(x2_show); title('分帧加窗后的信号');
%%
%补零
llframe2=512;
x3=zeros(numframe,llframe2);%每一帧初始化为512个采样点
for i=1:numframe
for j=1:400
x3(i, j)=x2(i, j);%每一帧的前400个点为原语音信号的每一帧
end
end %每一帧的第401-512个点没有赋值,因此还是初始化的值,都为零
x3_show=zeros(1,numframe*512);%矩阵转换,同上
t3=1;
for i=1:numframe
for j=1:512
x3_show(t3)=x3(i,j);
t3=t3+1;
end
end
subplot(224) %画出补零后的信号
plot(x3_show); title('补零后的信号');
wavwrite(x3,16000,16,'signalzero');
%%
%FFT
figure(4);
Y2=zeros(numframe,512);
for i=1:numframe
Y2(i, :) = abs(fft(x3(i, :))).^2;%求出每一帧信号的功率谱
end
subplot(211) %画出信号的功率谱色图
imagesc(20*log10(Y2'));
colorbar
Y2_show=zeros(1,numframe*512);%矩阵转换,同上
t2=1;
for i=1:numframe
for j=1:512
Y2_show(t2)=Y2(i,j);
t2=t2+1;
end
end
subplot(212) %画出信号的功率谱波形图
plot(Y2_show); title('功率谱');
%%
% make Mel filter
max_freq = 16000/2; % 最大频率为8000
step_size = max_freq/512;
Mf_max = 2595*log(1+max_freq/700); % 将最大频率映射到梅尔谱上
avg = Mf_max /41; % 找到梅尔谱上滤波器之间的间隔
Mel_f = zeros(1, 42);
for i=0:41
Mel_f(i+1) =avg*i; % 找到梅尔谱上滤波器中心点的位置
end
f = 700*(exp(Mel_f/2595)-1); % 将滤波器的中心点位置从梅尔谱映射到正常谱上
filt = zeros(40, 512); % 每一行代表一个滤波器
numfilter =40; % 滤波器个数
% make filters
for i=1:numfilter
num = 1;
for j=step_size:step_size:max_freq
if(j>=f(i)&&j<=f(i+1)) filt(i, num)=(j-f(i))/(f(i+1)-f(i));end
if(j>=f(i+1)&&j<=f(i+2)) filt(i, num)=(f(i+2)-j)/(f(i+2)-f(i+1));end
num = num+1;
end
end
figure(5); % 画出三角滤波器
for i = 1:numfilter
plot(filt(i,:));
hold on
end
title('梅尔滤波器');
%%
% filt power Spectrum
% 滤波
Y3 = Y2; % 功率谱
energy = zeros(numframe, 40); % 储存梅尔频谱
for i=1:numframe
for j=1:numfilter;
energy(i,j) = sum(Y3(i,:).*filt(j,:));
end
end
figure(6);
energy_show=zeros(1,numframe*40);
t=1;
for i=1:numframe
for j=1:40
energy_show(t)=energy(i,j);
t=t+1;
end
end
plot(energy_show);
title('Mel Spectrum');
Y4 = zeros(numframe, 40); % 对梅尔频谱取对数
for i = 1:numframe
Y4(i,:) = log10(energy(i,:));
end
figure(7);
Y4_show=zeros(1,numframe*40);
t=1;
for i=1:numframe
for j=1:40
Y4_show(t)=Y4(i,j);
t=t+1;
end
end
plot(Y4_show);
title('Log Mel Spectrum');
%%
% DCT
Y5 = zeros(numframe, 40);
for i =1:numframe
Y5(i,:) = dct(Y4(i,:)); % 对梅尔频谱进行DCT变换
end
figure(8);
Y5_show=zeros(1,numframe*40);
t=1;
for i=1:numframe
for j=1:40
Y5_show(t)=Y5(i,j);
t=t+1;
end
end
plot(Y5_show);
title('DCT 变换');
% 取前十三维
coe = zeros(numframe, 13);
for i=1:13
coe(:,i) = Y5(:,i); % 梅尔倒谱
end
figure(9)
imagesc(abs(coe)');
colorbar
title('未归一化的梅尔系数色图');
%%
% 归一化
z = zeros(numframe, 13);
for i=1:numframe
u = mean(coe(i,:));
o = std(coe(i,:));
z(i,:) = (coe(i,:)-u)/o;
end
%figure(10)
%imagesc(abs(z)');
评论0