WIP

parent a8fc0fb2
......@@ -65,9 +65,16 @@ namespace ITAPropagationModels
float fSpeedOfSound = ITAConstants::DEFAULT_SPEED_OF_SOUND_F;
} oEnvironmentState; //!< Environment state
enum EAtmoshpericAbsorption
{
NONE = -1,
ISO9613,
};
//! Propagation model configuration description
struct PropagationModelConfiguration
{
int iAtmosphericAbsorption = EAtmoshpericAbsorption::ISO9613;
int iDiffractionModel = DiffractionModels::MAEKAWA_DETOUR_LAW;
} oPropagationModelConfiguration; //!< Propagation model configuration
......@@ -110,6 +117,8 @@ namespace ITAPropagationModels
* @todo AER
*/
void Generate(const ITAGeo::CPropagationPathList& oPathList, ITABase::CHDFTSpectra& oFilter, bool* pbDFTDegreeTooSmall = NULL);
//! Generate single propagation path (for multi-channel receiver directivity)
inline void Generate(const ITAGeo::CPropagationPath& oPath, ITABase::CHDFTSpectra& oFilter, bool* pbDFTDegreeTooSmall = NULL)
{
ITAGeo::CPropagationPathList oPathList;
......
......@@ -191,27 +191,31 @@ void CFilterEngine::Generate(const ITAGeo::CPropagationPathList & oPathList, ITA
m_pAccumulatedSpectra = make_unique<ITABase::CHDFTSpectra>((float)oHDFTSpectra.GetSampleRate(), oHDFTSpectra.GetNumChannels(), oHDFTSpectra.GetDFTSize(), true);
// Domain-specific temporary variables
double dScalarMagnitude; //For the combination of all scalar filter components
ITABase::CThirdOctaveFactorMagnitudeSpectrum oThirdOctFactors; // For the combination of all third octave filter components
oThirdOctFactors.SetIdentity();
ITABase::CFiniteImpulseResponse oIR(oHDFTSpectra.GetDFTSize(), (float)oHDFTSpectra.GetSampleRate(), false);
for (auto& oPath : oPathList)
{
//Path length
double dPathLength = oPath.GetLength();
const double dPathLength = oPath.GetLength();
if (dPathLength == 0.0f)
ITA_EXCEPT_INVALID_PARAMETER("Encountered a path with no geometrical distance, could not generate filter");
//Include sound energy decrease due to the length of the path @todo this might get more complex with diffraction
dScalarMagnitude = 1 / dPathLength;
// Air attenuation according to ISO9613-1 (overrides third octaves, so no resetting required, do not change order!)
ITABase::ISO9613::AtmosphericAbsorption(oThirdOctFactors, (float)dPathLength, oEnvironmentState.dTemperature, oEnvironmentState.dHumidity);
if( oPropagationModelConfiguration.iAtmosphericAbsorption == EAtmoshpericAbsorption::ISO9613 )
{
// Air attenuation according to ISO9613-1 (overrides third octaves, so no resetting required, do not change order!)
ITABase::ISO9613::AtmosphericAbsorption(oThirdOctFactors, (float)dPathLength, oEnvironmentState.dTemperature, oEnvironmentState.dHumidity);
// Multiply the transmissionfactor of the air attenuation alpha: sqrt(1-|alpha|)
for (int iFrequencyIndex = 0; iFrequencyIndex < oThirdOctFactors.GetNumBands(); iFrequencyIndex++)
oThirdOctFactors[iFrequencyIndex] *= sqrt(1 - abs(oThirdOctFactors[iFrequencyIndex]));
// Multiply the transmissionfactor of the air attenuation alpha: sqrt(1-|alpha|)
for (int iFrequencyIndex = 0; iFrequencyIndex < oThirdOctFactors.GetNumBands(); iFrequencyIndex++)
oThirdOctFactors[iFrequencyIndex] *= sqrt(1 - abs(oThirdOctFactors[iFrequencyIndex]));
}
// Process path and assemble filter components domain by domain
......@@ -230,8 +234,9 @@ void CFilterEngine::Generate(const ITAGeo::CPropagationPathList & oPathList, ITA
if (pEmitter->pDirectivity)
{
const VistaVector3D v3Dir(pNextAnchor->v3InteractionPoint - pEmitter->v3InteractionPoint);
ITAGeo::Coordinates::CSpherical oDirection(v3Dir, m_iCoordinateSystemConvention);
const VistaVector3D v3DirGlobalCS(pNextAnchor->v3InteractionPoint - pEmitter->v3InteractionPoint);
const VistaVector3D v3DirLocalCS = pEmitter->qOrient.GetInverted().Rotate( v3DirGlobalCS );
ITAGeo::Coordinates::CSpherical oDirection( v3DirLocalCS, m_iCoordinateSystemConvention );
switch (pEmitter->pDirectivity->GetFormat())
{
case(ITAGeo::Directivity::IDirectivity::OPENDAFF):
......@@ -245,19 +250,21 @@ void CFilterEngine::Generate(const ITAGeo::CPropagationPathList & oPathList, ITA
}
}
}
break;
}
case(ITAGeo::CPropagationAnchor::ACOUSTIC_SENSOR):
{
auto pSensor = std::dynamic_pointer_cast<const ITAGeo::CSensor>(pAnchor);
if (i > 0)
if (i == 0)
ITA_EXCEPT_INVALID_PARAMETER("Propagation path invalid: detected a sensor anchor point at the beginning of the path (without a predecessor).");
auto pPreviousAnchor(oPath[i - 1]);
if (pSensor->pDirectivity)
{
const VistaVector3D v3Dir(pPreviousAnchor->v3InteractionPoint - pSensor->v3InteractionPoint);
ITAGeo::Coordinates::CSpherical oDirection(v3Dir, m_iCoordinateSystemConvention);
const VistaVector3D v3DirGlobalCS( pPreviousAnchor->v3InteractionPoint - pSensor->v3InteractionPoint );
const VistaVector3D v3DirLocalCS = pSensor->qOrient.GetInverted().Rotate( v3DirGlobalCS );
ITAGeo::Coordinates::CSpherical oDirection( v3DirLocalCS, m_iCoordinateSystemConvention );
switch (pSensor->pDirectivity->GetFormat())
{
case(ITAGeo::Directivity::IDirectivity::OPENDAFF):
......@@ -271,16 +278,13 @@ void CFilterEngine::Generate(const ITAGeo::CPropagationPathList & oPathList, ITA
else if (pDAFFDirectivity->GetDomain() == ITADomain::ITA_TIME_DOMAIN)
{
auto pDAFFDirectivityIR = std::dynamic_pointer_cast<const ITAGeo::Directivity::CDAFF_ImpulseResponse>(pSensor->pDirectivity);
// @todo jst
/*
pDAFFDirectivityIR->GetNearestNeighbourImpulseResponse(oDirection, oIR);
*/
}
}
//case(ITAGeo::Directivity::IDirectivity::???):
}
}
break;
}
case(ITAGeo::CPropagationAnchor::SPECULAR_REFLECTION):
{
......@@ -298,6 +302,7 @@ void CFilterEngine::Generate(const ITAGeo::CPropagationPathList & oPathList, ITA
oThirdOctFactors[j] *= pThirdOctaveMaterial->GetTransmissionFactor(j);
}
}
break;
}
}
}
......
......@@ -39,7 +39,7 @@ int main( int, char** )
auto pSenderLeft = make_shared< CEmitter >(VistaVector3D(-2.0f, 0.0f, 0.0f));
auto pSenderRight = make_shared< CEmitter >(VistaVector3D(2.0f, 0.0f, 0.0f));
shared_ptr< Directivity::CDAFF_ImpulseResponse > pHRIR = make_shared< Directivity::CDAFF_ImpulseResponse >();
auto pHRIR = make_shared< Directivity::CDAFF_ImpulseResponse >();
pHRIR->LoadFromFile("ITA_Artificial_Head_5x5_44kHz_128.v17.ir.daff");
auto pReceiver = make_shared< CSensor >(VistaVector3D(0.0f, 0.0f, 0.0f));
......
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