Commit 5d172dea authored by emerit's avatar emerit
Browse files

remove use of python

parent cb94687a
Loading
Loading
Loading
Loading
+38 −4
Original line number Diff line number Diff line
@@ -11,6 +11,28 @@ set(IVAS_TRUNK_ENC_PATH ${IVAS_TRUNK_PATH}/lib_enc)
set(IVAS_TRUNK_COM_PATH ${IVAS_TRUNK_PATH}/lib_com)
set(IVAS_TRUNK_DEBUG_PATH ${IVAS_TRUNK_PATH}/lib_debug)

option(USE_PYTHON "Use SOFA python reader" OFF)
option(USE_MATLAB "Use SOFA matlab reader" ON)

if (USE_MATLAB)
find_package(Matlab REQUIRED)
message("Matlab_VERSION = ${Matlab_VERSION}")
message("Matlab_ROOT_DIR = ${Matlab_ROOT_DIR}")
message("Matlab_INCLUDE_DIRS = ${Matlab_INCLUDE_DIRS}")
if (NOT Matlab_MAT_LIBRARY)
string(REPLACE  "mex" "mat" Matlab_MAT_LIBRARY ${Matlab_MEX_LIBRARY})
endif()
message("Matlab_MAT_LIBRARY = ${Matlab_MAT_LIBRARY}")
message("Matlab_LIBRARIES = ${Matlab_LIBRARIES}")
message("Matlab_MX_LIBRARY = ${Matlab_MX_LIBRARY}")
message("Matlab_MEX_LIBRARY = ${Matlab_MEX_LIBRARY}")
message("Matlab_ENGINE_LIBRARY = ${Matlab_ENGINE_LIBRARY}")
message("Matlab_DATAARRAY_LIBRARY = ${Matlab_DATAARRAY_LIBRARY}")
add_definitions(-DUSE_MATLAB)
include_directories(${Matlab_INCLUDE_DIRS} ${IVAS_TRUNK_UTIL_PATH} ${IVAS_TRUNK_ENC_PATH} ${IVAS_TRUNK_DEC_PATH} ${IVAS_TRUNK_REND_PATH} ${IVAS_TRUNK_COM_PATH} ${IVAS_TRUNK_DEBUG_PATH})
endif()

if (USE_PYTHON)
find_package(Python REQUIRED COMPONENTS Development Interpreter NumPy)

message("Python_EXECUTABLE = ${Python_EXECUTABLE}")
@@ -37,6 +59,7 @@ endif()
add_definitions(-DNPY_NO_DEPRECATED_API)

include_directories(${Python_INCLUDE_DIRS} ${Python_NumPy_INCLUDE_DIRS} ${IVAS_TRUNK_UTIL_PATH} ${IVAS_TRUNK_ENC_PATH} ${IVAS_TRUNK_DEC_PATH} ${IVAS_TRUNK_REND_PATH} ${IVAS_TRUNK_COM_PATH} ${IVAS_TRUNK_DEBUG_PATH})
endif()

set(SOURCE_FILES_C
    ${PROJECT_SOURCE_DIR}/ivas_crend_binaural_filter_design.c
@@ -77,11 +100,22 @@ add_library(${PROJECT_NAME}_lib STATIC ${SOURCE_FILES_C} ${SOURCE_FILES_H})

add_executable(${PROJECT_NAME} generate_crend_ivas_tables_from_sofa.c)

if (USE_MATLAB)
    if(UNIX AND NOT APPLE)
    target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_lib ${Matlab_MAT_LIBRARY} -lm -ldl)
    else()
message("Matlab_MX_LIBRARY = ${Matlab_MX_LIBRARY}")
    target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_lib  ${Matlab_MAT_LIBRARY} ${Matlab_LIBRARIES}  )
    endif()
endif()

if (USE_PYTHON)
    if(UNIX AND NOT APPLE)
        target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_lib ${Python_LIBRARIES} -lm -ldl)
    else()
        target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_lib ${Python_LIBRARIES})
    endif()
endif()

if(WIN32)
    add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
+214 −24
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@
#include <unistd.h>
#define MAX_PATH PATH_MAX
#endif
#ifdef _WIN32
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#include "options.h"
#include "ivas_cnst.h"
@@ -56,10 +59,14 @@
#undef M
#endif

#ifdef USE_MATLAB
#include "mat.h"
#else
#include <Python.h>
#include "numpy/utils.h"       // Include any other Numpy headers, UFuncs for example.
#include "numpy/numpyconfig.h" // Include any other Numpy headers, UFuncs for example.
#include "numpy/arrayobject.h" // Include any other Numpy headers, UFuncs for example.
#endif

