www.pudn.com > Get_HRtf.rar > Get_HRtf.m


function [L_IR,R_IR]=Get_HRIR(elev,azim) 
%  
%得到声源位置为elev,azim时,声源到左右耳的脉冲响应 
%L_IR为到左耳的脉冲响应,R_IR为到右耳的脉冲响应, 
%elev表示仰角 取值范围为[-40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90] 
%azim表示水平角 取值范围为0--360度 
 
ext='.dat'; 
root='compact\'; 
 
azim = round(azim); 
if ((azim < 0) | (azim >=360)) 
	error('azimuth must be between 0 and 360 degrees'); 
end 
 
if (~ismember(elev,[-40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90]))  %判断仰角是不是在MIT数据库中 
	error('elevation must be [-40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90] degrees'); 
end 
 
flag=0; 
if azim>180 
    azim=360-azim; 
    flag=1; 
end 
 
switch elev 
    case {-20,-10,0,10,20} %仰角为-20 10 0 10 20度时,水平测量间隔为5度 
        azim_below=floor(azim/5)*5; 
        azim_up=azim_below+5; 
        [L_IR,R_IR]=Azim_inter(elev,azim,azim_below,azim_up,flag); 
    case {-30,30}         %仰角为-30 30度时,水平测量间隔为6度 
        azim_below=floor(azim/6)*6; 
        azim_up=azim_below+6; 
        [L_IR,R_IR]=Azim_inter(elev,azim,azim_below,azim_up,flag); 
    case {-40,40}         %仰角为-40 40度时,水平测量间隔为360/56度 
        azim_below=round(floor(azim*56/360)*360/56); 
        azim_up=round(floor(azim*56/360)*360/56+360/56); 
        [L_IR,R_IR]=Azim_inter(elev,azim,azim_below,azim_up,flag); 
    case 50    %仰角为50度时,水平测量间隔为8度 
        azim_below=floor(azim/8)*8; 
        azim_up=azim_below+8; 
        [L_IR,R_IR]=Azim_inter(elev,azim,azim_below,azim_up,flag); 
    case 60   %仰角为60度时,水平测量间隔为10度 
        azim_below=floor(azim/10)*10; 
        azim_up=azim_below+10; 
        [L_IR,R_IR]=Azim_inter(elev,azim,azim_below,azim_up,flag); 
    case 70    %仰角为70度时,水平测量间隔为15度 
        azim_below=floor(azim/15)*15; 
        azim_up=azim_below+15; 
        [L_IR,R_IR]=Azim_inter(elev,azim,azim_below,azim_up,flag); 
    case 80    %仰角为80度时,水平测量间隔为30度 
        azim_below=floor(azim/30)*30; 
        azim_up=azim_below+30; 
        [L_IR,R_IR]=Azim_inter(elev,azim,azim_below,azim_up,flag); 
    otherwise  %仰角为90度时,水平只测一个点 
        L_Path= sprintf('%selev%d\\H%de%03da%s',... 
 	    root,round(elev),round(elev),0,ext); 
        tmp = readraw(Path); 
        L_IR = tmp(1:2:length(tmp)); 
        R_IR = tmp(2:2:length(tmp)); 
end 
         
        
 
function [L_IR,R_IR]=Azim_inter(elev,azim,azim_below,azim_up,flag) 
% 利用插值得到水平角为azim的左右耳HRIR 
%elev表示仰角 取值范围为[-40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90] 
%azim表示水平角 取值范围为0--360度 
%azim_below表示和水平角azim相邻的下限角度 
%azim_up表示和水平角azim相邻的上限角度 
ext='.dat'; 
root='compact\'; 
     
%得到水平角为与azim相邻下限角度时的左耳HRIR 
Path= sprintf('%selev%d\\H%de%03da%s',... 
root,round(elev),round(elev),azim_below,ext); 
tmp = readraw(Path); 
L_IR1 = tmp(1:2:length(tmp)); 
R_IR1 = tmp(2:2:length(tmp));; 
 
if azim_up<180 
    Path= sprintf('%selev%d\\H%de%03da%s',... 
    root,round(elev),round(elev),azim_up,ext); 
    tmp = readraw(Path); 
    L_IR2 = tmp(1:2:length(tmp)); 
    R_IR2 = tmp(2:2:length(tmp)); 
else 
     L_IR2=0; 
     R_IR2=0; 
 end 
 
L_IR=((azim-azim_below)*L_IR2+(azim_up-azim)*L_IR1)/(azim_up-azim_below); %由插值得到水平角为azim的左耳HRIR 
R_IR=((azim-azim_below)*R_IR2+(azim_up-azim)*R_IR1)/(azim_up-azim_below);%由插值得到水平角为azim的右耳HRIR 
 
if flag==1 
    IR_temp=L_IR; 
    L_IR=R_IR; 
    R_IR=IR_temp; 
end 
     
    
    
function [x] = readraw(pathname) 
 
% read raw HRTF data, big-endian (Motorola) format 
% pathname 
fid = fopen(pathname,'r','ieee-be'); 
if (fid == -1) 
	error(sprintf('cannot open file %s',pathname)); 
end 
x = fread(fid,inf,'short'); 
fclose(fid); 
% 
% return as row vector, +/- 1 max. 
% 
x = x' / 32768;