Commit f5c55cb2 authored by Adam Mills's avatar Adam Mills
Browse files

Removing the dependency on sofar from the HRIR generation scripts

parent 7a8335cc
Loading
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -29,8 +29,8 @@
%   the United Nations Convention on Contracts on the International Sales of Goods.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function IR_cldfb = SHD_2_ROM( py_path, rom_c_file, sofa_file, ambi_order, hrir_len )
% SHD_2_ROM( python_path, rom_c_file, sofa_file, ambisonics_order, hrir_length )
function IR_cldfb = SHD_2_ROM( rom_c_file, sofa_file, ambi_order, hrir_len )
% SHD_2_ROM( rom_c_file, sofa_file, ambisonics_order, hrir_length )
%
% - converts sphere-sampled Head Related Impulse Responses (HRIRs) given in sofa_file 
%   to the Spherical Harmonics domain (SHD) using generate_HOA_HRIRs_MOD_lens.m
@@ -55,9 +55,8 @@ end
% python -m pip install numpy

% convert sphere-sampled HRIRs to SHD HRIRs
write_out_sofa = 0;
[sofa_path,sofa_name, sofa_ext] = fileparts(sofa_file);
IR = generate_HOA_HRIRs_MOD_lens(ambi_order, py_path, sofa_path, [sofa_name,sofa_ext], hrir_len, write_out_sofa);
IR = generate_HOA_HRIRs_MOD_lens(ambi_order, sofa_path, [sofa_name,sofa_ext], hrir_len);

%% SHD -> CLDFB via least squares error optimization
[~,num_ears,num_ch] = size(IR);
+4 −4
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@
%   the United Nations Convention on Contracts on the International Sales of Goods.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function convert_SD2SHD_HRIRs(python_path, sofa_path, sofa_file, IR_size)
function convert_SD2SHD_HRIRs(sofa_path, sofa_file, IR_size)

data_struct = struct.empty(3,0);

@@ -38,7 +38,7 @@ sr_short = [48, 32, 16];
sr_dft_size  = [240, 160, 80];

% FOA
data_struct(1).IR_data = generate_HOA_HRIRs_MOD_lens(1, python_path, sofa_path, sofa_file, IR_size, 0);
data_struct(1).IR_data = generate_HOA_HRIRs_MOD_lens(1, sofa_path, sofa_file, IR_size);
data_struct(1).HOA_name     = 'FOA';
data_struct(1).n_HOA_ch     = 4;
data_struct(1).sr           = sr;
@@ -46,7 +46,7 @@ data_struct(1).sr_short = sr_short;
data_struct(1).sr_dft_size  = sr_dft_size;

% HOA2
data_struct(2).IR_data = generate_HOA_HRIRs_MOD_lens(2, python_path, sofa_path, sofa_file, IR_size, 0);
data_struct(2).IR_data = generate_HOA_HRIRs_MOD_lens(2, sofa_path, sofa_file, IR_size);
data_struct(2).HOA_name     = 'HOA2';
data_struct(2).n_HOA_ch     = 9;
data_struct(2).sr           = sr;
@@ -54,7 +54,7 @@ data_struct(2).sr_short = sr_short;
data_struct(2).sr_dft_size  = sr_dft_size;

% HOA3
data_struct(3).IR_data = generate_HOA_HRIRs_MOD_lens(3, python_path, sofa_path, sofa_file, IR_size, 0);
data_struct(3).IR_data = generate_HOA_HRIRs_MOD_lens(3, sofa_path, sofa_file, IR_size);
data_struct(3).HOA_name     = 'HOA3';
data_struct(3).n_HOA_ch     = 16;
data_struct(3).sr           = sr;
+2 −17
Original line number Diff line number Diff line
@@ -29,30 +29,20 @@
%   the United Nations Convention on Contracts on the International Sales of Goods.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function IR_data = generate_HOA_HRIRs_MOD_lens(order, python_path, sofa_path, sofa_file_name, ir_len, write_out_sofa)
function IR_data = generate_HOA_HRIRs_MOD_lens(order, sofa_path, sofa_file_name, ir_len)
    % HRIR convertor - Takes sphere sampled HRIRs and converts them to
    % HOA HRIRs.
    %
    % order - HOA order to be converted to.
    % python_path - path that points to the python binary that has the
    %   sofar python module installed. sofar is needed to read the .sofa
    %   files that contain the HRIRs.
    % sofa_path - path to the directory that contains the sofa files to be
    % converted.
    % sofa_file - file name of the HRTFs to be converted
    % ir_len - length of the IRs to be used.
    % write_out_sofa - boolean to enable/disable writing out of sofa
    %
    % Typical usage:
    %   generate_HOA_HRIRs_MOD_lens(1, "~/.pyenv/versions/3.8.16/bin/python", '~/git/ivas-pc-testfiles/sofa-files/', 'HRIR_128_48000.sofa', 128)
    %   generate_HOA_HRIRs_MOD_lens(1, '~/git/ivas-pc-testfiles/sofa-files/', 'HRIR_128_48000.sofa', 128)
    %

