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
datumDerMessung = datestr(x(1).datenum, 'dd.mm.yyyy');
% 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')
templateFileName = [protocolPath 'KundtGermanTemplate.tex'];
......
......@@ -36,7 +36,7 @@ function varargout = ita_beam_calibrate_array_positions(varargin)
% Created: 30-Aug-2010 / 08-Sep-2011
%% 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);
%%
......@@ -44,79 +44,51 @@ if numel(chImpResp) ~= sourcePos.nPoints
error('ITA_CALIBRATE_POS: Number of itaAudio objects must coincide with number of source nodes ');
else
tic;
%groupDelays = ita_groupdelay_ita(ita_time_window(chImpResp,[0.001 0.0015],'time','channeladaptive',true));
%meanDelays = mean(groupDelays.freq2value(sArgs.freqInterv));
%vdDist = meanDelays * 343;
%mdMeasuredDist = reshape(vdDist,recPos.nPoints, sourcePos.nPoints);
%mdMeasuredDist = mdMeasuredDist';
mdMeasuredDist = zeros(sourcePos.nPoints,recPos.nPoints);
measuredDist = zeros(recPos.nPoints,sourcePos.nPoints);
for i = 1:length(chImpResp)
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'])
else
groupDelays = ita_groupdelay_ita(ita_time_window(chImpResp(i),[0.001 0.0015],'time','channeladaptive',true));
meanDelays = mean(groupDelays.freq2value(sArgs.freqInterv(1),sArgs.freqInterv(2)));
mdMeasuredDist(i,:) = meanDelays * sArgs.speedOfSound;
% res_win = ita_time_window(ita_filter_bandpass(chImpResp(i),'lower',sArgs.freqInterv(1),'zerophase'),[0.2 0.4].*1e-3,'channeladaptive');
% measuredDist(:,i) = mean(freq2value(ita_groupdelay_ita(res_win),sArgs.freqInterv)) * sArgs.speedOfSound;
res_filt = ita_filter_bandpass(chImpResp(i),'lower',sArgs.freqInterv(1),'zerophase');
measuredDist(:,i) = ita_start_IR(res_filt)/res_filt.samplingRate * sArgs.speedOfSound;
end
end
tWinElapsed = toc;
toc;
end
miPos = [recPos.cart; sourcePos.cart];
tic;
[miOptPos resnorm] = runNonlinOpt(miPos, mdMeasuredDist,sArgs.statMicInd); %#ok<NASGU>
tOptElapsed = toc;
[optRecPos, optSrcPos] = runNonlinOpt(recPos.cart, sourcePos.cart, measuredDist,sArgs.statMicInd);
toc;
%% Set Output
varargout(1) = {miOptPos};
varargout(2) = {tWinElapsed};
varargout(3) = {tOptElapsed};
varargout(1) = {optRecPos};
varargout(2) = {optSrcPos};
end %end function
%% Subfunctions
function [x,fval] = runNonlinOpt(miPos,mdMeasuredDist,viStatInd)
nPoints = size(miPos,1);
nSource = size(mdMeasuredDist,1);
nRec = size(mdMeasuredDist,2);
function [optRec,optSrc,fval] = runNonlinOpt(recPos,srcPos,mdMeasuredDist,statInd)
logStatInd = false(1,nPoints);
logStatInd(viStatInd) = 1;
nRecs = size(recPos,1);
miStatZ = recPos(:,3);
miStatPos = recPos(statInd,:);
miDynPos = miPos(~logStatInd,:);
miStatPos = miPos(logStatInd,:);
options = optimset('TolFun', 1e-15, 'TolX', 1e-4, 'Display','on','Algorithm','levenberg-marquardt','MaxFunEvals',60000);
[res,fval] = lsqnonlin(@distDiffFun,[recPos; srcPos],[],[],options);
options = optimset('TolFun', 1e-15,'Display','on','Algorithm','levenberg-marquardt','MaxFunEvals',60000);
[res,fval] = lsqnonlin(@distDiffFun,miDynPos,[],[],options);
x = zeros(nPoints,3);
x(logStatInd,:) = miStatPos;
x(~logStatInd,:) = res;
optRec = res(1:nRecs,:);
optRec(statInd,:) = miStatPos;
optSrc = res(nRecs+1:end,:);
% Nested function that computes the objective function
function res = distDiffFun(miInpPos)
miCoord = zeros(nPoints,3);
miCoord(logStatInd,:) = miStatPos;
miCoord(~logStatInd,:) = miInpPos;
miInpPos(statInd,:) = miStatPos;
miInpPos(1:nRecs,3) = miStatZ;
%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]);
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;
res = mean(abs(pdist2(miInpPos(1:nRecs,:),miInpPos(nRecs+1:end,:)) - mdMeasuredDist),2);
end
end
......@@ -10,8 +10,7 @@ function varargout = surf(this, varargin)
% [input,sArgs] = ita_parse_arguments(sArgs,varargin);
numArgIn = nargin;
titleString = [];
% check if SH coefs are given
if numel(varargin{1}) > 0 &&...
......@@ -25,7 +24,6 @@ if numel(varargin{1}) > 0 &&...
nSHGrid = size(this.Y,2);
nSHData = size(varargin{1}(:),1);
if nSHGrid ~= nSHData
% error('the spherical harmonics dimensions don''t fit');
% TODO make autofit
if nSHGrid > nSHData
varargin{1} = [varargin{1}(:); zeros(nSHGrid - nSHData,1)];
......@@ -49,7 +47,7 @@ end
hFig = {surf@itaCoordinates(this, varargin{:})};
% set title
if numel(titleString)
if ~isempty(titleString)
title(titleString);
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
properties (GetAccess = 'public', SetAccess = 'private')
% raven
ravenExe64 = '..\bin64\RavenConsole64.exe'
ravenExe32 = '..\bin32\RavenConsole.exe'
ravenExe
ravenLogFile = 'RavenLog.txt'
ravenProjectFile
ravenIniFile
projectName
% general
......@@ -152,7 +152,12 @@ classdef itaRavenProject < handle
end
properties (GetAccess = 'private', SetAccess = 'private')
ravenExe64 = '..\bin64\RavenConsole64.exe'
ravenExe32 = '..\bin32\RavenConsole.exe'
rpf_ini
raven_ini
projectID
projectTag
......@@ -214,6 +219,47 @@ classdef itaRavenProject < handle
error('Only Windows OS are supported.');
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')
obj.loadRavenConfig(raven_project_file);
else
......@@ -228,6 +274,16 @@ classdef itaRavenProject < handle
%------------------------------------------------------------------
function setRavenExe(obj, 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
%------------------------------------------------------------------
......@@ -235,7 +291,12 @@ classdef itaRavenProject < handle
%loadRavenConfig - Reads an existing raven project file
%
% 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.ReadFile(filename);
......@@ -263,6 +324,16 @@ classdef itaRavenProject < handle
obj.logPerformance = obj.rpf_ini.GetValues('Global', 'logPerformance', 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] %
model_string = obj.rpf_ini.GetValues('Rooms', 'Model');
obj.modelFileList = textscan(model_string, '%s', 'Delimiter' , ',');
......@@ -338,6 +409,16 @@ classdef itaRavenProject < handle
obj.loadRavenConfig(filename);
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)
......@@ -361,8 +442,11 @@ classdef itaRavenProject < handle
delete(obj.ravenLogFile);
end
% system([obj.ravenExe ' "' obj.ravenProjectFile '" >> ' obj.ravenLogFile]);
prevPath = pwd;
cd(fileparts(obj.ravenExe));
dos([obj.ravenExe ' "' obj.ravenProjectFile '"'], '-echo');
disp('Done.');
cd(prevPath);
% restore the initial project name
obj.setProjectName(savedProjectName);
......@@ -432,6 +516,19 @@ classdef itaRavenProject < handle
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)
numReceivers = numel(xpositions) * numel(zpositions);
......@@ -1639,7 +1736,7 @@ classdef itaRavenProject < handle
%------------------------------------------------------------------
function binauralPoissonSequenceitaAudio = getBinauralPoissonSequenceItaAudio(obj)
data = load('..\RavenOutput\binauralPoissonNoiseProcess.txt');
data = load([ obj.pathResults '\binauralPoissonNoiseProcess.txt']);
binauralPoissonSequenceitaAudio = itaAudio;
binauralPoissonSequenceitaAudio.samplingRate = obj.sampleRate;
......
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
% auralization server and implements the full VA core interface
% in Matlab. This way you connect to an auralization server
% and control all of its features to perform a real-time
% auralization. In order to get understand to the concepts behind VA
% please refer to the VA documentation.
% in Matlab. You can connect to to the server
% and control all of its features to perform real-time
% auralization, including live tracking if available.
% 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
% same computer (localhost)
%
% va = itaVA('localhost');
% va = itaVA;
% va.connect;
%
% If no error occurs, you can then use the interface to work with
% the VA server. Best practice is to reset it first:
%
% va.reset
% the VA server.
%
% Then you can call other methods. For instance create a sound
% Now, you can call other methods. For instance create a sound
% source:
%
% sourceID = va.createSoundSource('Virtual sound source')
% sourceID = va.createSoundSource( 'My Matlab virtual sound source' )
%
% When everything is done, do not forget to close the connection.
% You can call disconnect on the instance or simply clear it:
%
% clear va
%
% - You can find more examples in the demo files
%
% Questions? Contact the author: Frank.Wefers@akustik.rwth-aachen.de
%
% Otherwise => Enjoy!
%
properties(Hidden = true, Access = private)
......@@ -45,6 +44,22 @@ classdef itaVA < handle
end
methods(Static)
function [ ok ] = check_for_mex_file()
% Checks if VAMatlab executable can be found.
if ~exist( 'VAMatlab', 'file' )
disp( 'Matlab binding for VA not complete (missing VAMatlab executable).' )
% file dialog
itaVA_setup()
% Re-check
ok = exist( 'VAMatlab', 'file' ) > 0;
else
ok = true;
end
end
function [version] = getVersion()
% Return the version of the VA Matlab interface
%
......@@ -55,6 +70,11 @@ classdef itaVA < handle
% Return values:
%
% version [string] Version string
if ~itaVA.check_for_mex_file()
error( 'Matlab binding for VA requires VAMatlab executable.' );
end
version = VAMatlab('getVersion');
end
......@@ -74,6 +94,11 @@ classdef itaVA < handle
% - If you do not want any messages from the extension
% set the verbose mode to 'quiet'
%
if ~itaVA.check_for_mex_file()
error( 'Matlab binding for VA requires VAMatlab executable.' );
end
VAMatlab('setVerboseMode', mode);
end
end
......@@ -100,6 +125,10 @@ classdef itaVA < handle
% core = itaVA('localhost:12340');
%
if ~itaVA.check_for_mex_file()
error( 'Matlab binding for VA requires VAMatlab executable.' );
end
if (nargin > 0)
this.connect(addressstring)
end
......
......@@ -2,7 +2,7 @@
va = itaVA( 'localhost' )
va.reset();
X = va.createAudiofileSignalSource( '$(VADataDir)\Audiofiles\Bauer.wav' );
X = va.createAudiofileSignalSource( 'Audiofiles/Bauer.wav' );
va.setAudiofileSignalSourcePlaybackAction( X, 'play' );
va.setAudiofileSignalSourceIsLooping( X, true );
S = va.createSoundSource( 'itaVA_Source' );
......@@ -14,7 +14,7 @@ mMods = va.enumerateModules;
modname = 'none';
for n = size( mMods, 1 )
if strcmp( 'GenericPath', mMods(n).name(1:11) )
if strcmp( 'PrototypeGenericPath', mMods(n).name( 1:size( 'PrototypeGenericPath', 2 ) ) )
modname = mMods(n).name;
break; % use first one found
end
......
This diff is collapsed.
if ~exist( 'VAServer.exe', 'file' )
itaVA_setup
end
[ basepath, basename, ext ]= fileparts( which( 'VAServer.exe') );
[ va_basepath, ~, ~ ]= fileparts( basepath );
conf_path1 = fullfile( 'conf', 'VACore.ini' );
conf_path2 = fullfile( pwd, 'MyVACore.ini' ); % also absolute path possible
va_args = [ 'localhost:12340 ' conf_path1 ];
os_call = [ which( 'VAServer.exe') ' ' va_args ' &' ];
return_to_dir = pwd;
cd( va_basepath );
[ status, cmdout ] = system( os_call );
cd( return_to_dir );
% After connect, also add the folder with your data like this
% va.add
\ No newline at end of file
Contact: rsc@akustik.rwth-aachen.de
Description: Database for (binaural) room impulse responses
function bindb()
% Synopsis:
% bindb() or bindb
% Description:
% Launch the bindb Toolbox feature.
% <ITA-Toolbox>
% This file is part of the application bindb for the ITA-Toolbox. All rights reserved.
% You can find the license for this m-file in the application folder.
% </ITA-Toolbox>
% Register globals
global bindb_data;
if isfield(bindb_data, 'Settings')
% Launch gui
bindb_gui();