Commit 9b2df9f3 authored by Michael Kohnen's avatar Michael Kohnen

Actualised metadata handling in itaHRTF, updated ambisonics and loudspeaker positions in VRLab

parent 7987fe99
......@@ -410,6 +410,8 @@ classdef itaHRTF < itaAudio
else
datatype='float';
end
case 'int32'
datatype='int';
end
metadata=daffv17_add_metadata(metadata,cell2mat(names(k)),datatype,tempMetadata.(names{k}));
end
......
......@@ -14,23 +14,26 @@ opts.heightCorrection = 0.0597; % in meter || ensures that the louds
opts=ita_parse_arguments(opts, varargin);
hc=opts.heightCorrection;
% X Y Z (openGL)
pos = itaCoordinates(zeros(12,3));
pos.r= 2.28;
pos.phi_deg=[45 315 225 135 0 270 180 90 0 270 180 90];
pos.theta_deg=[88.5 88.5 88.5 88.5 60 60 60 60 118 118 118 118];
pos.z=pos.z-hc;
if opts.virtualSpeaker
pos = [pos;...
0 0+hc 0;... % virtual speaker
0 3+hc 0]; % virtual speaker
pos.cart = [pos.cart;...
0 0 -2.3;... % virtual speaker
0 0 2.3]; % virtual speaker
end
if strcmp(opts.coordSystem,'openGL')
pos = ita_matlab2openGL(pos);
% Correction of head height
pos.z=pos.z-opts.heightCorrection;
if strcmpi(opts.coordSystem,'opengl')
pos.cart = ita_matlab2openGL(pos);
end
if (~opts.isItaCoordinates)
......
function [ loudspeakerSignals ] = ita_decodeAmbisonics( Bformat, LoudspeakerPos, varargin )
function [ OutputSignals ] = ita_decodeAmbisonics( Bformat, LoudspeakerPos, varargin )
%ITA_DECODEAMBISONICS Summary of this function goes here
% Detailed explanation goes here
......@@ -6,9 +6,9 @@ opts.decoding='remax'; % Decoding strategy (remax,inphase,plane)
opts = ita_parse_arguments(opts,varargin);
% Initializing further parameters
nmax=numel(Bformat);
nmax=max(Bformat.nChannels);
N=floor(sqrt(nmax)-1);
% Weighting for Inphase/ReMax
g_re=ones(nmax,1); %init weighting factors for ReMax
......@@ -23,7 +23,8 @@ if(sum(strcmp(lower(opts.decoding),{'remax' 'both'})))
% g_m=P_m(r_E) with n=0 for P
% r_E is largest root of P_(order+1)
syms x;
f=1/2^(TheOrder+1)/factorial(TheOrder+1)*diff(((x^2-1)^(TheOrder+1)),(TheOrder+1));%Legendre Polynom n=0 m=order+1
f=1/2^(N+1)/factorial(N+1)*diff(((x^2-1)^(N+1)),(N+1));%Legendre Polynom n=0 m=order+1
maxroot=max(eval(solve(f))); %find maximum root(Nullstelle)
for k=1:nmax
leggie=legendre(ita_sph_linear2degreeorder(k),abs(maxroot)); % g_m=P_m(r_E)
......@@ -35,41 +36,52 @@ end
% Inphase Decoding
if(sum(strcmp(lower(opts.decoding),{'inphase' 'both'})))
% Calculates the B-format channel weights for InPhase-Decoding
TheOrder = obj.ambGetOrder; % amb order from sim room
nmax = (TheOrder+1)^2; % number of channels
N = obj.ambGetOrder; % amb order from sim room
nmax = (N+1)^2; % number of channels
weightsInPhase=zeros(nmax,1);
N=numel(obj.monitorRoom.getSourcePosition)/3;% get number of loudspeaker
%Dissertation J.Daniel p.314, 'preserve Energy' in 0. order
%g_0=sqrt[N*(2*M+1)/(M+1)^2]
weightsInPhase(1)=sqrt(N*(2*TheOrder+1)/(TheOrder+1)^2);
weightsInPhase(1)=sqrt(N*(2*N+1)/(N+1)^2);
for k=2:nmax
m=ita_sph_linear2degreeorder(k);
% Dissertation J.Daniel p.314
% g_m=M!*(M+1)!/[(M+m+1)!*(M-n)!]
weightsInPhase(k)=factorial(TheOrder)*factorial(TheOrder+1)/factorial(m+TheOrder+1)/factorial(TheOrder-m);
weightsInPhase(k)=factorial(N)*factorial(N+1)/factorial(m+N+1)/factorial(N-m);
end
g_in=weightsInPhase;
end
weights=g_in.*g_re; %merge weighting factors
for k=1:numel(weights)
if isa(Bformat,'itaAudio')
for k=1:Bformat.nChannels
Bformat.time(:,k)=Bformat.time(:,k).*weights(k);
end
else
for k=1:numel(weights)
Bformat(:,k)=weights(k).*Bformat(:,k); %Apply weighting factors
end
end
% SH and inversion
Y = ita_sph_base(LS, TheOrder, 'real'); % generate basefunctions
Y = ita_sph_base(LoudspeakerPos, N, 'real'); % generate basefunctions
Yinv=pinv(Y); % calculate Pseudoinverse
if isa(Bformat,'itaAudio')
for k=1:LS.nPoints
OutputSignals(k)=sum(Bformat*Yinv(:,k)');
for k=1:LoudspeakerPos.nPoints
for l=1:nmax
temp(l)=Bformat.ch(l)*Yinv(l,k);
end
OutputSignals(k)=sum(temp);
end
OutputSignals=ita_merge(OutputSignals(:));
else
OutputSignals=Bformat*Yinv;
end
OutputSignals.channelCoordinates=LoudspeakerPos;
end
function [ Bformat ] = ita_encodeAmbisonics( sourcePos, varargin )
%ITA_ENCODEAMBISONICS Summary of this function goes here
function [ audioOut ] = ita_encodeAmbisonics( audioIn, order, sourcePos )
%ITA_ENCODEAMBISONICS Encodes a itaAudio with channel coordinates or a
% itaCoordinate with source positions into ambisonics channels
%
% Detailed explanation goes here
if nargin<1
error('Source position is needed as itaCoordiantes!');
end
if ~isa(sourcePos,'itaCoordinates')
error('First input data has to be an itaCoordinates!')
elseif isempty(sourcePos.cart)
error('First input data has to be an itaCoordinates WITH inputdata!')
%% Init
if isa(audioIn, 'itaAudio')
aud=true;
elseif isa(audioIn, 'itaCoordinates')
aud=false;
sourcePos=audioIn;
if nargin>2
error('For itaCoordinates no additional source positions can be given!');
end
else
error('itaAudio or itaCoordinates has to be the first input!');
end
opts.order=1; %Ambisonics truncation order
opts.audioSource=''; %Signal of the source (itaAudio or filename)
opts = ita_parse_arguments(opts, varargin);
% Encode Source
Bformat = ita_sph_base(sourcePos, opts.order, 'real');
if nargin<2
warning('SH Truncation order missing, assuming order of one');
order=1;
end
if ~isempty(opts.audioSource)
if isa(opts.audioSource,'char')
audioIn = ita_read(opts.audioSource);
elseif isa(opts.audioSource,'itaAudio')
audioIn = opts.audioSource;
elseif ~isa(audioIn,'itaAudio')
error('Audio input must eihter be itaAudio or valid filename (see ita_read)');
end
audioOut=audioIn*Bformat(1);
for k=2:numel(Bformat)
audioOut=ita_merge(audioOut,audioIn*Bformat(k));
if nargin<3 && aud
sourcePos=audioIn.channelCoordinates;
if sourcePos.nPoints<1 || ~isa(sourcePos,'itaCoordinates')
error('No sourcePos found or it is not itaCoordinates! Add channelCoordinates to itaAudio!')
end
Bformat=audioOut;
end
%% Encode Source
if ~aud
audioOut=ita_sph_base(sourcePos, order, 'real');
end
%% Applying audio data
if aud
audioOut=itaAudio;
audioOut_temp=itaAudio;
for idxCh=1:audioIn.nChannels
Bformat = ita_sph_base(sourcePos(idxCh), order, 'real');
for idxCoeff=1:numel(Bformat)
audioOut_temp(idxCoeff)=audioIn.ch(idxCh)*Bformat(idxCoeff);
end
if idxCh==1
audioOut=ita_merge(audioOut_temp);
else
audioOut=audioOut+ita_merge(audioOut_temp);
end
end
end
\ No newline at end of file
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