Adding OpenDAFF support for ita_read and ita_write, also extending DAFF writer...

Adding OpenDAFF support for ita_read and ita_write, also extending DAFF writer functionality in itaHRTF class. You may now pass daff_write arguments as further varargsin
parent 3d635eb7
function writeDAFFFile( this, file_path, metadata_user )
% Exports itaHRTF to a DAFF file
function writeDAFFFile( this, file_path, varargin )
% Exports itaHRTF to a DAFF file using daffv17_write
%
% Will export the entire angle range of the itaHRTF data set from
% minimum angle to maximum angle in theta and phi by an angular
% resulution of the range divided by the number of available spatial
% points as a equi-angular grid (regular grid, Gaussian sampling).
%
% Input: file_path (string) [optional]
% user metadata (struct created with daff_add_metadata) [optional]
% write_daff_args optional arguments (passed to daffv17_write) [optional]
%
% Required: OpenDAFF matlab scripts, http://www.opendaff.org
% (but included in ITA-Toolbox)
%
% Output: none
metadata = this.mMetadata;
if nargin >= 3
metadata = metadata_user;
end
hrtf_variable_name = inputname( 1 );
file_name = [ hrtf_variable_name '_' int2str( this.nSamples ) 'samples_' int2str( this.resAzimuth ) 'x' int2str( this.resElevation ) '.daff'];
if nargin >= 2
......@@ -25,6 +25,37 @@ if nargin == 0
end
%% Prepare daff_write arguments
if strcmp( this.domain, 'time' )
% Content type switcher between time domain (ir) and frequency domain (dft)
% (requires different data functions and content descriptor)
sIn.content = 'ir';
sIn.datafunc = @dfitaHRIRDAFFDataFunc;
sIn.zthreshold = -400; % zero threshold for discarding samples in beginning and end region of IR (where only noise is present)
elseif strcmp( this.domain, 'freq' )
sIn.content = 'dft';
sIn.datafunc = @dfitaHRTFDAFFDataFunc;
end
sIn.metadata = this.mMetadata;
sIn.quantization = 'float32';
sIn.userdata = this;
sIn.orient = [ 0 0 0 ];
sIn.quiet = false;
if ~isempty( varargin )
daff_write_args = ita_parse_arguments( sIn, varargin{ 1 } );
else
daff_write_args = ita_parse_arguments( sIn, varargin );
end
%% Inject content type indicator 'ir' or 'dft' into file name
ct_indicator = 'ir';
......@@ -39,6 +70,8 @@ else
file_path = fullfile( file_path, strjoin( {file_base_name 'v17' ct_indicator 'daff'}, '.' ) );
end
daff_write_args.filename = file_path;
%% Prepare angle ranges and resolution
......@@ -70,73 +103,55 @@ betarange = 180 - [ theta_start_deg theta_end_deg ]; % Flip poles (DAFF starts a
assert( betarange( 2 ) >= 0.0 )
assert( betarange( 1 ) <= 180.0 )
daff_write_args.betarange = alpharange;
daff_write_args.alphares = alphares;
daff_write_args.betarange = betarange;
daff_write_args.betares = betares;
%% Assemble metadata (if not already present)
keyname = 'Generation script';
if isempty(metadata) || ~any( strcmpi( { metadata(:).name }, keyname ) )
metadata = daffv17_add_metadata( metadata, keyname, 'String', 'writeDAFFFile.m' );
if isempty(daff_write_args.metadata) || ~any( strcmpi( { daff_write_args.metadata(:).name }, keyname ) )
daff_write_args.metadata = daffv17_add_metadata( daff_write_args.metadata, keyname, 'String', 'writeDAFFFile.m' );
end
keyname = 'Generation toolkit';
if ~any( strcmpi( { metadata(:).name }, keyname ) )
metadata = daffv17_add_metadata( metadata, keyname, 'String', 'ITA-Toolkit' );
if ~any( strcmpi( { daff_write_args.metadata(:).name }, keyname ) )
daff_write_args.metadata = daffv17_add_metadata( daff_write_args.metadata, keyname, 'String', 'ITA-Toolkit' );
end
keyname = 'Generation date';
if ~any( strcmpi( { metadata(:).name }, keyname ) )
metadata = daffv17_add_metadata( metadata, keyname, 'String', date );
if ~any( strcmpi( { daff_write_args.metadata(:).name }, keyname ) )
daff_write_args.metadata = daffv17_add_metadata( daff_write_args.metadata, keyname, 'String', date );
end
keyname = 'Git Version';
if ~any( strcmpi( { metadata(:).name }, keyname ) )
if ~any( strcmpi( { daff_write_args.metadata(:).name }, keyname ) )
versionHash = ita_git_getMasterCommitHash;
metadata = daffv17_add_metadata( metadata, keyname, 'String', versionHash );
daff_write_args.metadata = daffv17_add_metadata( daff_write_args.metadata, keyname, 'String', versionHash );
end
keyname = 'Web resource';
if ~any( strcmpi( { metadata(:).name }, keyname ) )
metadata = daffv17_add_metadata( metadata, keyname, 'String', 'http://www.ita-toolkit.org' );
if ~any( strcmpi( { daff_write_args.metadata(:).name }, keyname ) )
daff_write_args.metadata = daffv17_add_metadata( daff_write_args.metadata, keyname, 'String', 'http://www.ita-toolkit.org' );
end
%% Channels
channels=this.nChannels/this.nDirections;
if(channels<1)
warning('Number of channels per record was not detected correctly, assuming 2 channel records');
channels = 2;
end
% Content type switcher between time domain (ir) and frequency domain (dft)
% (requires different data functions)
if strcmp( this.domain, 'time' )
daff_write_args.channels = channels;
%% Call daff_write and pass argument list
daffv17_write( daff_write_args );
daffv17_write('filename', file_path, ...
'content', 'ir', ...
'datafunc', @dfitaHRIRDAFFDataFunc, ...
'channels', channels, ...
'alphares', alphares, ...
'alpharange', alpharange, ...
'betares', betares, ...
'betarange', betarange, ...
'orient', [ 0 0 0 ], ...
'metadata', metadata, ...
'userdata', this, ...
'quantization', 'float32', ...
'zthreshold', -inf );
elseif strcmp( this.domain, 'freq' )
daffv17_write('filename', file_path, ...
'content', 'dft', ...
'datafunc', @dfitaHRTFDAFFDataFunc, ...
'channels', channels, ...
'alphares', alphares, ...
'alpharange', alpharange, ...
'betares', betares, ...
'betarange', betarange, ...
'orient', [ 0 0 0 ], ...
'metadata', metadata, ...
'userdata', this, ...
'quantization', 'float32' );
end
......@@ -85,28 +85,42 @@ function [] = daffv17_write( varargin )
% Parse the arguments
args = struct();
for i=1:length(nonarg), args.(nonarg{i}) = false; end
i=1;
while i<=nargin
if ~ischar(varargin{i}), error(['Parameter ' num2str(i) ': String expected']); end
key = lower(varargin{i});
i = i+1;
r = nargin-i+1; % Number of remaining arguments
% Switch between single cell argument call and option list
if isa( varargin, 'cell' ) && length( varargin ) == 1 && isstruct( varargin{ 1 } )
switch key
case nonarg
args.(key) = true;
args = varargin{ 1 };
for i=1:length(nonarg)
if ~isfield( args, nonarg{ i } )
args.( nonarg{ i } ) = false;
end
end
% Options with one argument
case onearg
if (r < 1), error(['Option ''' key ''' requires an argument']); end
args.(key) = varargin{i};
else
for i=1:length(nonarg), args.(nonarg{i}) = false; end
i=1;
while i<=nargin
if ~ischar(varargin{i}), error(['Parameter ' num2str(i) ': String expected']); end
key = lower(varargin{i});
i = i+1;
otherwise
error(['Invalid option (''' key ''')']);
end
r = nargin-i+1; % Number of remaining arguments
switch key
case nonarg
args.(key) = true;
% Options with one argument
case onearg
if (r < 1), error(['Option ''' key ''' requires an argument']); end
args.(key) = varargin{i};
i = i+1;
otherwise
error(['Invalid option (''' key ''')']);
end
end
end
% Validate the arguments
......
function result = ita_read_daff( filename, varargin )
%ITA_READ_DAFF - Read Open Directional Audio File Format
% This function is based on the OpenDAFF DAFFv17 executable.
%
% It returns an itaHRTF object containing the data from a *.daff impulse response file.
%
% See also ita_read, ita_write, ita_write_daff.
% <ITA-Toolbox>
% This file is part of the ITA-Toolbox. Some rights reserved.
% You can find the license for this m-file in the license.txt file in the ITA-Toolbox folder.
% </ITA-Toolbox>
%% Return type of data this function can read
if nargin == 0
result{1}.extension = '.daff';
result{1}.comment = 'Open Directional Audio File Format (*.daff)';
return
end
if ~exist( filename, 'file' )
error( 'ITA_READ_DAFF: File does not exist' )
end
try
result = itaHRTF( 'daff', filename );
catch
error( 'ITA_READ_DAFF: Something went wrong' )
end
end
function result = ita_write_daff( varargin )
%ITA_WRITE_DAFF - Write Open Direction Audio File Format to disk
% This functions writes itaHRTF data to daff files
%
% Call: ita_write_daff ( itaHRTF, filename, options )
%
% Options: see write_daffv17 and @itaHRTF.writeDAFFFile for more details as arguments are passed on
%
%
% See also ita_read, ita_read_daff, ita_write, itaHRTF.
%
% Reference page in Help browser
% <a href="matlab:doc ita_write">doc ita_write</a>
% <ITA-Toolbox>
% This file is part of the ITA-Toolbox. Some rights reserved.
% You can find the license for this m-file in the license.txt file in the ITA-Toolbox folder.
% </ITA-Toolbox>
if nargin == 0 % Return possible argument layout
result{ 1 }.extension = '*.daff';
result{ 1 }.comment = 'OpenDAFF Files (*.daff)';
return
end
sArgs = struct( 'pos1_data', 'itaHRTF', 'pos2_filename', 'char', 'overwrite', false );
[ data, filename, sArgs, sOtherArgs ] = ita_parse_arguments( sArgs, varargin );
if exist( filename, 'file' ) && ~sArgs.overwrite % Error because file exists
error( 'ITA_WRITE_DAFF:FILE_EXISTS', [ mfilename ': Careful, file already exists, use overwrite option to disable error' ] )
else % Everything ok, save
ita_verbose_info( [ mfilename ': Careful, overwriting file if existing' ] );
if ~isempty( sOtherArgs )
data.writeDAFFFile( filename, sOtherArgs );
else
data.writeDAFFFile( filename );
end
end
result = 1;
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment