splitlp5.m

来自「这是一个用于语音信号处理的工具箱」· M 代码 · 共 145 行

M
145
字号
% FUNCTION: seperate the LP roots into a format and a balanced polynomial.
%   [Fpoly,Bpoly,FF,FB]=splitlp5(oripoly) gets the 13 roots of oripoly and 
%   splits them into Fpoly (constructed with formant roots) and Bpoly 
%   (unrelated roots).
%   In the function, we apply the pole-modificatoin algorithm to adjust
%   the radius of formant roots in order to get an accurate estimation
%
% INPUT: oripoly==LP polynomial, order of 13, the length is 14.
% OUTPUT: Fpoly==formant roots which are conjugated or on half sampling 
%               frequency, order is 10.
%        Bpoly==balanced poles which are real, order is 3.
%        FF == formant frequencies
%        FB == formant bandwidths

function [Fpoly,Bpoly,FF,FB]=splitlp5(oripoly);

%%% 0. calculate the roots(poles) from the LP polynomials
%%%    and sort it according to their angles
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
poles=roots(oripoly);
poles=poles(:)';
poles=poles( imag(poles)>=0 ); % remove the conjugate part
angs=angle(poles);
if find(angs==-pi)~=[]
   xindx=find(angs==-pi);
   angs(xindx)=-1*angs(xindx);
end
[angs,a_sort]=sort(angs);
poles=poles(a_sort);

%%% 1. put poles with imagnary part==0 into pole1; 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
indx1=find( imag(poles)==0 );
pole1=poles(indx1);
poles(indx1)=[];
angs(indx1)=[];

%% 2. Check if the number of poles in poles
%%    >5  => find the biggest bandwidth to frequency ratio
%%    <5  => issue an error message
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
npole=length(poles);

if npole>5
   ff=angs/pi*5000; % formant frquency
   rad=abs(poles); % pole radius
   tmp=(4*rad-1-rad.^2)./(2*rad);
   fb=acos(tmp)/pi*10000; % formant bandwidth

   ratio=fb./ff; % bandwidth to frequency ratio
   [dum,indx2]=sort(ratio);
   unwnt=indx2(6:npole); % the extra pole with big ratio
   pole1=[pole1 poles(unwnt)];
   poles(unwnt)=[];
   angs(unwnt)=[];

elseif npole==4
   [dum1,indx2]=min(pole1);
   pole1(indx2)=[];
   [dum2,indx2]=min(pole1);
   pole1(indx2)=[];
   sudo=sqrt((1+dum1)*(1+dum2))-1;
   sudo=sudo*exp(j*3.11); % create a complex pair of roots
   poles=[poles sudo];
   angs(5)=3.11;

elseif npole<4
   disp('Error in function splitlp5.');   
   disp('there is an error!  Less than 4 conjugated pairs are found.');
   disp(poles);
   disp(pole1);

end

%% 3. pole modification
%%%%%%%%%%%%%%%%%%%%%%%

% find the deleted poles
for i=1:length(pole1)
    if imag(pole1(i))~=0
       pole1=[pole1 conj(pole1(i))];
    end
end
ang1=angle(pole1);

% adjust the radius of the affected poles
npole=poles; % new poles 

for i=1:5    
    % correction for deleted poles
    tmp=angs(i); % angle of current selected pole
    fac5=ang1-tmp; % angle difference between poles and deleted poles
    idx3=1:length(pole1); % all pole1
    %idx3=find( (-1*pi/6)<fac5 & fac5<pi/6 ); % find pole1 in positive region
    fac5=fac5(idx3);

    dh=1;
    for ii=1:length(fac5)
        rj=abs( pole1(idx3(ii)) );  % radius of deleted pole
        %dh=(1+rj*rj-2*rj*cos( fac5(ii) ) )*2*dh; %=> under correction
        dh=(1+rj*rj-2*rj*cos( fac5(ii) ) )*dh; % => theoretic correction   
    end
 
    % correction for previous adjusted poles
    dhh=1;
    for k=1:(i-1)
        rk=abs( poles(k) ); % radius of previous pole
        delta=angs(k)-tmp; 
        rkp=abs( npole(k) ); % adjusted radius of previous pole
        dhh0=(1+rk*rk-2*rk*cos(delta));
        dhh1=(1+rkp*rkp-2*rkp*cos(delta));
        dhh=dhh*dhh0/dhh1;
    end

    ri=abs(poles(i)); % radius of affetced pole
    rn=1-sqrt(dh*dhh)*(1-ri); % radius of modified pole
    %[rj ri rn]
    npole(i)=rn*exp(j*tmp);
end

% 4. construct the formant polynomial and balanced polynomial
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FF=angle(npole)/pi*5000; % formant frequencies
rad=abs(npole);
tmp=(4*rad-1-rad.^2)./(2*rad);
FB=acos(tmp)/pi*10000; % formant bandwidth
[FF,idx]=sort(FF);
FB=FB(idx);

Fpoly=real( poly([npole conj(npole)]) );
Bpoly=real( poly(pole1) );

% plot the frequency responses
if nargout<2
   h0=freqz(1,oripoly,1000); % original LP spectrum
   h0=log(abs(h0));
   h1=freqz(1,real(poly([poles conj(poles)])),1000); % formant spectrum
   h1=log(abs(h1));
   h2=freqz(1,Fpoly,1000); % formant spectrum with pole modification
   h2=log(abs(h2));
   plot(1:5:5000,h0,'y-');hold on;
   plot(1:5:5000,h1,'y--');
   plot(1:5:5000,h2,'y.');hold off;
end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?