% Pointing to the correct python binary
py_env = pyenv;
if ~strcmp(py_env.Executable, python_path)
   pyenv('Version', python_path);
end

% Load in the support coefs
load('hrtf_support_coefs.mat', 'hrtf_support_coefs');
rmsSphere   = hrtf_support_coefs(order).rmsSphere;
@@ -128,11 +118,6 @@ IR = permute(IR_HOA, [2, 1, 3]);
HOAformat_str = ['HOA',num2str(order),'S'];
save(fullfile(erase(sofa_file_name, ".sofa") + "_converted_" +  HOAformat_str + ".mat"), "IR")

if (write_out_sofa == 1)
    H.updateSOFA(IR);
    H.writeSOFA(fullfile(erase(sofa_file_name, ".sofa") + "_converted_" +  HOAformat_str + ".sofa"));
end

IR_data = IR;


+8 −25
Original line number Diff line number Diff line
@@ -79,8 +79,6 @@ classdef hrtf_library_loader < handle
        Last_HRTFs=[];
        % Remember the unit vectors for the most recent HRTFs computed
        Last_UV=[];

        Sofa_File = [];
    end
  
    methods
@@ -90,14 +88,11 @@ classdef hrtf_library_loader < handle

        function readSOFA(obj, Lib_Name)
            
            % Read in the sofa file using 'sofar' python module
            sofa_file = py.sofar.read_sofa(Lib_Name);
            
            % This looks like a library built from a bunch of discrete
            % locations in free field
            % Let's figure out the source locations used in the HRTF library:
            Pos = hrtf_library_loader.convert_numpy_2darray(sofa_file.SourcePosition)';
            Units = strtrim(strsplit(string(sofa_file.SourcePosition_Units), ','));
            Pos = ncread(Lib_Name, 'SourcePosition');
            Units = strtrim(strsplit(ncreadatt(Lib_Name, 'SourcePosition', 'Units'), ','));
            
            assert( any(strcmpi(Units{1}, {'degree','radian'})), 'Unknown units');
            if strcmpi(Units{1},'degree'), Pos(1,:)=Pos(1,:)*pi/180; end
@@ -113,12 +108,12 @@ classdef hrtf_library_loader < handle
            NumLoc = size(XYZ,2);
            
            % Now, get the impulse repsonses:
            assert( isprop(sofa_file, 'GLOBAL_DataType'), 'Expected field: GLOBAL_DataType');
            Data.IR = hrtf_library_loader.convert_numpy_3darray(sofa_file.Data_IR);
            Data.SamplingRate = double(sofa_file.Data_SamplingRate);
            Data.SamplingRate_Units = string(sofa_file.Data_SamplingRate_Units);
            Data.Delay = hrtf_library_loader.convert_numpy_2darray(sofa_file.Data_Delay);
            switch lower(string(sofa_file.GLOBAL_DataType))
            DataType = ncreadatt(Lib_Name, '/', 'DataType');
            Data.IR = permute(ncread(Lib_Name, 'Data.IR'), [3, 2, 1]);
            Data.SamplingRate = ncread(Lib_Name, 'Data.SamplingRate');
            Data.SamplingRate_Units = ncreadatt(Lib_Name, 'Data.SamplingRate', 'Units');
            Data.Delay = permute(ncread(Lib_Name, 'Data.Delay'), [2, 1]);
            switch lower(DataType)
                case 'fir'
                    assert( size(Data.IR,2)>=2, 'Expecting 2 receivers (ears)');
                    if size(Data.IR,2)>2
@@ -160,18 +155,6 @@ classdef hrtf_library_loader < handle
            H.Info.Scaling      = 'Normalised to unity gain at 1kHz';

            obj.process_lib(H, Data.SamplingRate);
            obj.Sofa_File = sofa_file;
        end
        
        function updateSOFA(obj, data)
            right_shape = permute(data, [3, 2, 1]);
            obj.Sofa_File.Data_IR = py.numpy.array(right_shape);
            d = size(right_shape);
            obj.Sofa_File.SourcePosition = py.numpy.array(zeros(d(1), 3));
        end

        function writeSOFA(obj, file_name)
            py.sofar.write_sofa(file_name, obj.Sofa_File);
        end
        
        function IR = XYZ_to_IR( this, XYZ )