Commit b24842be authored by rbo's avatar rbo

Newer SOFA version (August 2016) and compiled files.

parent 117fb710
......@@ -41,7 +41,7 @@ switch Obj.GLOBAL_SOFAConventions
Obj.Data=rmfield(Obj.Data,'SOS');
Obj.API.Dimensions.Data=rmfield(Obj.API.Dimensions.Data,'SOS');
Obj=SOFAupdateDimensions(Obj);
case 'SimpleFreeFieldTF'
case {'SimpleFreeFieldTF' 'GeneralTF'}
fs=max(Obj.N)*2;
N=fs/min([min(diff(Obj.N)) Obj.N(1)]);
N=2*(round(N/2+1)-1);
......
function [out, azi, ele, idx] = SOFAspat(in,Obj,azi,ele)
function [out, azi, ele, idx] = SOFAspat(in,Obj,azi,ele,flag)
% SOFAspat
% [out, azi, ele, idx] = SOFAspat(in,Obj,azi,ele) spatializes the sound IN using
% the HRTFs from OBJ according to the trajectory given in AZI and ELE.
......@@ -7,6 +7,9 @@ function [out, azi, ele, idx] = SOFAspat(in,Obj,azi,ele)
% Obj: SOFA object containing the HRTFs
% azi, ele: vectors with the trajectory (in degrees) independent for
% azimuth and elevation
% flag: 'interaural-polar': azi and ele are given in the
% interaural-polar coordinate system as lateral and polar angles,
% respectively.
%
% Output:
% out: binaural signal
......@@ -57,6 +60,14 @@ else
ele=repmat(ele,1,S);
end;
%% Convert to spherical system if required
if exist('flag','var')
if strcmp(flag,'horizontal-polar')
x=SOFAconvertCoordinates([azi; ele; ones(size(azi))]','horizontal-polar','spherical');
azi=mod(x(:,1)',360);
ele=x(:,2)';
end
end
%% create a 2D-grid with nearest positions of the moving source
idx=zeros(S,1);
for ii=1:S % find nearest point on grid (LSP)
......@@ -87,12 +98,11 @@ while ii<iiend
%-----------
segTO=real(ifft(segFO)); % back to the time domain
out(ii+1:ii+2*N,:)=out(ii+1:ii+2*N,:)+segTO; % overlap and add
ii=ii+N*hop;
ii=ii+ceil(N*hop);
jj=jj+1;
end
%% Normalize
out(:,1)=out(:,1)/peak(1);
out(:,2)=out(:,2)/peak(2);
out=out./max(peak);
if exist('converted','var'), azi=nav2sph(azi,ele); end;
\ No newline at end of file
......@@ -43,4 +43,4 @@ Obj=SOFAupdateDimensions(Obj);
%% Fill with some additional data
Obj.GLOBAL_History='Converted from the ARI format';
if size(meta.pos,2)>2, Obj=SOFAaddVariable(Obj,'MeasurementSourceAudioChannel','M',meta.pos(1:size(hM,2),3)); end
Obj=SOFAaddVariable(Obj,'MeasurementAudioLatency','MR',meta.lat);
if isfield(meta,'lat'), Obj=SOFAaddVariable(Obj,'MeasurementAudioLatency','MR',meta.lat); end
function Obj = SOFAconvertBTDEI2SOFA(BTDEI)
% OBJ=SOFAconvertBTDEI2SOFA(BTDEI) converts the HRTFs described in BT-DEI
% to a SOFA object.
%
% BTDEI format is used by Michele Geronazzo, University of Padova.
%
% Copyright (C) 2012-2013 Acoustics Research Institute - Austrian Academy of Sciences;
% Licensed under the EUPL, Version 1.1 or as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "License")
% You may not use this work except in compliance with the License.
% You may obtain a copy of the License at: http://joinup.ec.europa.eu/software/page/eupl
% Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and limitations under the License.
% get empty object (the flag 'm' provides the mandatory fields only)
Obj=SOFAgetConventions('SimpleHeadphoneIR','m');
Obj.GLOBAL_Title = 'HPIR';
Obj.GLOBAL_DatabaseName = BTDEI.specs.Database;
Obj.GLOBAL_History = 'Converted from the BT-DEI format';
Obj.GLOBAL_License = 'Creative Commons Attribution-NonCommercial-ShareAlike 3.0';
Obj.GLOBAL_ApplicationName = 'HpTFs from DEI - University of Padova';
Obj.GLOBAL_ApplicationVersion = SOFAgetVersion('API');
Obj.GLOBAL_AuthorContact = 'geronazzo@dei.unipd.it';
Obj.GLOBAL_References = ['M. Geronazzo, F. Granza, S. Spagnol, F. Avanzini. ', ...
'A Standardized Repository of Head-Related and Headphone Impulse Response Data ', ...
'In 134th Convention of the Audio Engineering Society, May 2013.'];
Obj.GLOBAL_Organization = 'Department of Information Engineering, University of Padova';
Obj.GLOBAL_Comment = '';
% copy the data
% Emitter - Source
Obj.GLOBAL_SourceDescription = [BTDEI.hp.Id ' - ' BTDEI.hp.Producer ' ' BTDEI.hp.Model];
Obj.GLOBAL_SourceManufacturer = BTDEI.hp.Producer;
Obj.GLOBAL_SourceModel = BTDEI.hp.Model;
%Obj.GLOBAL_SourceURI = BTDEI.hp.Uri;
% Receiver - Listener
Obj.GLOBAL_SubjectID = BTDEI.specs.SubjectId;
Obj.GLOBAL_ListenerDescription = BTDEI.sbjType;
Obj.GLOBAL_ReceiverDescription = BTDEI.specs.MicrophonePosition; % qualitative data e.g. blocked ear canal, open ear canal, at the eardrum
Obj.ListenerPosition = [0 0 0];
Obj.ReceiverPosition = [0 0.09 0; 0 -0.09 0];
Obj.SourcePosition = [0 0 0];
Obj.EmitterPosition = [0 0.09 0; 0 -0.09 0];
%% Fill data with data
Obj.Data.SamplingRate = BTDEI.specs.SampleRate; % Sampling rate
% calculate the effective size of the data matrix
M = length(BTDEI.data); % number of repositionings
R = size(BTDEI.data(1).HpIR,2); % number of channels (stereo)
len_vec = zeros(M,1);
for ii=1:M
len_vec(ii)= length(BTDEI.data(ii).HpIR);
end
N = max(len_vec);
Obj.API.M=M;
Obj.API.R=R;
Obj.API.N=N;
% store IR data
Obj.Data.IR = NaN(M,R,N); % data.IR must be [M R N]
for aa=1:M
HpIR = [BTDEI.data(aa).HpIR; zeros((N-length(BTDEI.data(aa).HpIR)),2)];
Obj.Data.IR(aa,1,:)= HpIR(:,1)';
Obj.Data.IR(aa,2,:)= HpIR(:,2)';
end
% update dimensions
Obj = SOFAupdateDimensions(Obj);
end
function Obj=SOFAconvertTUBerlinBRIR2SOFA(irs)
% OBJ=SOFAconvertTUBerlin2SOFA(irs) converts the HRTFs described in irs
% (see TU-Berlin HRTF format) to a SOFA object, using the MultiSpeakerBRIR
% Convention.
%
% SOFA API - demo script
% Copyright (C) 2012-2013 Acoustics Research Institute - Austrian Academy of Sciences
% Licensed under the EUPL, Version 1.1 or as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "License")
% You may not use this work except in compliance with the License.
% You may obtain a copy of the License at: http://joinup.ec.europa.eu/software/page/eupl
% Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and limitations under the License.
%% Get an empy conventions structure
Obj = SOFAgetConventions('MultiSpeakerBRIR');
%% Fill data with data
Obj.Data.IR = zeros(size(irs.left,2),2,1,size(irs.left,1));
Obj.Data.IR(:,1,:) = shiftdim(shiftdim(irs.left,-2),3); % irs.left is [N M], data.IR must be [M R E N]
Obj.Data.IR(:,2,:) = shiftdim(shiftdim(irs.right,-2),3);
Obj.Data.SamplingRate = irs.fs;
%% Fill with attributes
Obj.GLOBAL_ListenerShortName = 'KEMAR';
Obj.GLOBAL_History='Converted from the TU-Berlin format';
Obj.GLOBAL_Comment = irs.description;
Obj.GLOBAL_License = 'Creative Commons Attribution-NonCommercial-ShareAlike 3.0';
Obj.GLOBAL_ApplicationName = 'BRIR from TU Berlin';
Obj.GLOBAL_ApplicationVersion = '1.0';
Obj.GLOBAL_AuthorContact = 'hagen.wierstorf@tu-berlin.de';
Obj.GLOBAL_References = [''];
Obj.GLOBAL_Origin = 'TU Berlin';
Obj.GLOBAL_Organization = 'Quality and Usability Lab, Technische Universitaet Berlin';
Obj.GLOBAL_DatabaseName = 'TU Berlin';
Obj.GLOBAL_Title = 'BRIR TU Berlin';
Obj.GLOBAL_ListenerDescription = irs.head;
Obj.GLOBAL_ReceiverDescription = 'Large ears (KB0065 + KB0066) with G.R.A.S. 40AO pressure microphones';
Obj.GLOBAL_SourceDescription = 'Genelec 8030A';
Obj.GLOBAL_RoomType = 'reverberant';
Obj.GLOBAL_RoomDescription = '';
%% Fill the mandatory variables
% MultiSpeakerBRIR
% === Source ===
Obj.SourcePosition = [0 0 0]; % center of loudspeaker array
Obj.EmitterPosition = irs.source_position';
Obj.EmitterView = irs.head_position';
Obj.EmitterUp = [0 0 1];
% === Listener ===
% number of measurements
M = length(irs.apparent_elevation);
distance = sqrt(sum((irs.source_position-irs.head_position).^2));
Obj.ListenerPosition = irs.head_position';
[x,y,z] = sph2cart(fixnan(irs.head_azimuth'), ...
repmat(fixnan(irs.head_elevation'),size(irs.head_azimuth')), ...
repmat(distance,size(irs.head_azimuth')));
Obj.ListenerView = [x,y,z];
Obj.ListenerUp = [0 0 1];
% Receiver position for a dummy head (imported from SimpleFreeFieldHRIR)
Obj.ReceiverPosition = [0,-0.09,0; 0,0.09,0];
%% Update dimensions
Obj=SOFAupdateDimensions(Obj);
end
function x = fixnan(x)
if isnan(x), x=0; end
end
% SOFA API demo script
% load HRTF in BT-DEI format and save in SOFA format.
% Copyright (C) 2012-2013 Acoustics Research Institute - Austrian Academy of Sciences;
% Licensed under the EUPL, Version 1.1 or as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "License")
% You may not use this work except in compliance with the License.
% You may obtain a copy of the License at: http://joinup.ec.europa.eu/software/page/eupl
% Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and limitations under the License.
%% Define parameters
% Headphone index of the files to convert
hp= 'H010';
% Subject index of the files to convert
subject= 'S115';
% Measurement index of the files to convert
setm= 'Set02'; %Set01 Set02 ...
% File name of the BTDEI file
BTDEIfold='COMPENSATED'; %RAW %COMPENSATED %EQUALIZED
% Data compression (0..uncompressed, 9..most compressed)
compression=1; % results in a nice compression within a reasonable processing time
%% load BTDEI file \ load database structure data
f=filesep;
BTDEI_hp_add=fullfile(fileparts(SOFAdbPath),'BTDEI',hp,'headphones_info.mat');
BTDEI_add=fullfile(fileparts(SOFAdbPath),'BTDEI',hp,subject,setm,BTDEIfold,'MAT',[hp '_' subject '_btdei.mat']);
disp(['Loading BT-DEI data']);
try
datasheet = load(BTDEI_hp_add);
BTDEI.hp = datasheet.hp_specs;
switch subject
case 'S115'
BTDEI.sbjType = 'dummy head with large pinna';
case 'S116'
BTDEI.sbjType = 'dummy head without pinna';
case 'S117'
BTDEI.sbjType = 'dummy head without pinna';
otherwise
BTDEI.sbjType = 'human';
end
container = load(BTDEI_add);
BTDEI.specs = container.specs;
BTDEI.data = container.data;
catch e
error(['Convertion - Error message: ' e.message]);
end
BTDEI.type = BTDEIfold;
BTDEI.typeset = setm;
%% convert
Obj = SOFAconvertBTDEI2SOFA(BTDEI);
Obj.GLOBAL_Comment = SOFAappendText(Obj,'GLOBAL_Comment',BTDEIfold);
%% save SOFA file
SOFAfn=fullfile(SOFAdbPath,'sofa_api_mo_test',['BTDEI-hp_' hp '_subj_' subject '-' setm '-' BTDEIfold '.sofa']);
disp(['Saving: ' SOFAfn])
SOFAsave(SOFAfn, Obj, compression);
function [] = NETCDFdisplay(filename)
%NETCDFDISPLAY
% [] = NETCDFdisplay(filename) displays information about specified SOFA file
% SOFA API - demo script
% load headphone IRs from a SOFA file from the ARI headphones database
% SOFA API - function matlab/NETCDFdisplay
% Copyright (C) 2012 Acoustics Research Institute - Austrian Academy of Sciences
% Copyright (C) 2012-2013 Acoustics Research Institute - Austrian Academy of Sciences
% Licensed under the EUPL, Version 1.1 or as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "License")
% You may not use this work except in compliance with the License.
% You may obtain a copy of the License at: http://joinup.ec.europa.eu/software/page/eupl
% Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and limitations under the License.
ncdisp(filename);
end %of function
\ No newline at end of file
%% Define parameters
% Subject index of the file to convert
subjectID='NH5';
%% Load SOFA file
SOFAfn=fullfile(SOFAdbPath, 'headphones', 'ari', ['hpir_' lower(subjectID) '.sofa']);
disp(['Loading: ' SOFAfn]);
X=SOFAload(SOFAfn);
%% Plot amplitude spectra
figure;
hold on; box on;
cols=['bgrmky'];
meastime=[0; diff(X.MeasurementDate)];
for ii=1:X.API.M
plot(20*log10(abs(fft(squeeze(X.Data.IR(ii,1,:)),X.Data.SamplingRate))),cols(ii));
if ii>1, leg{ii}=['#' num2str(ii) ':' num2str(meastime(ii)) ' seconds later']; end
end
axis([0 X.Data.SamplingRate/2 -80 20]);
leg{1}='#1, first measurement';
legend(leg);
\ No newline at end of file
% SOFA API - demo script
% Copyright (C) 2012-2014 Acoustics Research Institute - Austrian Academy of Sciences
% Licensed under the EUPL, Version 1.1 or as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "License")
% You may not use this work except in compliance with the License.
% You may obtain a copy of the License at: http://joinup.ec.europa.eu/software/page/eupl
% Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and limitations under the License.
%
% load HRTF and plots CTF and average DTF
%
%% Define parameters
% Subject index of the file to convert
subject=3;
% Data compression (0..uncompressed, 9..most compressed)
compression=1; % results in a nice compression within a reasonable processing time
%% load SOFA file
SOFAfn=fullfile(SOFAdbPath, 'database', 'cipic', ['subject_' sprintf('%03d',subject) '.sofa']);
X=SOFAload(SOFAfn);
[D,C]=SOFAhrtf2dtf(X);
% close all;
f = figure;
set(f, 'Position', [50, 400, 1100, 500]);
subplot(1,2,1);
data=(20*log10(abs(fft(squeeze(C.Data.IR(1,1,:))))));
stepsize=C.Data.SamplingRate/length(data)*2;
plot(1:stepsize:C.Data.SamplingRate,data(1:length(data)/2));
% ax=gca; set(ax,'XScale','log');
hold on; grid on;
subplot(1,2,2);
% plot(20*log10(abs(fft(squeeze(C.Data.IR(1,1,1:length(C.Data.IR)/2))))));
data=(20*log10(abs(fft(squeeze(C.Data.IR(1,2,:))))));
stepsize=C.Data.SamplingRate/length(data)*2;
plot(1:stepsize:C.Data.SamplingRate,data(1:length(data)/2));
% ax=gca; set(ax,'XScale','log');
hold on; grid on;
[D,CC]=SOFAhrtf2dtf(D);
subplot(1,2,1);
data=(20*log10(abs(fft(squeeze(CC.Data.IR(1,1,:))))));
stepsize=CC.Data.SamplingRate/length(data)*2;
plot(1:stepsize:CC.Data.SamplingRate,data(1:length(data)/2),'r');
title('left');
xlabel('f (in Hz)'); ylabel('dB');
legend('CTF','Avg DTF','Location','Best')
subplot(1,2,2);
% plot(20*log10(abs(fft(squeeze(CC.Data.IR(1,1,1:length(C.Data.IR)/2))))),'r');
data=(20*log10(abs(fft(squeeze(CC.Data.IR(1,2,:))))));
stepsize=CC.Data.SamplingRate/length(data)*2;
plot(1:stepsize:CC.Data.SamplingRate,data(1:length(data)/2),'r');
title('right');
xlabel('f (in Hz)'); ylabel('dB');
legend('CTF','Avg DTF','Location','Best');
......@@ -6,14 +6,20 @@
% Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and limitations under the License.
%% load a SOFA file
%% load a SOFA file in SimpleFreeFieldHRIR
SOFAfile=fullfile(SOFAdbPath,'database','ari','dtf_nh2.sofa');
Obj=SOFAload(SOFAfile);
% plot ETC horizontal plane
figure;
SOFAplotHRTF(Obj,'ETCHorizontal',1);
% plot magnitude spectrum in the median plane, channel 2
figure;
SOFAplotHRTF(Obj,'MagMedian',2);
%% load a GeneralTF SOFA file
SOFAfile=fullfile(SOFAdbPath,'database','ari (sim)','hrtf_nh5_ref.sofa');
Obj=SOFAload(SOFAfile);
% plot magnitude spectrum in the median plane, channel 1
figure;
SOFAplotHRTF(Obj,'MagMedian',1);
......@@ -46,4 +46,7 @@ xlabel('Time index');
legend({'Requested', 'Actual'},'Location','Best');
%% Play the sound - use headphones!
if ~exist('dontplay','var'); wavplay(out,Obj.Data.SamplingRate); end
\ No newline at end of file
if ~exist('dontplay','var');
p=audioplayer(out, Obj.Data.SamplingRate);
play(p);
end
\ No newline at end of file
% Script for testing the string array feature of SOFA
%% Test Strings as application-specific variable
% Load some arbritrary HRTFs
hrtf = SOFAload(fullfile(SOFAdbPath, 'database','ari','dtf_nh2.sofa'));
% Add a string array
str={};
for ii=1:hrtf.API.M
str{ii,1}=['String' num2str(round(rand(1,1)*10000))];
end
% SOFAaddVariable(Obj,Name,Dim,Value)
hrtf2 = SOFAaddVariable(hrtf,'Test','MS',str);
% Save as SOFA
SOFAsave('stringtest_applicationvar.sofa',hrtf2);
% Reload the file
hrtf = SOFAload('stringtest_applicationvar.sofa');
% compare the strings
if prod(strcmp(hrtf.Test,hrtf2.Test))
disp('SimpleFreeFieldHRIR: String Load-Reload: OK');
delete('stringtest_applicationvar.sofa');
else
error('String comparison showed differences');
end
clear all
%% Test with conventions GeneralString
% Create an empty object
Obj = SOFAgetConventions('GeneralString');
% Create numeric data with M=15, R=2, N=10
Obj.Data.Double=rand(15,2,10);
% Create string arrays
str2={}; str={};
for ii=1:15
id = num2str(round(rand(1,1)*1000000));
str{ii,1}=['X' id];
str2{ii,1}=['Left' id];
str2{ii,2}=['Right' id];
end
Obj.String2 = str2; % String1=[MRS]
Obj.Data.String1 = str; % Data.String1=[MS]
Obj.Data.String2 = str2; % Data.String2=[MRS]
% Add a new string with dimensions [RS]
strn={'left ear'; 'right ear'};
Obj = SOFAaddVariable(Obj, 'Ears', 'RS', strn);
% Update dimensions
Obj = SOFAupdateDimensions(Obj);
% Save as SOFA
SOFAsave('stringtest_generalstring.sofa',Obj);
% Reload the file
Obj2 = SOFAload('stringtest_generalstring.sofa');
% Compare the strings
if ~prod(strcmp(Obj2.Data.String2,Obj.Data.String2))
error('Data.String2: Comparison showed differences');
end
if ~prod(strcmp(Obj2.String2,Obj.String2))
error('String2: Comparison showed differences');
end
if ~prod(strcmp(Obj2.Data.String1,Obj.Data.String1))
error('Data.String1: Comparison showed differences');
end
if ~prod(strcmp(Obj2.Ears,Obj.Ears))
error('Ears: Comparison showed differences');
end
disp('GeneralString: String1, String2, Data, Ears: Load-Reload: OK');
clear all
delete('stringtest_generalstring.sofa');
function fix_creation_order_issue(ncfile)
% FIX_CREATION_ORDER_ISSUE
% fix_creation_order_issue(nc4file) tries to fix certain netCDF-4 files
% by deleting the '_Netcdf4Dimid' attribute.
%
% This file was downloaded from http://mexcdf.sourceforge.net/downloads/fix_netcdf4_dimid.m
% and fixes problems with Matlab < 2011b, see http://mexcdf.sourceforge.net/faq.php
%
%
fid = H5F.open(ncfile,'H5F_ACC_RDWR','H5P_DEFAULT');
v = version('-release');
switch(v)
case {'2011a', '2010b' };
cleanup_group(fid,fid);
case {'2010a','2009b'}
cleanup_group_2010a(fid,'/');
otherwise
error('not tested on this release');
end
H5F.close(fid);
try
nc_dump(ncfile);
catch
fprintf('No SNCTOOLS on your path, you need to manually verify that the issue is fixed.\n');
end
%--------------------------------------------------------------------------
function cleanup_group_2010a(parent_gid,child_group_name)
fprintf('Descending into group %s...\n', child_group_name);
child_gid = H5G.open(parent_gid,child_group_name);
idx = -1;
more_objects = true;
while more_objects
idx = idx+1;
objname = H5G.get_objname_by_idx(child_gid,idx);
if isempty(objname)
more_objects = false;
else
% get information about this group
statbuf=H5G.get_objinfo(child_gid,objname,0);
switch (statbuf.type)
case H5ML.get_constant_value('H5G_GROUP')
cleanup_group_2010a(child_gid,objname);
case H5ML.get_constant_value('H5G_DATASET')
obj_id = H5D.open(child_gid,objname);
cleanup_object_2010a(obj_id);
H5D.close(obj_id);
case H5ML.get_constant_value('H5G_TYPE')
obj_id = H5T.open(child_gid,objname);
cleanup_object_2010a(obj_id);
H5T.close(obj_id);
otherwise
fprintf ( ' Unhandled object type (does this ever happen? : %s\n', name);
end
end
end
H5G.close(child_gid);
fprintf('Ascending from group %s...\n', child_group_name);
%--------------------------------------------------------------------------
function cleanup_group(parent_gid,gid)
% netCDF uses indexing by creation order, so that's what we'll do too
idx_type = 'H5_INDEX_CRT_ORDER';
order = 'H5_ITER_INC';
child_group_name = H5I.get_name(gid);
fprintf('Descending into group %s...\n', child_group_name);
info = H5G.get_info(gid);
for j = 0:info.nlinks-1
name = H5L.get_name_by_idx(parent_gid,child_group_name,idx_type,order,j,'H5P_DEFAULT');
obj_id = H5O.open(gid,name,'H5P_DEFAULT');
info = H5O.get_info(obj_id);
switch(info.type)
case H5ML.get_constant_value('H5O_TYPE_GROUP')
cleanup_group(gid,obj_id);
case H5ML.get_constant_value('H5O_TYPE_DATASET')
cleanup_object(gid,name,obj_id);
case H5ML.get_constant_value('H5O_TYPE_NAMED_DATATYPE')
cleanup_object(gid,name,obj_id);
end
H5O.close(obj_id);
end
fprintf('Ascending from group %s...\n', H5I.get_name(gid));
%--------------------------------------------------------------------------
function cleanup_object(gid,objname,obj_id)
fprintf('Processing object %s... \n', objname);
% Does the attribute even exist?
try
attrid = H5A.open_by_name(gid,objname,'_Netcdf4Dimid','H5P_DEFAULT','H5P_DEFAULT');
% OK it's there. Delete it.
H5A.close(attrid);
fprintf('\t''_Netcdf4Dimid'' removed from ''%s'' ...\n', objname);
H5A.delete(obj_id,'_Netcdf4Dimid');
catch me
% Most likely the attribute didn't exist.
fprintf('\t''_Netcdf4Dimid'' does not exist, skipping ...\n');
end
return
%--------------------------------------------------------------------------
function cleanup_object_2010a(obj_id)
% 2010a lacks the "H5A.open_by_name" function
fprintf('Processing object %s... \n', H5I.get_name(obj_id));
% Does the attribute even exist?
try
attrid = H5A.open_name(obj_id,'_Netcdf4Dimid');
% OK it's there. Delete it.
H5A.close(attrid);
fprintf('\t''_Netcdf4Dimid'' removed from ''%s'' ...\n', H5I.get_name(obj_id));
H5A.delete(obj_id,'_Netcdf4Dimid');
catch me
% Most likely the attribute didn't exist.
fprintf('\t''_Netcdf4Dimid'' does not exist, skipping ...\n');
end
return
......@@ -11,7 +11,13 @@
*** DEVELOPMENT STATUS ***
*** v1.0.1 (10.6.2016)
*** v1.0.2 (16.8.2016)
- SOFAplotHRTF: extended to SimpleFreeFieldTF and some cases of GeneralTF
- SOFAplotGeometry: extended to SimpleFreeFieldTF
- SOFAconvertTUBerling2SOFA: uses MultiSpeakerBRIR now
- SOFAspat, SOFAcalculateAPV: minor bug fixes
*** v1.0.1 (10.6.2015)
- miro class is not supported in Octave. Error is thrown in demo_FHK2SOFA and converterFHK2SOFA
- demo_BTDEI2SOFA: bug fix in renamed BTDEI files
- demo_SOFA2ARI: bug fix in coordinate comparison
......
function [Obj,Dims] = NETCDFload(filename,flags)
%% NETCDFLOAD
% Obj = NETCDFload(filename,'all') reads the SOFA object OBJ with all data from
% a SOFA file.
%
% Obj = NETCDFload(filename,'nodata') ignores the Data. variables while
% reading.
%
% Obj = NETCDFload(filename,[START COUNT]) reads only COUNT number of
% measurements beginning with the index START.
%
% [Obj,Dims] = NETCDFload(...) returns the dimension variables found in
% the file as a string.
% SOFA API - function matlab/NETCDFload
% Copyright (C) 2012 Acoustics Research Institute - Austrian Academy of Sciences
% Licensed under the EUPL, Version 1.1 or as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "License")
% You may not use this work except in compliance with the License.
% You may obtain a copy of the License at: http://joinup.ec.europa.eu/software/page/eupl
% Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and limitations under the License.
%% Global definitions
glob='GLOBAL_';
globid=netcdf.getConstant('GLOBAL');
%% Open the NETCDF file
try
var='opening file';
ncid = netcdf.open(filename,'NC_NOWRITE');% open file
var='inquirying data';
[numdims,numvars,numglob] = netcdf.inq(ncid); % get number of anything
%% Load global attributes
for ii=0:numglob-1
var = netcdf.inqAttName(ncid,globid,ii);
Obj.([glob var]) = netcdf.getAtt(ncid,globid,var);
end