/*------------------------------------------------------------------------------------------*
 * Constants
@@ -222,6 +229,7 @@ char *h_file_path = NULL;
char *rom_file_name = NULL;
uint16_t frame_len_ms = 5;

#ifndef USE_MATLAB
PyObject *sofa_load_func = NULL;
PyObject *sofa_find_dir_func = NULL;

@@ -252,6 +260,7 @@ int numpy_import_array( int ret )
    return 0;
}

#endif
/*------------------------------------------------------------------------------------------*
 * Standalone Renderer program
 *
@@ -638,6 +647,9 @@ int main( int argc, char *argv[] )
    char *tmpstr = strstr( ivas_path, "/binauralRenderer_interface" );
#endif
    tmpstr[0] = '\0';

#ifndef USE_MATLAB

    Py_Initialize();

    PyObject *sysPath = PySys_GetObject( (char *) "path" );
@@ -749,7 +761,7 @@ int main( int argc, char *argv[] )
            free( binary_common_file_name );
        return -1;
    }

#endif
    int err = 0;
    for ( ; i < argc; i++ )
    {
@@ -849,16 +861,39 @@ int main( int argc, char *argv[] )
    if ( binary_file_path )
        free( binary_file_path );



#ifndef USE_MATLAB
    Py_DECREF( sofa_find_dir_func );
    Py_DECREF( sofa_load_func );

    Py_Finalize();
#endif

    return err;
}

int32_t find_pos_spheric( const double *Source_Position_Cartesian, int32_t numPos, const double dir_spheric[3] )
{
    double valmax = 0;
    int32_t indmax = -1;
    int32_t ind;
    double dir_cart[3];
    double tmp;
    dir_cart[0] = ( dir_spheric[2] * cos( dir_spheric[0] * M_PI / 180. ) * cos( dir_spheric[1] * M_PI / 180. ) );
    dir_cart[1] = ( dir_spheric[2] * sin( dir_spheric[0] * M_PI / 180. ) * cos( dir_spheric[1] * M_PI / 180. ) );
    dir_cart[2] = dir_spheric[2] * sin( dir_spheric[1] * M_PI / 180. );

    for ( ind = 0; ind < numPos; ind++ )
    {
        tmp = Source_Position_Cartesian[ind * 3] * dir_cart[0] + Source_Position_Cartesian[ind * 3 + 1] * dir_cart[1] + Source_Position_Cartesian[ind * 3 + 2] * dir_cart[2];
        if ( tmp > valmax )
        {
            valmax = tmp;
            indmax = ind;
        }
    }
    return indmax;
}

int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *cfgReader )
{
    char *sofa_file_path = NULL;
@@ -867,7 +902,6 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
    const char *sofaDataBaseName = "";
    const char *sofaListenerName = "";
    double *data_IR_current = NULL;
    double *sofa_data_IR_val = NULL;
    double *sofa_data_IR_val_48k = NULL;
    double *sofa_data_IR_val_32k = NULL;
    double *sofa_data_IR_val_16k = NULL;
@@ -875,6 +909,12 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
    double *sofa_delay_val = NULL;
    double *sofa_src_pos_val = NULL;
    double *sofa_src_pos_cart_val = NULL;

    long sofa_sample_rate = 0;
    double a[3] = { 0 };
    double t[3] = { 0 };
    long nearest;
#ifndef USE_MATLAB
    PyObject *args = NULL;
    PyObject *kwargs = NULL;

@@ -882,12 +922,9 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
    PyArrayObject *sofa_data_IR = NULL;
    PyArrayObject *sofa_data_IR_48k = NULL;
    PyArrayObject *sofa_delay = NULL;
    long sofa_sample_rate = 0;
    PyArrayObject *sofa_src_pos_cart = NULL;
    PyArrayObject *dir_t = NULL;
    double a[3] = { 0 };
    double t[3] = { 0 };
    long nearest;
#endif
    /*------------------------------------------------------------------------------------------*
     * Parse command line and initialize renderer
     *------------------------------------------------------------------------------------------*/
@@ -900,6 +937,148 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
    }
    strcpy( sofa_file_path, file_path );

