writeDAFFFile.m 3.98 KB
Newer Older
1
function writeDAFFFile( this, file_path, metadata_user )
2 3
% Exports itaHRTF to a DAFF file
%
4
% Input:    file_path (string) [optional]
5 6 7 8 9 10 11 12 13 14 15 16 17
%           user metadata (struct created with daff_add_metadata) [optional]
%
% Required: OpenDAFF matlab scripts, http://www.opendaff.org
%           (but included in ITA-Toolbox)
%
% Output: none

metadata = [];
if nargin >= 3
    metadata = metadata_user;
end

hrtf_variable_name = inputname( 1 );
18
file_name = [ hrtf_variable_name '_' int2str( this.nSamples ) 'samples_' int2str( this.resAzimuth ) 'x' int2str( this.resElevation ) '.daff'];
19
if nargin >= 2
20
    file_name = file_path;    
21 22 23 24 25 26 27 28 29 30 31 32 33 34
end

if nargin == 0
    error( 'Not enough input arguments' );
end


%% Inject content type indicator 'ir' or 'dft' into file name

ct_indicator = 'ir';
if strcmp( this.domain, 'freq' )
    ct_indicator = 'dft';
end

35 36 37
[ file_path, file_base_name, file_suffix ] = fileparts( file_name );
if ~strcmp( file_suffix, '.daff' )
    file_path = fullfile( file_path, strjoin( {file_base_name file_suffix 'v17' ct_indicator 'daff' }, '.' ) );
38
else
39
    file_path = fullfile( file_path, strjoin( {file_base_name 'v17' ct_indicator 'daff'}, '.' ) );
40 41 42 43 44 45 46 47 48
end


%% Prepare angle ranges and resolution

theta_start_deg = rad2deg( min( this.channelCoordinates.theta ) );
theta_end_deg = rad2deg( max( this.channelCoordinates.theta ) );
theta_num_elements = size( unique( this.channelCoordinates.theta ), 1 );

49 50
phi_start_deg = rad2deg( min( mod( this.channelCoordinates.phi, 2*pi ) ) );
phi_end_deg = rad2deg( max( mod( this.channelCoordinates.phi, 2*pi ) ) );
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
phi_num_elements = size( unique( this.channelCoordinates.phi ), 1 );

assert( phi_num_elements ~= 0 );
alphares = ( phi_end_deg - phi_start_deg ) / phi_num_elements; % phi end does not cover entire circle in this case
alphares_full_circle = ( phi_end_deg - phi_start_deg ) / ( phi_num_elements - 1 ); % phi end does not cover entire circle in this case
if phi_end_deg + alphares_full_circle >= 360.0
    alpharange = [ phi_start_deg ( phi_end_deg + alphares_full_circle ) ]; % Account for full circle
    alphares = alphares_full_circle;
else
    alpharange = [ phi_start_deg phi_end_deg ];
end

assert( theta_num_elements ~= 0 );
betares = ( theta_end_deg - theta_start_deg ) / ( theta_num_elements - 1 ); % phi end does not cover entire circle
betarange = 180 - [ theta_start_deg theta_end_deg ]; % Flip poles (DAFF starts at south pole)

%% Assemble metadata

metadata = daffv17_add_metadata( metadata, 'Generation script', 'String', 'writeDAFFFile.m' );
metadata = daffv17_add_metadata( metadata, 'Generation toolkit', 'String', 'ITA-Toolkit' );
metadata = daffv17_add_metadata( metadata, 'Generation date', 'String', date );
metadata = daffv17_add_metadata( metadata, 'Web resource', 'String', 'http://www.ita-toolkit.org' );

channels = 2; % this.nChannels < does not work?

% Content type switcher between time domain (ir) and frequency domain (dft)
% (requires different data functions)
if strcmp( this.domain, 'time' )

    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' );
           
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