Skip to content
Snippets Groups Projects
Commit 740fea37 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Improving propagation models and extending filter engine with material manager

parent 31f3d4d4
No related branches found
No related tags found
No related merge requests found
......@@ -20,14 +20,12 @@ set( ITAPropagationModelsHeader
"include/ITAPropagationModels/Definitions.h"
"include/ITAPropagationModels/DiffractionFilter.h"
"include/ITAPropagationModels/FilterEngine.h"
"include/ITAPropagationModels/FilterGenerator.h"
"include/ITAPropagationModels/Maekawa.h"
"include/ITAPropagationModels/Svensson.h"
"include/ITAPropagationModels/UTD.h"
)
set( ITAPropagationModelsSources
"src/ITAPropagationModels/FilterEngine.cpp"
"src/ITAPropagationModels/FilterGenerator.cpp"
"src/ITAPropagationModels/Maekawa.cpp"
"src/ITAPropagationModels/Svensson.cpp"
"src/ITAPropagationModels/UTD.cpp"
......
......@@ -25,17 +25,18 @@
// ITA includes
#include <ITAGeo/Base.h>
#include <ITAGeo/Material//Manager.h>
#include <ITAHDFTSpectra.h>
#include <ITAHDFTSpectrum.h>
// STL includes
#include <vector>
namespace ITAPropagationModels
{
using namespace std;
//! Transfer function filter generator for propagation paths
/**
* Generates transfer functions in the frequency-domain that
......@@ -98,7 +99,7 @@ namespace ITAPropagationModels
void ApplyTransmissionModel( ITAGeo::CPropagationPathList& oPathList, int iModel = -1 ); // @todo
//! Generate multi-channel propagation path (for multi-channel receiver directivitiy)
//! Generate multi-channel propagation path (for multi-channel receiver directivity)
/**
* @todo AER
*/
......@@ -112,6 +113,12 @@ namespace ITAPropagationModels
Generate( oPathList, oTF );
};
//! Sets a connection to the material manager
void SetMaterialManager( const ITAGeo::CMaterialManager* pMaterialManager );
// Returns pointer to material manager or null
const ITAGeo::CMaterialManager* GetMaterialManager() const;
private:
unique_ptr<ITABase::CHDFTSpectra> m_pAccumulatedSpectra; //!< Gathered propagation paths from list
......@@ -128,7 +135,7 @@ namespace ITAPropagationModels
};
const ITAGeo::CMaterialManager* m_pMaterialManager;
const double m_dHumidity = 80.0;
const double m_dTemperature = 20.0;
......
/*
* ----------------------------------------------------------------
*
* ITA geometrical acoustics
* (c) Copyright Institute of Technical Acoustics (ITA)
* RWTH Aachen University, Germany, 2015-2018
*
* ----------------------------------------------------------------
* ____ __________ _______
* // / //__ ___/ // _ |
* // / // / // /_| |
* // / // / // ___ |
* //__/ //__/ //__/ |__|
*
* ----------------------------------------------------------------
*
*/
#ifndef INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_FILTER_GENERATOR
#define INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_FILTER_GENERATOR
#include "Base.h"
#include "Definitions.h"
#include "DiffractionFilter.h"
// ITA includes
#include <ITAGeo/Base.h>
#include <ITAHDFTSpectra.h>
#include <ITAHDFTSpectrum.h>
// STL includes
#include <vector>
namespace ITAPropagationModels
{
//! Transfer function filter generator for propagation paths
/**
* Generates transfer functions in the frequency-domain that
* can be used as filters, e.g. for auralization.
*/
class ITA_PROPAGATION_MODELS_API CTFGenerator
{
public:
//! Construct a generator with predetermined output channels, e.g. for binaural or SH filters
/**
* @param[in] iNumOutputChannels Number of output channels
* @param[in] iDFTSize Length of the DFT used to construct and combine filter components
* @param[in] fSamplingRate Filer sampling rate
*/
CTFGenerator( const int iNumOutputChannels, const int iDFTSize = 128, const float fSamplingRate = 44100.0f );
//! Cunstruct a generator with matching properties of a target spectrum
inline CTFGenerator( const ITABase::CHDFTSpectrum& pTransferFunction )
: CTFGenerator( 1, pTransferFunction.GetDFTSize(), pTransferFunction.GetSampleRate() )
{
};
//! Cunstruct a generator with matching properties of multi-channel target spectra
CTFGenerator( const ITABase::CHDFTSpectra& pTransferFunctions )
: CTFGenerator( pTransferFunctions.GetNumChannels(), pTransferFunctions.GetDFTSize(), pTransferFunctions.GetSampleRate() )
{
};
//! Generate a single-channel transfer function
inline void GenerateTF( ITABase::CHDFTSpectrum& pTransferFunction )
{
const std::vector< ITABase::CHDFTSpectrum* > vpSpectra = { &( pTransferFunction ) };
ITABase::CHDFTSpectra oTF( vpSpectra );
GenerateTF( oTF );
};
//! Generate a multi-channel transfer function
inline void GenerateTF( ITABase::CHDFTSpectra& pTransferFunctions );
private:
};
}
#endif // INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_FILTER_GENERATOR
#include <ITAPropagationModels/FilterGenerator.h>
#include <ITAPropagationModels/FilterEngine.h>
// ITA includes
#include <ITAException.h>
......@@ -13,7 +13,6 @@
// STL includes
#include <assert.h>
#include <stdio.h>
#include "..\..\include\ITAPropagationModels\FilterEngine.h"
//Spline
......@@ -23,6 +22,7 @@
using namespace ITAPropagationModels;
CFilterEngine::CFilterEngine()
:m_pMaterialManager( nullptr )
{
}
......@@ -85,11 +85,11 @@ void CFilterEngine::ApplyAcousticModels(ITAGeo::CPropagationPathList & oPathList
void CFilterEngine::ApplyDiffractionModel( ITAGeo::CPropagationPathList & oPathList, int iModel )
{
int iDiffractionModel;
int iDiffractionModelResolution;
if( iModel == -1 )
iDiffractionModel = m_DefaultValues::iDiffractionModel;
iDiffractionModelResolution = m_DefaultValues::iDiffractionModel;
else
iDiffractionModel = iModel;
iDiffractionModelResolution = iModel;
for( auto& oPath : oPathList )
{
......@@ -106,29 +106,26 @@ void CFilterEngine::ApplyDiffractionModel(ITAGeo::CPropagationPathList & oPathLi
{
auto pApex = std::dynamic_pointer_cast< ITAGeo::CITADiffractionWedgeApertureBase >( pCurrentAnchor );
if (iDiffractionModel == ITAGeo::IAcousticMaterial::THIRD_OCTAVE)
if( iDiffractionModelResolution == ITAGeo::IAcousticMaterial::THIRD_OCTAVE )
{
auto pAcousticMaterial = make_shared<ITAGeo::CThirdOctaveMaterial>();
auto vfFrequencies = pAcousticMaterial->oAbsorptionCoefficients.GetCenterFrequencies();
vector<float> vfAbsorptionCoeffs;
for (auto fFrequency : vfFrequencies)
for( size_t i = 0; i < vfFrequencies.size(); i++ )
{
double dDiffractionFactor;
auto fFrequency = vfFrequencies[ i ];
// TODO: Change diffraction calculation, just for testing
double dDirectLength, dDetourLength;
Maekawa::GetDirectLengthAndDetourLength( pLastAnchor->v3InteractionPoint, pNextAnchor->v3InteractionPoint, pApex, dDirectLength, dDetourLength );
dDiffractionFactor = Maekawa::CalculateDiffractionFactor(dDirectLength, dDetourLength, fFrequency, ITAConstants::SPEED_OF_SOUND_F);
const double dDiffractionFactor = Maekawa::CalculateDiffractionFactor( dDirectLength, dDetourLength, fFrequency, ITAConstants::SPEED_OF_SOUND_F );
// Absorption coefficient alpha = 1 - |D|^2
vfAbsorptionCoeffs.push_back(1.0f - pow(dDiffractionFactor,2));
const float fAlpha = float( 1.0f - pow( dDiffractionFactor, 2 ) );
pAcousticMaterial->oAbsorptionCoefficients.SetValue( i, fAlpha );
}
pAcousticMaterial->oAbsorptionCoefficients.SetMagnitudes(vfAbsorptionCoeffs);
pApex->pAcousticMaterial = pAcousticMaterial;
}
else
......@@ -246,6 +243,16 @@ void ITAPropagationModels::CFilterEngine::ApplySensorModel(ITAGeo::CPropagationP
}
}
void ITAPropagationModels::CFilterEngine::SetMaterialManager( const ITAGeo::CMaterialManager* pMaterialManager )
{
m_pMaterialManager = pMaterialManager;
}
const ITAGeo::CMaterialManager* ITAPropagationModels::CFilterEngine::GetMaterialManager() const
{
return m_pMaterialManager;
}
//TODO: delete pragma warning after implementation of function
#pragma warning( push )
#pragma warning( disable : 4100)
......@@ -340,20 +347,22 @@ void CFilterEngine::Generate(const ITAGeo::CPropagationPathList & oPathList, ITA
//Interpolate third octaves and multiply calculated values with third octave and scalar factors and add delay due to sound propagation
for( int i = 0; i < iHDFTSize; i++ )
{
// @todo JST/AER: I think this is not correctly using the spline interp, especially tval should be a base value of given frequency, not integer/index
const float fDFTSpectrum = spline_b_val( ( int ) vfDFTCoordinatesIn.size(), &vfDFTCoordinatesIn[ 0 ], &oThirdOctFactors[ 0 ], ( float ) i );
// @todo: m_pTempPropPathSpectra is untouched -> unity until here ...
const complex<float> fSpectrumData( ( *m_pTempPropPathSpectra )[ 0 ]->GetData()[ 2 * i ], ( *m_pTempPropPathSpectra )[ 0 ]->GetData()[ 2 * i + 1 ] );
complex<float> cfMultipliedSpectra = fSpectrumData * fDFTSpectrum * fScalarMagnitude;
(*m_pTempPropPathSpectra)[iChannel]->SetCoeff(i, cfMultipliedSpectra);
( *m_pTempPropPathSpectra )[ 0 ]->SetCoeff( i, cfMultipliedSpectra );
//Get the delay [samples] and calculate the phase shift according to the shift theorem
// DFT(x(k-Delta)) = exp(-j * omega_k * delta) * X(k) , with omega_k = 2 * pi * k / N
float fDelaySamples = fPathLength / m_fSpeedOfSound * ( float ) oHDFTSpectra.GetSampleRate();
float fDelayPhase = -fDelaySamples* ITAConstants::TWO_PI_F * i / oHDFTSpectra.GetDFTSize();
(*m_pTempPropPathSpectra)[iChannel]->SetPhasePreserveMagnitude(i, fDelayPhase);
( *m_pTempPropPathSpectra )[ 0 ]->SetPhasePreserveMagnitude( i, fDelayPhase );
}
......
#include <ITAPropagationModels/FilterGenerator.h>
// ITA includes
#include <ITAException.h>
#include <ITAGeo/Halfedge/MeshModel.h>
// Vista includes
#include <VistaMath/VistaGeometries.h>
// STL includes
#include <assert.h>
#include <stdio.h>
using namespace ITAGeo;
using namespace ITAPropagationModels;
ITAPropagationModels::CTFGenerator::CTFGenerator( const int iNumOutputChannels, const int iDFTSize /*= 128 */, const float fSamplingRate )
{
}
void ITAPropagationModels::CTFGenerator::GenerateTF( ITABase::CHDFTSpectra& pTransferFunctions )
{
}
......@@ -18,7 +18,10 @@
#include <ITAPropagationModels/FilterEngine.h>
#include <ITAGeo/Base.h>
#include <ITAGeo/Material/Manager.h>
#include <ITAFFTUtils.h>
#include <ITAISO9613.h>
......@@ -30,27 +33,23 @@ using namespace ITAPropagationModels;
int main( int, char** )
{
/*
|___x___|
/\
s \ r
\ /
___x___
|______|
// _______
// |___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 ) );
CMaterialDirectory oMaterialDirectory( "./" );
auto pReflection = make_shared< CSpecularReflection >( VistaVector3D( 0.0f, 2.0f, 0.0f ) );
auto pDiffraction = make_shared< CITADiffractionOuterWedgeAperture >();
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);
pReflection->pAcousticMaterial = oMaterialDirectory.GetMaterial( "stonewall" );
auto pW = std::make_shared< CITADiffractionOuterWedgeAperture >();
pW->v3AperturePoint.SetValues( 0.0f, 1.0f, 0.0f );
......@@ -76,32 +75,22 @@ int main(int, char**)
oPathDiffraction.push_back( pReceiver );
CPropagationPathList oPathList;
/*oPathList.push_back(oPathDirect);
oPathList.push_back(oPathDirect);
oPathList.push_back(oPathReflection);
oPathList.push_back(oPathDiffraction);
*/
oPathList.Load("PropagationPathListExample.json");
CFilterEngine oFilter;
oFilter.ApplyAcousticModels(oPathList);
CFilterEngine oFilterEngine;
oFilterEngine.SetMaterialManager( &oMaterialDirectory );
oFilterEngine.ApplyAcousticModels( oPathList );
// Set filter length according to the maximum path length
const float fSpeedOfSound = ITAConstants::SPEED_OF_SOUND_F; //Approximation of speed of sound at ~20C
const float fSpeedOfSound = SPEED_OF_SOUND_F; //Approximation of speed of sound at ~20C
const float fSampleRate = 44.1e3f;
int iFilterLengthSamples = ( int ) ( oPathList.GetMaxLength() / fSpeedOfSound * fSampleRate );
iFilterLengthSamples = int( iFilterLengthSamples * 1.5f );
int iFilterLength = (int)(oPathList.GetMaxLength()/ fSpeedOfSound * fSampleRate );
iFilterLength =(int) iFilterLength * 1.5;
ITABase::CHDFTSpectra oSpectra(fSampleRate, pReceiver->iNumChannels, iFilterLength);
ITABase::CHDFTSpectra oTransmissionFilter( fSampleRate, pReceiver->iNumChannels, iFilterLengthSamples );
oFilterEngine.Generate( oPathList, oTransmissionFilter );
oFilter.Generate(oPathList, oSpectra);
ITAFFTUtils::Export(oSpectra[0], "FilterEngine_Example.wav");
ITAFFTUtils::Export( &oTransmissionFilter, "FilterEngineTest.wav" ); // Exports in time domain as impulse response (IR)
}
[Material]
name= Steinwand
notes=
# 20 | 25 | 31.5 | 40 | 50 | 63 | 80 | 100 | 125 | 160 | 200 | 250 | 315 | 400 | 500 | 630 | 800 | 1000 | 1250 | 1600 | 2000 | 2500 | 3150 | 4000 | 5000 | 6300 | 8000 | 10000 | 12500 | 16000 | 20000
absorp= 0.02,0.02,0.02,0.0233333,0.0266667,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.03,0.0333333,0.0366667,0.04,0.0433333,0.0466667,0.05,0.0566667,0.0633333,0.07,0.07,0.07,0.07,0.0733333,0.0766667,0.08,0.08
scatter= 0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.15,0.183333,0.216667,0.25,0.283333,0.316667,0.35,0.333333,0.316667,0.3,0.3,0.3,0.3,0.333333,0.366667,0.4,0.4,0.4,0.4,0.433333,0.466667,0.5,0.5
interpol= 1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment