Loading scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SD_2_ROM.mdeleted 100644 → 0 +0 −117 Original line number Diff line number Diff line %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, % Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other % contributors to this repository. All Rights Reserved. % % This software is protected by copyright law and by international treaties. % The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, % Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other % contributors to this repository retain full ownership rights in their respective contributions in % the software. This notice grants no license of any kind, including but not limited to patent % license, nor is any license granted by implication, estoppel or otherwise. % % Contributors are required to enter into the IVAS codec Public Collaboration agreement before making % contributions. % % This software is provided "AS IS", without any express or implied warranties. The software is in the % development stage. It is intended exclusively for experts who have experience with such software and % solely for the purpose of inspection. All implied warranties of non-infringement, merchantability % and fitness for a particular purpose are hereby disclaimed and excluded. % % Any dispute, controversy or claim arising under or in relation to providing this software shall be % submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in % accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and % the United Nations Convention on Contracts on the International Sales of Goods. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function IR_cldfb = SD_2_ROM( rom_c_file, sofa_file) % SD_2_ROM( rom_c_file, sofa_file, ambisonics_order, hrir_length ) % % Derived from SHD_2_ROM.m % - loads sphere-sampled Head Related Impulse Responses (HRIRs) given in sofa_file % - converts SD HRIRs to Complex Low Delay Filter Bank (CLDFB) domain using fir_to_cldfb_fir.m % - writes CLDFB HRIRs to c-code ROM tables. [thispath,~,~] = fileparts(mfilename('fullpath')); thispath = [thispath,filesep]; if ~exist('sofa_file','var') || isempty(sofa_file) sofa_file = fullfile(thispath,'..','HRIRs_sofa','HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'); end %% load SD HRIRs H = hrtf_library_loader(); H.readSOFA(char(sofa_file)); ls_struct = get_ls_layout_config('Combined'); IR_SD = H.XYZ_to_IR_SD([deg2rad(ls_struct.azi); deg2rad(ls_struct.ele)]); %% SD -> CLDFB via least squares error optimization [~,num_ears,num_ch] = size(IR_SD); num_cldfb_taps = 3; IR_cldfb = zeros(60,num_cldfb_taps,num_ears,num_ch); % 60 frequency bands eval_flag = 0; % optional, = 1 requires signal processing toolbox (fftfilt) legacy_flag = 1; % = 1 used to indicate slightly too short buffers as used to generate tested coefficients for pos = 1:num_ch disp(['Channel ',num2str(pos),'/',num2str(num_ch)]) for ear = 1:num_ears IR_cldfb(:,:,ear,pos) = fir_to_cldfb_fir( IR_SD(:,ear,pos), num_cldfb_taps, eval_flag, legacy_flag ); end end %% CLDFB -> ROM latency_s = 0.000666667; % No added latency from conversion method max_band = 50; % Compute 60 bands, but only use 50 in ROM table IR_cldfb_rom = permute(IR_cldfb, [3 1 4 2]); % after permute: [ears(2), bands(60), chans(16), taps(3)] IR_cldfb_rom = IR_cldfb_rom(:,1:max_band,:,:); if ~exist('rom_c_file','var') || isempty(rom_c_file) rom_c_file = [thispath,'ivas_rom_binauralRenderer_combined.c']; % fullfile(thispath,'..','..','..','lib_rend',['ivas_rom_binauralRenderer_',order,'.c']); end fid = fopen(rom_c_file,'wt'); fprintf(fid, 'const float FASTCONV_HRIR_latency_s = %10.9ff;\n', latency_s); write_one_ear( fid, 'const float leftHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', real(IR_cldfb_rom(1,:,:,:))); write_one_ear( fid, 'const float leftHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', imag(IR_cldfb_rom(1,:,:,:))); write_one_ear( fid, 'const float rightHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', real(IR_cldfb_rom(2,:,:,:))); write_one_ear( fid, 'const float rightHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', imag(IR_cldfb_rom(2,:,:,:))); fclose(fid); function write_one_ear( fid, first_line, IR_cldfb_rom) IR_cldfb_rom = squeeze(IR_cldfb_rom); [num_bands,num_chans, num_taps] = size(IR_cldfb_rom); num_spaces = 4; num_spaces_cur = 0; fprintf(fid,[first_line,'\n{\n']); num_spaces_cur = num_spaces_cur + num_spaces; for band = 1:num_bands fprintf(fid,[blanks(num_spaces_cur),'{\n']); num_spaces_cur = num_spaces_cur + num_spaces; for chan = 1:num_chans fprintf(fid,[blanks(num_spaces_cur),'{']); for tap = 1:num_taps if tap == num_taps fprintf(fid,'%+ff',IR_cldfb_rom(band,chan,tap)); else fprintf(fid,'%+ff, ',IR_cldfb_rom(band,chan,tap)); end end if chan == num_chans fprintf(fid,'}\n'); else fprintf(fid,'},\n'); end end num_spaces_cur = num_spaces_cur - num_spaces; if band == num_bands fprintf(fid,[blanks(num_spaces_cur),'}\n']); else fprintf(fid,[blanks(num_spaces_cur),'},\n']); end end fprintf(fid,'};\n\n'); scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SHD_2_ROM.m +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ function IR_cldfb = SHD_2_ROM( rom_c_file, sofa_file, ambi_order, hrir_len ) [thispath,~,~] = fileparts(mfilename('fullpath')); thispath = [thispath,filesep]; %py_path = 'C:\Users\xxxx\AppData\Local\Programs\Python\Python39\python.exe'; % may look like this if ~exist('sofa_file','var') || isempty(sofa_file) sofa_file = fullfile(thispath,'..','HRIRs_sofa','HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'); end Loading @@ -49,6 +50,11 @@ if ~exist('hrir_len','var') hrir_len = 128; end %% convert sphere-sampled HRIRs to SHD HRIRs % requires: % python -m pip install sofar % python -m pip install numpy % convert sphere-sampled HRIRs to SHD HRIRs [sofa_path,sofa_name, sofa_ext] = fileparts(sofa_file); IR = generate_HOA_HRIRs_MOD_lens(ambi_order, sofa_path, [sofa_name,sofa_ext], hrir_len); Loading scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_ls_layout_config.mdeleted 100644 → 0 +0 −136 Original line number Diff line number Diff line function ls_struct = get_ls_layout_config(ls_layout_config) ls_struct = struct; switch ls_layout_config case 'FOA' ls_struct.name = 'FOA'; ls_struct.nb_channel = 4; ls_struct.azi = [0 0 0 0]; ls_struct.ele = [0 0 0 0]; ls_struct.isloudspeaker = 0; ls_struct.sba_order = 1; ls_struct.num_lfe = 0; ls_struct.lfe_index = zeros(0,0); case 'HOA2' ls_struct.name = 'HOA2'; ls_struct.nb_channel = 9; ls_struct.azi = [0 0 0 0 0 0 0 0 0]; ls_struct.ele = [0 0 0 0 0 0 0 0 0]; ls_struct.isloudspeaker = 0; ls_struct.sba_order = 2; ls_struct.num_lfe = 0; ls_struct.lfe_index = zeros(0,0); case 'HOA3' ls_struct.name = 'HOA3'; ls_struct.nb_channel = 16; ls_struct.azi = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; ls_struct.ele = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; ls_struct.isloudspeaker = 0; ls_struct.sba_order = 3; ls_struct.num_lfe = 0; ls_struct.lfe_index = zeros(0,0); case {'CICP2', '2d0'} ls_struct.name = 'CICP2'; ls_struct.nb_channel = 2; ls_struct.azi = [30 -30]; ls_struct.ele = [0 0]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; ls_struct.lfe_index = zeros(0,0); case {'CICP6', 'cicp6', '5d1'} ls_struct.name = 'CICP6'; ls_struct.nb_channel = 6; ls_struct.azi = [30 -30 0 0 110 -110]; ls_struct.ele = [0 0 0 0 0 0]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 1; ls_struct.lfe_index = [4]; case {'CICP12', 'cicp12', '7d1'} % 3 front, 4 surround + 1LFE ls_struct.name = 'CICP12'; ls_struct.nb_channel = 8; ls_struct.azi = [30 -30 0 0 110 -110 135 -135]; ls_struct.ele = [0 0 0 0 0 0 0 0]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 1; ls_struct.lfe_index = [4]; case {'CICP16', 'cicp16', '5d1p4'} ls_struct.name = 'CICP16'; ls_struct.nb_channel = 10; ls_struct.azi = [30 -30 0 0 110 -110 30 -30 110 -110]; ls_struct.ele = [0 0 0 0 0 0 35 35 35 35]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 1; ls_struct.lfe_index = [4]; case {'CICP13', 'cicp13','22d2'} ls_struct.name = 'CICP13'; ls_struct.nb_channel = 24; ls_struct.azi = [60 -60 0 0 135 -135 30 -30 180 0 90 -90 45 -45 0 0 135 -135 90 -90 180 0 45 -45]; ls_struct.ele = [0 0 0 0 0 0 0 0 0 0 0 0 35 35 35 90 35 35 35 35 35 -15 -15 -15]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 2; ls_struct.lfe_index = [4 10]; case {'CICP19', 'cicp19','7d1p4'} ls_struct.name = 'CICP19'; ls_struct.nb_channel = 12; ls_struct.azi = [30 -30 0 0 135 -135 90 -90 30 -30 135 -135]; ls_struct.ele = [0 0 0 0 0 0 0 0 35 35 35 35]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 1; ls_struct.lfe_index = [4]; case {'Combined'} ls_struct.name = 'Combined'; ls_struct.nb_channel = 15; ls_struct.azi = [30 -30 0 135 -135 110 -110 90 -90 30 -30 110 -110 135 -135]; ls_struct.ele = [0 0 0 0 0 0 0 0 0 35 35 35 35 35 35]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'Lebedev_26'} ls_struct.name = 'Leb26'; ls_struct.nb_channel = 26; ls_struct.azi = [0 180.0 90.0 270.0 0 0 90.0 90.0 270.0 270.0 0 0 180.0 180.0 45.0 315.0 135.0 225.0 45.0 45.0 315.0 315.0 135.0 135.0 225.0 225.0]; ls_struct.ele = [0 0 0 0 90.0 -90.0 45.0 -45.0 45.0 -45.0 45.0 -45.0 45.0 -45.0 0 0 0 0 35.3 -35.3 35.3 -35.3 35.3 -35.3 35.3 -35.3]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'cube_8'} ls_struct.name = 'Cub8'; ls_struct.nb_channel = 8; ls_struct.azi = [45 45 135 135 225 225 315 315]; ls_struct.ele = [35.3 -35.3 35.3 -35.3 35.3 -35.3 35.3 -35.3]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'BINAURAL', 'BINAURAL_ROOM'} ls_struct.name = 'BINAURAL'; ls_struct.nb_channel = 2; ls_struct.azi = [90 -90]; ls_struct.ele = [0 0]; ls_struct.isloudspeaker = 2; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'STEREO'} ls_struct.name = 'STEREO'; ls_struct.nb_channel = 2; ls_struct.azi = [90 -90]; ls_struct.ele = [0 0]; ls_struct.isloudspeaker = 2; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'MONO'} ls_struct.name = 'MONO'; ls_struct.nb_channel = 1; ls_struct.azi = [0]; ls_struct.ele = [0]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; otherwise error('Loudspeaker layout not supported!'); end scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/hrtf_library_loader.m +3 −44 Original line number Diff line number Diff line Loading @@ -157,11 +157,6 @@ classdef hrtf_library_loader < handle obj.process_lib(H, Data.SamplingRate); end function IR = XYZ_to_IR_SD( this, XYZ ) [HRTF_L, HRTF_R] = this.getHRTF_SD(XYZ); IR = permute(cat(3,HRTF_L,HRTF_R),[1,3,2]); end function IR = XYZ_to_IR( this, XYZ ) IR = permute(cat(3,this.getHRTF_L(XYZ),this.getHRTF_R(XYZ)),[1,3,2]); end Loading Loading @@ -229,19 +224,6 @@ classdef hrtf_library_loader < handle obj.Last_UV=[]; end function [HRTFs_L, HRTFs_R] = getHRTF_SD(obj, varargin) % GETHRTF_SD Get the SD HRTFs for both ears from the library % Given [N] direction-of-arrival vectors, returns an array % of size [Len]x[N], containing the N HRTFs. % Examples: % HRTFs = H.getHRTF_SD(Az,El) % Az and El are both Nx1 or 1xN vectors (in radians) % HRTFs = H.getHRTF_SD( Angles ) % Angles is a 2xN array of Az,El column pairs (in radians) % HRTFs = H.getHRTF_SD(X, Y, Z) % X,Y,Z are all 1xN or Nx1 vectors % HRTFs = H.getHRTF_SD(Vects) % Vects is a 3xN array of X,Y,Z column vectors UnitVecs = make_unit_vectors(varargin{:}); [HRTFs_L, HRTFs_R] = obj.Fetch_Discrete_HRTFs(UnitVecs); end function HRTFs = getHRTF_L(obj,varargin) % GETHRTF_L Get one or more Left-ear HRTFs from the library % Given [N] direction-of-arrival vectors, returns an array Loading Loading @@ -361,32 +343,9 @@ classdef hrtf_library_loader < handle end end function [TempL,TempR]=Fetch_Discrete_HRTFs(obj, UnitVecs) % We have set of unit-vectors, so we need to fetch the Left/Right % HRTFs at these (interpolated) angle positions NoVecs=size(UnitVecs,2); TempL=zeros(size(obj.Discrete_HRTFs,1),NoVecs); TempR=zeros(size(obj.Discrete_HRTFs,1),NoVecs); for k=1:NoVecs % For each direction (specified by a column of UnitVecs), we need % to figure out which HRTF Direction Vectors match the % given position IndSubset=1:size(obj.Discrete_UnitVectors,2); Dists=sum( (obj.Discrete_UnitVectors - repmat(UnitVecs(:,k),[1 size(obj.Discrete_UnitVectors,2)])).^2); [minDist, Dir] = min(Dists(IndSubset)); % 10e-e4 is roughly the error for 1deg offset on the sphere if abs(minDist) > 10e-3 error("Could not find an IR exactly matching this position, please check HRTF set!"); end TempL(:,k)=obj.Discrete_HRTFs(:,Dir,1); TempR(:,k)=obj.Discrete_HRTFs(:,Dir,2); end end function [TempL,TempR]=Interpolate_Discrete_HRTFs(obj,UnitVecs) % We have set of unit-vectors, so we need to build the Left/Right % We have set of unit-vectors, so we need to buld the Left/Right % HRTFs at these (interpolated) angle positions NoVecs=size(UnitVecs,2); TempL=zeros(size(obj.Discrete_HRTFs_GD_Mag,1),NoVecs); Loading @@ -403,7 +362,7 @@ classdef hrtf_library_loader < handle % Find the HRTF_Library direction closest to our target direction [~,NextDir] = min(Dists(IndSubset)); v=obj.Discrete_UnitVectors(:,IndSubset(NextDir)); GotSet=[GotSet IndSubset(NextDir)]; % Add this direction to the set GotSet=[GotSet IndSubset(NextDir)]; % Add this directon to the set IndSubset=IndSubset([1:NextDir-1,NextDir+1:end]); tmpV=UnitVecs(:,k)-v; if sum(tmpV.^2)>1e-20 Loading Loading
scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SD_2_ROM.mdeleted 100644 → 0 +0 −117 Original line number Diff line number Diff line %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, % Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other % contributors to this repository. All Rights Reserved. % % This software is protected by copyright law and by international treaties. % The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, % Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other % contributors to this repository retain full ownership rights in their respective contributions in % the software. This notice grants no license of any kind, including but not limited to patent % license, nor is any license granted by implication, estoppel or otherwise. % % Contributors are required to enter into the IVAS codec Public Collaboration agreement before making % contributions. % % This software is provided "AS IS", without any express or implied warranties. The software is in the % development stage. It is intended exclusively for experts who have experience with such software and % solely for the purpose of inspection. All implied warranties of non-infringement, merchantability % and fitness for a particular purpose are hereby disclaimed and excluded. % % Any dispute, controversy or claim arising under or in relation to providing this software shall be % submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in % accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and % the United Nations Convention on Contracts on the International Sales of Goods. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function IR_cldfb = SD_2_ROM( rom_c_file, sofa_file) % SD_2_ROM( rom_c_file, sofa_file, ambisonics_order, hrir_length ) % % Derived from SHD_2_ROM.m % - loads sphere-sampled Head Related Impulse Responses (HRIRs) given in sofa_file % - converts SD HRIRs to Complex Low Delay Filter Bank (CLDFB) domain using fir_to_cldfb_fir.m % - writes CLDFB HRIRs to c-code ROM tables. [thispath,~,~] = fileparts(mfilename('fullpath')); thispath = [thispath,filesep]; if ~exist('sofa_file','var') || isempty(sofa_file) sofa_file = fullfile(thispath,'..','HRIRs_sofa','HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'); end %% load SD HRIRs H = hrtf_library_loader(); H.readSOFA(char(sofa_file)); ls_struct = get_ls_layout_config('Combined'); IR_SD = H.XYZ_to_IR_SD([deg2rad(ls_struct.azi); deg2rad(ls_struct.ele)]); %% SD -> CLDFB via least squares error optimization [~,num_ears,num_ch] = size(IR_SD); num_cldfb_taps = 3; IR_cldfb = zeros(60,num_cldfb_taps,num_ears,num_ch); % 60 frequency bands eval_flag = 0; % optional, = 1 requires signal processing toolbox (fftfilt) legacy_flag = 1; % = 1 used to indicate slightly too short buffers as used to generate tested coefficients for pos = 1:num_ch disp(['Channel ',num2str(pos),'/',num2str(num_ch)]) for ear = 1:num_ears IR_cldfb(:,:,ear,pos) = fir_to_cldfb_fir( IR_SD(:,ear,pos), num_cldfb_taps, eval_flag, legacy_flag ); end end %% CLDFB -> ROM latency_s = 0.000666667; % No added latency from conversion method max_band = 50; % Compute 60 bands, but only use 50 in ROM table IR_cldfb_rom = permute(IR_cldfb, [3 1 4 2]); % after permute: [ears(2), bands(60), chans(16), taps(3)] IR_cldfb_rom = IR_cldfb_rom(:,1:max_band,:,:); if ~exist('rom_c_file','var') || isempty(rom_c_file) rom_c_file = [thispath,'ivas_rom_binauralRenderer_combined.c']; % fullfile(thispath,'..','..','..','lib_rend',['ivas_rom_binauralRenderer_',order,'.c']); end fid = fopen(rom_c_file,'wt'); fprintf(fid, 'const float FASTCONV_HRIR_latency_s = %10.9ff;\n', latency_s); write_one_ear( fid, 'const float leftHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', real(IR_cldfb_rom(1,:,:,:))); write_one_ear( fid, 'const float leftHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', imag(IR_cldfb_rom(1,:,:,:))); write_one_ear( fid, 'const float rightHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', real(IR_cldfb_rom(2,:,:,:))); write_one_ear( fid, 'const float rightHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]=', imag(IR_cldfb_rom(2,:,:,:))); fclose(fid); function write_one_ear( fid, first_line, IR_cldfb_rom) IR_cldfb_rom = squeeze(IR_cldfb_rom); [num_bands,num_chans, num_taps] = size(IR_cldfb_rom); num_spaces = 4; num_spaces_cur = 0; fprintf(fid,[first_line,'\n{\n']); num_spaces_cur = num_spaces_cur + num_spaces; for band = 1:num_bands fprintf(fid,[blanks(num_spaces_cur),'{\n']); num_spaces_cur = num_spaces_cur + num_spaces; for chan = 1:num_chans fprintf(fid,[blanks(num_spaces_cur),'{']); for tap = 1:num_taps if tap == num_taps fprintf(fid,'%+ff',IR_cldfb_rom(band,chan,tap)); else fprintf(fid,'%+ff, ',IR_cldfb_rom(band,chan,tap)); end end if chan == num_chans fprintf(fid,'}\n'); else fprintf(fid,'},\n'); end end num_spaces_cur = num_spaces_cur - num_spaces; if band == num_bands fprintf(fid,[blanks(num_spaces_cur),'}\n']); else fprintf(fid,[blanks(num_spaces_cur),'},\n']); end end fprintf(fid,'};\n\n');
scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/SHD_2_ROM.m +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ function IR_cldfb = SHD_2_ROM( rom_c_file, sofa_file, ambi_order, hrir_len ) [thispath,~,~] = fileparts(mfilename('fullpath')); thispath = [thispath,filesep]; %py_path = 'C:\Users\xxxx\AppData\Local\Programs\Python\Python39\python.exe'; % may look like this if ~exist('sofa_file','var') || isempty(sofa_file) sofa_file = fullfile(thispath,'..','HRIRs_sofa','HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'); end Loading @@ -49,6 +50,11 @@ if ~exist('hrir_len','var') hrir_len = 128; end %% convert sphere-sampled HRIRs to SHD HRIRs % requires: % python -m pip install sofar % python -m pip install numpy % convert sphere-sampled HRIRs to SHD HRIRs [sofa_path,sofa_name, sofa_ext] = fileparts(sofa_file); IR = generate_HOA_HRIRs_MOD_lens(ambi_order, sofa_path, [sofa_name,sofa_ext], hrir_len); Loading
scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/get_ls_layout_config.mdeleted 100644 → 0 +0 −136 Original line number Diff line number Diff line function ls_struct = get_ls_layout_config(ls_layout_config) ls_struct = struct; switch ls_layout_config case 'FOA' ls_struct.name = 'FOA'; ls_struct.nb_channel = 4; ls_struct.azi = [0 0 0 0]; ls_struct.ele = [0 0 0 0]; ls_struct.isloudspeaker = 0; ls_struct.sba_order = 1; ls_struct.num_lfe = 0; ls_struct.lfe_index = zeros(0,0); case 'HOA2' ls_struct.name = 'HOA2'; ls_struct.nb_channel = 9; ls_struct.azi = [0 0 0 0 0 0 0 0 0]; ls_struct.ele = [0 0 0 0 0 0 0 0 0]; ls_struct.isloudspeaker = 0; ls_struct.sba_order = 2; ls_struct.num_lfe = 0; ls_struct.lfe_index = zeros(0,0); case 'HOA3' ls_struct.name = 'HOA3'; ls_struct.nb_channel = 16; ls_struct.azi = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; ls_struct.ele = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; ls_struct.isloudspeaker = 0; ls_struct.sba_order = 3; ls_struct.num_lfe = 0; ls_struct.lfe_index = zeros(0,0); case {'CICP2', '2d0'} ls_struct.name = 'CICP2'; ls_struct.nb_channel = 2; ls_struct.azi = [30 -30]; ls_struct.ele = [0 0]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; ls_struct.lfe_index = zeros(0,0); case {'CICP6', 'cicp6', '5d1'} ls_struct.name = 'CICP6'; ls_struct.nb_channel = 6; ls_struct.azi = [30 -30 0 0 110 -110]; ls_struct.ele = [0 0 0 0 0 0]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 1; ls_struct.lfe_index = [4]; case {'CICP12', 'cicp12', '7d1'} % 3 front, 4 surround + 1LFE ls_struct.name = 'CICP12'; ls_struct.nb_channel = 8; ls_struct.azi = [30 -30 0 0 110 -110 135 -135]; ls_struct.ele = [0 0 0 0 0 0 0 0]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 1; ls_struct.lfe_index = [4]; case {'CICP16', 'cicp16', '5d1p4'} ls_struct.name = 'CICP16'; ls_struct.nb_channel = 10; ls_struct.azi = [30 -30 0 0 110 -110 30 -30 110 -110]; ls_struct.ele = [0 0 0 0 0 0 35 35 35 35]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 1; ls_struct.lfe_index = [4]; case {'CICP13', 'cicp13','22d2'} ls_struct.name = 'CICP13'; ls_struct.nb_channel = 24; ls_struct.azi = [60 -60 0 0 135 -135 30 -30 180 0 90 -90 45 -45 0 0 135 -135 90 -90 180 0 45 -45]; ls_struct.ele = [0 0 0 0 0 0 0 0 0 0 0 0 35 35 35 90 35 35 35 35 35 -15 -15 -15]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 2; ls_struct.lfe_index = [4 10]; case {'CICP19', 'cicp19','7d1p4'} ls_struct.name = 'CICP19'; ls_struct.nb_channel = 12; ls_struct.azi = [30 -30 0 0 135 -135 90 -90 30 -30 135 -135]; ls_struct.ele = [0 0 0 0 0 0 0 0 35 35 35 35]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 1; ls_struct.lfe_index = [4]; case {'Combined'} ls_struct.name = 'Combined'; ls_struct.nb_channel = 15; ls_struct.azi = [30 -30 0 135 -135 110 -110 90 -90 30 -30 110 -110 135 -135]; ls_struct.ele = [0 0 0 0 0 0 0 0 0 35 35 35 35 35 35]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'Lebedev_26'} ls_struct.name = 'Leb26'; ls_struct.nb_channel = 26; ls_struct.azi = [0 180.0 90.0 270.0 0 0 90.0 90.0 270.0 270.0 0 0 180.0 180.0 45.0 315.0 135.0 225.0 45.0 45.0 315.0 315.0 135.0 135.0 225.0 225.0]; ls_struct.ele = [0 0 0 0 90.0 -90.0 45.0 -45.0 45.0 -45.0 45.0 -45.0 45.0 -45.0 0 0 0 0 35.3 -35.3 35.3 -35.3 35.3 -35.3 35.3 -35.3]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'cube_8'} ls_struct.name = 'Cub8'; ls_struct.nb_channel = 8; ls_struct.azi = [45 45 135 135 225 225 315 315]; ls_struct.ele = [35.3 -35.3 35.3 -35.3 35.3 -35.3 35.3 -35.3]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'BINAURAL', 'BINAURAL_ROOM'} ls_struct.name = 'BINAURAL'; ls_struct.nb_channel = 2; ls_struct.azi = [90 -90]; ls_struct.ele = [0 0]; ls_struct.isloudspeaker = 2; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'STEREO'} ls_struct.name = 'STEREO'; ls_struct.nb_channel = 2; ls_struct.azi = [90 -90]; ls_struct.ele = [0 0]; ls_struct.isloudspeaker = 2; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; case {'MONO'} ls_struct.name = 'MONO'; ls_struct.nb_channel = 1; ls_struct.azi = [0]; ls_struct.ele = [0]; ls_struct.isloudspeaker = 1; ls_struct.sba_order = -1; ls_struct.num_lfe = 0; otherwise error('Loudspeaker layout not supported!'); end
scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/hrtf_library_loader.m +3 −44 Original line number Diff line number Diff line Loading @@ -157,11 +157,6 @@ classdef hrtf_library_loader < handle obj.process_lib(H, Data.SamplingRate); end function IR = XYZ_to_IR_SD( this, XYZ ) [HRTF_L, HRTF_R] = this.getHRTF_SD(XYZ); IR = permute(cat(3,HRTF_L,HRTF_R),[1,3,2]); end function IR = XYZ_to_IR( this, XYZ ) IR = permute(cat(3,this.getHRTF_L(XYZ),this.getHRTF_R(XYZ)),[1,3,2]); end Loading Loading @@ -229,19 +224,6 @@ classdef hrtf_library_loader < handle obj.Last_UV=[]; end function [HRTFs_L, HRTFs_R] = getHRTF_SD(obj, varargin) % GETHRTF_SD Get the SD HRTFs for both ears from the library % Given [N] direction-of-arrival vectors, returns an array % of size [Len]x[N], containing the N HRTFs. % Examples: % HRTFs = H.getHRTF_SD(Az,El) % Az and El are both Nx1 or 1xN vectors (in radians) % HRTFs = H.getHRTF_SD( Angles ) % Angles is a 2xN array of Az,El column pairs (in radians) % HRTFs = H.getHRTF_SD(X, Y, Z) % X,Y,Z are all 1xN or Nx1 vectors % HRTFs = H.getHRTF_SD(Vects) % Vects is a 3xN array of X,Y,Z column vectors UnitVecs = make_unit_vectors(varargin{:}); [HRTFs_L, HRTFs_R] = obj.Fetch_Discrete_HRTFs(UnitVecs); end function HRTFs = getHRTF_L(obj,varargin) % GETHRTF_L Get one or more Left-ear HRTFs from the library % Given [N] direction-of-arrival vectors, returns an array Loading Loading @@ -361,32 +343,9 @@ classdef hrtf_library_loader < handle end end function [TempL,TempR]=Fetch_Discrete_HRTFs(obj, UnitVecs) % We have set of unit-vectors, so we need to fetch the Left/Right % HRTFs at these (interpolated) angle positions NoVecs=size(UnitVecs,2); TempL=zeros(size(obj.Discrete_HRTFs,1),NoVecs); TempR=zeros(size(obj.Discrete_HRTFs,1),NoVecs); for k=1:NoVecs % For each direction (specified by a column of UnitVecs), we need % to figure out which HRTF Direction Vectors match the % given position IndSubset=1:size(obj.Discrete_UnitVectors,2); Dists=sum( (obj.Discrete_UnitVectors - repmat(UnitVecs(:,k),[1 size(obj.Discrete_UnitVectors,2)])).^2); [minDist, Dir] = min(Dists(IndSubset)); % 10e-e4 is roughly the error for 1deg offset on the sphere if abs(minDist) > 10e-3 error("Could not find an IR exactly matching this position, please check HRTF set!"); end TempL(:,k)=obj.Discrete_HRTFs(:,Dir,1); TempR(:,k)=obj.Discrete_HRTFs(:,Dir,2); end end function [TempL,TempR]=Interpolate_Discrete_HRTFs(obj,UnitVecs) % We have set of unit-vectors, so we need to build the Left/Right % We have set of unit-vectors, so we need to buld the Left/Right % HRTFs at these (interpolated) angle positions NoVecs=size(UnitVecs,2); TempL=zeros(size(obj.Discrete_HRTFs_GD_Mag,1),NoVecs); Loading @@ -403,7 +362,7 @@ classdef hrtf_library_loader < handle % Find the HRTF_Library direction closest to our target direction [~,NextDir] = min(Dists(IndSubset)); v=obj.Discrete_UnitVectors(:,IndSubset(NextDir)); GotSet=[GotSet IndSubset(NextDir)]; % Add this direction to the set GotSet=[GotSet IndSubset(NextDir)]; % Add this directon to the set IndSubset=IndSubset([1:NextDir-1,NextDir+1:end]); tmpV=UnitVecs(:,k)-v; if sum(tmpV.^2)>1e-20 Loading