Aufgrund einer Wartung wird GitLab am 28.09. zwischen 10:00 und 11:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 28.09. between 10:00 and 11:00 am.

Commit 7f92fd90 authored by Florian Pausch's avatar Florian Pausch

Merge branch 'master' of https://git.rwth-aachen.de/ita/toolbox

parents 2e44e5b5 1284d051
...@@ -120,7 +120,7 @@ end ...@@ -120,7 +120,7 @@ end
datumDerMessung = datestr(x(1).datenum, 'dd.mm.yyyy'); datumDerMessung = datestr(x(1).datenum, 'dd.mm.yyyy');
% TODO: in GUI auswhlen % TODO: in GUI auswhlen
protocolPath = [ita_toolbox_path filesep 'applications' filesep 'Kundt' filesep 'Protocol' filesep]; protocolPath = [ita_toolbox_path filesep 'applications' filesep 'Measurement' filesep 'ImpedanceTube' filesep 'Protocol' filesep];
if strcmpi(protocolLanguage, 'german') if strcmpi(protocolLanguage, 'german')
templateFileName = [protocolPath 'KundtGermanTemplate.tex']; templateFileName = [protocolPath 'KundtGermanTemplate.tex'];
......
...@@ -23,7 +23,7 @@ function varargout = ita_beam_calibrate_array_positions(varargin) ...@@ -23,7 +23,7 @@ function varargout = ita_beam_calibrate_array_positions(varargin)
% See also: % See also:
% ita_toolbox_gui, ita_read, ita_write, ita_generate % ita_toolbox_gui, ita_read, ita_write, ita_generate
% %
% Reference page in Help browser % Reference page in Help browser
% <a href="matlab:doc ita_beam_calibrate_array_positions">doc ita_beam_calibrate_array_positions</a> % <a href="matlab:doc ita_beam_calibrate_array_positions">doc ita_beam_calibrate_array_positions</a>
% <ITA-Toolbox> % <ITA-Toolbox>
...@@ -33,90 +33,62 @@ function varargout = ita_beam_calibrate_array_positions(varargin) ...@@ -33,90 +33,62 @@ function varargout = ita_beam_calibrate_array_positions(varargin)
% Author: Adrian Fazekas / Markus Mueller Trapet -- Email: mmt@akustik.rwth-aachen.de % Author: Adrian Fazekas / Markus Mueller Trapet -- Email: mmt@akustik.rwth-aachen.de
% Created: 30-Aug-2010 / 08-Sep-2011 % Created: 30-Aug-2010 / 08-Sep-2011
%% Initialization and Input Parsing %% Initialization and Input Parsing
sArgs = struct('pos1_chImpResp','itaAudio', 'pos2_recPos','itaMicArray','pos3_sourcePos','itaMicArray','statMicInd', [],'winTime',[],'freqInterv',[1000,4000],'speedOfSound',343); sArgs = struct('pos1_chImpResp','itaAudio', 'pos2_recPos','itaMicArray','pos3_sourcePos','itaMicArray','statMicInd', [],'freqInterv',[1000,4000],'speedOfSound',343);
[chImpResp,recPos,sourcePos,sArgs] = ita_parse_arguments(sArgs,varargin); [chImpResp,recPos,sourcePos,sArgs] = ita_parse_arguments(sArgs,varargin);
%% %%
if numel(chImpResp) ~= sourcePos.nPoints if numel(chImpResp) ~= sourcePos.nPoints
error('ITA_CALIBRATE_POS: Number of itaAudio objects must coincide with number of source nodes '); error('ITA_CALIBRATE_POS: Number of itaAudio objects must coincide with number of source nodes ');
else else
tic; tic;
%groupDelays = ita_groupdelay_ita(ita_time_window(chImpResp,[0.001 0.0015],'time','channeladaptive',true)); measuredDist = zeros(recPos.nPoints,sourcePos.nPoints);
%meanDelays = mean(groupDelays.freq2value(sArgs.freqInterv));
%vdDist = meanDelays * 343;
%mdMeasuredDist = reshape(vdDist,recPos.nPoints, sourcePos.nPoints);
%mdMeasuredDist = mdMeasuredDist';
mdMeasuredDist = zeros(sourcePos.nPoints,recPos.nPoints);
for i = 1:length(chImpResp) for i = 1:length(chImpResp)
if (chImpResp(i).nChannels ~= recPos.nPoints) if (chImpResp(i).nChannels ~= recPos.nPoints)
error(['ITA_CALIBRATE_POS: Number of channels of itaAudio object ',num2str(i),' must be equal to number of microphone nodes']) error(['ITA_CALIBRATE_POS: Number of channels of itaAudio object ',num2str(i),' must be equal to number of microphone nodes'])
else else
% res_win = ita_time_window(ita_filter_bandpass(chImpResp(i),'lower',sArgs.freqInterv(1),'zerophase'),[0.2 0.4].*1e-3,'channeladaptive');
groupDelays = ita_groupdelay_ita(ita_time_window(chImpResp(i),[0.001 0.0015],'time','channeladaptive',true)); % measuredDist(:,i) = mean(freq2value(ita_groupdelay_ita(res_win),sArgs.freqInterv)) * sArgs.speedOfSound;
meanDelays = mean(groupDelays.freq2value(sArgs.freqInterv(1),sArgs.freqInterv(2))); res_filt = ita_filter_bandpass(chImpResp(i),'lower',sArgs.freqInterv(1),'zerophase');
mdMeasuredDist(i,:) = meanDelays * sArgs.speedOfSound; measuredDist(:,i) = ita_start_IR(res_filt)/res_filt.samplingRate * sArgs.speedOfSound;
end end
end end
tWinElapsed = toc; toc;
end end
miPos = [recPos.cart; sourcePos.cart];
tic; tic;
[miOptPos resnorm] = runNonlinOpt(miPos, mdMeasuredDist,sArgs.statMicInd); %#ok<NASGU> [optRecPos, optSrcPos] = runNonlinOpt(recPos.cart, sourcePos.cart, measuredDist,sArgs.statMicInd);
tOptElapsed = toc; toc;
%% Set Output %% Set Output
varargout(1) = {miOptPos}; varargout(1) = {optRecPos};
varargout(2) = {tWinElapsed}; varargout(2) = {optSrcPos};
varargout(3) = {tOptElapsed};
end %end function end %end function
%% Subfunctions %% Subfunctions
function [x,fval] = runNonlinOpt(miPos,mdMeasuredDist,viStatInd) function [optRec,optSrc,fval] = runNonlinOpt(recPos,srcPos,mdMeasuredDist,statInd)
nPoints = size(miPos,1);
nSource = size(mdMeasuredDist,1);
nRec = size(mdMeasuredDist,2);
logStatInd = false(1,nPoints);
logStatInd(viStatInd) = 1;
miDynPos = miPos(~logStatInd,:); nRecs = size(recPos,1);
miStatPos = miPos(logStatInd,:); miStatZ = recPos(:,3);
miStatPos = recPos(statInd,:);
options = optimset('TolFun', 1e-15,'Display','on','Algorithm','levenberg-marquardt','MaxFunEvals',60000); options = optimset('TolFun', 1e-15, 'TolX', 1e-4, 'Display','on','Algorithm','levenberg-marquardt','MaxFunEvals',60000);
[res,fval] = lsqnonlin(@distDiffFun,miDynPos,[],[],options); [res,fval] = lsqnonlin(@distDiffFun,[recPos; srcPos],[],[],options);
x = zeros(nPoints,3); optRec = res(1:nRecs,:);
x(logStatInd,:) = miStatPos; optRec(statInd,:) = miStatPos;
x(~logStatInd,:) = res; optSrc = res(nRecs+1:end,:);
% Nested function that computes the objective function % Nested function that computes the objective function
function res = distDiffFun(miInpPos) function res = distDiffFun(miInpPos)
miCoord = zeros(nPoints,3); miInpPos(statInd,:) = miStatPos;
miCoord(logStatInd,:) = miStatPos; miInpPos(1:nRecs,3) = miStatZ;
miCoord(~logStatInd,:) = miInpPos;
%Calculate the distances from the sources to the microphones %Calculate the distances from the sources to the microphones
mdXDiff = repmat(miCoord(1:nRec,1)',[nSource 1]) - repmat(miCoord(nRec + 1:nPoints,1),[1 nRec]); res = mean(abs(pdist2(miInpPos(1:nRecs,:),miInpPos(nRecs+1:end,:)) - mdMeasuredDist),2);
mdYDiff = repmat(miCoord(1:nRec,2)',[nSource 1]) - repmat(miCoord(nRec + 1:nPoints,2),[1 nRec]);
mdZDiff = repmat(miCoord(1:nRec,3)',[nSource 1]) - repmat(miCoord(nRec + 1:nPoints,3),[1 nRec]);
%Transform the cartesian coordinates of the differences into spherical
%coordinates
[mdTheta mdPhi mdRDiff] = cart2sph(mdXDiff(:), mdYDiff(:), mdZDiff(:)); %#ok<ASGLU>
mdEstDistance = reshape(mdRDiff, [nSource nRec]);
%res = mdDistance;
res = mdEstDistance - mdMeasuredDist;
end end
end end
...@@ -10,8 +10,7 @@ function varargout = surf(this, varargin) ...@@ -10,8 +10,7 @@ function varargout = surf(this, varargin)
% [input,sArgs] = ita_parse_arguments(sArgs,varargin); % [input,sArgs] = ita_parse_arguments(sArgs,varargin);
numArgIn = nargin; titleString = [];
% check if SH coefs are given % check if SH coefs are given
if numel(varargin{1}) > 0 &&... if numel(varargin{1}) > 0 &&...
...@@ -25,7 +24,6 @@ if numel(varargin{1}) > 0 &&... ...@@ -25,7 +24,6 @@ if numel(varargin{1}) > 0 &&...
nSHGrid = size(this.Y,2); nSHGrid = size(this.Y,2);
nSHData = size(varargin{1}(:),1); nSHData = size(varargin{1}(:),1);
if nSHGrid ~= nSHData if nSHGrid ~= nSHData
% error('the spherical harmonics dimensions don''t fit');
% TODO make autofit % TODO make autofit
if nSHGrid > nSHData if nSHGrid > nSHData
varargin{1} = [varargin{1}(:); zeros(nSHGrid - nSHData,1)]; varargin{1} = [varargin{1}(:); zeros(nSHGrid - nSHData,1)];
...@@ -49,7 +47,7 @@ end ...@@ -49,7 +47,7 @@ end
hFig = {surf@itaCoordinates(this, varargin{:})}; hFig = {surf@itaCoordinates(this, varargin{:})};
% set title % set title
if numel(titleString) if ~isempty(titleString)
title(titleString); title(titleString);
end end
......
function varargout = ita_sph_sampling_eigenmike(varargin)
%ITA_SPH_SAMPLING_EIGENMIKE - Generate Eigenmike em32 sampling
% Microphone positions based on the pentakis dodecahedron, exact positions
% can be found under:
% https://www.mhacoustics.com/sites/default/files/EigenStudio%20User%20Manual%20R02A.pdf
%
% Zero degrees in azimuth aligns with the “mh acoustics” logo on the
% microphone shaft
%
% Syntax:
% sampling = ita_sph_sampling_eigenmike()
%
% See also:
% ita_sph_sampling
%
% Reference page in Help browser
% <a href="matlab:doc ita_sph_sampling_eigenmike">doc ita_sph_sampling_eigenmike</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>
% Author: Marco Berzborn -- Email: mbe@akustik.rwth-aachen.de
% Created: 18-Oct-2016
positions = [
0.0420 69.0000 0
0.0420 90.0000 32.0000
0.0420 111.0000 0
0.0420 90.0000 328.0000
0.0420 32.0000 0
0.0420 55.0000 45.0000
0.0420 90.0000 69.0000
0.0420 125.0000 45.0000
0.0420 148.0000 0
0.0420 125.0000 315.0000
0.0420 90.0000 291.0000
0.0420 55.0000 315.0000
0.0420 21.0000 91.0000
0.0420 58.0000 90.0000
0.0420 121.0000 90.0000
0.0420 159.0000 89.0000
0.0420 69.0000 180.0000
0.0420 90.0000 212.0000
0.0420 111.0000 180.0000
0.0420 90.0000 148.0000
0.0420 32.0000 180.0000
0.0420 55.0000 225.0000
0.0420 90.0000 249.0000
0.0420 125.0000 225.0000
0.0420 148.0000 180.0000
0.0420 125.0000 135.0000
0.0420 90.0000 111.0000
0.0420 55.0000 135.0000
0.0420 21.0000 269.0000
0.0420 58.0000 270.0000
0.0420 122.0000 270.0000
0.0420 159.0000 271.0000
];
positions(:,2:3) = positions(:,2:3)/180*pi;
sampling = itaSamplingSph(positions,'sph');
sampling.nmax = 4;
varargout{1} = sampling;
end
...@@ -58,11 +58,11 @@ classdef itaRavenProject < handle ...@@ -58,11 +58,11 @@ classdef itaRavenProject < handle
properties (GetAccess = 'public', SetAccess = 'private') properties (GetAccess = 'public', SetAccess = 'private')
% raven % raven
ravenExe64 = '..\bin64\RavenConsole64.exe'
ravenExe32 = '..\bin32\RavenConsole.exe'
ravenExe ravenExe
ravenLogFile = 'RavenLog.txt' ravenLogFile = 'RavenLog.txt'
ravenProjectFile ravenProjectFile
ravenIniFile
projectName projectName
% general % general
...@@ -152,7 +152,12 @@ classdef itaRavenProject < handle ...@@ -152,7 +152,12 @@ classdef itaRavenProject < handle
end end
properties (GetAccess = 'private', SetAccess = 'private') properties (GetAccess = 'private', SetAccess = 'private')
ravenExe64 = '..\bin64\RavenConsole64.exe'
ravenExe32 = '..\bin32\RavenConsole.exe'
rpf_ini rpf_ini
raven_ini
projectID projectID
projectTag projectTag
...@@ -214,6 +219,47 @@ classdef itaRavenProject < handle ...@@ -214,6 +219,47 @@ classdef itaRavenProject < handle
error('Only Windows OS are supported.'); error('Only Windows OS are supported.');
end end
itaRavenProjectPath = which('itaRavenProject.m');
obj.ravenIniFile = [ itaRavenProjectPath(1:end-9) '.ini'];
ravenIniExists = exist(obj.ravenIniFile,'file');
if (ravenIniExists)
% load path from itaRaven.ini
obj.raven_ini = IniConfig();
obj.raven_ini.ReadFile(obj.ravenIniFile);
obj.ravenExe = obj.raven_ini.GetValues('Global', 'PathRavenExe', obj.ravenExe);
obj.raven_ini.WriteFile(obj.ravenIniFile);
end
if (~exist(obj.ravenExe,'file'))
% neither the default raven console or the path in
% itaRaven.ini was not found, try to locate
% RavenConsole
locatedRavenExe = which(obj.ravenExe(10:end));
if isempty(locatedRavenExe)
disp('[itaRaven]: No raven binary was found! Please select path to RavenConsole.exe!');
[ selectedRavenExe, selectedRavenPath] = uigetfile('*.exe',' No raven binary was found! Please select path to RavenConsole.exe');
obj.ravenExe = [ selectedRavenPath selectedRavenExe];
else
obj.ravenExe = locatedRavenExe;
end
if (~ravenIniExists)
obj.raven_ini = IniConfig();
% obj.raven_ini.ReadFile(obj.ravenIniFile);
obj.raven_ini.AddSections({'Global'});
obj.raven_ini.AddKeys('Global', {'PathRavenExe'}, {obj.ravenExe});
else
obj.raven_ini.SetValues('Global', {'PathRavenExe'}, {obj.ravenExe});
end
obj.raven_ini.WriteFile(obj.ravenIniFile);
end
% check if raven project file exists
if (nargin > 0) && exist(raven_project_file, 'file') if (nargin > 0) && exist(raven_project_file, 'file')
obj.loadRavenConfig(raven_project_file); obj.loadRavenConfig(raven_project_file);
else else
...@@ -228,6 +274,16 @@ classdef itaRavenProject < handle ...@@ -228,6 +274,16 @@ classdef itaRavenProject < handle
%------------------------------------------------------------------ %------------------------------------------------------------------
function setRavenExe(obj, newRavenExe) function setRavenExe(obj, newRavenExe)
obj.ravenExe = newRavenExe; obj.ravenExe = newRavenExe;
if (exist(obj.ravenIniFile,'file'))
obj.raven_ini.SetValues('Global', {'PathRavenExe'}, {obj.ravenExe});
obj.raven_ini.WriteFile(obj.ravenIniFile);
else
obj.raven_ini = IniConfig();
obj.raven_ini.AddSections({'Global'});
obj.raven_ini.AddKeys('Global', {'PathRavenExe'}, {obj.ravenExe});
end
end end
%------------------------------------------------------------------ %------------------------------------------------------------------
...@@ -235,7 +291,12 @@ classdef itaRavenProject < handle ...@@ -235,7 +291,12 @@ classdef itaRavenProject < handle
%loadRavenConfig - Reads an existing raven project file %loadRavenConfig - Reads an existing raven project file
% %
obj.ravenProjectFile = filename; % change relative to absolute path
if (~strcmp(filename(2),':'))
obj.ravenProjectFile = [pwd '\' filename];
else
obj.ravenProjectFile = filename;
end
obj.rpf_ini = IniConfig(); obj.rpf_ini = IniConfig();
obj.rpf_ini.ReadFile(filename); obj.rpf_ini.ReadFile(filename);
...@@ -263,6 +324,16 @@ classdef itaRavenProject < handle ...@@ -263,6 +324,16 @@ classdef itaRavenProject < handle
obj.logPerformance = obj.rpf_ini.GetValues('Global', 'logPerformance', 0); obj.logPerformance = obj.rpf_ini.GetValues('Global', 'logPerformance', 0);
obj.keepOutputFiles = obj.rpf_ini.GetValues('Global', 'keepOutputFiles', 0); obj.keepOutputFiles = obj.rpf_ini.GetValues('Global', 'keepOutputFiles', 0);
% change relative to absolute paths
if obj.ravenExe(2) == ':' % absolute path
ravenBasePath = fileparts(fileparts(obj.ravenExe)); % base path of raven
if (strcmp(obj.pathResults(1:2),'..')), obj.pathResults = [ ravenBasePath obj.pathResults(3:end) ]; end
if (strcmp(obj.pathDirectivities(1:2),'..')), obj.pathDirectivities = [ ravenBasePath obj.pathDirectivities(3:end) ]; end
if (strcmp(obj.pathMaterials(1:2),'..')), obj.pathMaterials = [ ravenBasePath obj.pathMaterials(3:end) ]; end
if (strcmp(obj.fileHRTF(1:2),'..')), obj.fileHRTF = [ ravenBasePath obj.fileHRTF(3:end) ]; end
end
% [Rooms] % % [Rooms] %
model_string = obj.rpf_ini.GetValues('Rooms', 'Model'); model_string = obj.rpf_ini.GetValues('Rooms', 'Model');
obj.modelFileList = textscan(model_string, '%s', 'Delimiter' , ','); obj.modelFileList = textscan(model_string, '%s', 'Delimiter' , ',');
...@@ -338,6 +409,16 @@ classdef itaRavenProject < handle ...@@ -338,6 +409,16 @@ classdef itaRavenProject < handle
obj.loadRavenConfig(filename); obj.loadRavenConfig(filename);
end end
%------------------------------------------------------------------
function saveRavenConfig(obj, filename)
%saveRavenConfig - Saves the current object in a (different)
%raven project file. Can be used as a log if various
%simulations are run with multiple configurations
%
obj.rpf_ini.WriteFile(filename);
end
%------------------------------------------------------------------ %------------------------------------------------------------------
function run(obj) function run(obj)
...@@ -361,8 +442,11 @@ classdef itaRavenProject < handle ...@@ -361,8 +442,11 @@ classdef itaRavenProject < handle
delete(obj.ravenLogFile); delete(obj.ravenLogFile);
end end
% system([obj.ravenExe ' "' obj.ravenProjectFile '" >> ' obj.ravenLogFile]); % system([obj.ravenExe ' "' obj.ravenProjectFile '" >> ' obj.ravenLogFile]);
prevPath = pwd;
cd(fileparts(obj.ravenExe));
dos([obj.ravenExe ' "' obj.ravenProjectFile '"'], '-echo'); dos([obj.ravenExe ' "' obj.ravenProjectFile '"'], '-echo');
disp('Done.'); disp('Done.');
cd(prevPath);
% restore the initial project name % restore the initial project name
obj.setProjectName(savedProjectName); obj.setProjectName(savedProjectName);
...@@ -432,6 +516,19 @@ classdef itaRavenProject < handle ...@@ -432,6 +516,19 @@ classdef itaRavenProject < handle
end end
%------------------------------------------------------------------
function openOutputFolder(obj)
% opens the output folder in windows explorer
if (exist(obj.pathResults,'dir'))
dos(['C:\Windows\Explorer.exe ' obj.pathResults]);
else
disp('Output Folder does not exist!');
end
end
%------------------------------------------------------------------ %------------------------------------------------------------------
function numReceivers = createReceiverArray(obj, xpositions, zpositions, yheight) function numReceivers = createReceiverArray(obj, xpositions, zpositions, yheight)
numReceivers = numel(xpositions) * numel(zpositions); numReceivers = numel(xpositions) * numel(zpositions);
...@@ -1639,7 +1736,7 @@ classdef itaRavenProject < handle ...@@ -1639,7 +1736,7 @@ classdef itaRavenProject < handle
%------------------------------------------------------------------ %------------------------------------------------------------------
function binauralPoissonSequenceitaAudio = getBinauralPoissonSequenceItaAudio(obj) function binauralPoissonSequenceitaAudio = getBinauralPoissonSequenceItaAudio(obj)
data = load('..\RavenOutput\binauralPoissonNoiseProcess.txt'); data = load([ obj.pathResults '\binauralPoissonNoiseProcess.txt']);
binauralPoissonSequenceitaAudio = itaAudio; binauralPoissonSequenceitaAudio = itaAudio;
binauralPoissonSequenceitaAudio.samplingRate = obj.sampleRate; binauralPoissonSequenceitaAudio.samplingRate = obj.sampleRate;
......
classdef itaVA < handle classdef itaVA < handle
%ITAVA Remote interface for VA real-time auralization servers %ITAVA Remote network interface to VA (Virtual Acoustics), the real-time
%auralization software made by ITA.
% %
% This class realizes a remote connection to a VA real-time % This class realizes a remote connection to a VA real-time
% auralization server and implements the full VA core interface % auralization server and implements the full VA core interface
% in Matlab. This way you connect to an auralization server % in Matlab. You can connect to to the server
% and control all of its features to perform a real-time % and control all of its features to perform real-time
% auralization. In order to get understand to the concepts behind VA % auralization, including live tracking if available.
% please refer to the VA documentation. % In order to get understand to the concepts behind VA
% please refer to the VA documentation or have a look at the example scripts.
% %
% Usage & examples: % See also: itaVA_example_simple, itaVA_example_tracked_listener,
% itaVA_example_generic_path_renderer, itaVA_example_random_numbers
%
% Quick usage:
% %
% - Create an interface and connect to the server running on the % - Create an interface and connect to the server running on the
% same computer (localhost) % same computer (localhost)
% %
% va = itaVA('localhost'); % va = itaVA;
% va.connect;
% %
% If no error occurs, you can then use the interface to work with % If no error occurs, you can then use the interface to work with
% the VA server. Best practice is to reset it first: % the VA server.
%
% va.reset
% %
% Then you can call other methods. For instance create a sound % Now, you can call other methods. For instance create a sound
% source: % source:
% %
% sourceID = va.createSoundSource('Virtual sound source') % sourceID = va.createSoundSource( 'My Matlab virtual sound source' )
%