Home > SUpDEq-v5.0.0 > supdeq_sofa2hrtf.m

supdeq_sofa2hrtf

PURPOSE ^

% SUpDEq - Spatial Upsampling by Directional Equalization

SYNOPSIS ^

function hrtfDataset = supdeq_sofa2hrtf(SOFAobj, N, samplingGrid, FFToversize)

DESCRIPTION ^

% SUpDEq - Spatial Upsampling by Directional Equalization

 function hrtfDataset = supdeq_sofa2hrtf(SOFAobj, N, samplingGrid, FFToversize)

 This function transformes a 'SimpleFreeFieldHRIR' SOFA file to frequency 
 domain and writes a hrtf dataset struct suitable for the SUpDEq toolbox.

 Output:
 hrtfDataset   - Struct with HRTFsfor the left (HRTF_L) and right (HRTF_R) 
                 channel/ear, absolute frequency scale f, 
                 maximum transform order N, FFToversize, and samplingGrid

 Input:
 SOFAobj       - Measurement data in form of a SOFA object
 N             - Maximal transform order N
 samplingGrid  - Optional input [default = nan]
                 If a spatial sampling grid is passed, it must be a Qx3 
                 matrix where the first column holds the azimuth, the 
                 second the elevation, and the third the sampling weights.
                 In this case, the sampling grid with weights will be
                 written to the struct. Otherwise, the sampling grid
                 stored in the SOFA file, transformed to SH coordinates,
                 will be written to the struct.
                 Azimuth positions in degree. Can be scalar or vector of size(el)
                 (0=front, 90=left, 180=back, 270=right)
                 (0 points to positive x-axis, 90 to positive y-axis)
                 Elevations in degree. Can be scalar or vector of size(az)
                 (0=North Pole, 90=front, 180=South Pole)
                 (0 points to positive z-axis, 180 to negative z-axis)
 FFToversize   - FFToversize rises the FFT Blocksize [default = 1]
                 A FFT of the blocksize (FFToversize*NFFT) is applied
                 to the time domain data,  where  NFFT is determinded
                 as the next power of two of the signalSize  which is
                 signalSize = (lastSample-firstSample).

 Dependencies: SOFA API

 (C) 2018 by JMA, Johannes M. Arend
             TH Köln - University of Applied Sciences
             Institute of Communications Engineering
             Department of Acoustics and Audio Signal Processing

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 %% SUpDEq - Spatial Upsampling by Directional Equalization
0002 %
0003 % function hrtfDataset = supdeq_sofa2hrtf(SOFAobj, N, samplingGrid, FFToversize)
0004 %
0005 % This function transformes a 'SimpleFreeFieldHRIR' SOFA file to frequency
0006 % domain and writes a hrtf dataset struct suitable for the SUpDEq toolbox.
0007 %
0008 % Output:
0009 % hrtfDataset   - Struct with HRTFsfor the left (HRTF_L) and right (HRTF_R)
0010 %                 channel/ear, absolute frequency scale f,
0011 %                 maximum transform order N, FFToversize, and samplingGrid
0012 %
0013 % Input:
0014 % SOFAobj       - Measurement data in form of a SOFA object
0015 % N             - Maximal transform order N
0016 % samplingGrid  - Optional input [default = nan]
0017 %                 If a spatial sampling grid is passed, it must be a Qx3
0018 %                 matrix where the first column holds the azimuth, the
0019 %                 second the elevation, and the third the sampling weights.
0020 %                 In this case, the sampling grid with weights will be
0021 %                 written to the struct. Otherwise, the sampling grid
0022 %                 stored in the SOFA file, transformed to SH coordinates,
0023 %                 will be written to the struct.
0024 %                 Azimuth positions in degree. Can be scalar or vector of size(el)
0025 %                 (0=front, 90=left, 180=back, 270=right)
0026 %                 (0 points to positive x-axis, 90 to positive y-axis)
0027 %                 Elevations in degree. Can be scalar or vector of size(az)
0028 %                 (0=North Pole, 90=front, 180=South Pole)
0029 %                 (0 points to positive z-axis, 180 to negative z-axis)
0030 % FFToversize   - FFToversize rises the FFT Blocksize [default = 1]
0031 %                 A FFT of the blocksize (FFToversize*NFFT) is applied
0032 %                 to the time domain data,  where  NFFT is determinded
0033 %                 as the next power of two of the signalSize  which is
0034 %                 signalSize = (lastSample-firstSample).
0035 %
0036 % Dependencies: SOFA API
0037 %
0038 % (C) 2018 by JMA, Johannes M. Arend
0039 %             TH Köln - University of Applied Sciences
0040 %             Institute of Communications Engineering
0041 %             Department of Acoustics and Audio Signal Processing
0042 
0043 function hrtfDataset = supdeq_sofa2hrtf(SOFAobj, N, samplingGrid, FFToversize)
0044 
0045 if nargin < 3
0046     samplingGrid = [];
0047 end
0048 
0049 if nargin < 4
0050     FFToversize = 1;
0051 end
0052 
0053 %Check FFToversize parameter
0054 if FFToversize < 1
0055     warning('FFToversize needs to >= 1. Set to default = 1.');
0056     FFToversize = 1;
0057 end
0058 
0059 %Check grid if passed
0060 if ~isempty(samplingGrid)
0061     if size(samplingGrid,2) > size(samplingGrid,1)
0062         samplingGrid = samplingGrid';
0063     end
0064     
0065     if size(samplingGrid,2) ~= 3
0066         warning('No sampling weights passed. Using sampling grid defined in SOFA object.')
0067         samplingGrid = [];
0068     end
0069 end
0070 
0071 %Check SOFA object
0072 if ~strcmp(SOFAobj.GLOBAL_SOFAConventions,'SimpleFreeFieldHRIR')
0073     error('Function only valid for SOFA convention "SimpleFreeFieldHRIR"');
0074 end
0075 
0076 %% Transform data to frequency domain
0077 
0078 %Get IRs
0079 irL = squeeze(SOFAobj.Data.IR(:,1,:)); 
0080 irR = squeeze(SOFAobj.Data.IR(:,2,:));
0081 
0082 %Zero pad to get length according to FFToversize
0083 if FFToversize > 1
0084     NFFT = 2^nextpow2(size(irL,2));
0085     NFFT = NFFT*FFToversize;
0086     irL = [irL, zeros(size(irL,1),NFFT-size(irL,2))];
0087     irR = [irR, zeros(size(irR,1),NFFT-size(irR,2))];
0088 else
0089     if size(irL,2) == 2^nextpow2(size(irL,2))
0090         NFFT = size(irL,2);
0091     else
0092         NFFT = 2^nextpow2(size(irL,2));
0093         irL = [irL, zeros(size(irL,1),NFFT-size(irL,2))];
0094         irR = [irR, zeros(size(irR,1),NFFT-size(irR,2))];
0095     end
0096 end
0097 
0098 %Transform HRIRs to frequency domain (HRTFs)
0099 HRTF_L = fft(irL,[],2);
0100 HRTF_R = fft(irR,[],2);
0101 %Cut at fs/2
0102 HRTF_L = HRTF_L(:,1:end/2+1);
0103 HRTF_R = HRTF_R(:,1:end/2+1);
0104 
0105 %If no samplingGrid was passed, use samplingGrid from SOFA
0106 if isempty(samplingGrid)
0107     %Get samplingGrid from SOFA object
0108     samplingGrid = SOFAobj.SourcePosition(:,1:2);
0109 
0110     %Transform samplingGrid to SH coordinate system
0111     samplingGrid(:,1) = mod(samplingGrid(:,1),360);
0112     samplingGrid(:,2) = 90-samplingGrid(:,2);
0113 end
0114 
0115 %Write f
0116 f = linspace(0,SOFAobj.Data.SamplingRate/2,NFFT/2+1);
0117 
0118 %Write output struct
0119 hrtfDataset.HRTF_L          = HRTF_L;
0120 hrtfDataset.HRTF_R          = HRTF_R;
0121 hrtfDataset.f               = f;
0122 hrtfDataset.Nmax            = N;
0123 hrtfDataset.FFToversize     = FFToversize;
0124 hrtfDataset.samplingGrid    = samplingGrid;
0125 hrtfDataset.sourceDistance  = SOFAobj.SourcePosition(1,3); 
0126 
0127 end
0128

Generated on Wed 30-Nov-2022 14:15:00 by m2html © 2005