function writeDAFFFile( this, filePath, metadata_user ) % Exports itaHRTF to a DAFF file % % Input: filePath / fileName (string) [optional] % 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 ); fileName = [ hrtf_variable_name '_' int2str( this.nSamples ) 'samples_' int2str( this.resAzimuth ) 'x' int2str(this.resElevation) '.daff']; if nargin >= 2 fileName = filePath; 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 file_path = ''; file_path_base = strsplit( fileName, '.' ); if ~strcmp( file_path_base(end), 'daff' ) file_path = strjoin( [ file_path_base(:) ct_indicator 'daff' ], '.' ); else file_path = strjoin( [ file_path_base(1:end-1) ct_indicator 'daff' ], '.' ); 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 ); phi_start_deg = rad2deg( min( this.channelCoordinates.phi ) ); phi_end_deg = rad2deg( max( this.channelCoordinates.phi ) ); 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