#ifdef USE_MATLAB
    MATFile *mat_fp = matOpen( sofa_file_path, "r" );
    if ( mat_fp == NULL )
    {
        printf( "Error reading existing matrix LocalDouble\n" );
        usage_gen_crend_tables();
        free( sofa_file_path );
        return -1;
    }

    mxArray *sofa = matGetVariable( mat_fp, "Sofa" );
    if ( sofa == NULL )
    {
        printf( "Error reading existing matrix LocalDouble\n" );
        usage_gen_crend_tables();
        free( sofa_file_path );
        matClose( mat_fp );
        return -1;
    }

    mwSize total_num_of_elements;
    mwIndex index = 0;
    int number_of_fields, field_index;
    const char *field_name;
    const mxArray *data;
    const double *sampleRate;

    //    total_num_of_elements = mxGetNumberOfElements( sofa );
    number_of_fields = mxGetNumberOfFields( sofa );

    /* For the given index, walk through each field. */
    for ( field_index = 0; field_index < number_of_fields; field_index++ )
    {
        //       display_subscript( structure_array_ptr, index );
        field_name = mxGetFieldNameByNumber( sofa,
                                             field_index );
        if ( strcmp( field_name, "DatabaseName" ) == 0 )
        {
            sofaDataBaseName = mxArrayToUTF8String( mxGetFieldByNumber( sofa,
                                                                        index,
                                                                        field_index ) );
            if ( sofaDataBaseName == NULL )
            {
                printf( "\tEmpty Field for %s\n", field_name );
            }
        }
        if ( strcmp( field_name, "ListenerShortName" ) == 0 )
        {
            sofaListenerName = mxArrayToUTF8String( mxGetFieldByNumber( sofa,
                                                                        index,
                                                                        field_index ) );
            if ( sofaListenerName == NULL )
            {
                printf( "\tEmpty Field for %s\n", field_name );
            }
        }
        if ( strcmp( field_name, "latencys" ) == 0 )
        {
            sofa_latencys = mxGetPr( mxGetFieldByNumber( sofa,
                                                         index,
                                                         field_index ) );
            if ( sofa_latencys == NULL )
            {
                printf( "\tEmpty Field for %s\n", field_name );
            }
        }
        if ( strcmp( field_name, "DataResampled" ) == 0 )
        {
            data = mxGetFieldByNumber( sofa,
                                       index,
                                       field_index );
            if ( data == NULL )
            {
                printf( "\tEmpty Field for %s\n", field_name );
                free( sofa_file_path );
                matClose( mat_fp );
                return -1;
            }

            total_num_of_elements = mxGetNumberOfElements( data );

            for ( indSR = 0; indSR < total_num_of_elements; indSR++ )
            {
                sampleRate = mxGetPr( mxGetFieldByNumber( data,
                                                          indSR,
                                                          1 ) );
                if ( *sampleRate == 48000 )
                {
                    const mwSize *dims = mxGetDimensions( mxGetFieldByNumber( data,
                                                                              indSR,
                                                                              0 ) );
                    sofa_N = sofa_N_48k = (int32_t) dims[0];
                    sofa_R = (int32_t) dims[1];
                    sofa_M = (int32_t) dims[2];
                    sofa_data_IR_val_48k = mxGetPr( mxGetFieldByNumber( data,
                                                                        indSR,
                                                                        0 ) );
                }
                if ( *sampleRate == 32000 )
                {
                    sofa_data_IR_val_32k = mxGetPr( mxGetFieldByNumber( data,
                                                                        indSR,
                                                                        0 ) );
                }
                if ( *sampleRate == 16000 )
                {
                    sofa_data_IR_val_16k = mxGetPr( mxGetFieldByNumber( data,
                                                                        indSR,
                                                                        0 ) );
                }
            }
        }
        if ( strcmp( field_name, "PosCartesian" ) == 0 )
        {
            sofa_src_pos_cart_val = mxGetPr( mxGetFieldByNumber( sofa,
                                                                 index,
                                                                 field_index ) );
            if ( sofa_src_pos_cart_val == NULL )
            {
                printf( "\tEmpty Field for %s\n", field_name );
                free( sofa_file_path );
                matClose( mat_fp );
                return -1;
            }
        }
        if ( strcmp( field_name, "PosSpherical" ) == 0 )
        {
            sofa_src_pos_val = mxGetPr( mxGetFieldByNumber( sofa,
                                                            index,
                                                            field_index ) );
            if ( sofa_src_pos_val == NULL )
            {
                printf( "\tEmpty Field for %s\n", field_name );
                free( sofa_file_path );
                matClose( mat_fp );
                return -1;
            }
        }
    }
    //    }

#else
    int ret = PyCallable_Check( sofa_load_func );
    if ( ret )
    {
@@ -963,6 +1142,7 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
            }
        }
    }
#endif

    struct ivas_layout_config lscfg;

@@ -996,6 +1176,7 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
        long nearest = 0;
        // int nd = 1;
        // int64_t n = 3;
