Home > SUpDEq-v5.0.0 > evaluation > supdeq_calcSpectralDifference.m

supdeq_calcSpectralDifference

PURPOSE ^

% SUpDEq - Spatial Upsampling by Directional Equalization

SYNOPSIS ^

function results = supdeq_calcSpectralDifference( testHRTFdataset, referenceHRTFdataset, samplingGrid, fs, filterMode, plotResults)

DESCRIPTION ^

% SUpDEq - Spatial Upsampling by Directional Equalization

 function results = supdeq_calcSpectralDifference( testHRTFdataset, referenceHRTFdataset, samplingGrid, fs, filterMode, plotResults)

 This function calculates the spectral differences between a test and a 
 reference HRTF dataset at given spatial sampling points

 Output:
 results               - Results struct with spectral difference per
                         frequency and sampling point in dB (20*log10)
                         (specDifferencePerPoint) for left and right channel
                         spectral difference averaged over all spatial 
                         sampling points in dB (20*log10) for left and 
                         right channel (specDifference) as well as mean of 
                         specDifference in dB for left and right channel
                         --> Spectral difference averaged over all spatial 
                         sampling points and frequencies
                         (meanSpecDifference). Additionally, 
                         meanSpecDifference_freqRange provides the mean
                         spectral difference in a frequency range between
                         100Hz and 12kHz. "f" is a frequency vector

                         Optional: filterMode = true
                         Results struct with spectral difference per
                         frequency and sampling point in dB (20*log10)
                         (specDifferencePerPoint) for left and right
                         channel, spectral difference averaged over all spatial 
                         sampling points in dB (20*log10) for left and 
                         right channel and for every of the 40 filter bands
                         ("specDiffPerBand_L/R"). Additionally,
                         "specDiffL_meanPerBand" returns the mean spectral
                         difference per band (mean per band of
                         specDiffPerBand_L/R), fc returns the center
                         frequencies of the auditory filterbank, and f
                         is a frequency vector.

 Input:        
 testHRTFdataset       - Struct with (SH-Coefficients) of the test 
                         HRTF dataset (for example the de-equalized HRTF set
                         or any other HRTF set based on the referenceHRTFdataset) 
                         for the left (Hl_nm) and right (Hr_nm), channel/ear, 
                         absolute frequency scale f, transform order N, and FFToversize
 referenceHRTFdataset  - Struct with (SH-Coefficients) of the reference 
                         HRTF dataset for the left (Hl_nm) and right (Hr_nm), channel/ear, 
                         absolute frequency scale f, transform order N, and FFToversize
                         NOTE: testHRTFdataset and referenceHRTFdataset
                         need to have the same FFT size and FFToversize!!
 samplingGrid          - Spatial sampling grid. Must be a Qx2 matrix where 
                         the first column holds the azimuth and the second 
                         the elevation.
                         If no samplingGrid (or []) is passed, the default
                         sampling grid is passed (Lebedev grid with 2702
                         nodes)
 fs                    - Sampling Rate
                         Default: 48000
 filterMode            - Filter mode true/false. Use auditory filterbank
                         with 40 bands (fLow = 50 Hz, fHigh = 20kHz)
                         Default: false
 plotResults          -  plotResults true/false. Simple plot...
                         Default: false

 Dependencies: Auditory Modeling Toolbox (AMT), if filterMode = true

 (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 results = supdeq_calcSpectralDifference( testHRTFdataset, referenceHRTFdataset, samplingGrid, fs, filterMode, plotResults)
0004 %
0005 % This function calculates the spectral differences between a test and a
0006 % reference HRTF dataset at given spatial sampling points
0007 %
0008 % Output:
0009 % results               - Results struct with spectral difference per
0010 %                         frequency and sampling point in dB (20*log10)
0011 %                         (specDifferencePerPoint) for left and right channel
0012 %                         spectral difference averaged over all spatial
0013 %                         sampling points in dB (20*log10) for left and
0014 %                         right channel (specDifference) as well as mean of
0015 %                         specDifference in dB for left and right channel
0016 %                         --> Spectral difference averaged over all spatial
0017 %                         sampling points and frequencies
0018 %                         (meanSpecDifference). Additionally,
0019 %                         meanSpecDifference_freqRange provides the mean
0020 %                         spectral difference in a frequency range between
0021 %                         100Hz and 12kHz. "f" is a frequency vector
0022 %
0023 %                         Optional: filterMode = true
0024 %                         Results struct with spectral difference per
0025 %                         frequency and sampling point in dB (20*log10)
0026 %                         (specDifferencePerPoint) for left and right
0027 %                         channel, spectral difference averaged over all spatial
0028 %                         sampling points in dB (20*log10) for left and
0029 %                         right channel and for every of the 40 filter bands
0030 %                         ("specDiffPerBand_L/R"). Additionally,
0031 %                         "specDiffL_meanPerBand" returns the mean spectral
0032 %                         difference per band (mean per band of
0033 %                         specDiffPerBand_L/R), fc returns the center
0034 %                         frequencies of the auditory filterbank, and f
0035 %                         is a frequency vector.
0036 %
0037 % Input:
0038 % testHRTFdataset       - Struct with (SH-Coefficients) of the test
0039 %                         HRTF dataset (for example the de-equalized HRTF set
0040 %                         or any other HRTF set based on the referenceHRTFdataset)
0041 %                         for the left (Hl_nm) and right (Hr_nm), channel/ear,
0042 %                         absolute frequency scale f, transform order N, and FFToversize
0043 % referenceHRTFdataset  - Struct with (SH-Coefficients) of the reference
0044 %                         HRTF dataset for the left (Hl_nm) and right (Hr_nm), channel/ear,
0045 %                         absolute frequency scale f, transform order N, and FFToversize
0046 %                         NOTE: testHRTFdataset and referenceHRTFdataset
0047 %                         need to have the same FFT size and FFToversize!!
0048 % samplingGrid          - Spatial sampling grid. Must be a Qx2 matrix where
0049 %                         the first column holds the azimuth and the second
0050 %                         the elevation.
0051 %                         If no samplingGrid (or []) is passed, the default
0052 %                         sampling grid is passed (Lebedev grid with 2702
0053 %                         nodes)
0054 % fs                    - Sampling Rate
0055 %                         Default: 48000
0056 % filterMode            - Filter mode true/false. Use auditory filterbank
0057 %                         with 40 bands (fLow = 50 Hz, fHigh = 20kHz)
0058 %                         Default: false
0059 % plotResults          -  plotResults true/false. Simple plot...
0060 %                         Default: false
0061 %
0062 % Dependencies: Auditory Modeling Toolbox (AMT), if filterMode = true
0063 %
0064 % (C) 2018 by JMA, Johannes M. Arend
0065 %             TH Köln - University of Applied Sciences
0066 %             Institute of Communications Engineering
0067 %             Department of Acoustics and Audio Signal Processing
0068 
0069 function results = supdeq_calcSpectralDifference( testHRTFdataset, referenceHRTFdataset, samplingGrid, fs, filterMode, plotResults)
0070 
0071 %Default sampling grid (Lebedev grid with 2702 nodes)
0072 if nargin < 3 || isempty(samplingGrid)
0073     samplingGrid = supdeq_lebedev(2702);
0074 end
0075 
0076 if nargin < 4 || isempty(fs)
0077     fs = 48000;
0078 end
0079 
0080 if nargin < 5 || isempty(filterMode)
0081     filterMode = false;
0082 end
0083 
0084 if nargin < 6
0085     plotResults = false;
0086 end
0087 
0088 
0089 %% Filter mode off
0090 if ~filterMode
0091     
0092     %Get HRTFs according to sampling grid
0093     fprintf('Extracting 2 x %d HRTFs. This may take some time...\n',size(samplingGrid,1));
0094     [HRTFs_Test_L,HRTFs_Test_R] = supdeq_getArbHRTF(testHRTFdataset,samplingGrid,[],[],'ak');
0095     [HRTFs_Ref_L,HRTFs_Ref_R]   = supdeq_getArbHRTF(referenceHRTFdataset,samplingGrid,[],[],'ak');
0096     fprintf('2 x %d HRTFs extracted...\n',size(samplingGrid,1))
0097     
0098     %Calculate spectral difference
0099     disp('Calculating spectral differences...');
0100     specDiffL = abs( 20*log10(abs(HRTFs_Ref_L.')) - 20*log10(abs(HRTFs_Test_L.')));
0101     specDiffR = abs( 20*log10(abs(HRTFs_Ref_R.')) - 20*log10(abs(HRTFs_Test_R.')));
0102     specDiffLperPoint = specDiffL;
0103     specDiffRperPoint = specDiffR;
0104     specDiffL = sum(specDiffL,2);
0105     specDiffR = sum(specDiffR,2);
0106     specDiffL = specDiffL/size(samplingGrid,1);
0107     specDiffR = specDiffR/size(samplingGrid,1);
0108     
0109     %Get values from 100Hz - 12 kHz
0110     lowBin  = round(size(referenceHRTFdataset.f,2) / referenceHRTFdataset.f(end) * 100) + 1;
0111     highBin = round(size(referenceHRTFdataset.f,2) / referenceHRTFdataset.f(end) * 12000) + 1; 
0112 
0113     %Write results struct
0114     results.specDifferencePerPoint          = {specDiffLperPoint, specDiffRperPoint};
0115     results.specDifference                  = [specDiffL,specDiffR];
0116     results.meanSpecDifference              = mean(results.specDifference);
0117     results.meanSpecDifference_freqRange    = mean(results.specDifference(lowBin:highBin,:));
0118     results.f                               = referenceHRTFdataset.f;
0119 
0120     disp('Done with calculation of spectral differences...');
0121     
0122     if plotResults
0123         figure;
0124         semilogx(results.f,results.specDifference(:,1),'k','LineWidth',1.5);
0125         hold on;
0126         semilogx(results.f,results.specDifference(:,2),'r','LineWidth',1.5);
0127         grid on;
0128         xlim([20,20000]);
0129         xlabel('Frequency [Hz]');
0130         ylabel('Spectral difference [dB]');
0131         legend('Left','Right','Location','NorthWest');
0132     end
0133     
0134 end
0135 
0136 %% Filter mode on
0137 if filterMode
0138     
0139     %Get HRIRs according to sampling grid
0140     HRIRs_Test = zeros((size(testHRTFdataset.f,2)*2-2) / testHRTFdataset.FFToversize,2,size(samplingGrid,1));
0141     HRIRs_Ref = zeros((size(referenceHRTFdataset.f,2)*2-2) / referenceHRTFdataset.FFToversize,2,size(samplingGrid,1));
0142     
0143     fprintf('Extracting 2 x %d HRIRs. This may take some time...\n',size(samplingGrid,1));
0144     [HRIRs_Test_L,HRIRs_Test_R] = supdeq_getArbHRIR(testHRTFdataset,samplingGrid,[],[],'ak');
0145     [HRIRs_Ref_L,HRIRs_Ref_R]   = supdeq_getArbHRIR(referenceHRTFdataset,samplingGrid,[],[],'ak');
0146     %Kind of a workaround, but 4-D arrays needed later....
0147     HRIRs_Test(:,1,:)   = reshape(HRIRs_Test_L,[size(HRIRs_Test,1),1,size(HRIRs_Test,3)]);
0148     HRIRs_Test(:,2,:)   = reshape(HRIRs_Test_R,[size(HRIRs_Test,1),1,size(HRIRs_Test,3)]);
0149     HRIRs_Ref(:,1,:)    = reshape(HRIRs_Ref_L,[size(HRIRs_Ref,1),1,size(HRIRs_Ref,3)]); 
0150     HRIRs_Ref(:,2,:)    = reshape(HRIRs_Ref_R,[size(HRIRs_Ref,1),1,size(HRIRs_Ref,3)]);
0151     fprintf('2 x %d HRIRs extracted...\n',size(samplingGrid,1))
0152     
0153     %Zero-pad to 512 samples (if length is smaller) to get higher frequency
0154     %resolution. This only works if HRIRs_Test and HRIRs_Ref have equal
0155     %length!
0156     newLength = 512;
0157     if size(HRIRs_Test,1) < newLength
0158         zeroPad = zeros(newLength-size(HRIRs_Test,1),2,size(samplingGrid,1));
0159         HRIRs_Test  = [HRIRs_Test;zeroPad];
0160         HRIRs_Ref   = [HRIRs_Ref;zeroPad];
0161         %Calc f needed later for results struct
0162         f = linspace(0,fs/2,newLength/2+1);
0163     else
0164         f = linspace(0,fs/2,size(HRIRs_Test,1)/2+1);
0165     end
0166        
0167     %Filter HRIRs with auditory filter bank (settings lead to 40 bands)
0168     %Output is a 4D array with [samples X filterBand x channel x
0169     %samplingPoint]
0170     disp('Applying auditory filter bank. This may take some time...');
0171     HRIRs_Test_filt = auditoryfilterbank(HRIRs_Test,fs,'flow',50,'fhigh',20000);
0172     [HRIRs_Ref_filt,fc]  = auditoryfilterbank(HRIRs_Ref,fs,'flow',50,'fhigh',20000);
0173     disp('Done with filtering...');
0174     
0175     %Perform FFT
0176     disp('Calculating spectral differences...');
0177     HRTFs_Test_filt = fft(HRIRs_Test_filt);
0178     HRTFs_Test_filt = HRTFs_Test_filt(1:size(HRTFs_Test_filt,1)/2+1,:,:,:);
0179     HRTFs_Ref_filt  = fft(HRIRs_Ref_filt);
0180     HRTFs_Ref_filt = HRTFs_Ref_filt(1:size(HRTFs_Ref_filt,1)/2+1,:,:,:);
0181     
0182     %Calculate spectral difference for each band
0183     specDiffL = squeeze(abs(20*log10(abs(HRTFs_Ref_filt(:,:,1,:))) - 20*log10(abs(HRTFs_Test_filt(:,:,1,:)))));
0184     specDiffR = squeeze(abs(20*log10(abs(HRTFs_Ref_filt(:,:,2,:))) - 20*log10(abs(HRTFs_Test_filt(:,:,2,:)))));
0185     specDiffLperPoint = specDiffL;
0186     specDiffRperPoint = specDiffR;
0187     %Average across spatial sampling points
0188     specDiffL = sum(specDiffL,3);
0189     specDiffR = sum(specDiffR,3);
0190     for i = 1:size(specDiffL,2)
0191         specDiffL(:,i) = specDiffL(:,i)/size(samplingGrid,1);
0192         specDiffR(:,i) = specDiffR(:,i)/size(samplingGrid,1);
0193     end
0194     %Get mean per band
0195     for i = 1:size(specDiffL,2)
0196         specDiffL_meanPerBand(i,:) = mean(specDiffL(:,i));
0197         specDiffR_meanPerBand(i,:) = mean(specDiffR(:,i));
0198     end
0199     
0200     %Write results struct
0201     results.specDiffPerPointAndBand_L   = specDiffLperPoint;
0202     results.specDiffPerPointAndBand_R   = specDiffRperPoint; 
0203     results.specDiffPerBand_L           = specDiffL;
0204     results.specDiffPerBand_R           = specDiffR;
0205     results.specDiffL_meanPerBand       = specDiffL_meanPerBand;
0206     results.specDiffR_meanPerBand       = specDiffR_meanPerBand;
0207     results.fc                          = fc;
0208     results.f                           = f;
0209 
0210     disp('Done with calculation of spectral differences...');
0211     
0212     if plotResults
0213         figure;
0214         semilogx(results.fc,results.specDiffL_meanPerBand,'k','LineWidth',1.5);
0215         hold on;
0216         semilogx(results.fc,results.specDiffR_meanPerBand,'r','LineWidth',1.5);
0217         grid on;
0218         xlim([20,20000]);
0219         xlabel('Frequency [Hz]');
0220         ylabel('Spectral Difference [dB]');
0221         legend('Left','Right','Location','NorthWest');
0222     end
0223     
0224 end
0225 
0226 
0227 end
0228

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