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;