Commit 8fa0729c authored by Armin Erraji's avatar Armin Erraji

Added function Generate() (work in process) as well as functions...

Added function Generate() (work in process) as well as functions ApplyEmitterModel() and ApplySensorModel().
parent f0d68036
......@@ -82,6 +82,20 @@ namespace ITAPropagationModels
*/
void ApplyReflectionModel( ITAGeo::CPropagationPathList& oPathList, int iModel = -1 );
//!Applies emitter models
/**
* @param[out] oPathList Propagation path list
* @param[in] iModel Acoustic material model type. If value is set to -1, the default material model is used.
*/
void ApplyEmitterModel(ITAGeo::CPropagationPathList& oPathList, int iModel = -1);
//!Applies sensor models
/**
* @param[out] oPathList Propagation path list
* @param[in] iModel Acoustic material model type. If value is set to -1, the default material model is used.
*/
void ApplySensorModel(ITAGeo::CPropagationPathList& oPathList, int iModel = -1);
void ApplyTransmissionModel( ITAGeo::CPropagationPathList& oPathList, int iModel = -1 ); // @todo
//! Generate multi-channel propagation path (for multi-channel receiver directivitiy)
......@@ -103,13 +117,23 @@ namespace ITAPropagationModels
unique_ptr<ITABase::CHDFTSpectra> m_pAccumulatedSpectra; //!< Gathered propagation paths from list
unique_ptr<ITABase::CHDFTSpectra> m_pTempPropPathSpectra; //!< Single prop-path spectra
static struct m_DefaultModels //!< Default values
static struct m_DefaultValues //!< Default values
{
static const int iReflectionModel = ITAGeo::IAcousticMaterial::SCALAR;
static const int iDiffractionModel = ITAGeo::IAcousticMaterial::THIRD_OCTAVE;
static const int iEmitterModel = ITAGeo::IAcousticMaterial::SCALAR;
static const int iSensorModel = ITAGeo::IAcousticMaterial::SCALAR;
};
const float m_fSpeedOfSound = 344.0f;
const float m_fSampleRate = 44.1e3;
const int m_iFilterLength = 64;
static struct m_DefaultDiffractionModel //!< Default values for diffractions
{
int iModel = 1;
......
......@@ -13,6 +13,11 @@
#include <stdio.h>
#include "..\..\include\ITAPropagationModels\FilterEngine.h"
//Spline
#include <spline.h>
using namespace ITAPropagationModels;
CFilterEngine::CFilterEngine()
......@@ -27,7 +32,7 @@ int CFilterEngine::GetNumSensorChannels(const ITAGeo::CPropagationPathList& oPat
{
//Check for correct structur of oPathList
if(!HasSameSensorAnchor(oPathList))
ITA_EXCEPT1(INVALID_PARAMETER, "The propagation path list has more than multiple sensor anchors or last anchor of paths is not a sensor.");
ITA_EXCEPT1(INVALID_PARAMETER, "The propagation path list has multiple sensor anchors or last anchor of paths is not a sensor.");
//Cast the sensor that is always the last propagation anchor of a path
auto pSensor = std::dynamic_pointer_cast<ITAGeo::CSensor>(oPathList[0][oPathList[0].size() - 1]);
......@@ -45,7 +50,7 @@ bool CFilterEngine::HasSameSensorAnchor(const ITAGeo::CPropagationPathList& oPat
{
if (oPath[oPath.size() - 1]->iAnchorType == ITAGeo::CPropagationAnchor::ACOUSTIC_SENSOR)
{
if (pSensor = nullptr)
if (pSensor == nullptr)
pSensor = std::dynamic_pointer_cast<ITAGeo::CSensor>(oPath[oPath.size() - 1]);
else if (pSensor != oPath[oPath.size() - 1])
return false; // not the same sensor
......@@ -62,11 +67,18 @@ bool CFilterEngine::HasSameSensorAnchor(const ITAGeo::CPropagationPathList& oPat
void CFilterEngine::ApplyAcousticModels(ITAGeo::CPropagationPathList & oPathList)
{
//Apply emitter model
ApplyEmitterModel(oPathList);
//Apply reflection model
ApplyReflectionModel(oPathList);
//Apply diffraction model
ApplyDiffractionModel(oPathList);
//Apply sensor model
ApplySensorModel(oPathList);
}
void CFilterEngine::ApplyDiffractionModel(ITAGeo::CPropagationPathList & oPathList, int iModel)
......@@ -85,7 +97,7 @@ void CFilterEngine::ApplyDiffractionModel(ITAGeo::CPropagationPathList & oPathLi
{
auto pApex = std::dynamic_pointer_cast<ITAGeo::CITADiffractionWedgeAperture>(pCurrentAnchor);
if (m_DefaultModels::iDiffractionModel == ITAGeo::IAcousticMaterial::THIRD_OCTAVE)
if (m_DefaultValues::iDiffractionModel == ITAGeo::IAcousticMaterial::THIRD_OCTAVE)
{
auto pAcousticMaterial = make_shared<ITAGeo::CThirdOctaveMaterial>();
......@@ -97,8 +109,10 @@ void CFilterEngine::ApplyDiffractionModel(ITAGeo::CPropagationPathList & oPathLi
{
const float fWaveNumberRad = 2.0f * ITAConstants::PI_F * fFrequency / 344.0; //TODO: Change speed of sound value
complex <float> cfDiffractionCoeff;
UTD::CalculateDiffractionCoefficient(pLastAnchor->v3InteractionPoint, pNextAnchor->v3InteractionPoint, pApex, fWaveNumberRad, cfDiffractionCoeff);
UTD::CalculateDiffractionCoefficient(pLastAnchor->v3InteractionPoint, pNextAnchor->v3InteractionPoint, pApex, fWaveNumberRad, cfDiffractionCoeff, UTD::UTD_APPROX_KAWAI_KOUYOUMJIAN);
//TODO:delete just for testing
cfDiffractionCoeff = 0.7;
vfAbsorptionCoeffs.push_back(1.0f - abs(cfDiffractionCoeff));
}
......@@ -124,17 +138,82 @@ void CFilterEngine::ApplyReflectionModel(ITAGeo::CPropagationPathList & oPathLis
//If the anchor is a reflection and the acoustic material is not set yet, set it to default values
if ((pAnchor->iAnchorType == ITAGeo::CPropagationAnchor::SPECULAR_REFLECTION) && (pAnchor->pAcousticMaterial == NULL))
{
if (m_DefaultModels::iReflectionModel == ITAGeo::IAcousticMaterial::SCALAR)
if (m_DefaultValues::iReflectionModel == ITAGeo::IAcousticMaterial::SCALAR)
{
//Set material with default values(current reflection factor: 0.7. See constructor of CScalarMaterial)
pAnchor->pAcousticMaterial = make_shared<ITAGeo::CScalarMaterial>();
}
else //if (m_DefaultModels::iReflectionModel == ITAGeo::IAcousticMaterial::THIRD_OCTAVE)
else //if (m_DefaultValues::iReflectionModel == ITAGeo::IAcousticMaterial::THIRD_OCTAVE)
{
ITA_EXCEPT_NOT_IMPLEMENTED;
}
}
}
}
}
void ITAPropagationModels::CFilterEngine::ApplyEmitterModel(ITAGeo::CPropagationPathList & oPathList, int iModel)
{
//Apply the emitter acoustic material. The emitter is always the first anchor of the propagation paths.
for (auto& oPath : oPathList)
{
//If the anchor is a reflection and the acoustic material is not set yet, set it to default values
if (oPath[0]->iAnchorType == ITAGeo::CPropagationAnchor::ACOUSTIC_EMITTER)
{
if (oPath[0]->pAcousticMaterial == NULL)
{
if (m_DefaultValues::iEmitterModel == ITAGeo::IAcousticMaterial::SCALAR)
{
//Set material with factor 1.0
auto pAcousticMaterial = make_shared<ITAGeo::CScalarMaterial>();
pAcousticMaterial->cdTransmissionFactor = 1.0f;
pAcousticMaterial->cdReflectionFactor = 0.0f;
oPath[0]->pAcousticMaterial = pAcousticMaterial;
}
else //TODO: add cases like if (m_DefaultValues::iEmitterModel == ITAGeo::IAcousticMaterial::THIRD_OCTAVE)
{
ITA_EXCEPT_NOT_IMPLEMENTED;
}
}
}
else
{
ITA_EXCEPT1(INVALID_PARAMETER, "The propagation paths must always start with an emitter anchor.");
}
}
}
void ITAPropagationModels::CFilterEngine::ApplySensorModel(ITAGeo::CPropagationPathList & oPathList, int iModel)
{
//Check for correct structur of oPathList
if (!HasSameSensorAnchor(oPathList))
ITA_EXCEPT1(INVALID_PARAMETER, "The propagation path list has multiple sensor anchors or last anchor of paths is not a sensor.");
//Because, the sensor is always the same anchor, only the first reference must be checked and eventually set
auto& oPath = oPathList[0];
//Apply the sensor acoustic material. The sensor is always the last anchor of the propagation paths
if (oPath[oPath.size() - 1]->pAcousticMaterial == NULL)
{
if (m_DefaultValues::iSensorModel == ITAGeo::IAcousticMaterial::SCALAR)
{
//Set material with factor 1.0
auto pAcousticMaterial = make_shared<ITAGeo::CScalarMaterial>();
pAcousticMaterial->cdTransmissionFactor = 1.0f;
pAcousticMaterial->cdReflectionFactor = 0.0f;
oPath[oPath.size() - 1]->pAcousticMaterial = pAcousticMaterial;
}
else //TODO: add cases like if (m_DefaultValues::iEmitterModel == ITAGeo::IAcousticMaterial::THIRD_OCTAVE)
{
ITA_EXCEPT_NOT_IMPLEMENTED;
}
}
}
......@@ -143,7 +222,91 @@ void CFilterEngine::ApplyTransmissionModel(ITAGeo::CPropagationPathList & oPathL
ITA_EXCEPT_NOT_IMPLEMENTED;
}
void CFilterEngine::Generate(const ITAGeo::CPropagationPathList & oPathList, ITABase::CHDFTSpectra & oFilter)
void CFilterEngine::Generate(const ITAGeo::CPropagationPathList & oPathList, ITABase::CHDFTSpectra & oHDFTSpectra)
{
//Check for correct structur of oPathList
if (!HasSameSensorAnchor(oPathList))
ITA_EXCEPT1(INVALID_PARAMETER, "The propagation path list has more than multiple sensor anchors or last anchor of paths is not a sensor.");
for (auto& oPath : oPathList)
{
//At first, combine all scalar filter components
float fScalarMagnitude = 1.0f;
for (auto& pAnchor : oPath)
{
if (pAnchor->pAcousticMaterial->GetType() == ITAGeo::IAcousticMaterial::SCALAR)
{
//Type cast of the acoustic material
auto pScalarMaterial = std::dynamic_pointer_cast<ITAGeo::CScalarMaterial>(pAnchor->pAcousticMaterial);
if(pAnchor->iAnchorType == ITAGeo::CPropagationAnchor::SPECULAR_REFLECTION)
fScalarMagnitude *= abs(pScalarMaterial->cdReflectionFactor);
else
fScalarMagnitude *= abs(pScalarMaterial->cdTransmissionFactor);
}
}
//Thereafter, combine all third octave filter components
vector<float> vfThirdOctMagnitudes;
for (auto& pAnchor : oPath)
{
if (pAnchor->pAcousticMaterial->GetType() == ITAGeo::IAcousticMaterial::THIRD_OCTAVE)
{
//Type cast of the acoustic material
auto pThirdOctaveMaterial = std::dynamic_pointer_cast<ITAGeo::CThirdOctaveMaterial>(pAnchor->pAcousticMaterial);
//At the first anchor with third octave material, set all start values to the prior calculated scalar magnitude
//The first and the last values are set to zero
if (vfThirdOctMagnitudes.size() == 0)
{
vfThirdOctMagnitudes.push_back(0.0f);
for (int i = 0; i < pThirdOctaveMaterial->GetNumBands();i++)
{
vfThirdOctMagnitudes.push_back(fScalarMagnitude);
}
vfThirdOctMagnitudes.push_back(0.0f);
}
//Multiply the scale values of the respective bands
for (int i = 0; i < pThirdOctaveMaterial->GetNumBands(); i++)
{
vfThirdOctMagnitudes[i+1] *= abs(1 - pThirdOctaveMaterial->oAbsorptionCoefficients[i]);
}
}
}
//Set the HDFT spectrum of the current path
ITABase::CHDFTSpectrum oHDFTSpectrum(oHDFTSpectra.GetSampleRate(), oHDFTSpectra.GetDFTSize(), true);
vector<float> vfDFTCoordinatesIn;
vector<complex<float>> vcfDFTSpectrum;
const int iDFTSize = oHDFTSpectrum.GetSize();
//Add zero, because the third octave spectrum doesn't contain 0 Hz
vfDFTCoordinatesIn.push_back(0);
//Get the corresponding DFT coordinates from the third octave coordinates
for (auto& fFreq : ITABase::CThirdOctaveGainMagnitudeSpectrum::GetCenterFrequencies())
{
vfDFTCoordinatesIn.push_back(fFreq*(iDFTSize - 1) / (oHDFTSpectra.GetSampleRate() / 2));
}
//Add iDFTSize-1, because the third octave spectrum doesn't contain the threshold value at the half samplerate
vfDFTCoordinatesIn.push_back(iDFTSize - 1);
//Get the DFT spectrum by spline interpolation and set them to the HDFTSpectrum object
for (int i = 0; i < iDFTSize; i++)
{
vcfDFTSpectrum.push_back(spline_b_val(vfDFTCoordinatesIn.size(), &vfDFTCoordinatesIn[0], &vfThirdOctMagnitudes[0], i));
oHDFTSpectrum.SetCoeff(i, vcfDFTSpectrum[i]);
}
m_pTempPropPathSpectra->
}
ITA_EXCEPT_NOT_IMPLEMENTED;
}
......@@ -3,3 +3,4 @@ cmake_minimum_required( VERSION 2.8 )
add_subdirectory( "Kirchhoff" )
add_subdirectory( "Svensson" )
add_subdirectory( "UTD" )
add_subdirectory( "FilterEngine" )
cmake_minimum_required( VERSION 2.8 )
project( ITAPropagationModelsTest )
list( APPEND CMAKE_MODULE_PATH "$ENV{VISTA_CMAKE_COMMON}" )
include( VistaCommon )
vista_use_package( ITABase REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITAPropagationModels REQUIRED FIND_DEPENDENCIES )
vista_use_package( ITAFFT REQUIRED FIND_DEPENDENCIES )
if( ITA_CORE_LIBS_BUILD_STATIC )
add_definitions( -DITA_BASE_STATIC )
endif( )
if( ITA_GEOMETRICAL_ACOUSTICS_BUILD_STATIC )
add_definitions( -DITA_PROPAGATION_MODELS_STATIC _DITA_PROPAGATION_PATH_SIM_STATIC -DITA_GEO_STATIC )
endif( )
add_executable( FilterEngineTest FilterEngineTest.cpp )
target_link_libraries( FilterEngineTest ${VISTA_USE_PACKAGE_LIBRARIES} )
vista_configure_app( FilterEngineTest )
vista_install( FilterEngineTest )
vista_create_default_info_file( FilterEngineTest )
set_property( TARGET FilterEngineTest PROPERTY FOLDER "ITAGeometricalAcoustics/Tests/ITAPropagationModels" )
/*
* ----------------------------------------------------------------
*
* ITA geometrical acoustics
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2018
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#include <ITAPropagationModels/FilterEngine.h>
#include <ITAGeo/Base.h>
using namespace std;
using namespace ITAConstants;
using namespace ITAGeo;
using namespace ITAPropagationModels;
int main(int, char**)
{
const float fSpeedOfSound = 344.0f;
const float fSampleRate = 44.1e3;
const int iFilterLength = 64;
// _______
// |___x___|
// / \
// s r
// \ /
// x______
// |______|
auto pSender = make_shared< CEmitter >(VistaVector3D(-2.0f, 0.0f, 0.0f));
auto pReceiver = make_shared< CSensor >(VistaVector3D(2.0f, 0.0f, 0.0f));
auto pReflection = make_shared< CSpecularReflection >(VistaVector3D(0.0f, 2.0f, 0.0f));
auto pDiffraction = make_shared< CITADiffractionWedgeAperture >();
pDiffraction->v3AperturePoint = VistaVector3D(0.0f, -2.0f, 0.0f);
pDiffraction->v3VertextStart = VistaVector3D(0.0f, -2.0f, 1.0f);
pDiffraction->v3VertextEnd = VistaVector3D(0.0f, -2.0f, -1.0f);
pDiffraction->v3MainWedgeFaceNormal = VistaVector3D(-1.0f, 0.0f, 0.0f);
pDiffraction->v3OppositeWedgeFaceNormal = VistaVector3D(0.0f, 1.0f, 0.0f);
auto pW = std::make_shared< CITADiffractionWedgeAperture >();
pW->v3AperturePoint.SetValues(0.0f, 1.0f, 0.0f);
pW->v3MainWedgeFaceNormal.SetValues(-1.0f, 1.0f, .0f);
pW->v3MainWedgeFaceNormal.Normalize();
pW->v3OppositeWedgeFaceNormal.SetValues(1.0f, 1.0f, .0f);
pW->v3OppositeWedgeFaceNormal.Normalize();
pW->v3VertextStart.SetValues(.0f, 1.0f, -1.0f);
pW->v3VertextEnd.SetValues(.0f, 1.0f, 1.0f);
CPropagationPath oPathReflection;
oPathReflection.push_back(pSender);
oPathReflection.push_back(pReflection);
oPathReflection.push_back(pReceiver);
CPropagationPath oPathDiffraction;
oPathDiffraction.push_back(pSender);
oPathDiffraction.push_back(pW);
oPathDiffraction.push_back(pReceiver);
CPropagationPathList oPathList;
oPathList.push_back(oPathReflection);
oPathList.push_back(oPathDiffraction);
CFilterEngine oFilter;
oFilter.ApplyAcousticModels(oPathList);
ITABase::CHDFTSpectra oSpectra(fSampleRate, pReceiver->iNumChannels, iFilterLength);
oFilter.Generate(oPathList, oSpectra);
}
\ 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