#ifndef USE_MATLAB
        npy_intp dim[1] = { 3 };

        dir_t = (PyArrayObject *) PyArray_SimpleNewFromData( 1, dim, NPY_DOUBLE, t );
@@ -1007,13 +1188,16 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c

            return -1;
        }
#endif
    }
    /* get index to a position given in t (in spherical) */
    int *index_pos = (int *) malloc( sizeof( int ) * lscfg.nb_channel );
    uint32_t maxDel48kHz = 0;
    if ( index_pos == NULL )
    {
#ifndef USE_MATLAB
        Py_DECREF( py_results );
#endif
        free( sofa_file_path );
        fprintf( stderr, "Cannot alloc sofa_file_path !\n\n" );
        return -1;
@@ -1035,16 +1219,20 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
                                        // tmp[2] = t[2];
                                        // fprintf( stderr, "Wanted Position: %lf, %lf, %lf\n", t[0], t[1], t[2] );
                                        // fprintf( stderr, "Wanted Position: %lf, %lf, %lf\n", tmp[0], tmp[1], tmp[2] );
#ifdef USE_MATLAB
            nearest = find_pos_spheric( sofa_src_pos_cart_val, sofa_M, t );
#else
            py_results = PyObject_CallFunction( sofa_find_dir_func, "OO", (PyObject *) sofa_src_pos_cart, (PyObject *) dir_t );
            nearest = PyLong_AsLong( py_results );
#endif
            if ( ( nearest >= 0 ) && ( nearest < sofa_M ) )
            {
                a[0] = sofa_src_pos_val[nearest * 3];
                a[0] = sofa_src_pos_val[nearest * 3] * 180. / M_PI;
                if ( a[0] < 0 )
                {
                    a[0] += 360.;
                }
                a[1] = sofa_src_pos_val[nearest * 3 + 1];
                a[1] = sofa_src_pos_val[nearest * 3 + 1] * 180. / M_PI;
                a[2] = sofa_src_pos_val[nearest * 3 + 2];
            }

@@ -1061,10 +1249,10 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
                free( sofa_file_path );
                return -1;
            }
            if ( a[0] > 180 )
                a[0] -= 360;
            if ( a[0] < -180 )
                a[0] += 360;
            if ( a[0] > 180. )
                a[0] -= 360.;
            if ( a[0] < -180. )
                a[0] += 360.;
            fprintf( stderr, "Nearest Position: %f, %f, %f\n", a[0], a[1], a[2] );
            fprintf( stderr, "Nearest position found at: %ld\n", nearest );
            index_pos[i] = nearest;
@@ -1077,7 +1265,6 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
        uint32_t size = (uint32_t) sofa_R;
        uint32_t delL = 0, delR = 0;
    }

    size_t len_ls_cfg_name = strlen( lscfg.name );

    double latency_48k = 0;
@@ -1261,8 +1448,7 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
        }
        else
        {
            ivas_set_hrtf_fr( &hrtf_data, ivas_hrtf, frame_len
            );
            ivas_set_hrtf_fr( &hrtf_data, ivas_hrtf, frame_len );
        }
        hrtf_data.latency_s += 0.000000001f;

@@ -1313,8 +1499,12 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c
        ivas_hrtf_close( &hrtf_data );
    }

#ifdef USE_MATLAB
    matClose( mat_fp );
#else
    Py_DECREF( args );
    Py_DECREF( py_results );
#endif

    if ( sofa_file_path )
        free( sofa_file_path );
+8 −5
Original line number Diff line number Diff line
@@ -83,6 +83,9 @@ dataSpec.romOutDir = rom_path;
Mod_Hrf_Itd_Main(dataSpec);

%% generate crend rom  or binary values
SOFA_save_to_mat(hrir_file);
SOFA_save_to_mat(brir_file);

convert_SD2SHD_HRIRs(hrir_path,hrir_file_name,128);

command = ['.' filesep() 'generate_crend_ivas_tables'];
@@ -99,11 +102,11 @@ end

command = [command ...
                    ' 5 ' ...
                    hrir_file ' ' ...
                    erase(hrir_file,'.sofa') '_FOA.sofa ' ... 
                    erase(hrir_file,'.sofa') '_HOA2.sofa ' ... 
                    erase(hrir_file,'.sofa') '_HOA3.sofa ' ... 
                    brir_file ];
                    erase(hrir_file,'.sofa') '.mat ' ...
                    erase(hrir_file,'.sofa') '_FOA.mat ' ... 
                    erase(hrir_file,'.sofa') '_HOA2.mat ' ... 
                    erase(hrir_file,'.sofa') '_HOA3.mat ' ... 
                    erase(brir_file,'.sofa') '.mat ' ];

