Finishing renaming of Kirchhoff to Maekawa method and making some interface...

Finishing renaming of Kirchhoff to Maekawa method and making some interface changes for a more simple usage of the Maekawa methods
parent d09f0a28
......@@ -19,8 +19,8 @@
*
*/
#ifndef INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_KIRCHHOFF
#define INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_KIRCHHOFF
#ifndef INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_MAEKAWA
#define INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_MAEKAWA
#include "Definitions.h"
......@@ -35,50 +35,52 @@
namespace ITAPropagationModels
{
//! Diffraction calculation based on Kirchhoff approximation
//! Diffraction calculation based on Maekawa
/**
* @sa Maekawa, Z.; Noise reduction by screens Applied Acoustics; 1968, 1, 157 - 173
* @sa Pierce, A. D.; Diffraction of sound around corners and over wide barriers; J. Acoust. Soc. Am., 1974, 55, 941-955
*/
namespace Kirchhoff
namespace Maekawa
{
//! Validates if Kirchhoff diffraction method can be applied
//! Validates if Maekawa diffraction method can be applied
/**
* The Kirchhoff detour method only makes sense if the source is
* The Maekawa method only makes sense if the source is
* occluded by obstacles in it's way to the receiver (or vice versa).
* This may include specular reflections, but inverse wedges (corners) have to
* be excluded because they can not occlude entities.
*
* @param[in] oPropPath Propagation path to be simulated
* @return True, if Kirchhoff can be used (makes sense for this path)
* @param[in] v3SourcePos Source position
* @param[in] v3TargetPos Target position
* @param[in] pApex Aperture point on wedge
*
* @sa KirchhoffDetourAndLength
* @sa KirchhoffDiffractionFilter
* @return True, if Maekawa can be used (diffracting into shadow zone)
*
* @sa MaekawaDetourAndLength
* @sa MaekawaDiffractionFilter
*
* @note Throws ITAException on error
*
*/
bool ITA_PROPAGATION_MODELS_API IsApplicable( const ITAGeo::CPropagationPath& oPropPath );
bool ITA_PROPAGATION_MODELS_API IsApplicable( const VistaVector3D& v3SourcePos, const VistaVector3D& v3TargetPos, std::shared_ptr< const ITAGeo::CITADiffractionWedgeAperture > pApex );
//! Calculates the detour of a propagation path for the Kirchhoff method
//! Calculates the detour of a propagation path for the Maekawa method
/**
* Calculates the direct path vs. detour path by taking diffraction anchors into account.
* It is recommended to validate the path, first. Otherwise unpredictable results will occur.
*
* 1. Specular reflections will increase the direct path length AND detour length
* 2. Only diffraction around a wedge are treated (diffraction angle greater \pi, where 0 would be back-scattering and \pi is gracing angle)
* Calculates the direct path vs. detour path by taking the diffraction anchor into account.
*
* @param[in] oPropPath Propagation path to be simulated
* @param[in] v3SourcePos Source position
* @param[in] v3TargetPos Target position
* @param[in] pApex Aperture point on wedge
* @param[out] dPropagationLengthDirect Propagation path length without occlusion [m]
* @param[out] dPropagationLengthDetour Propagation path detour length with occlusion [m]
*
* @sa IsKirchhoffApplicable
* @sa IsMaekawaApplicable
*
* @note Throws ITAException on error
*
*/
void ITA_PROPAGATION_MODELS_API GetDirectLengthAndDetourLength( const ITAGeo::CPropagationPath& oPropPath, double& dPropagationLengthDirect, double& dPropagationLengthDetour );
void ITA_PROPAGATION_MODELS_API GetDirectLengthAndDetourLength( const VistaVector3D& v3SourcePos, const VistaVector3D& v3TargetPos, std::shared_ptr< const ITAGeo::CITADiffractionWedgeAperture > pApex, double& dPropagationLengthDirect, double& dPropagationLengthDetour );
//! Calculates the detour-and-direct-path difference of a propagation path for the Kirchhoff method
//! Calculates the detour-and-direct-path difference of a propagation path for the Maekawa method
/**
* @param[in] dPropagationLengthDirect Direct path length [m] (sometimes referred to as 'd')
* @param[in] dPropagationLengthDetour Detour path length [m] (sometimes referred to as 'A+B')
......@@ -90,7 +92,7 @@ namespace ITAPropagationModels
*/
double ITA_PROPAGATION_MODELS_API KirchhoffDelta( const double dPropagationLengthDirect, const double dPropagationLengthDetour );
//! Calculates the detour-and-direct-path inverse difference factor of a propagation path for the Kirchhoff method
//! Calculates the detour-and-direct-path inverse difference factor of a propagation path for the Maekawa method
/**
* @return Kirchhoff delta factor (ratio), always greater or equal 1.0
*
......@@ -99,79 +101,38 @@ namespace ITAPropagationModels
*/
inline double KirchhoffDeltaInverseFactor( const double dPropagationLengthDirect, const double dPropagationLengthDetour )
{
const double dKirchhoffDelta = Kirchhoff::KirchhoffDelta( dPropagationLengthDirect, dPropagationLengthDetour );
const double dKirchhoffDelta = Maekawa::KirchhoffDelta( dPropagationLengthDirect, dPropagationLengthDetour );
const double dKirchhoffDeltaInverseFactor = ( dPropagationLengthDirect + dKirchhoffDelta ) / dPropagationLengthDirect;
return dKirchhoffDeltaInverseFactor;
};
//! Calculate diffraction filter (frequency domain) based on the Kirchhoff detour method
//! Calculate diffraction filter based on the Maekawa detour method
/**
* This function calculates the Kirchhoff diffraction filter based on detour length around a wedge obstacle
* This function calculates the Maekawa diffraction filter based on detour length around a wedge obstacle
* and the direct path length with and withont any obstacles.
*
* @param[in] dPropagationLengthDirect Direct path length [m]
* @param[in] dPropagationLengthDetour Detour path length [m]
* @param[out] oTransferFunction Destination filter of simulation (zero-phase frequency domain magnitude spectrum)
* @param[in] fFrequency Frequency [Hz]
* @param[in] fSpeedOfSound Speed of sound [m/s]
*
*/
void ITA_PROPAGATION_MODELS_API CalculateDiffractionFilter( const double dPropagationLengthDirect, const double dPropagationLengthDetour, ITABase::CHDFTSpectrum& oTransferFunction, const float fSpeedOfSound = 344.0f );
float ITA_PROPAGATION_MODELS_API CalculateDiffractionFilterCoefficient( const double dPropagationLengthDirect, const double dPropagationLengthDetour, const float fFrequency, const float fSpeedOfSound = 344.0f );
//! Calculate diffraction filter (frequency domain) based on the Kirchhoff detour method for a single wedge
//! Calculate diffraction filter (frequency domain) based on the Maekawa detour method
/**
* This function calculates the Kirchhoff diffraction filter based on detour length around a wedge obstacle
* and the direct path length with and without any obstacles.
*
* @param[in] oPropPath Propagation path
* @param[out] oTransferFunction Destination filter of simulation (frequency domain)
*
* @return True, if Kirchhoff method could be applied
*
* @note Throws ITAException on error
*
*/
inline bool CalculateDiffractionFilter( const ITAGeo::CPropagationPath& oPropPath, ITABase::CHDFTSpectrum& oTransferFunction, const float fSpeedOfSound = 344.0f )
{
if( !Kirchhoff::IsApplicable( oPropPath ) )
return false;
double dDirect, dDetour;
Kirchhoff::GetDirectLengthAndDetourLength( oPropPath, dDirect, dDetour );
Kirchhoff::CalculateDiffractionFilter( dDirect, dDetour, oTransferFunction, fSpeedOfSound );
return true;
};
//! Calculate diffraction filter (frequency domain) based on the Kirchhoff detour method for a single wedge
/**
* This function calculates the Kirchhoff diffraction filter based on detour length around a wedge obstacle
* and the direct path length with and without any obstacles.
*
* @param[in] pSource Source of propagation (previous anchor point of path)
* @param[in] pWedge Diffraction wedge of propagation
* @param[in] pTarget Target of propagation (next anchor point of path)
* @param[out] oTransferFunction Destination filter of simulation (frequency domain)
*
* @return True, if Kirchhoff method could be applied
* This function calculates the Maekawa diffraction filter based on detour length around a wedge obstacle
* and the direct path length with and withont any obstacles.
*
* @note Throws ITAException on error
* @param[in] dPropagationLengthDirect Direct path length [m]
* @param[in] dPropagationLengthDetour Detour path length [m]
* @param[out] oTransferFunction Destination filter of simulation (zero-phase frequency domain magnitude spectrum)
* @param[in] fSpeedOfSound Speed of sound [m/s]
*
*/
inline bool CalculateDiffractionFilter( std::shared_ptr< ITAGeo::CPropagationAnchor > pSource, std::shared_ptr< ITAGeo::CITADiffractionWedgeAperture > pWedge, std::shared_ptr< ITAGeo::CPropagationAnchor > pTarget, ITABase::CHDFTSpectrum& oTransferFunction, const float fSpeedOfSound = 344.0f )
{
if( !pWedge->IsOccluding( pSource, pTarget ) )
return false;
// A little dirty removing const, but we know what we are doing, here.
ITAGeo::CPropagationPath oPropPath;
oPropPath.push_back( pSource );
oPropPath.push_back( pWedge );
oPropPath.push_back( pTarget );
const ITAGeo::CPropagationPath& oConstPropPath( oPropPath ); // Not necessary, just making a point
return CalculateDiffractionFilter( oConstPropPath, oTransferFunction, fSpeedOfSound );
};
void ITA_PROPAGATION_MODELS_API CalculateDiffractionFilter( const double dPropagationLengthDirect, const double dPropagationLengthDetour, ITABase::CHDFTSpectrum& oTransferFunction, const float fSpeedOfSound = 344.0f );
}
}
#endif // INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_KIRCHHOFF
#endif // INCLUDE_WATCHER_ITA_PROPAGATION_MODELS_MAEKAWA
#include <ITAPropagationModels/Kirchhoff.h>
#include <ITAPropagationModels/Maekawa.h>
#include <ITAException.h>
#include <cassert>
using namespace ITAGeo;
using namespace ITAPropagationModels;
bool Kirchhoff::IsApplicable( const CPropagationPath& oPropPath )
bool Maekawa::IsApplicable( const VistaVector3D& v3SourcePos, const VistaVector3D& v3TargetPos, std::shared_ptr< const ITAGeo::CITADiffractionWedgeAperture > pApex )
{
if( oPropPath.size() < 3 )
ITA_EXCEPT1( INVALID_PARAMETER, "Propagation path needs at least 3 anchors for Kirchhoff method" );
auto pAnchorDirectLazy( oPropPath[ 0 ] );
if( pAnchorDirectLazy->iAnchorType == CPropagationAnchor::INVALID )
ITA_EXCEPT1( INVALID_PARAMETER, "First geo propagation anchor is invalid, please purge first." );
auto pAnchorTail( oPropPath[ oPropPath.size() - 1 ] );
if( pAnchorTail->iAnchorType == CPropagationAnchor::INVALID )
ITA_EXCEPT1( INVALID_PARAMETER, "Last geo propagation anchor is invalid, please purge first." );
// We don't care for first and last anchor's type (except invalid)
for( size_t i = 1; i < oPropPath.size() - 1; i++ )
{
auto pAnchorPrev( oPropPath[ i - 1 ] );
auto pAnchorCur( oPropPath[ i ] );
auto pAnchorNext( oPropPath[ i + 1 ] );
if( pAnchorCur->iAnchorType == CPropagationAnchor::INVALID )
ITA_EXCEPT1( INVALID_PARAMETER, "Geo propagation path has invalid anchors, please purge first." );
if( pAnchorCur->iAnchorType == CPropagationAnchor::DIFFRACTION_APEX )
{
auto pWedge = std::dynamic_pointer_cast< CITADiffractionWedgeAperture>( pAnchorCur );
// Check if prev and next anchors are occluded by wedge
if( !pWedge->IsOccluding( pAnchorPrev, pAnchorNext ) )
return false;
}
}
return true;
return pApex->IsOccluding( v3SourcePos, v3TargetPos );
}
void Kirchhoff::GetDirectLengthAndDetourLength( const CPropagationPath& oPropPath, double& dPropagationLengthDirect, double& dPropagationLengthDetour )
void Maekawa::GetDirectLengthAndDetourLength( const VistaVector3D& v3SourcePos, const VistaVector3D& v3TargetPos, std::shared_ptr< const ITAGeo::CITADiffractionWedgeAperture > pApex, double& dPropagationLengthDirect, double& dPropagationLengthDetour )
{
if( oPropPath.size() < 3 )
ITA_EXCEPT1( INVALID_PARAMETER, "Propagation path needs at least 3 anchors for Kirchhoff method" );
auto pAnchorDirectLazy( oPropPath[ 0 ] );
if( pAnchorDirectLazy->iAnchorType == CPropagationAnchor::INVALID )
ITA_EXCEPT1( INVALID_PARAMETER, "First geo propagation anchor is invalid, please purge." );
auto pAnchorTail( oPropPath[ oPropPath.size() - 1 ] );
if( pAnchorTail->iAnchorType == CPropagationAnchor::INVALID )
ITA_EXCEPT1( INVALID_PARAMETER, "Last geo propagation anchor is invalid, please purge." );
dPropagationLengthDetour = ( pApex->v3InteractionPoint - v3SourcePos ).GetLength() + ( v3TargetPos - pApex->v3InteractionPoint ).GetLength();
dPropagationLengthDirect = ( v3TargetPos - v3SourcePos ).GetLength();
// We don't care for first and last anchor's type (except invalid)
dPropagationLengthDirect = 0.0f;
dPropagationLengthDetour = 0.0f;
for( size_t i = 1; i < oPropPath.size(); i++ )
{
auto pAnchorPrev( oPropPath[ i - 1 ] );
auto pAnchorCur( oPropPath[ i ] );
if( pAnchorCur->iAnchorType == CPropagationAnchor::INVALID )
ITA_EXCEPT1( INVALID_PARAMETER, "Geo propagation path has invalid anchors, please purge first." );
// Detour is everything ...
const VistaVector3D vIntermediateLine = pAnchorCur->v3InteractionPoint - pAnchorPrev->v3InteractionPoint;
const double dIntermediateLength = vIntermediateLine.GetLength();
dPropagationLengthDetour += dIntermediateLength;
// ... but direct path skips diffraction anchors
if( pAnchorCur->iAnchorType != CPropagationAnchor::DIFFRACTION_APEX || pAnchorCur == pAnchorTail )
{
const VistaVector3D vIntermediateDirectLine = pAnchorCur->v3InteractionPoint - pAnchorDirectLazy->v3InteractionPoint;
const double dIntermediateDirectLine = vIntermediateDirectLine.GetLength();
dPropagationLengthDirect += dIntermediateDirectLine;
pAnchorDirectLazy = pAnchorCur;
}
}
// Zero-length path would be crude, make assertion here to give user a hint that something is wrong with his input
assert( dPropagationLengthDetour > 0.0f );
assert( dPropagationLengthDirect > 0.0f );
return;
}
double Kirchhoff::KirchhoffDelta( const double dPropagationLengthDirect, const double dPropagationLengthDetour )
double Maekawa::KirchhoffDelta( const double dPropagationLengthDirect, const double dPropagationLengthDetour )
{
if( dPropagationLengthDirect <= 0.0f )
ITA_EXCEPT1( INVALID_PARAMETER, "Diffraction direct path length can not be zero or negative" );
......@@ -105,7 +36,7 @@ double Kirchhoff::KirchhoffDelta( const double dPropagationLengthDirect, const d
return dKirchhoffDelta;
}
void Kirchhoff::CalculateDiffractionFilter( const double dDirect, const double dDetour, ITABase::CHDFTSpectrum& oTransferFunction, const float fSpeedOfSound /*= 344.0f*/ )
void Maekawa::CalculateDiffractionFilter( const double dDirect, const double dDetour, ITABase::CHDFTSpectrum& oTransferFunction, const float fSpeedOfSound /*= 344.0f*/ )
{
assert( fSpeedOfSound > 0.0f );
if( fSpeedOfSound <= 0.0f )
......@@ -117,8 +48,14 @@ void Kirchhoff::CalculateDiffractionFilter( const double dDirect, const double d
const int iDFTSize = oTransferFunction.GetSize();
for( int i = 1; i < iDFTSize - 1; i++ )
{
const double dFrequency = oTransferFunction.GetFrequencyResolution() * i;
const double dFresnelNumber = 2.0f * Kirchhoff::KirchhoffDelta( dDirect, dDetour ) * dFrequency / fSpeedOfSound; // Sometimes referred to as 'N'
oTransferFunction.SetCoeffRI( i, float( dFresnelNumber ) );
const float fFrequency = oTransferFunction.GetFrequencyResolution() * i;
const float fCoefficient = CalculateDiffractionFilterCoefficient( dDirect, dDetour, fFrequency, fSpeedOfSound );
oTransferFunction.SetCoeffRI( i, fCoefficient );
}
}
float ITA_PROPAGATION_MODELS_API ITAPropagationModels::Maekawa::CalculateDiffractionFilterCoefficient( const double dPropagationLengthDirect, const double dPropagationLengthDetour, const float fFrequency, const float fSpeedOfSound /*= 344.0f */ )
{
// @todo daniel armin
ITA_EXCEPT_NOT_IMPLEMENTED;
}
cmake_minimum_required( VERSION 2.8 )
add_subdirectory( "Kirchhoff" )
add_subdirectory( "Maekawa" )
add_subdirectory( "Svensson" )
add_subdirectory( "UTD" )
add_subdirectory( "FilterEngine" )
......@@ -16,11 +16,11 @@ if( ITA_GEOMETRICAL_ACOUSTICS_BUILD_STATIC )
add_definitions( -DITA_PROPAGATION_MODELS_STATIC _DITA_PROPAGATION_PATH_SIM_STATIC -DITA_GEO_STATIC )
endif( )
add_executable( KirchhoffTest KirchhoffTest.cpp )
target_link_libraries( KirchhoffTest ${VISTA_USE_PACKAGE_LIBRARIES} )
add_executable( MaekawaTest MaekawaTest.cpp )
target_link_libraries( MaekawaTest ${VISTA_USE_PACKAGE_LIBRARIES} )
vista_configure_app( KirchhoffTest )
vista_install( KirchhoffTest )
vista_create_default_info_file( KirchhoffTest )
vista_configure_app( MaekawaTest )
vista_install( MaekawaTest )
vista_create_default_info_file( MaekawaTest )
set_property( TARGET KirchhoffTest PROPERTY FOLDER "ITAGeometricalAcoustics/Tests/ITAPropagationModels" )
set_property( TARGET MaekawaTest PROPERTY FOLDER "ITAGeometricalAcoustics/Tests/ITAPropagationModels" )
......@@ -16,7 +16,7 @@
*
*/
#include <ITAPropagationModels/Kirchhoff.h>
#include <ITAPropagationModels/Maekawa.h>
#include <ITAException.h>
#include <ITAStopWatch.h>
......@@ -36,7 +36,7 @@ using namespace ITAPropagationModels;
static float g_fSampleRate = 44.1e3f;
static int g_iFilterLength = 128;
//! Tests running the Kirchhoff model functions
//! Tests running the Maekawa model functions
/**
*
*/
......@@ -63,26 +63,26 @@ int main( int, char** )
try
{
if( Kirchhoff::IsApplicable( oPropPath ) )
cout << "[OK] Kirchhoff method can be applied for this path" << endl;
if( Maekawa::IsApplicable( pS->v3InteractionPoint, pR->v3InteractionPoint, pW ) )
cout << "[OK] Maekawa method can be applied for this path" << endl;
else
cout << "[BAD] Kirchhoff method can't be applied for this path, trying anyway" << endl;
cout << "[BAD] Maekawa method can't be applied for this path, trying anyway" << endl;
double dPropLendthDirect, dPropLengthDetour;
Kirchhoff::GetDirectLengthAndDetourLength( oPropPath, dPropLendthDirect, dPropLengthDetour );
double dPropLengthDirect, dPropLengthDetour;
Maekawa::GetDirectLengthAndDetourLength( pS->v3InteractionPoint, pR->v3InteractionPoint, pW, dPropLengthDirect, dPropLengthDetour );
cout << "Kirchhoff direct path length: " << dPropLendthDirect << " m" << endl;
cout << "Kirchhoff detour path length: " << dPropLengthDetour << " m" << endl;
cout << "Kirchhoff delta: " << Kirchhoff::KirchhoffDelta( dPropLendthDirect, dPropLengthDetour ) << " m" << endl;
cout << "Maekawa direct path length: " << dPropLengthDirect << " m" << endl;
cout << "Maekawa detour path length: " << dPropLengthDetour << " m" << endl;
cout << "Kirchhoff delta: " << Maekawa::KirchhoffDelta( dPropLengthDirect, dPropLengthDetour ) << " m" << endl;
ITABase::CHDFTSpectrum oDiffractionTF( g_fSampleRate, g_iFilterLength / 2 + 1, true );
ITAStopWatch sw; sw.start();
Kirchhoff::CalculateDiffractionFilter( dPropLendthDirect, dPropLengthDetour, oDiffractionTF );
cout << "Kirchhoff filter generation calculation time: " << timeToString( sw.stop() ) << endl;
Maekawa::CalculateDiffractionFilter( dPropLengthDirect, dPropLengthDetour, oDiffractionTF );
cout << "Maekawa filter generation calculation time: " << timeToString( sw.stop() ) << endl;
cout << oDiffractionTF.ToString() << endl;
ITAFFTUtils::Export( &oDiffractionTF, "KirchhoffTestIR.wav" );
ITAFFTUtils::Export( &oDiffractionTF, "MaekawaTestIR.wav" );
}
catch( const VistaExceptionBase& e )
{
......
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