Commit 5ee5fc9f authored by michael.kohnen's avatar michael.kohnen

Merge branch 'master' into ita_3da_dev

parents f7c7fa9c 398ada13
......@@ -61,7 +61,7 @@ CTC = itaAudio(cols,rows);
opts.alpha = 1e-10; % intern regularization for the wiener case
opts.beta = 0.001; % regularization parameter
opts.delay = 400; % required delay to allow for causal filter
opts.winLim = [.7 85]; % limits for windowing (suppress artifacts at the end of HRIR caused by time shifting)
opts.winLim = [0.7 0.85]; % limits for windowing (suppress artifacts at the end of HRIR caused by time shifting)
opts.filterType = 'reg'; %
opts.warping = 0;
opts.smoothing = 0;
......
......@@ -7,6 +7,7 @@ function varargout = ita_beam_beamforming(varargin)
% The optional fourth argument specifies the algorithm:
%
% types:
% (0) conventional with phase (for e.g. auralization)
% (1) conventional -- default
% (2) Minimum-Variance Distortionless Response (MVDR)
% (3) MUSIC
......@@ -87,7 +88,7 @@ idxVec = zeros(16,p.nBins);
if ~sArgs.type
typeStr = 'Delay-and-Sum w/o CSM';
ita_verbose_info([thisFuncStr 'Computing beamforming using type ''' typeStr ''''],1);
B = squeeze(abs(sum(bsxfun(@times,conj(permute(steeringVector,[3 1 2])),P.'),2)).^2);
B = squeeze(sum(bsxfun(@times,conj(permute(steeringVector,[3 1 2])),P.'),2)).';
else
switch sArgs.type
case 1
......@@ -128,7 +129,10 @@ else
end
% correct to obtain source strengths
B = sqrt(max(0,real(B))).*4*pi;
if sArgs.type
B = sqrt(max(0,real(B)));
end
B = B.*4*pi;
% create the audio object
if isa(p,'itaAudio')
......
......@@ -3,7 +3,7 @@
## License
Copyright 2016 Institute of Technical Acoustics, RWTH Aachen University
Copyright 2016 - 2018 Institute of Technical Acoustics, RWTH Aachen University
Licensed under the Apache License, Version 2.0 (the "License");
you may not use the OpenDAFF software package except in compliance with the License.
......
......@@ -430,8 +430,15 @@ function [] = daffv17_write( varargin )
% note: use round here to avoid errors if alphapoints are not exactly
% integers but within epsilon
x = cell( round( args.alphapoints ), round( args.betapoints ), args.channels );
args.userdata = args.userdata.buildsearchdatabase;
% Speed up for itaHRTF class
if isa( args.userdata, 'itaHRTF' )
args.userdata = args.userdata.buildsearchdatabase;
end
disp( 'Starting to gather data via callback function, this might take a while ...' )
for b=1:args.betapoints
tic
beta = betastart + (b-1)*args.betares;
% Write just one record at the poles
......@@ -790,7 +797,10 @@ function [] = daffv17_write( varargin )
props.numRecords = props.numRecords + 1;
end
disp( [ 'Processed beta angle ' num2str( beta ) ', took ' num2str( toc ) ] )
end
disp( '... and data has been assembled. Will write to file now.' )
fprintf( 'Global peak: %+0.1f dB (%0.6f)\n', 20*log10(props.globalPeak), props.globalPeak );
......
function daffv17_convert_from_itaHRTF( itaHRTF_obj, file_path, metadata_user )
% Exports itaHRTF to a DAFF file
%
% Input: file_path (string) [optional]
% user metadata (struct created with daff_add_metadata) [optional]
%
% Required: ITA-Toolbox, http://www.ita-toolbox.org
% (includes itaHRTF class)
%
% Output: none
metadata = [];
if nargin >= 3
metadata = metadata_user;
end
hrtf_variable_name = inputname( 1 );
file_name = [ hrtf_variable_name '_' int2str( itaHRTF_obj.nSamples ) 'samples_' int2str( itaHRTF_obj.resAzimuth ) 'x' int2str(itaHRTF_obj.resElevation) '.daff'];
if nargin >= 2
file_name = file_path;
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( itaHRTF_obj.domain, 'freq' )
ct_indicator = 'dft';
end
file_path_base = strsplit( file_name, '.' );
if ~strcmp( file_path_base(end), 'daff' )
file_path = strjoin( [ file_path_base(:) 'v17' ct_indicator 'daff' ], '.' );
else
file_path = strjoin( [ file_path_base(1:end-1) 'v17' ct_indicator 'daff' ], '.' );
end
%% Prepare angle ranges and resolution
theta_start_deg = rad2deg( min( itaHRTF_obj.channelCoordinates.theta ) );
theta_end_deg = rad2deg( max( itaHRTF_obj.channelCoordinates.theta ) );
theta_num_elements = size( unique( itaHRTF_obj.channelCoordinates.theta ), 1 );
phi_start_deg = rad2deg( min( mod( itaHRTF_obj.channelCoordinates.phi, 2*pi ) ) );
phi_end_deg = rad2deg( max( mod( itaHRTF_obj.channelCoordinates.phi, 2*pi ) ) );
phi_num_elements = size( unique( itaHRTF_obj.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', 'daffv17_convert_from_itaHRTF.m' );
metadata = daffv17_add_metadata( metadata, 'Generation date', 'String', date );
channels = 2; % this.nChannels < does not work?
% Content type switcher between time domain (ir) and frequency domain (dft)
% (requires different data functions)
if strcmp( itaHRTF_obj.domain, 'time' )
daffv17_write('filename', file_path, ...
'content', 'ir', ...
'datafunc', @dfitaHRIR, ...
'channels', channels, ...
'alphares', alphares, ...
'alpharange', alpharange, ...
'betares', betares, ...
'betarange', betarange, ...
'orient', [ 0 0 0 ], ...
'metadata', metadata, ...
'userdata', itaHRTF_obj, ...
'quantization', 'float32' );
elseif strcmp( itaHRTF_obj.domain, 'freq' )
daffv17_write('filename', file_path, ...
'content', 'dft', ...
'datafunc', @dfitaHRTF, ...
'channels', channels, ...
'alphares', alphares, ...
'alpharange', alpharange, ...
'betares', betares, ...
'betarange', betarange, ...
'orient', [ 0 0 0 ], ...
'metadata', metadata, ...
'userdata', itaHRTF_obj, ...
'quantization', 'float32' );
end
function [ data, samplerate, metadata ] = dfitaHRIR( alpha, beta, itaHRTF_obj )
samplerate = itaHRTF_obj.samplingRate;
hrtf = itaHRTF_obj.findnearestHRTF( 180 - beta, alpha );
% DAFF requires data alignment by multiple of 4
nResidual = mod( hrtf.nSamples, 4 );
data = [ hrtf.timeData', zeros( hrtf.nChannels, nResidual ) ];
metadata = [];
end
function [ data, samplerate, isSymetric, metadata ] = dfitaHRTF( alpha, beta, itaHRTF_obj )
samplerate = itaHRTF_obj.samplingRate;
isSymetric = false;
hrtf = itaHRTF_obj.findnearestHRTF( 180 - beta, alpha );
% DAFF requires data alignment by multiple of 4. Interpolate by zero padding
% in time domain
nResidual = mod( hrtf.nSamples, 4 );
if nResidual ~= 0
data = ifft( [ hrtf.timeData', zeros( hrtf.nChannels, nResidual ) ] );
else
data = hrtf.freqData';
end
metadata = [];
end
%
% OpenDAFF
%
% The ITA Artificial Head HRIR data set can be obtained from:
% http://www.akustik.rwth-aachen.de/go/id/pein/lidx/1
%
% Requires the ITA Toolbox: http://git.rwth-aachen.de/ita/toolbox
%
addpath( '../..' ) % Find daffv17_write and daffv17_add_metadata function
metadata = [];
metadata = daffv17_add_metadata( metadata, 'Description', 'String', 'ITA Artificial Head' );
metadata = daffv17_add_metadata( metadata, 'Creation date', 'String', date );
metadata = daffv17_add_metadata( metadata, 'License', 'String', 'CC BY-NC 4.0' );
metadata = daffv17_add_metadata( metadata, 'CC License Deed', 'String', 'https://creativecommons.org/licenses/by-nc/4.0/' );
metadata = daffv17_add_metadata( metadata, 'Generation script', 'String', 'Opendaff-v1.7/matlab/hrtfs/ITAKunstkopfAcademic/export_ITAKunstkopfAcademic.m' );
metadata = daffv17_add_metadata( metadata, 'Web Resource (2016)', 'String', 'http://www.akustik.rwth-aachen.de/cms/Technische-Akustik/Studium/~edgv/Lehrmaterialien/' );
hrir_1x1 = ita_read( 'finishedHRTF_1deg.ita' );
hrir_1x1.writeDAFFFile( 'ITA_Artificial_Head_5x5_44kHz_532.daff', { 'metadata', metadata } );
hrir_5x5 = ita_read( 'finishedHRTF_5deg.ita' );
hrir_5x5.writeDAFFFile( 'ITA_Artificial_Head_5x5_44kHz_532', { 'metadata', metadata } );
d = floor( mean( ita_start_IR( hrir_5x5 ) ) );
tc = [ 1 127 ] + d - 20;
hrir_5x5_128 = ita_time_crop( hrir_5x5, tc, 'samples' );
metadata_128 = daffv17_add_metadata( metadata, 'START_IR_SAMPLE_MEAN', 'FLOAT', d );
metadata_128 = daffv17_add_metadata( metadata_128, 'TIME_CROP_SAMPLES', 'STRING', num2str( tc ) );
hrir_5x5_128.writeDAFFFile( 'ITA_Artificial_Head_5x5_44kHz_128', { 'metadata', metadata_128 } );
% If required, uncomment
% daffv15_convert_from_daffv17( 'ITA_Artificial_Head_5x5_44kHz_128.v17.ir.daff', 'ITA_Artificial_Head_5x5_44kHz_128.v15.ir.daff' )
tc = [ 1 256 ] + d - 40;
hrir_5x5_256 = ita_time_crop( hrir_5x5, tc, 'samples' );
metadata_256 = daffv17_add_metadata( metadata, 'START_IR_SAMPLE_MEAN', 'FLOAT', d );
metadata_256 = daffv17_add_metadata( metadata_256, 'TIME_CROP_SAMPLES', 'STRING', num2str( tc ) );
hrir_5x5_256.writeDAFFFile( 'ITA_Artificial_Head_5x5_44kHz_256', { 'metadata', metadata_256 } );
......@@ -5,20 +5,20 @@
% The ITA Kunstkopf Academic HRIR data set can be obtained from:
% http://www.akustik.rwth-aachen.de/cms/Technische-Akustik/Studium/~edgv/Lehrmaterialien/
addpath( '../..' ) % Find daff_write and daff_add_metadata function
addpath( '../..' ) % Find daff_write and daffv17_add_metadata function
metadata = [];
metadata = daff_add_metadata( metadata, 'Description', 'String', 'ITA Kunstkopf HRIR (Academic)' );
metadata = daff_add_metadata( metadata, 'Creation date', 'String', date );
metadata = daff_add_metadata( metadata, 'License', 'String', 'CC BY-NC 4.0' );
metadata = daff_add_metadata( metadata, 'CC License Deed', 'String', 'https://creativecommons.org/licenses/by-nc/4.0/' );
metadata = daff_add_metadata( metadata, 'Generation script', 'String', 'Opendaff-v1.7/matlab/hrtfs/ITAKunstkopfAcademic/export_ITAKunstkopfAcademic.m' );
metadata = daff_add_metadata( metadata, 'Web Resource (2016)', 'String', 'http://www.akustik.rwth-aachen.de/cms/Technische-Akustik/Studium/~edgv/Lehrmaterialien/' );
metadata = daffv17_add_metadata( metadata, 'Description', 'String', 'ITA Kunstkopf HRIR (Academic)' );
metadata = daffv17_add_metadata( metadata, 'Creation date', 'String', date );
metadata = daffv17_add_metadata( metadata, 'License', 'String', 'CC BY-NC 4.0' );
metadata = daffv17_add_metadata( metadata, 'CC License Deed', 'String', 'https://creativecommons.org/licenses/by-nc/4.0/' );
metadata = daffv17_add_metadata( metadata, 'Generation script', 'String', 'Opendaff-v1.7/matlab/hrtfs/ITAKunstkopfAcademic/export_ITAKunstkopfAcademic.m' );
metadata = daffv17_add_metadata( metadata, 'Web Resource (2016)', 'String', 'http://www.akustik.rwth-aachen.de/cms/Technische-Akustik/Studium/~edgv/Lehrmaterialien/' );
config.basepath = 'ITA_Academic_HRIRs_2008-12-22/Standard';
metadata_standard = daff_add_metadata( metadata, 'Postprocessing', 'String', 'Untouched' );
metadata_standard = daffv17_add_metadata( metadata, 'Postprocessing', 'String', 'Untouched' );
daff_write( 'filename', 'ITAKunstkopfAcademicStandard.ir.daff', ...
daffv17_write( 'filename', 'ITAKunstkopfAcademicStandard.ir.daff', ...
'content', 'ir', ...
'datafunc', @dfITAKunstkopfAcademic, ...
'userdata', config, ...
......@@ -32,9 +32,9 @@ daff_write( 'filename', 'ITAKunstkopfAcademicStandard.ir.daff', ...
config.basepath = 'ITA_Academic_HRIRs_2008-12-22/Free-field equalized';
metadata_equalized = daff_add_metadata( metadata, 'Postprocessing', 'String', 'Free-field pressure equalized' );
metadata_equalized = daffv17_add_metadata( metadata, 'Postprocessing', 'String', 'Free-field pressure equalized' );
daff_write( 'filename', 'ITAKunstkopfAcademicFreeFieldEqualized.ir.daff', ...
daffv17_write( 'filename', 'ITAKunstkopfAcademicFreeFieldEqualized.ir.daff', ...
'content', 'ir', ...
'datafunc', @dfITAKunstkopfAcademic, ...
'userdata', config, ...
......
function [] = daffv17_convert_from_aktools( target_file_path, export_properties, additional_metadata )
export_properties.samplerate = 44100;
export_properties.numchannels = 2 * ceil( ( export_properties.hatorange( 2 ) - export_properties.hatorange( 1 ) ) / export_properties.hatores + 1 );
combined_metadata = daffv17_add_metadata( additional_metadata, 'Converter script', 'String', 'daffv17_convert_from_aktools.m' );
combined_metadata = daffv17_add_metadata( combined_metadata, 'Conversion date', 'String', date );
daffv17_write( 'filename', target_file_path, ...
'datafunc', @dfAKtools, ...
'userdata', export_properties, ...
'metadata', combined_metadata, ...
'content', 'ir', ...
'alphares', export_properties.alphares, ...
'alpharange', export_properties.alpharange, ...
'betares', export_properties.betares, ...
'betarange', export_properties.betarange, ...
'orient', [ 0 0 0 ], ...
'channels', export_properties.numchannels, ...
'quantization', 'float32' );
function [ data, samplerate, metadata ] = dfAKtools( alpha, beta, config )
%DFAKTOOLS Summary of this function goes here
% Retrieves data from FABIAN via AKtools using AKhrirInterpolation
% routine for azimuth, elevation and head-above-torso orientation
% First two channels are always neutral hato position (for backwards
% compatibility)
% Define range angle vector with neutral direction as first entry
assert( config.hatorange( 1 ) <= 0 && config.hatorange( 2 ) >= 0 )
hato_negative_range = config.hatorange( 1 ):config.hatores:-config.hatores;
hato_positive_range = config.hatores:config.hatores:config.hatorange( 2 );
hato = [ 0 hato_negative_range hato_positive_range ];
[ l, r ] = AKhrirInterpolation( alpha, beta - 90, hato );
l = l';
r = r';
% Interleave for DAFF (odd = left, even = right)
data = reshape( [ l(:) r(:) ]', 2 * size( l, 1 ), [] );
samplerate = config.samplerate;
metadata = daffv17_add_metadata( [], 'AKhrirInterpolation_hato_parameter', 'STRING', num2str( hato ) );
end
%% Pull in FABIAN database from AKtools
% Resources
% http://dx.doi.org/10.14279/depositonce-5718.2
% http://www.ak.tu-berlin.de/menue/digitale_ressourcen/research_tools/aktools/
AKdependencies('FABIAN')
%% Configure
export_properties = struct();
export_properties.alphares = 5;
export_properties.alpharange = [0 360];
export_properties.betares = 5;
export_properties.betarange = [0 180];
export_properties.hatores = 5;
export_properties.hatorange = [-40 40];
%% Set up metadata
additional_metadata = daffv17_add_metadata( [], 'hato', 'BOOL', true );
additional_metadata = daffv17_add_metadata( additional_metadata, 'hato_res_deg', 'FLOAT', export_properties.hatores );
additional_metadata = daffv17_add_metadata( additional_metadata, 'hato_start_deg', 'FLOAT', export_properties.hatorange( 1 ) );
additional_metadata = daffv17_add_metadata( additional_metadata, 'hato_end_deg', 'FLOAT', export_properties.hatorange( 2 ) );
additional_metadata = daffv17_add_metadata( additional_metadata, 'AKtools_resource', 'STRING', 'http://www.ak.tu-berlin.de/menue/digitale_ressourcen/research_tools/aktools/' );
additional_metadata = daffv17_add_metadata( additional_metadata, 'FABIAN_resource', 'STRING', 'http://dx.doi.org/10.14279/depositonce-5718.2' );
additional_metadata = daffv17_add_metadata( additional_metadata, 'FABIAN_license', 'STRING', 'Creative Commons BY-NC-SA 4.0' );
%% Export
daffv17_convert_from_aktools( 'FABIAN_HATO_5x5x5_256_44100Hz.v17.ir.daff', export_properties, additional_metadata )
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