Commit c4566f8e authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Refactoring AirTrafficNoise renderer, also improving some problematic functions

parent e6799cf2
......@@ -16,6 +16,9 @@
#if VACORE_WITH_RENDERER_BINAURAL_AIR_TRAFFIC_NOISE
#include "VAAirTrafficNoiseSoundReceiver.h"
#include "VAAirTrafficNoiseSoundSource.h"
// VA includes
#include <VA.h>
#include <VAObjectPool.h>
......@@ -57,7 +60,7 @@ class CVABATNSoundPathFactory;
* binaural receiver including multiple audio effects:
* - Directivity
* - Doppler-Shifts
* - Air-Absorption [TODO?!]
* - Air-Absorption
* - 1/r-Distance-Law
*
*/
......@@ -109,117 +112,6 @@ private:
const CVAAudioRendererInitParams m_oParams; //!< Create a const copy of the init params
//! Interne Beschreibung einer Schallquelle
class CVABATNSource : public CVAPoolObject
{
public:
class Config
{
public:
double dMotionModelWindowSize;
double dMotionModelWindowDelay;
int iMotionModelNumHistoryKeys;
};
inline CVABATNSource( const Config& oConf_ )
: oConf( oConf_ )
{};
const Config oConf;
CVASoundSourceDesc* pData; //!< (Unversioned) Source description
CVASharedMotionModel* pMotionModel;
bool bDeleted;
VAVec3 vPredPos; //!< Estimated position
VAVec3 vPredView; //!< Estimated Orientation (View-Vektor)
VAVec3 vPredUp; //!< Estimated Orientation (Up-Vektor)
bool bValidTrajectoryPresent; //!< Estimation possible -> valid trajectory present
// Pool-Konstruktor
inline void PreRequest()
{
pData = nullptr;
CVABasicMotionModel::Config oDefaultConfig;
oDefaultConfig.dWindowDelay = oConf.dMotionModelWindowDelay;
oDefaultConfig.dWindowSize = oConf.dMotionModelWindowSize;
oDefaultConfig.iNumHistoryKeys = oConf.iMotionModelNumHistoryKeys;
pMotionModel = new CVASharedMotionModel( new CVABasicMotionModel( oDefaultConfig ), true );
bValidTrajectoryPresent = false;
};
inline void PreRelease()
{
delete pMotionModel;
pMotionModel = nullptr;
};
inline double GetCreationTimestamp() const
{
return m_dCreationTimeStamp;
};
private:
double m_dCreationTimeStamp; //!< Date of creation within streaming context
};
//! Internal listener representation
class CVABATNSoundReceiver : public CVAPoolObject
{
public:
class Config
{
public:
double dMotionModelWindowSize;
double dMotionModelWindowDelay;
int iMotionModelNumHistoryKeys;
};
inline CVABATNSoundReceiver( CVACoreImpl* pCore, const Config& oConf )
: pCore( pCore ), oConf( oConf )
{};
CVACoreImpl* pCore;
const Config oConf;
CVAListenerDesc* pData; //!< (Unversioned) Listener description
CVASharedMotionModel* pMotionModel;
bool bDeleted;
VAVec3 vPredPos; //!< Estimated position
VAVec3 vPredView; //!< Estimated Orientation (View-Vektor)
VAVec3 vPredUp; //!< Estimated Orientation (Up-Vektor)
bool bValidTrajectoryPresent; //!< Estimation possible -> valid trajectory present
ITASampleFrame* psfOutput; //!< Accumulated listener output signals @todo check if sample frame is also deleted after usage
inline void PreRequest()
{
pData = nullptr;
CVABasicMotionModel::Config oListenerMotionConfig;
oListenerMotionConfig.dWindowDelay = oConf.dMotionModelWindowDelay;
oListenerMotionConfig.dWindowSize = oConf.dMotionModelWindowSize;
oListenerMotionConfig.iNumHistoryKeys = oConf.iMotionModelNumHistoryKeys;
pMotionModel = new CVASharedMotionModel( new CVABasicMotionModel( oListenerMotionConfig ), true );
bValidTrajectoryPresent = false;
psfOutput = nullptr;
};
// Pool-Destruktor
inline void PreRelease()
{
delete pMotionModel;
pMotionModel = nullptr;
};
};
private:
CVACoreImpl* m_pCore; //!< Pointer to VACore
CVASceneState* m_pCurSceneState;
......@@ -234,7 +126,7 @@ private:
IVAObjectPool* m_pSourcePool;
IVAObjectPool* m_pListenerPool;
std::map< int, CVABATNSource* > m_mSources; //!< Interne Abbildung der verfgbaren Quellen
std::map< int, CVABATNSoundSource* > m_mSources; //!< Interne Abbildung der verfgbaren Quellen
std::map< int, CVABATNSoundReceiver* > m_mListeners; //!< Interne Abbildung der verfgbaren Hrer
double m_dGroundPlanePosition; //!< Position of ground plane (height) for reflection calculation
......@@ -253,13 +145,13 @@ private:
bool m_bSpreadingLossExternalSimulation; //!< If true, internal simulation is skipped and parameters are expected to be set using external SetParameters() call
CVABATNSoundReceiver::Config m_oDefaultListenerConf; //!< Default listener config for factory object creation
CVABATNSource::Config m_oDefaultSourceConf; //!< Default source config for factory object creation
CVABATNSoundSource::Config m_oDefaultSourceConf; //!< Default source config for factory object creation
class CVABATNUpdateMessage : public CVAPoolObject
class CUpdateMessage : public CVAPoolObject
{
public:
std::list< CVABATNSource* > vNewSources;
std::list< CVABATNSource* > vDelSources;
std::list< CVABATNSoundSource* > vNewSources;
std::list< CVABATNSoundSource* > vDelSources;
std::list< CVABATNSoundReceiver* > vNewListeners;
std::list< CVABATNSoundReceiver* > vDelListeners;
std::list< CVABATNSoundPath* > vNewPaths;
......@@ -277,14 +169,14 @@ private:
};
IVAObjectPool* m_pUpdateMessagePool; // really necessary?
CVABATNUpdateMessage* m_pUpdateMessage;
CUpdateMessage* m_pUpdateMessage;
//! Data in context of audio process
struct
{
tbb::concurrent_queue< CVABATNUpdateMessage* > m_qpUpdateMessages; //!< Update messages list
tbb::concurrent_queue< CUpdateMessage* > m_qpUpdateMessages; //!< Update messages list
std::list< CVABATNSoundPath* > m_lSoundPaths; //!< List of sound paths
std::list< CVABATNSource* > m_lSources; //!< List of sources
std::list< CVABATNSoundSource* > m_lSources; //!< List of sources
std::list< CVABATNSoundReceiver* > m_lListener; //!< List of listeners
ITASampleBuffer m_sbTempBufD; //!< Temporally used buffer to store a block of samples during processing (direct sound)
ITASampleBuffer m_sbTempBufR; //!< Temporally used buffer to store a block of samples during processing (reflected sound)
......@@ -298,9 +190,9 @@ private:
void UpdateSources();
CVABATNSoundReceiver* CreateSoundReceiver( int iID, const CVAReceiverState* );
void DeleteListener( int iID );
CVABATNSource* CreateSoundSource( int iID, const CVASoundSourceState* );
CVABATNSoundSource* CreateSoundSource( int iID, const CVASoundSourceState* );
void DeleteSource( int iID );
CVABATNSoundPath* CreateSoundPath( CVABATNSource*, CVABATNSoundReceiver* );
CVABATNSoundPath* CreateSoundPath( CVABATNSoundSource*, CVABATNSoundReceiver* );
void DeleteSoundPath( CVABATNSoundPath* );
void UpdateTrajectories();
......
#include "VAAirTrafficNoiseSoundPath.h"
#include <ITAISO9613.h>
CVABATNSoundPath::CVABATNSoundPath( double dSamplerate, int iBlocklength, int iHRIRFilterLength, int iDirFilterLength, int iFilterBankType )
: dGroundReflectionPlanePosition( 0 )
{
oDirSoundPath.pThirdOctaveFilterBank = CITAThirdOctaveFilterbank::Create( dSamplerate, iBlocklength, iFilterBankType );
oRefSoundPath.pThirdOctaveFilterBank = CITAThirdOctaveFilterbank::Create( dSamplerate, iBlocklength, iFilterBankType );
oDirSoundPath.pThirdOctaveFilterBank->SetIdentity();
oRefSoundPath.pThirdOctaveFilterBank->SetIdentity();
float fReserverdMaxDelaySamples = ( float ) ( 3 * dSamplerate ); // 3 Sekunden ~ 1km Entfernung
m_iDefaultVDLSwitchingAlgorithm = CITAVariableDelayLine::CUBIC_SPLINE_INTERPOLATION;
oDirSoundPath.pVariableDelayLine = new CITAVariableDelayLine( dSamplerate, iBlocklength, fReserverdMaxDelaySamples, m_iDefaultVDLSwitchingAlgorithm );
oRefSoundPath.pVariableDelayLine = new CITAVariableDelayLine( dSamplerate, iBlocklength, fReserverdMaxDelaySamples, m_iDefaultVDLSwitchingAlgorithm );
oDirSoundPath.pFIRConvolverChL = new ITAUPConvolution( iBlocklength, iHRIRFilterLength );
oRefSoundPath.pFIRConvolverChL = new ITAUPConvolution( iBlocklength, iHRIRFilterLength );
oDirSoundPath.pFIRConvolverChR = new ITAUPConvolution( iBlocklength, iHRIRFilterLength );
oRefSoundPath.pFIRConvolverChR = new ITAUPConvolution( iBlocklength, iHRIRFilterLength );
oDirSoundPath.pFIRConvolverChL->SetFilterExchangeFadingFunction( ITABase::FadingFunction::COSINE_SQUARE );
oRefSoundPath.pFIRConvolverChL->SetFilterExchangeFadingFunction( ITABase::FadingFunction::COSINE_SQUARE );
oDirSoundPath.pFIRConvolverChR->SetFilterExchangeFadingFunction( ITABase::FadingFunction::COSINE_SQUARE );
oRefSoundPath.pFIRConvolverChR->SetFilterExchangeFadingFunction( ITABase::FadingFunction::COSINE_SQUARE );
oDirSoundPath.pFIRConvolverChL->SetFilterCrossfadeLength( ( std::min )( iBlocklength, 32 ) );
oRefSoundPath.pFIRConvolverChL->SetFilterCrossfadeLength( ( std::min )( iBlocklength, 32 ) );
oDirSoundPath.pFIRConvolverChR->SetFilterCrossfadeLength( ( std::min )( iBlocklength, 32 ) );
oRefSoundPath.pFIRConvolverChR->SetFilterCrossfadeLength( ( std::min )( iBlocklength, 32 ) );
oDirSoundPath.pFIRConvolverChL->SetGain( 0.0f, true );
oRefSoundPath.pFIRConvolverChL->SetGain( 0.0f, true );
oDirSoundPath.pFIRConvolverChR->SetGain( 0.0f, true );
oRefSoundPath.pFIRConvolverChR->SetGain( 0.0f, true );
ITAUPFilter* pDHRIRFilterChL = oDirSoundPath.pFIRConvolverChL->RequestFilter();
ITAUPFilter* pRHRIRFilterChL = oRefSoundPath.pFIRConvolverChL->RequestFilter();
ITAUPFilter* pDHRIRFilterChR = oDirSoundPath.pFIRConvolverChR->RequestFilter();
ITAUPFilter* pRHRIRFilterChR = oRefSoundPath.pFIRConvolverChR->RequestFilter();
pDHRIRFilterChL->identity();
pRHRIRFilterChL->identity();
pDHRIRFilterChR->identity();
pRHRIRFilterChR->identity();
oDirSoundPath.pFIRConvolverChL->ExchangeFilter( pDHRIRFilterChL );
oRefSoundPath.pFIRConvolverChL->ExchangeFilter( pRHRIRFilterChL );
oDirSoundPath.pFIRConvolverChR->ExchangeFilter( pDHRIRFilterChR );
oRefSoundPath.pFIRConvolverChR->ExchangeFilter( pRHRIRFilterChR );
// Auto-release filter after it is not used anymore
oDirSoundPath.pFIRConvolverChL->ReleaseFilter( pDHRIRFilterChL );
oRefSoundPath.pFIRConvolverChL->ReleaseFilter( pRHRIRFilterChL );
oDirSoundPath.pFIRConvolverChR->ReleaseFilter( pDHRIRFilterChR );
oRefSoundPath.pFIRConvolverChR->ReleaseFilter( pRHRIRFilterChR );
m_sfHRIRTemp.init( 2, iHRIRFilterLength, false );
}
CVABATNSoundPath::~CVABATNSoundPath()
{
delete oDirSoundPath.pThirdOctaveFilterBank;
delete oRefSoundPath.pThirdOctaveFilterBank;
delete oDirSoundPath.pVariableDelayLine;
delete oRefSoundPath.pVariableDelayLine;
delete oDirSoundPath.pFIRConvolverChL;
delete oRefSoundPath.pFIRConvolverChL;
delete oDirSoundPath.pFIRConvolverChR;
delete oRefSoundPath.pFIRConvolverChR;
}
void CVABATNSoundPath::UpdateMetrics()
{
if( pSoundSource->vPredPos != pSoundReceiver->vPredPos )
{
oDirSoundPath.oRelations.Calc( pSoundSource->vPredPos, pSoundSource->vPredView, pSoundSource->vPredUp, pSoundReceiver->vPredPos, pSoundReceiver->vPredView, pSoundReceiver->vPredUp );
// Mirror at reflecting plane
double dDSourcePosY = pSoundSource->vPredPos.y;
double dRSourcePosY = dGroundReflectionPlanePosition - ( dDSourcePosY - dGroundReflectionPlanePosition );
VAVec3 vRSourcePos( pSoundSource->vPredPos.x, dRSourcePosY, pSoundSource->vPredPos.z );
oRefSoundPath.oRelations.Calc( vRSourcePos, pSoundSource->vPredView, pSoundSource->vPredUp, pSoundReceiver->vPredPos, pSoundReceiver->vPredView, pSoundReceiver->vPredUp );
}
}
void CVABATNSoundPath::UpdateSoundSourceDirectivity()
{
// Direct sound path
DAFFContentMS* pDirectivityDataNew = ( DAFFContentMS* ) oDirSoundPath.oDirectivityStateNew.pData;
DAFFContentMS* pDirectivityDataCur = ( DAFFContentMS* ) oDirSoundPath.oDirectivityStateCur.pData;
oDirSoundPath.oDirectivityStateNew.bDirectivityEnabled = true;
if( pDirectivityDataNew == nullptr )
{
// Directivity not yet set ... or removed
oDirSoundPath.oSoundSourceDirectivityMagnitudes.SetIdentity();
oDirSoundPath.oDirectivityStateNew.iRecord = -1;
}
else
{
// Update directivity data set
pDirectivityDataNew->getNearestNeighbour( DAFF_OBJECT_VIEW, float( oDirSoundPath.oRelations.dAzimuthS2L ), float( oDirSoundPath.oRelations.dElevationS2L ), oDirSoundPath.oDirectivityStateNew.iRecord );
if( oDirSoundPath.oDirectivityStateCur.iRecord != oDirSoundPath.oDirectivityStateNew.iRecord )
{
std::vector< float > vfGains( ITABase::CThirdOctaveMagnitudeSpectrum::GetNumBands() );
pDirectivityDataNew->getMagnitudes( oDirSoundPath.oDirectivityStateNew.iRecord, 0, &vfGains[ 0 ] );
oDirSoundPath.oSoundSourceDirectivityMagnitudes.SetMagnitudes( vfGains );
}
}
// Acknowledge new state
oDirSoundPath.oDirectivityStateCur = oDirSoundPath.oDirectivityStateNew;
// Reflected sound path
pDirectivityDataNew = ( DAFFContentMS* ) oRefSoundPath.oDirectivityStateNew.pData;
pDirectivityDataCur = ( DAFFContentMS* ) oRefSoundPath.oDirectivityStateCur.pData;
oRefSoundPath.oDirectivityStateNew.bDirectivityEnabled = true;
if( pDirectivityDataNew == nullptr )
{
// Directivity not yet set ... or removed
oRefSoundPath.oSoundSourceDirectivityMagnitudes.SetIdentity(); // set identity once
oRefSoundPath.oDirectivityStateNew.iRecord = -1;
}
else
{
// Update directivity data set
pDirectivityDataNew->getNearestNeighbour( DAFF_OBJECT_VIEW, float( oRefSoundPath.oRelations.dAzimuthS2L ), float( oRefSoundPath.oRelations.dElevationS2L ), oRefSoundPath.oDirectivityStateNew.iRecord );
if( oRefSoundPath.oDirectivityStateCur.iRecord != oRefSoundPath.oDirectivityStateNew.iRecord )
{
std::vector< float > vfGains( ITABase::CThirdOctaveMagnitudeSpectrum::GetNumBands() );
pDirectivityDataNew->getMagnitudes( oRefSoundPath.oDirectivityStateNew.iRecord, 0, &vfGains[ 0 ] );
oRefSoundPath.oSoundSourceDirectivityMagnitudes.SetMagnitudes( vfGains );
}
}
// Acknowledge new state
oRefSoundPath.oDirectivityStateCur = oRefSoundPath.oDirectivityStateNew;
return;
}
void CVABATNSoundPath::UpdateMediumPropagation( double dSpeedOfSound )
{
assert( dSpeedOfSound > 0 );
// Simple time delay by a direct line-of-sight propagation
oDirSoundPath.dPropagationTime = oDirSoundPath.oRelations.dDistance / dSpeedOfSound;
oRefSoundPath.dPropagationTime = oRefSoundPath.oRelations.dDistance / dSpeedOfSound;
}
void CVABATNSoundPath::UpdateTemporalVariation()
{
oDirSoundPath.oATVGenerator.getNoiseMagnitudes( oDirSoundPath.oTemporalVariationMagnitudes );
oRefSoundPath.oATVGenerator.getNoiseMagnitudes( oRefSoundPath.oTemporalVariationMagnitudes );
return;
}
void CVABATNSoundPath::UpdateAirAttenuation( const double dTemperatur, const double dPressure, const double dHumidity )
{
ITABase::ISO9613::AtmosphericAbsorption( oDirSoundPath.oAirAttenuationMagnitudes, oDirSoundPath.oRelations.dDistance, dTemperatur, dHumidity, dPressure );
ITABase::ISO9613::AtmosphericAbsorption( oRefSoundPath.oAirAttenuationMagnitudes, oRefSoundPath.oRelations.dDistance, dTemperatur, dHumidity, dPressure );
for( int n = 0; n < oDirSoundPath.oAirAttenuationMagnitudes.GetNumBands(); n++ )
oDirSoundPath.oAirAttenuationMagnitudes.SetMagnitude( n, 1 - oDirSoundPath.oAirAttenuationMagnitudes[ n ] );
for( int n = 0; n < oRefSoundPath.oAirAttenuationMagnitudes.GetNumBands(); n++ )
oRefSoundPath.oAirAttenuationMagnitudes.SetMagnitude( n, 1 - oRefSoundPath.oAirAttenuationMagnitudes[ n ] );
}
void CVABATNSoundPath::CalculateInverseDistanceDecrease()
{
// Gain limiter
const double MINIMUM_DISTANCE = 1 / db20_to_ratio( 10 );
double dDDistance = ( std::max )( ( double ) oDirSoundPath.oRelations.dDistance, MINIMUM_DISTANCE );
double dRDistance = ( std::max )( ( double ) oRefSoundPath.oRelations.dDistance, MINIMUM_DISTANCE );
assert( dDDistance > 0.0f );
assert( dRDistance > 0.0f );
oDirSoundPath.dGeometricalSpreadingLoss = 1.0f / dDDistance;
oRefSoundPath.dGeometricalSpreadingLoss = 1.0f / dRDistance;
}
void CVABATNSoundPath::UpdateSoundReceiverDirectivity()
{
CVADirectivityDAFFHRIR* pDirSoundPathHRIRDataNew = ( CVADirectivityDAFFHRIR * ) ( oDirSoundPath.oSoundReceiverDirectivityStateNew.pData );
bool bForeUpdate = false;
if( pDirSoundPathHRIRDataNew != nullptr )
{
// Quick check if nearest neighbour is equal
if( pDirSoundPathHRIRDataNew->GetProperties()->bSpaceDiscrete )
pDirSoundPathHRIRDataNew->GetNearestNeighbour( float( oDirSoundPath.oRelations.dAzimuthL2S ), float( oDirSoundPath.oRelations.dElevationL2S ), &oDirSoundPath.oSoundReceiverDirectivityStateNew.iRecord );
else
bForeUpdate = true; // Update always required, if non-discrete data
}
if( ( oDirSoundPath.oSoundReceiverDirectivityStateCur != oDirSoundPath.oSoundReceiverDirectivityStateNew ) || bForeUpdate )
{
ITAUPFilter* pHRIRFilterChL = oDirSoundPath.pFIRConvolverChL->GetFilterPool()->RequestFilter();
ITAUPFilter* pHRIRFilterChR = oDirSoundPath.pFIRConvolverChR->GetFilterPool()->RequestFilter();
if( pDirSoundPathHRIRDataNew == nullptr )
{
pHRIRFilterChL->identity();
pHRIRFilterChR->identity();
}
else
{
int iNewFilterLength = pDirSoundPathHRIRDataNew->GetProperties()->iFilterLength;
if( m_sfHRIRTemp.length() != iNewFilterLength )
{
m_sfHRIRTemp.init( 2, iNewFilterLength, false );
}
if( iNewFilterLength > oDirSoundPath.pFIRConvolverChL->GetMaxFilterlength() )
{
VA_WARN( "BATNSoundPath", "HRIR too long for convolver, cropping. Increase HRIR filter length in BinauralFreefieldAudioRenderer configuration." );
iNewFilterLength = oDirSoundPath.pFIRConvolverChL->GetMaxFilterlength();
}
if( pDirSoundPathHRIRDataNew->GetProperties()->bSpaceDiscrete )
{
pDirSoundPathHRIRDataNew->GetHRIRByIndex( &m_sfHRIRTemp, oDirSoundPath.oSoundReceiverDirectivityStateNew.iRecord, float( oDirSoundPath.oRelations.dDistance ) );
oDirSoundPath.oSoundReceiverDirectivityStateNew.fDistance = float( oDirSoundPath.oRelations.dDistance );
}
else
{
pDirSoundPathHRIRDataNew->GetHRIR( &m_sfHRIRTemp,
float( oDirSoundPath.oRelations.dAzimuthL2S ), float( oDirSoundPath.oRelations.dElevationL2S ), float( oDirSoundPath.oRelations.dDistance ) );
}
pHRIRFilterChL->Load( m_sfHRIRTemp[ 0 ].data(), iNewFilterLength );
pHRIRFilterChR->Load( m_sfHRIRTemp[ 1 ].data(), iNewFilterLength );
}
oDirSoundPath.pFIRConvolverChL->ExchangeFilter( pHRIRFilterChL );
oDirSoundPath.pFIRConvolverChR->ExchangeFilter( pHRIRFilterChR );
oDirSoundPath.pFIRConvolverChL->ReleaseFilter( pHRIRFilterChL );
oDirSoundPath.pFIRConvolverChR->ReleaseFilter( pHRIRFilterChR );
// Ack
oDirSoundPath.oSoundReceiverDirectivityStateCur = oDirSoundPath.oSoundReceiverDirectivityStateNew;
}
// Reflected sound path
CVADirectivityDAFFHRIR* pRefSoundPathHRIRDataNew = ( CVADirectivityDAFFHRIR * ) ( oRefSoundPath.oSoundReceiverDirectivityStateNew.pData );
bForeUpdate = false;
if( pRefSoundPathHRIRDataNew != nullptr )
{
// Quick check if nearest neighbour is equal
if( pRefSoundPathHRIRDataNew->GetProperties()->bSpaceDiscrete )
pRefSoundPathHRIRDataNew->GetNearestNeighbour( float( oRefSoundPath.oRelations.dAzimuthL2S ), float( oRefSoundPath.oRelations.dElevationL2S ), &oRefSoundPath.oSoundReceiverDirectivityStateNew.iRecord );
else
bForeUpdate = true; // Update always required, if non-discrete data
}
if( ( oRefSoundPath.oSoundReceiverDirectivityStateCur != oRefSoundPath.oSoundReceiverDirectivityStateNew ) || bForeUpdate )
{
ITAUPFilter* pHRIRFilterChL = oRefSoundPath.pFIRConvolverChL->GetFilterPool()->RequestFilter();
ITAUPFilter* pHRIRFilterChR = oRefSoundPath.pFIRConvolverChR->GetFilterPool()->RequestFilter();
if( pRefSoundPathHRIRDataNew == nullptr )
{
pHRIRFilterChL->identity();
pHRIRFilterChR->identity();
}
else
{
int iNewFilterLength = pRefSoundPathHRIRDataNew->GetProperties()->iFilterLength;
if( m_sfHRIRTemp.length() != iNewFilterLength )
{
m_sfHRIRTemp.init( 2, iNewFilterLength, false );
}
if( iNewFilterLength > oRefSoundPath.pFIRConvolverChL->GetMaxFilterlength() )
{
VA_WARN( "BATNSoundPath", "HRIR too long for convolver, cropping. Increase HRIR filter length in BinauralFreefieldAudioRenderer configuration." );
iNewFilterLength = oRefSoundPath.pFIRConvolverChL->GetMaxFilterlength();
}
if( pRefSoundPathHRIRDataNew->GetProperties()->bSpaceDiscrete )
{
pRefSoundPathHRIRDataNew->GetHRIRByIndex( &m_sfHRIRTemp, oRefSoundPath.oSoundReceiverDirectivityStateNew.iRecord, float( oRefSoundPath.oRelations.dDistance ) );
oRefSoundPath.oSoundReceiverDirectivityStateNew.fDistance = float( oRefSoundPath.oRelations.dDistance );
}
else
{
pRefSoundPathHRIRDataNew->GetHRIR( &m_sfHRIRTemp,
float( oRefSoundPath.oRelations.dAzimuthL2S ), float( oRefSoundPath.oRelations.dElevationL2S ), float( oRefSoundPath.oRelations.dDistance ) );
}
pHRIRFilterChL->Load( m_sfHRIRTemp[ 0 ].data(), iNewFilterLength );
pHRIRFilterChR->Load( m_sfHRIRTemp[ 1 ].data(), iNewFilterLength );
}
/* searching problem
oRefSoundPath.pFIRConvolverChL->ExchangeFilter( pHRIRFilterChL );
oRefSoundPath.pFIRConvolverChR->ExchangeFilter( pHRIRFilterChR );
oRefSoundPath.pFIRConvolverChL->ReleaseFilter( pHRIRFilterChL );
oRefSoundPath.pFIRConvolverChR->ReleaseFilter( pHRIRFilterChR );
*/
// Ack
oRefSoundPath.oSoundReceiverDirectivityStateCur = oRefSoundPath.oSoundReceiverDirectivityStateNew;
}
}
/*
* --------------------------------------------------------------------------------------------
*
* VVV VVV A Virtual Acoustics (VA) | http://www.virtualacoustics.org
* VVV VVV AAA Licensed under the Apache License, Version 2.0
* VVV VVV AAA
* VVV VVV AAA Copyright 2015-2018
* VVVVVV AAA Institute of Technical Acoustics (ITA)
* VVVV AAA RWTH Aachen University
*
* --------------------------------------------------------------------------------------------
*/
#ifndef IW_VACORE_BINAURAL_AIR_TRAFFIC_SOUND_PATH
#define IW_VACORE_BINAURAL_AIR_TRAFFIC_SOUND_PATH
#include "VAAirTrafficNoiseSoundSource.h"
#include "VAAirTrafficNoiseSoundReceiver.h"
// VA includes
#include <VA.h>
#include <VAObjectPool.h>
#include "../../../Motion/VAMotionModelBase.h"
#include "../../../Motion/VASharedMotionModel.h"
#include "../../../Scene/VAScene.h"
#include "../../../VASourceListenerMetrics.h"
#include "../../../core/core.h"
#include "../../../Filtering/VATemporalVariations.h"
#include "../../../directivities/VADirectivityDAFFEnergetic.h"
#include "../../../directivities/VADirectivityDAFFHRIR.h"
// ITA includes
#include <ITADataSourceRealization.h>
#include <ITASampleBuffer.h>
#include <ITAVariableDelayLine.h>
#include <ITAThirdOctaveMagnitudeSpectrum.h>
#include <ITAUPConvolution.h>
#include <ITAUPFilter.h>
#include <ITAUPFilterPool.h>
#include <ITAThirdOctaveFilterbank.h>
// 3rdParty includes
#include <tbb/concurrent_queue.h>
// STL Includes
class CVABATNSoundPath : public CVAPoolObject
{
public:
virtual ~CVABATNSoundPath();
//! Retarded metrics of sound path
class Metrics
{
public:
double dRetardedDistance; //!< Metrical distance to retarded sound position
VAQuat qAngleRetSourceToListener; //!< Immediate angle of incidence to retarded source position in listener reference frame in YPR convention
VAQuat qAngleListenerToRetSource; //!< Retarded angle of incidence to listener in source reference frame in YPR convention
};
//! State of directivity
class CSoundSourceDirectivityState
{
public:
inline CSoundSourceDirectivityState()
: pData( NULL )
, iRecord( -1 )
, bDirectivityEnabled( true ) {};