sofacoustics / sofatoolbox Goto Github PK
View Code? Open in Web Editor NEWSOFA Toolbox (API for Matlab, Octave)
Home Page: http://sofaconventions.org
License: European Union Public License 1.2
SOFA Toolbox (API for Matlab, Octave)
Home Page: http://sofaconventions.org
License: European Union Public License 1.2
I'm using the "SOFAconvertMIT2SOFA" function to render a sofa object from the "full" folder with the IR saved in wav-files.
This works fine with the original "full folder" of the MIT but if I'm inserting my own IR into the folder structure I'm getting error messages.
Those differ slightly from case to case.
Case 1:
I replaced some IRs of the ones of the MIT with my own IRs (different length but same format, bit depth and sample rate).
Error Message:
Unable to perform assignment because the size of the left side is 1-by-1-by-449615 and the size of the right side is 1-by-512.
Error in SOFAconvertMIT2SOFA (line 49)
Obj.Data.IR(ii,idx(1),:) = audioread(fn)'; % data.IR must be [M R N]
Case 2:
I used just my own measured IRs. Those are the same files like in Case 1.
Error Message:
Error using audioread>readaudio (line 143)
The filename specified was not found in the MATLAB path.Error in audioread (line 136)
[y, Fs] = readaudio (filename, range, datatype);Error in SOFAconvertMIT2SOFA (line 49)
Obj.Data.IR(ii,idx(1),:) = audioread(fn)'; % data.IR must be [M R N]
Annotation: I used the right labeling of the files. The files of the MIT and mine are just differing in size and IR information and I don't see that the API is "interested" in the length or the frequency spectrum of my IRs.
It would really help if someone has got an explanation for those errors!
Please feel free to ask for more information, if you need any to help me on this.
I'm looking forward to your help!
SOFAcheckFilename('filename')
works as expected. (although there is a problem with file names shorter than 7 characters due to the implmentation of checking for remote files ... this should be reworked as well.)
SOFAcheckFilename("filename")
fails with "Filename must be a string.". This is due to strings and character vectors apparently being different things in Matlab. heavy eye rolling.
The function can be made work with strings in the following way. I didn't bother to make a PR (yet), since I don't know if you would want to make a proper rework of the function (i.e. not losing backwards compatibility towards Matlab versions before R2016b and being more error proof in general.
% filename = string?
if isstring(fn)
fn = char(fn);
end
if ~ischar(fn)
error('Filename must be a string.');
end
General
convention does not define the dimension E
.mrn
but can not be mrne
I would suggest to drop the convention, because I do not see a clear way of defining it. This is why:
If the convention is general, the dimensions mrn
must be allowed for Data_IR
(or Data_Imag
). In this case E
must defined by another variable. The only chance I see would be EmitterPosition
because all other variables referring to the emitter are optional. However the EmitterPosition
can also be IC
in which case E
can not be defined and any toolbox validating the convention or SOFA files of that convention would crash.
Of course the dimension E
could be specified by the user. But that would break the general idea of SOFA at least API_MO and sofar.
We would not loose much, if we removed General
as long as we have General*
with * referring to the data types FIR, FIR-E, TF, TF-E, and SOS (See #39).
I see that the programs in the example are all sofa files based on FIR data, but the data format I generated with mesh2hrtf is TF. In SOFA specs 0.6 I saw that TF format is still supported, but I want to know if there is an easy way to convert between TF format and FIR format.
Fix or provide compiled conventions with the package...
I want to test a sofa file by listening to a test audio file through it.
For this I'm using the given code of the README.md. But I always get the following error:
Error using conv (line 28)
A and B must be vectors.
The code I used was the following:
>> apparentSourceVector(91, 1)
SOFAplotGeometry(hrtf, 91);
soundInput = audioread(wav);
soundOutput = [conv(squeeze(hrtf.Data.IR(91, 1, :)), soundInput) ...
conv(squeeze(hrtf.Data.IR(91, 2, :)), soundInput)];
sound(soundOutput, hrtf.Data.SamplingRate);
I tried several sofa-files, but this always comes up.
PS: If you've got any tips how I could test my file in a nother way, I'd be glad to get some input.
Hi,
I used the Mesh2HRTF project for calculating HRTFs. It uses the SOFA matlab api to save the sofa file. But it uses the "GeneralTF" convention. The authors of Mesh2HRTF claimed in their paper on page 5 that the SOFA-API provides scripts for the conversion from the ‘General-TF’-Convention to the ‘SimpleFreeField-HRIR’-Convention. However, I am unable to locate such a script.
I am very new to the field and so would highly appreciate if you could help me with this conversion.
Regards,
Akshat Jain
Generalize SOFAplotGeometry for other coordinate types
I noted that there is no GeneralSOS
convention. It would be consistent to have it and fairly easy to generate, and it could easily be verified using sofar. Should we add it?
As our API should be used by as many people as possible our current license is not really suitable.
If you are working on open source software, the biggest problem is that it is not compatible with GPL. If you are working in the industry, you are forced to use the same license for your product.
If we really want the latter I would propose to at least switch to a GPL compatible license, like GPL 2. Otherwise I would propose to switch to a more relax license, like the Apache 2.0 or BSD 3-clause, which is much shorter and easier to read.
Attempting to apply the function SOFAhrtf2dtf to data read from teh HUTUBS HRTF da fails, as the database apparently does not have does not have a field called "GLOBAL_Comment".
This may be solved by changing lie 137 from:
dtf.GLOBAL_Comment = [dtf.GLOBAL_Comment '. Directional transfer functions (DTFs) were generated by removing from the HRTFs the direction-independent log-amplitude spectrum for each ear.'];
to:
if isfield(dtf, 'GLOBAL_Comment')
dtf.GLOBAL_Comment = [dtf.GLOBAL_Comment '. Directional transfer functions (DTFs) were generated by removing from the HRTFs the direction-independent log-amplitude spectrum for each ear.'];
else
dtf.GLOBAL_Comment = 'Directional transfer functions (DTFs) were generated by removing from the HRTFs the direction-independent log-amplitude spectrum for each ear.';
end
Hallo,
I have troubles creating a sofa-file and would appriciate help on this.
The problem:
I have created an object with the function "SOFAconvertMIT2SOFA".
Now I want to safe this object as a sofa-file using the function "SOFAsave".
But everytime I try to do this I'm getting the following Error:
Dot indexing is not supported for variables of this type.
Error in SOFAsave (line 33)
ObjCheck = SOFAgetConventions(Obj.GLOBAL_SOFAConventions,'m');
My code:
>> sofa=SOFAconvertMIT2SOFA('C:\Users\felix\Desktop\SOFA API for Matlab and Octave 1.1.3\HRTFs\MIT KEMAR','normal');
>> SOFAsave('C:\Users\felix\Desktop\SOFA API for Matlab and Octave 1.1.3\HRTFs\MIT KEMAR\sofa.sofa','sofa')
SOFAcalculateAPV calculated a wrong azimuth angle. I fixed it by disabling all the conversion to and back from horizontal-polar coordinate in order to calculate the apparent elevation.
This means the apparent elevation could be broken now and has to be checked again.
the tests/s2j
folder contains a number of binaries without source-code
sofa2json
libnetcdf_c++4.so.1.0.3
i'd suggest to:
sofa2json
libmysofa
libnetcdfc++4
packge (to the docker image can be used without having to manually provide an outdated and unmaintained binary blob)useful function.
Add a README describing the installation and usage of the SOFAlizer in the SOFAlizer folder.
encode parameters with colors in the tables of the conventions, consider inheritations, limitations, ... ?
any more ideas?
planned for SOFA 3.0
Improve stability of function SOFAload, considering:
Hello,
I use some of the features, primarily "SOFAplotHRTF" in the latest Octave 6.3 and there is an issue to get (Obj.SourcePosition_Type,'cartesian')
support code to work.
The fix I use is replacing lines 131 and 132 from:
Obj.SourcePosition(ii,1)=rad2deg(Obj.SourcePosition(ii,1));
Obj.SourcePosition(ii,1)=npi2pi(Obj.SourcePosition(ii,1),'degrees'); % requires Mapping toolbox in Matlab
to
Obj.SourcePosition(ii,1)=npi2pi(Obj.SourcePosition(ii,1)); % https://github.com/alfoltranteam/octave-map/blob/master/src/npi2pi.m
Obj.SourcePosition(ii,1)=rad2deg(Obj.SourcePosition(ii,1));
npi2pi.m function may require Mapping toolbox, but there is an open source alternative from https://github.com/alfoltranteam/octave-map/blob/master/src/npi2pi.m which does not support 'degrees' mode. With this simple change the code should work both in Matlab and Octave irrespective of the Mapping toolbox.
Best Regrds,
Sergejs
Hello,
I'm testing HRTF interpolation using the demo_FreeFieldHRTF script, and it works fine when using the thk dataset. However when I try it for the cipic dataset by replacing the line
IR=SOFAload('db://database/thk/HRIR_L2354.sofa');
with
IR=SOFAload('db://database/cipic/subject_003.sofa');
the intepolated magnitude spectra in the median plane doesn't resemble at all the reference plot. I did try using Lmax as the SH order, but no improvements - this might be a naive issue, but can you help me figure this out?
Hi,
I am having some issues, loading a SOFA file, that I have created myself, using python-sofa 0.2.0 attached in a zip archive.
I can load the file in Python, but using SOFA API for Matlab and Octave 1.0.4 throws an error, when I try to do the same.
I cannot exclude the possibility that the SOFA file itself is malformed, but the nature of the error puzzles me.
When trying to read the SOFA file in Matlab (R2018b), I see that while reading the attribute "ListenerPosition", "Type' holding the value 'cartesian', the function getAtt.m throws an error because the command in line 51:
xtype = netcdflib('inqAtt',ncid,varid,attname);
returns xtype = 12, and the subsequent switch case tests for integer values in the closed range [1:11].
As a result, the function is unable to return a valid funcstr, and instead it returns an error.
The error appears to me to be somewhat similar to the errors reported in the now closed issue 16
The attached testfile is based on another file, and comparing the properties for the Listener.Position.Type in Python shows that they are the same for the original file and for the decimate one, I have generated in Python.
Is there any simple tests/verifications that I can do to shed some more light on this issue?
Br,
Jacob Riiser
which would resample HRIRs/SRIRs to an other sampling rate and update the metadata accordingly.
Demo script should load data from server, adapt the data and plot the figure according to the paper.
Error in line 61 of demo_SOFAstrings: Comparison between Obj.Data.String1 and Obj2.Data.String1 fails. In Obj2, the strings are longer and end with a blank. This should not happen.
SOFAplotGeometry does not work when using one Receiver only.
Duplicating Receiver and its coordinates help using the function.
Conventions: SimpleFreeFieldHRIR
Consider EmitterPosition when processing the source where appropriate.
c09ffe2 and v1 was branched off the master
version from May 4th. I suppose the included history.txt
reflects the included changes over v1.1.1
:
https://github.com/sofacoustics/API_MO/blob/c09ffe2247d93d758763faadac7c31b2925d8cb0/API_MO/history.txt#L15-L18
However, it is clear that some changes compared to the version in master seem to be missing:
https://github.com/sofacoustics/API_MO/blob/982faf5cd26cad552759b15c38422ec6fefaa5e6/API_MO/history.txt#L37-L41
The following commits seem to be related to v1.1.2
, but I am not sure that is all of them:
569cee7
b78c969
cfc00aa
cfc00aa (maybe, something seems to have gone with this commit)
Using Octave's addpath function isn't ideal since there's no guarantee that different users will install the API in the same path. It would possibly make things easier if the API was on the Octave package manager.
https://github.com/gnu-octave/packages/blob/main/CONTRIBUTING.md
SOFAstart does not restart, when executed again (in order to speed-up the execution). But, sometimes, it does not start, even on the first start of the Toolbox. This throws an error, especially when the conventions need to be compiled.
Improve the behavior of SOFAstart.
Hello,
I am playing around with the CIPIC dataset and noticed the results for the conversion with SOFAconvertCIPIC2SOFA.m results in HRIR for the ipsislateral ear having lower amplitude than the contralateral ear. The CIPIC HRTFs in sofaconventions.org also seem to have the same issue (assuming channel 1 is for left and 2 is for the right, as is described in all the other datasets).
Here is an example of such observation:
The code used to plot the image above:
CIPIC = load([local '\hrir_final.mat']);
Obj=SOFAconvertCIPIC2SOFA(CIPIC);
idx = dsearchn(Obj.SourcePosition(:,[1,2]), [90, 0]);
ir = squeeze(Obj.Data.IR(idx,:,:));
plot(ir.')
legend('left', 'right')
title(['azim: ' num2str(Obj.SourcePosition(idx,1)),...
'° elev: ' num2str(Obj.SourcePosition(idx,2)) '°']);
Implement in SOFAupgradeConventions() an automatic upgrade of MultiSpeakerBRIR files to SingleRoomSRIR.
Example for such a file: http://sofacoustics.org/data/database/sbsbrir/SBSBRIR_x-0pt5y-0pt5.sofa or http://sofacoustics.org/data/database/thk/BRIR_CR1_KU_MICS_L.sofa
I have created a sofa-file using the SOFAconvertMIT2SOFA function.
Now I want to use the rendered sofa-file with the IEM AdpativeBinauralDecoder (BETA) but the plugin gives me the following error:
" Weights generation failed. Error: Generic error. Failed to load HRTF."
Since other sofa-files work the problem probably is my generated file.
I'll paste my code bellow. I would be greatful, if someone could help me on this.
>> SOFAconvertMIT2SOFA('C:\Users\felix\Desktop\SOFA API for Matlab and Octave 1.1.3\HRTFs\MIT KEMAR','normal')
ans =
struct with fields:
GLOBAL_Conventions: 'SOFA'
GLOBAL_Version: '1.0'
GLOBAL_SOFAConventions: 'SimpleFreeFieldHRIR'
GLOBAL_SOFAConventionsVersion: '1.0'
GLOBAL_APIName: 'ARI SOFA API for Matlab/Octave'
GLOBAL_APIVersion: '1.1.3'
GLOBAL_ApplicationName: ''
GLOBAL_ApplicationVersion: ''
GLOBAL_AuthorContact: ''
GLOBAL_Comment: ''
GLOBAL_DataType: 'FIR'
GLOBAL_History: 'Converted from the MIT format'
GLOBAL_License: 'No license provided, ask the author for permission'
GLOBAL_Organization: ''
GLOBAL_References: ''
GLOBAL_RoomType: 'free field'
GLOBAL_Origin: ''
GLOBAL_DateCreated: '1999-11-16 20:01:52'
GLOBAL_DateModified: ''
GLOBAL_Title: ''
ListenerPosition: [0 0 0]
API: [1×1 struct]
ListenerPosition_Type: 'cartesian'
ListenerPosition_Units: 'metre'
ReceiverPosition: [2×3 double]
ReceiverPosition_Type: 'cartesian'
ReceiverPosition_Units: 'metre'
SourcePosition: [710×3 double]
SourcePosition_Type: 'spherical'
SourcePosition_Units: 'degree, degree, metre'
EmitterPosition: [0 0 0]
EmitterPosition_Type: 'cartesian'
EmitterPosition_Units: 'metre'
GLOBAL_DatabaseName: ''
GLOBAL_ListenerShortName: 'KEMAR, normal pinna'
ListenerUp: [0 0 1]
ListenerView: [1 0 0]
ListenerView_Type: 'cartesian'
ListenerView_Units: 'metre'
Data: [1×1 struct]
>> OBJ=ans
OBJ =
struct with fields:
GLOBAL_Conventions: 'SOFA'
GLOBAL_Version: '1.0'
GLOBAL_SOFAConventions: 'SimpleFreeFieldHRIR'
GLOBAL_SOFAConventionsVersion: '1.0'
GLOBAL_APIName: 'ARI SOFA API for Matlab/Octave'
GLOBAL_APIVersion: '1.1.3'
GLOBAL_ApplicationName: ''
GLOBAL_ApplicationVersion: ''
GLOBAL_AuthorContact: ''
GLOBAL_Comment: ''
GLOBAL_DataType: 'FIR'
GLOBAL_History: 'Converted from the MIT format'
GLOBAL_License: 'No license provided, ask the author for permission'
GLOBAL_Organization: ''
GLOBAL_References: ''
GLOBAL_RoomType: 'free field'
GLOBAL_Origin: ''
GLOBAL_DateCreated: '1999-11-16 20:01:52'
GLOBAL_DateModified: ''
GLOBAL_Title: ''
ListenerPosition: [0 0 0]
API: [1×1 struct]
ListenerPosition_Type: 'cartesian'
ListenerPosition_Units: 'metre'
ReceiverPosition: [2×3 double]
ReceiverPosition_Type: 'cartesian'
ReceiverPosition_Units: 'metre'
SourcePosition: [710×3 double]
SourcePosition_Type: 'spherical'
SourcePosition_Units: 'degree, degree, metre'
EmitterPosition: [0 0 0]
EmitterPosition_Type: 'cartesian'
EmitterPosition_Units: 'metre'
GLOBAL_DatabaseName: ''
GLOBAL_ListenerShortName: 'KEMAR, normal pinna'
ListenerUp: [0 0 1]
ListenerView: [1 0 0]
ListenerView_Type: 'cartesian'
ListenerView_Units: 'metre'
Data: [1×1 struct]
>> SOFAsave('C:\Users\felix\Desktop\SOFA API for Matlab and Octave 1.1.3\HRTFs\MIT KEMAR\heureka.sofa',OBJ)
ans =
struct with fields:
GLOBAL_Conventions: 'SOFA'
GLOBAL_Version: '1.0'
GLOBAL_SOFAConventions: 'SimpleFreeFieldHRIR'
GLOBAL_SOFAConventionsVersion: '1.0'
GLOBAL_APIName: 'ARI SOFA API for Matlab/Octave'
GLOBAL_APIVersion: '1.1.3'
GLOBAL_ApplicationName: ''
GLOBAL_ApplicationVersion: ''
GLOBAL_AuthorContact: ''
GLOBAL_Comment: ''
GLOBAL_DataType: 'FIR'
GLOBAL_History: 'Converted from the MIT format'
GLOBAL_License: 'No license provided, ask the author for permission'
GLOBAL_Organization: ''
GLOBAL_References: ''
GLOBAL_RoomType: 'free field'
GLOBAL_Origin: ''
GLOBAL_DateCreated: '1999-11-16 20:01:52'
GLOBAL_DateModified: '2021-09-02 11:36:24'
GLOBAL_Title: ''
ListenerPosition: [0 0 0]
API: [1×1 struct]
ListenerPosition_Type: 'cartesian'
ListenerPosition_Units: 'metre'
ReceiverPosition: [2×3 double]
ReceiverPosition_Type: 'cartesian'
ReceiverPosition_Units: 'metre'
SourcePosition: [710×3 double]
SourcePosition_Type: 'spherical'
SourcePosition_Units: 'degree, degree, metre'
EmitterPosition: [0 0 0]
EmitterPosition_Type: 'cartesian'
EmitterPosition_Units: 'metre'
GLOBAL_DatabaseName: ''
GLOBAL_ListenerShortName: 'KEMAR, normal pinna'
ListenerUp: [0 0 1]
ListenerView: [1 0 0]
ListenerView_Type: 'cartesian'
ListenerView_Units: 'metre'
Data: [1×1 struct]
>>
Hi all, the SOFA files on http://sofacoustics.org/data/database/cipic/ apparently were generated with API_MO/converters/SOFAconvertCIPIC2SOFA.m
before 279c2e1 compensated for the reversal in lateral angle direction. It would be great if corrected files could be uploaded there.
The update of the csv-conventions contains errors. Here are the questions and issues in several cases the changes violate AES69:
GeneralFreeFieldDirectivity 1.0:
GeneralFreeFieldDirectivity 1.1:
FreeFieldHRTF 1.0:
@petibub @isfmiho can we discuss future convention updates before pushing to master? sofar also uses the conventions files and pushing changes without any testing can break SOFAtoolbox and sofar.
Implement in SOFAupgradeConventions() an automatic upgrade of SingleRoomDRIR files to SingleRoomSRIR.
Example for such a file: http://sofacoustics.org/data/database/thk/DRIR_CR1_VSA_50RS_L.sofa
When I try to save a file with the new convention which has SourceUp and SourceView in the .API.Dimensions it complains.
If I delete this two it saves them correctly.
Error using NETCDFsave
Error processing SourceUp
Error message: Unrecognized field name "SourceUp".
Error in SOFAsave (line 96)
NETCDFsave(filename,Obj,Compression);
Error in supdeq_helper (line 119)
SOFAsave(sprintf('KU100.sofa',FinalIRlength),Obj2,0);
Demos assume that HRTF files have been saved in the SOFAdbPath.
When HRTF files are not there, ask the user for a download.
Since commit 20dfca1 I get the error:
Error using SOFAupdateDimensions (line 107)
Data.Delay: dimension could not be matched.
Error in SOFAload (line 178)
Obj = SOFAupdateDimensions(Obj);
Seems to be a problem with updating the dimension of Data.Delay, which in 0.1 used to be IR or MR and from 0.2 on has to be IRE or MRE.
SOFAload() should be extended to partially read any dimension and to accept a vector of indices as input, e.g. something like this: Obj = SOFAload(fn,E,[1 3 4]) reads only data for emitters 1, 3 and 4.
I need to create a HRIR that doesn't change the signal, but in the process of creating I ran into this problem:
When I load a .sofa file (from MIT) with SOFAload function and then save it again with SOFAsave the information that is there changes (regardless of level of compression I choose) - I can see by the size of the new file, and because Unity (specifically Steam Audio) can't read it, while before it could.
In attachment there is the original .sofa file from MIT and the file after being read and saved using the API (Matlab_edit sofa file). There is also a print of the code (which is pretty basic).
General_FIRE 1.0 is deprecated according to sofaconventions.org and https://www.sofaconventions.org/conventions/ but contained in the current SOFAtoolbox release. Is this intended?
The conventions should be handled at a central place (maybe even in an extra repository, which would have the downside that a user would have to install two different software packages, which is not a good idea. Or we include also an automatic download of the Conventions.)
The following proposal uses only one repository for all things:
CDL
folder.Conventions
folder, which includes the up-to-date Convention definitions, maybe in the same format as it is currently stored in the conventions
folder under API_MO
API_MO
and API_Cpp
should then use the central Conventions
folder as a source for getting the conventions informationIn the conventions FreeFieldHRTF.csv
and SimpleFreeFieldHRTF.csv
the line
N:Units hertz attribute
must be replaces by
N:Units hertz m attribute
because N:Units is a mandatory parameter according to AES69-2020 Tables C.3 and C.4. Note that C.4 forgets to mention that N:LongName is optional
According to http://www.sofaconventions.org/mediawiki/index.php/MultiSpeakerBRIR, version 0.3 of MultiSpeakerBRIR uses SOFA 1.0 which reflects the standard AES69-2015. According to the AES Standard, "EmitterDescription", "ListenerDescription", ... are optional fields. However,
sofa = SOFAgetConventions('MultiSpeakerBRIR');
sofa.EmitterDescription = 'test';
SOFAupdateDimensions( sofa );
yields
Error using SOFAupdateDimensions (line 85)
EmitterDescription seems to be a user-defined variable without a dimension.
Loading e.g. hrtf_ci1.sofa from ari (bte) fails:
h = SOFAload('D:\temp\sofa\hrtf_ci1.sofa')
file: 'C:\Program Files\MATLAB\R2018a\toolbox\matlab\imagesci\+netcdf\getVar.m'
name: 'getVar'
line: 136
file: 'C:\Users\<user>\Documents\MATLAB\API_MO\netcdf\NETCDFload.m'
name: 'NETCDFload'
line: 104
file: 'C:\Users\<user>\Documents\MATLAB\API_MO\SOFAload.m'
name: 'SOFAload'
line: 118
Error using SOFAload (line 123)
Error loading the file: D:\temp\sofa\hrtf_ci1.sofa
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.