%display(command);

+113 −0
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 SOFA_save_to_mat(Lib_Name,outputSofaPath,sampleRates)
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here

if nargin == 1
    outputSofaPath = [erase(Lib_Name,'.sofa') '.mat'];
    sampleRates = [48000 32000 16000];
end
if nargin == 2
    sampleRates = [48000 32000 16000];
end

if isfile(Lib_Name)
        if isfile(outputSofaPath)
            delete(outputSofaPath);
        end

        Sofa = struct('Sofa',struct());

        sofa_data = ncinfo(Lib_Name);
        for indVar = 1:length(sofa_data.Variables)
            if (strcmp(sofa_data.Variables(indVar).Name, 'latencys'))
               Sofa.latencys = ncread(Lib_Name,'latencys');
            end
        end
        
        Sofa.Pos = ncread(Lib_Name, 'SourcePosition');
        Sofa.Units = strtrim(strsplit(ncreadatt(Lib_Name, 'SourcePosition', 'Units'), ','));
        
        assert( any(strcmpi(Sofa.Units{1}, {'degree','radian'})), 'Unknown units');
        if strcmpi(Sofa.Units{1},'degree'), Sofa.Pos(1,:)=Sofa.Pos(1,:)*pi/180; end
        assert( any(strcmpi(Sofa.Units{2}, {'degree','radian'})), 'Unknown units');
        if strcmpi(Sofa.Units{2},'degree'), Sofa.Pos(2,:)=Sofa.Pos(2,:)*pi/180; end
        assert( any(strcmpi(Sofa.Units{3}, {'metre','meter','inch'})), 'Unknown units');
        if strcmpi(Sofa.Units{3},'inch'  ), Sofa.Pos(3,:)=Sofa.Pos(3,:)*0.0254; end
        Sofa.PosSpherical = Sofa.Pos;
        Sofa.Pos = Sofa.Pos(3,:) .* ...
          [cos(Sofa.Pos(2,:)).*[cos(Sofa.Pos(1,:));sin(Sofa.Pos(1,:))];sin(Sofa.Pos(2,:))];
        
        Sofa.PosCartesian = make_unit_vectors(Sofa.Pos);
        NumLoc = size(Sofa.PosCartesian,2);
        
        % Now, get the impulse repsonses:
        Sofa.DataType = ncreadatt(Lib_Name, '/', 'DataType');
        Sofa.Data.IR = ncread(Lib_Name, 'Data.IR');
        Sofa.Data.SamplingRate = ncread(Lib_Name, 'Data.SamplingRate');
        Sofa.Data.SamplingRate_Units = ncreadatt(Lib_Name, 'Data.SamplingRate', 'Units');
        Sofa.Data.Delay = permute(ncread(Lib_Name, 'Data.Delay'), [2, 1]);
        switch lower(Sofa.DataType)
            case 'fir'
                assert( size(Sofa.Data.IR,2)>=2, 'Expecting 2 receivers (ears)');
                if size(Sofa.Data.IR,2)>2
                    Sofa.Data.IR = Sofa.Data.IR(:,1:2,:);
                    Sofa.Data.Delay = Sofa.Data.Delay(:,1:2);
                end
                assert( size(Sofa.Data.IR,3)==NumLoc, 'IR is incorrect size');
                assert( all(diff(Sofa.Data.Delay,1,2)==0), ...
                    'Non-zero inter-aural delay offset not (yet) implemented');
                assert(strcmp(Sofa.Data.SamplingRate_Units,'hertz'), 'unknown samplerate units');
            otherwise
                error(['unknown GLOBAL_DataType = ', hrtf.GLOBAL_DataType]);
        end
        
        for ind = 1:length(sampleRates)
            if sampleRates(ind) == Sofa.Data.SamplingRate
                Sofa.DataResampled(ind).IR = Sofa.Data.IR;
            else
                Sofa.DataResampled(ind).IR = resample(Sofa.Data.IR, sampleRates(ind),Sofa.Data.SamplingRate, Dimension=3);
            end
            Sofa.DataResampled(ind).SamplingRate = sampleRates(ind); 
        end

   Sofa.License = ncreadatt(Lib_Name,'/','License');
   Sofa.ListenerShortName = ncreadatt(Lib_Name,'/','ListenerShortName');
   Sofa.DatabaseName = ncreadatt(Lib_Name,'/','DatabaseName');
   Sofa.Title = ncreadatt(Lib_Name,'/','Title');
   Sofa.SOFAConventions = ncreadatt(Lib_Name,'/','SOFAConventions');
    
   save(outputSofaPath, 'Sofa');

end
 No newline at end of file