Commit 2b37d8b0 authored by Michael Kohnen's avatar Michael Kohnen
Browse files

Ambisonics Encoder running and tested

parent fedaaee3
......@@ -6,17 +6,17 @@
[Output:VRLAB_LS_ALL]
Description = ITA VRLab setup using all available broadband loudspeaker (O300 & O110)
Enabled = false
Devices = LS_FL, LS_FR, LS_RL, LS_RR, LS_TF, LS_TR, LS_TB, LS_TL, LS_BF, LS_BR, LS_BB, LS_BL
Devices = LS_FL, LS_FR, LS_RR, LS_RL, LS_TF, LS_TR, LS_TB, LS_TL, LS_BF, LS_BR, LS_BB, LS_BL
[Output:VRLAB_VLS_ALL]
Description = ITA VRLab setup using all available broadband loudspeaker (O300 & O110)
Enabled = false
Devices = LS_FL, LS_FR, LS_RL, LS_RR, LS_TF, LS_TR, LS_TB, LS_TL, LS_BF, LS_BR, LS_BB, LS_BL, LS_VU, LS_VD
Enabled = true
Devices = LS_FL, LS_FR, LS_RR, LS_RL, LS_TF, LS_TR, LS_TB, LS_TL, LS_BF, LS_BR, LS_BB, LS_BL, LS_VU, LS_VD
[Output:VRLAB_LS_HORIZONTAL]
Description = ITA VRLab setup using loudspeaker ring in horizontal plane at user's head elevation
Enabled = true
Devices = LS_FL, LS_FR, LS_RL, LS_RR
Devices = LS_FL, LS_FR, LS_RR, LS_RL
[Output:VRLAB_LS_STEREO]
Description = ITA VRLab simple stereo setup
......
......@@ -1093,14 +1093,6 @@ void CVAAmbisonicsFreeFieldAudioRenderer::UpdateSoundPaths()
pPath->oDirectivityStateNew.pData = (IVADirectivity*)pSourceNew->GetDirectivityData();
}
/*if (pListenerNew == nullptr)
{
pPath->oHRIRStateNew.pData = nullptr;
}
else
{
pPath->oHRIRStateNew.pData = (IVAHRIRDataset*)pListenerNew->GetHRIRDataset();
}*/
}
return;
......@@ -1123,37 +1115,11 @@ CVAAFFSoundPath::CVAAFFSoundPath(double dSamplerate, int iBlocklength, int iDirF
{
pThirdOctaveFilterBank = CITAThirdOctaveFilterbank::Create(dSamplerate, iBlocklength,
CITAThirdOctaveFilterbank::FIR_SPLINE_LINEAR_PHASE);
//CVAThirdOctaveFilterbank::IIR_BIQUADS_ORDER10 );
pThirdOctaveFilterBank->SetIdentity();
float fReserverdMaxDelaySamples = (float)(3 * dSamplerate); // 3 Sekunden ~ 1km Entfernung
m_iDefaultVDLSwitchingAlgorithm = CITAVariableDelayLine::LINEAR_INTERPOLATION;
pVariableDelayLineCh = new CITAVariableDelayLine(dSamplerate, iBlocklength, fReserverdMaxDelaySamples, m_iDefaultVDLSwitchingAlgorithm);
//pVariableDelayLineChR = new CVAVariableDelayLine(dSamplerate, iBlocklength, fReserverdMaxDelaySamples, m_iDefaultVDLSwitchingAlgorithm);
/*pFIRConvolverCh = new DSMBCConvolver(iBlocklength, iHRIRFilterLength);
pFIRConvolverCh->setFilterExchangeMode(DSMBCConvolver::CROSSFADE_COSINE_SQUARE);
pFIRConvolverCh->setFilterCrossfadeLength((std::min)(iBlocklength, 32));
pFIRConvolverCh->setGain(0.0f, true);
DSMBCFilter* pHRIRFilterChL = pFIRConvolverCh->requestFilter();
pHRIRFilterChL->identity();
pFIRConvolverCh->exchangeFilter(pHRIRFilterCh);
pFIRConvolverChR = new DSMBCConvolver(iBlocklength, iHRIRFilterLength);
pFIRConvolverChR->setFilterExchangeMode(DSMBCConvolver::CROSSFADE_COSINE_SQUARE);
pFIRConvolverChR->setFilterCrossfadeLength((std::min)(iBlocklength, 32));
pFIRConvolverChR->setGain(0.0f, true);
DSMBCFilter* pHRIRFilterChR = pFIRConvolverChR->requestFilter();
pHRIRFilterChR->identity();
pFIRConvolverChL->exchangeFilter(pHRIRFilterChR);
// Auto-release filter after it is not used anymore
pFIRConvolverChL->releaseFilter(pHRIRFilterChL);
pFIRConvolverChR->releaseFilter(pHRIRFilterChR);
m_sfHRIRTemp.init(2, iHRIRFilterLength, false);
*/
}
CVAAFFSoundPath::~CVAAFFSoundPath()
......@@ -1240,96 +1206,6 @@ double CVAAFFSoundPath::CalculateInverseDistanceDecrease() const
return fInverseDistanceDecrease;
}
/*void CVAAFFSoundPath::UpdateHRIR(const CVAListenerState::CVAAnthropometricParameter& oAnthroParameters)
{
IVAHRIRDataset* pHRIRDataNew = oHRIRStateNew.pData;
bool bForeUpdate = false;
if (pHRIRDataNew != nullptr)
{
// Quick check if nearest neighbour is equal
if (pHRIRDataNew->GetProperties()->bSpaceDiscrete)
pHRIRDataNew->GetNearestNeighbour(float(oRelations.dAzimuthL2S), float(oRelations.dElevationL2S), &oHRIRStateNew.iRecord);
else
bForeUpdate = true; // Update always required, if non-discrete data
}
if ((oHRIRStateCur != oHRIRStateNew) || bForeUpdate)
{
DSMBCFilter* pHRIRFilterChL = pFIRConvolverChL->getFilterPool()->requestFilter();
DSMBCFilter* pHRIRFilterChR = pFIRConvolverChR->getFilterPool()->requestFilter();
if (pHRIRDataNew == nullptr)
{
pHRIRFilterChL->identity();
pHRIRFilterChR->identity();
}
else
{
int iNewFilterLength = pHRIRDataNew->GetProperties()->iFilterLength;
if (m_sfHRIRTemp.length() != iNewFilterLength)
{
m_sfHRIRTemp.init(2, iNewFilterLength, false);
}
if (iNewFilterLength > pFIRConvolverChL->getMaxFilterlength())
{
VA_WARN("CVAAFFSoundPath", "HRIR too long for convolver, cropping. Increase HRIR filter length in AmbisonicsFreefieldAudioRenderer configuration.");
iNewFilterLength = pFIRConvolverChL->getMaxFilterlength();
}
if (pHRIRDataNew->GetProperties()->bSpaceDiscrete)
{
pHRIRDataNew->GetHRIRByIndex(&m_sfHRIRTemp, oHRIRStateNew.iRecord, float(oRelations.dDistance));
oHRIRStateNew.fDistance = float(oRelations.dDistance);
}
else
{
pHRIRDataNew->GetHRIR(&m_sfHRIRTemp, float(oRelations.dAzimuthL2S),
float(oRelations.dElevationL2S), float(oRelations.dDistance));
}
pHRIRFilterChL->load(m_sfHRIRTemp[0].data(), iNewFilterLength);
pHRIRFilterChR->load(m_sfHRIRTemp[1].data(), iNewFilterLength);
}
pFIRConvolverChL->exchangeFilter(pHRIRFilterChL);
pFIRConvolverChR->exchangeFilter(pHRIRFilterChR);
pFIRConvolverChL->releaseFilter(pHRIRFilterChL);
pFIRConvolverChR->releaseFilter(pHRIRFilterChR);
// Ack
oHRIRStateCur = oHRIRStateNew;
}
double dITDCorrectionShift = .0f;
if (pHRIRDataNew)
{
// Calculate individualized ITD based on anthropometric data
// Source: ???
double daw = -8.7231e-4;
double dbw = 0.0029;
double dah = -3.942e-4;
double dbh = 6.0476e-4;
double dad = 4.2308e-4;
double dbd = oAnthroParameters.GetHeadDepthParameterFromLUT(oAnthroParameters.dHeadDepth);
double dDeltaWidth = oAnthroParameters.dHeadWidth - pHRIRDataNew->GetProperties()->oAnthroParams.dHeadWidth;
double dDeltaHeight = oAnthroParameters.dHeadHeight - pHRIRDataNew->GetProperties()->oAnthroParams.dHeadHeight;
double dDeltaDepth = oAnthroParameters.dHeadDepth - pHRIRDataNew->GetProperties()->oAnthroParams.dHeadDepth;
double dPhiRad = oRelations.dAzimuthL2S * ITAConstants::PI_F / 180.0;
double dThetaRad = -(oRelations.dElevationL2S * ITAConstants::PI_F / 180.0 - ITAConstants::PI_F / 2.0f);
double dAmplitude = dPhiRad * (dDeltaWidth * (dThetaRad * dThetaRad * daw + dThetaRad * dbw) + dDeltaHeight * (dThetaRad * dThetaRad * dah + dThetaRad * dbh) + dDeltaDepth * (dThetaRad * dThetaRad * dad + dThetaRad * dbd));
dITDCorrectionShift = std::sin(dPhiRad) * dAmplitude;
}
// Apply individualized delay
float fPreviousDelayTimeL = pVariableDelayLineChL->GetNewDelayTime();
float fPreviousDelayTimeR = pVariableDelayLineChR->GetNewDelayTime();
pVariableDelayLineChL->SetDelayTime(fPreviousDelayTimeL - float(dITDCorrectionShift));
pVariableDelayLineChR->SetDelayTime(fPreviousDelayTimeR + float(dITDCorrectionShift));
return;
}
*/
int CVAAmbisonicsFreeFieldAudioRenderer::CallObject(const CVAStruct& oArgs, CVAStruct& oReturn)
{
oReturn.Clear();
......@@ -1429,14 +1305,14 @@ std::vector<double> CVAAmbisonicsFreeFieldAudioRenderer::vdRealvalued_basefuncti
{
std::vector<double> Y;
Y.resize((maxOrder+1)*(maxOrder+1));
Y=dAssociateLegendre(maxOrder,cos(elevation));
Y = dAssociateLegendre(maxOrder, cos(elevation / 180 * 3.14159265359));
for (int n=0;n<=maxOrder;n++)
{
for (int m=1;m<=n;m++)
{
Y[GetIndex(m,n)]*=cos(m*azimuth);
Y[GetIndex(-m,n)]*=sin(m*azimuth);
Y[GetIndex(m,n)]*=cos(m*azimuth/180*3.14159265359);
Y[GetIndex(-m, n)] *= sin(m*azimuth / 180 * 3.14159265359);
}
}
return Y;
......@@ -1444,13 +1320,13 @@ std::vector<double> CVAAmbisonicsFreeFieldAudioRenderer::vdRealvalued_basefuncti
double CVAAmbisonicsFreeFieldAudioRenderer::dNormalizeConst(int m, int n)
{
if (m%2)
if (m%2==1)
double Res=-1;
else
double Res=1;
return sqrt((2*n+1) * (2-iKronecker(m)) * iFactorial(n-m) / (4*3.141592565359*iFactorial(n+m)) );
return sqrt((2*n+1) * (2-iKronecker(m)) * factorial(n-m) / (4*3.141592565359*factorial(n+m)) );
}
int CVAAmbisonicsFreeFieldAudioRenderer::iKronecker(int m)
......@@ -1463,36 +1339,46 @@ int CVAAmbisonicsFreeFieldAudioRenderer::iKronecker(int m)
std::vector<double> CVAAmbisonicsFreeFieldAudioRenderer::dAssociateLegendre(int N, double mu)
{
double dN = 0;
std::vector<double> P;
P.resize((N+1)*(N+1));
P[0]=1.0*dNormalizeConst(0,0);
for (int n=1; n<N; n++)
P[0] = 1.0;// *dNormalizeConst(0, 0);
for (int n=1; n<=N; n++)
{
P[GetIndex(n,n)]=(-(2*n-1)*P[GetIndex((n-1),(n-1))]*sqrt(1-(mu*mu)))*dNormalizeConst(n,n);
dN = dNormalizeConst(n, n);
P[GetIndex(n, n)] = (-(2 * n - 1)*P[GetIndex((n - 1), (n - 1))] * sqrt(1 - (mu*mu)));// *dN;
if(n>1)
if(n>=1)
{
P[GetIndex(n-1,n)]=(-( (2*n) - 1 )*mu*P[GetIndex(n-1,n-1)])*dNormalizeConst(n-1,n); //m-ter Grad
if(n>2)
dN = dNormalizeConst(n - 1, n);
P[GetIndex(n - 1, n)] = (-((2 * n) - 1)*mu*P[GetIndex(n - 1, n - 1)]);// *dN; //m-ter Grad
if(n>=2)
{
for (int m=0; m<(n-2); m++)
{
P[GetIndex(m,n)]=1/(n-m)*(2*n-1)*mu*P[GetIndex(m,n-1)]-(n+m-1)*P[GetIndex(m,n-2)]*dNormalizeConst(m,n);
dN = dNormalizeConst(m, n);
P[GetIndex(m, n)] = 1 / (n - m)*(2 * n - 1)*mu*P[GetIndex(m, n - 1)] - (n + m - 1)*P[GetIndex(m, n - 2)];// *dN;
}
}
}
for (int m=1; m<=n; m++)
{
P[GetIndex(-m,n)]=P[GetIndex(m,n)];
P[GetIndex(-m, n)] = P[GetIndex(m, n)];
}
}
for (int n = 0; n < (N+1); n++)
{
P[GetIndex(0, n)] *= dNormalizeConst(0, n);
for (int m = 1; m <= n; m++)
{
P[GetIndex(m, n)] *= dNormalizeConst(m, n);
P[GetIndex(-m, n)] = P[GetIndex(m, n)];
}
}
return P;
}
int CVAAmbisonicsFreeFieldAudioRenderer::iFactorial(int in)
{
return factorial(in);
}
int CVAAmbisonicsFreeFieldAudioRenderer::GetIndex(int m, int n)
{
......
Supports Markdown
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