www.pudn.com > lsp.rar > lsp.m
%F1,F2,F3,F4
clear;
[y,fs,nbits]=wavread('F:\语音库\实验语音\dress6.wav');
y=filter([1 -0.975],[1],y);%预加重,系数等于0.975
all_length=length(y);
figure(100);set(gcf,'Color','White');
specgram(y(:,1),1024,fs,40,16);
%本实验中采样率为8kHz,帧长取256,持续时间t=256/8000=31.75ms,帧移为1/4帧长
N=256;%帧长
fm=N*1/4; %帧移
franum=floor((length(y)-N+fm)/fm);%计算总帧数
D_lpcc=16; p=13; LSFArray=[zeros(1,p)'];
xl = 0:fs/(2*N-1):fs;
for num=1:franum
for q=1:N
h(q)=0.54-0.46*cos(2*pi*q/N);%汉明窗
x(q)=y((num-1)*fm+q)*h(q);
end%加窗后的短时信号
%subplot(2,1,1);
%plot(x);axis([1 256 0 0.045]);
x_fft = abs(fft(x,N)).^2;
A = lpc(x,p);
A_fft = abs(fft(A,N)).^2;
lpcc=lpc_to_lpcc(A,p);%lpc to lpcc
%figure(2);plot(A_fft(1:128),'.');
[A_fft_dec,ind_a_fft] = sort(A_fft(1:128));%找出极值点
lsf = poly2lsf(A);
freq = lsf/2/pi*fs;
freq_array = [0];
LSFArray = [LSFArray lsf];
for k = 1 : p-1
delta_lsf(k) = lsf(k+1) - lsf(k); %差分线谱对
end
[d_lsf_dec,ind_lsf] = sort(delta_lsf);%升序排序后的差分线谱对
%figure(3);plot(delta_lsf,'.');
% 找出相邻频带
[ind_lsf_d,ind_ind_lsf] = sort(ind_lsf(1:8));%对差分线谱对的标号进行排序,找出标号所对应的相邻频带
k = 1; sum = 1; index = 1;
for i = k+1 : 8
if abs( ind_lsf_d(k) - ind_lsf_d(i) )==sum%相邻频段
sum = sum + 1;
else
if sum > 1 && i == k + sum%在相邻的(一段元素)区域中选择最小差分线谱对
if sum > 3%对长相邻区域的处理 选取出两个共振峰
[minlsf,min_indx] = min(delta_lsf(ind_lsf_d(k:i-1)));
%[maxlsf,max_indx] = max(delta_lsf(ind_lsf_d(k:i-1)));
[lsf1,ind_lfs1] = sort( delta_lsf(ind_lsf_d(k:i-1)) );
for j = 2 : sum
if abs(ind_lfs1(j) - ind_lfs1(1)) > 1
max_indx = ind_lfs1(j);
break;
end
end
freq_array = [freq_array ind_lsf_d(min_indx+k-1)];
freq_array = [freq_array ind_lsf_d(max_indx+k-1)];
index = index + 2;
sum = 1;
k = i;
else %短相邻区域的处理 选取出一个共振峰
[minlsf,min_indx] = min(delta_lsf(ind_lsf_d(k:i-1)));
freq_array = [freq_array ind_lsf_d(min_indx+k-1)];
index = index + 1;
sum = 1;
k = i;
end
else
freq_array = [freq_array ind_lsf_d(k)];
index = index + 1;
k = k + 1;
end
end
end
if sum <= 3
if k == 8%对数组末尾元素的处理
freq_array = [freq_array ind_lsf_d(k)];
index = index + 1;
else
[minlsf,min_indx] = min(delta_lsf(ind_lsf_d(k:i)));
freq_array = [freq_array ind_lsf_d(min_indx+k-1)];
index = index + 1;
end
else %对长相邻区域的处理
[minlsf,min_indx] = min(delta_lsf(ind_lsf_d(k:i)));
freq_array = [freq_array ind_lsf_d(min_indx+k-1)];
%[maxlsf,max_indx] = max( abs( ind_lsf_d(min_indx+k-1)-ind_lsf_d(k:i) ) );
%[maxlsf,max_indx] = max(delta_lsf(ind_lsf_d(k:i)));
[lsf2,ind_lfs2] = sort( delta_lsf(ind_lsf_d(k:i)) );
for j = 2 : sum
if abs(ind_lfs2(j) - ind_lfs2(1)) > 1
max_indx = ind_lfs2(j);
break;
end
end
freq_array = [freq_array ind_lsf_d(max_indx+k-1)];
index = index + 2;
end
[formant,ind_f] = sort(freq(freq_array(2:index))'+delta_lsf(freq_array(2:index))/2/pi*fs*0.5);
band = delta_lsf(freq_array(2:index))/2/pi*fs;
bandw = band(ind_f(1:index-1));
%formant = sort(freq(freq_array(2:4))+delta_lsf(freq_array(2:4))/2/pi*fs);%前3个共振峰
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 已算得当前帧的共振峰的频率(formant)和带宽(bandw) %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 将共振峰映射到倒谱域 %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
C = formant_to_lpcc(formant,bandw,index-1,D_lpcc,fs);
figure(100);
hold on;
x = num*fm/fs;
%for ii=1:kmt
plot(x,formant,'.');
%end
set(gca,'FontSize',10);set(gcf,'Color','White');
xlabel('Time(s)'); ylabel('Frequency(Hz)');
%legend('F1', 'F2','F3','F4');
end
%save data_6_4 formant franum fs fm;