Commit 632ea5af authored by henryjandrew's avatar henryjandrew

gergee branc 'feature/reusable_clustering' of...

gergee branc 'feature/reusable_clustering' of https://git.rwth-aachen.de/ita/VACore into feature/reusable_clustering
parents 7d528cb1 48c9bf44
......@@ -280,6 +280,7 @@ if( ITA_VACORE_WITH_RENDERER_BINAURAL_FREE_FIELD )
add_definitions( "-DVACORE_WITH_RENDERER_BINAURAL_FREE_FIELD" )
endif( )
if( ITA_VACORE_WITH_RENDERER_BINAURAL_ARTIFICIAL_REVERB )
vista_use_package( DspFilters REQUIRED FIND_DEPENDENCIES )
add_definitions( "-DVACORE_WITH_RENDERER_BINAURAL_ARTIFICIAL_REVERB" )
endif( )
if( ITA_VACORE_WITH_RENDERER_BINAURAL_ROOM_ACOUSTICS )
......
......@@ -36,73 +36,72 @@ void CVABinauralClustering::RemoveWaveFront( int sourceID )
m_iDelWaveFrontIDs.insert( sourceID );
}
void CVABinauralClustering::Init( int listenerID, CVABinauralClusteringDirectionReceiver* listener, int numClusters )
void CVABinauralClustering::Init( int iSoundReceiverID, CVABinauralClusteringDirectionReceiver* pSoundReceiver, int iNumClusters )
{
m_iSoundReceiverID = listenerID;
pListener = listener;
m_iNumClusters = numClusters;
m_dDistanceThreshold = 4. / numClusters;
m_iSoundReceiverID = iSoundReceiverID;
m_pReceiver = pSoundReceiver;
m_iNumClusters = iNumClusters;
m_dDistanceThreshold = 4. / iNumClusters;
pOutput = new ITASampleFrame( 2, listener->pOutput->GetLength(), true );
m_pOutput = new ITASampleFrame( 2, pSoundReceiver->pOutput->GetLength(), true );
for( int i = 0; i < numClusters; ++i )
for( int i = 0; i < iNumClusters; ++i )
{
// initialize left channel convolver for each cluster
ITAUPConvolution * _FIRConvolverChL = new ITAUPConvolution( VAConfig::blockLength, VAConfig::hrirLength );
_FIRConvolverChL->SetFilterExchangeFadingFunction( ITABase::FadingFunction::COSINE_SQUARE );
_FIRConvolverChL->SetFilterCrossfadeLength( ( std::min )( VAConfig::blockLength, 32 ) );
_FIRConvolverChL->SetGain( 1.0f, true );
ITAUPConvolution* pFIRConvolverChL = new ITAUPConvolution( VAConfig::blockLength, VAConfig::hrirLength );
pFIRConvolverChL->SetFilterExchangeFadingFunction( ITABase::FadingFunction::COSINE_SQUARE );
pFIRConvolverChL->SetFilterCrossfadeLength( ( std::min )( VAConfig::blockLength, 32 ) );
pFIRConvolverChL->SetGain( 1.0f, true );
ITAUPFilter* HRIRFilterChL = _FIRConvolverChL->RequestFilter();
HRIRFilterChL->identity();
_FIRConvolverChL->ExchangeFilter( HRIRFilterChL );
_FIRConvolverChL->ReleaseFilter( HRIRFilterChL );
ITAUPFilter* pHRIRFilterChL = pFIRConvolverChL->RequestFilter();
pHRIRFilterChL->identity();
pFIRConvolverChL->ExchangeFilter( pHRIRFilterChL );
pFIRConvolverChL->ReleaseFilter( pHRIRFilterChL );
mFIRConvolversL.insert( std::pair< int, ITAUPConvolution* >( i, _FIRConvolverChL ) );
mFIRConvolversL.insert( std::pair< int, ITAUPConvolution* >( i, pFIRConvolverChL ) );
// initialize right channel convolver for each cluster
ITAUPConvolution * _FIRConvolverChR = new ITAUPConvolution( VAConfig::blockLength, VAConfig::hrirLength );
ITAUPConvolution* pFIRConvolverChR = new ITAUPConvolution( VAConfig::blockLength, VAConfig::hrirLength );
_FIRConvolverChR->SetFilterExchangeFadingFunction( ITABase::FadingFunction::COSINE_SQUARE );
_FIRConvolverChR->SetFilterCrossfadeLength( ( std::min )( VAConfig::blockLength, 32 ) );
_FIRConvolverChR->SetGain( 1.0f, true );
pFIRConvolverChR->SetFilterExchangeFadingFunction( ITABase::FadingFunction::COSINE_SQUARE );
pFIRConvolverChR->SetFilterCrossfadeLength( ( std::min )( VAConfig::blockLength, 32 ) );
pFIRConvolverChR->SetGain( 1.0f, true );
ITAUPFilter* HRIRFilterChR = _FIRConvolverChR->RequestFilter();
HRIRFilterChR->identity();
ITAUPFilter* pHRIRFilterChR = pFIRConvolverChR->RequestFilter();
pHRIRFilterChR->identity();
_FIRConvolverChR->ExchangeFilter( HRIRFilterChR );
_FIRConvolverChR->ReleaseFilter( HRIRFilterChR );
pFIRConvolverChR->ExchangeFilter( pHRIRFilterChR );
pFIRConvolverChR->ReleaseFilter( ^pHRIRFilterChR );
mFIRConvolversR.insert( std::pair< int, ITAUPConvolution* >( i, _FIRConvolverChR ) );
mFIRConvolversR.insert( std::pair< int, ITAUPConvolution* >( i, pFIRConvolverChR ) );
}
m_pCurState.reset( new CVABinauralClusteringState( m_iNumClusters, pListener, clusterPool, &mFIRConvolversL, &mFIRConvolversR ) );
m_pCurState.reset( new CVABinauralClusteringState( m_iNumClusters, m_pReceiver, clusterPool, &mFIRConvolversL, &mFIRConvolversR ) );
m_pPrevState = m_pCurState;
}
ITASampleFrame* CVABinauralClustering::GetOutput()
{
pOutput->zero();
m_pOutput->zero();
// swap out clustering state
if( m_pNextState != nullptr )
{
m_pCurState = m_pNextState;
}
std::map< int, CVABinauralClusteringDirection*>::const_iterator cit;
std::map< int, CVABinauralClusteringDirection* >::const_iterator cit;
for( cit = m_pCurState->clusters.begin(); cit != m_pCurState->clusters.end(); ++cit )
{
CVABinauralClusteringDirection* pClusteringDirection( cit->second );
ITASampleFrame* pClusteringDirectionOutput = pClusteringDirection->GetOutput();
( *pOutput )[ 0 ] += ( *pClusteringDirectionOutput )[ 0 ];
( *pOutput )[ 1 ] += ( *pClusteringDirectionOutput )[ 1 ];
( *m_pOutput )[ 0 ] += ( *pClusteringDirectionOutput )[ 0 ];
( *m_pOutput )[ 1 ] += ( *pClusteringDirectionOutput )[ 1 ];
// *pOutput += *pClusteringDirectionOutput; // @todo jst: switch to this implementation
}
return pOutput;
return m_pOutput;
}
void CVABinauralClustering::Update()
......@@ -113,7 +112,7 @@ void CVABinauralClustering::Update()
//VABinauralClusteringState* state = new VABinauralClusteringState(_numClusters, _listener, clusterPool, FIRConvolversL, FIRConvolversR); //new VABinauralClusteringState(*m_pCurState);
//std::shared_ptr<VABinauralClusteringState> state = std::make_shared<VABinauralClusteringState>(*_prevState);
std::shared_ptr<CVABinauralClusteringState> state = std::make_shared<CVABinauralClusteringState>( m_iNumClusters, pListener, clusterPool, &mFIRConvolversL, &mFIRConvolversR );
std::shared_ptr<CVABinauralClusteringState> state = std::make_shared<CVABinauralClusteringState>( m_iNumClusters, m_pReceiver, clusterPool, &mFIRConvolversL, &mFIRConvolversR );
// remove removed sources
std::set< int >::const_iterator it;
......
......@@ -17,7 +17,7 @@
#include "../Receiver/VABinauralClusteringDirectionReceiver.h"
#include "../WaveFront/VABinauralWaveFront.h"
//! Binaural clustering direction instance used for each binaural clustering direction receiver
//! Binaural clustering engine providing directional clustering of wave fronts for binaural a sound receiver
/**
* Processes the output by gathering processing data from all linked wave fronts.
* Convolves the clustering direction by an HRIR set using an FIR filter engine, while
......@@ -27,8 +27,6 @@
*/
class CVABinauralClustering : public CVAPoolObject
{
// friend VABinauralClusteringState;
public:
IVAObjectPool* clusterPool;
......@@ -38,22 +36,23 @@ public:
//! Initialize clustering instance for a binaural receiver
void Init( int iReceiverID, CVABinauralClusteringDirectionReceiver* pReceiver, int iNumClusters );
//! Processes the audio stream and returns the calculated samples
ITASampleFrame* GetOutput();
void Update();
void AddWaveFront( int sourceID, IVABinauralWaveFront* source );
void RemoveWaveFront( int sourceID );
void AddWaveFront( int iWaveFrontID, IVABinauralWaveFront* pWaveFront );
void RemoveWaveFront( int iWaveFrontID );
std::map< int, ITAUPConvolution* > mFIRConvolversL;
std::map< int, ITAUPConvolution* > mFIRConvolversR;
private:
int m_iSoundReceiverID;
int m_iNumClusters; //!< Cluster budget (maximum number of usable clusters)
double m_dDistanceThreshold; //!< Threshold for clustering algorithm (abstract "distance"), see MA 2019 Msch
ITASampleFrame* pOutput;
CVABinauralClusteringDirectionReceiver* pListener;
ITASampleFrame* m_pOutput;
CVABinauralClusteringDirectionReceiver* m_pReceiver;
std::set< int > m_iDelWaveFrontIDs;
......@@ -64,8 +63,6 @@ private:
std::map< int, IVABinauralWaveFront* > m_mUnassignedWaveFronts;
std::map< int, IVABinauralWaveFront* > m_mAssignedWaveFronts;
//std::pair< int, CVABinauralClusteringDirection* > AssignToClusteringDirection( CVABinauralClusteringState* pClusteringState, CVABinauralWaveFrontBase* pWaveFront, double dThreshold, int iNumFreeClusters );
void PreRequest();
void PreRelease();
};
......
......@@ -34,8 +34,8 @@ CVABinauralClusteringDirection::~CVABinauralClusteringDirection()
void CVABinauralClusteringDirection::Init( int iID, IVABinauralWaveFront* pWaveFront, CVABinauralClusteringDirectionReceiver* pReceiver, ITAUPConvolution* pFIRConvolverChL, ITAUPConvolution* pFIRConvolverChR )
{
m_pClusteringDirectionReceiver = pReceiver;
v3ClusteringDirectionPos = pWaveFront->GetPosition() - pReceiver->v3PredictedPosition;
v3ClusteringDirectionPos.Norm();
m_v3ClusteringDirectionPos = pWaveFront->GetPosition() - pReceiver->v3PredictedPosition;
m_v3ClusteringDirectionPos.Norm();
m_pFIRConvolverChL = pFIRConvolverChL;
m_pFIRConvolverChR = pFIRConvolverChR;
......@@ -64,7 +64,7 @@ void CVABinauralClusteringDirection::Init( int iID, IVABinauralWaveFront* pWaveF
void CVABinauralClusteringDirection::Init( CVABinauralClusteringDirection* pClusterDirection )
{
m_pClusteringDirectionReceiver = pClusterDirection->m_pClusteringDirectionReceiver;
v3ClusteringDirectionPos = pClusterDirection->v3ClusteringDirectionPos;
m_v3ClusteringDirectionPos = pClusterDirection->m_v3ClusteringDirectionPos;
const int iOutputLength = m_pClusteringDirectionReceiver->pOutput->GetLength();
......@@ -86,16 +86,16 @@ ITASampleFrame* CVABinauralClusteringDirection::GetOutput()
// Get time-of-arrival for this clustering direction
VARelationMetrics oClusterSourceMetrics;
oClusterSourceMetrics.calc( m_pClusteringDirectionReceiver->v3PredictedPosition, m_pClusteringDirectionReceiver->predView, m_pClusteringDirectionReceiver->predUp, m_pClusteringDirectionReceiver->v3PredictedPosition + v3ClusteringDirectionPos );
oClusterSourceMetrics.calc( m_pClusteringDirectionReceiver->v3PredictedPosition, m_pClusteringDirectionReceiver->predView, m_pClusteringDirectionReceiver->predUp, m_pClusteringDirectionReceiver->v3PredictedPosition + m_v3ClusteringDirectionPos );
// double toaHRTFChL = _listener->toaEstimator->getTOALeft(clusterSourceMetrics.phi, clusterSourceMetrics.theta);
// double toaHRTFChR = _listener->toaEstimator->getTOARight(clusterSourceMetrics.phi, clusterSourceMetrics.theta);
// @todo use listener orientation (quaternion?) to roate the ears in the global coordinate systems
double toaHRTFChL = m_pClusteringDirectionReceiver->pTimeOfArrivalEstimator->getTOA( VAVec3( -1, 0, 0 ), v3ClusteringDirectionPos );
double toaHRTFChR = m_pClusteringDirectionReceiver->pTimeOfArrivalEstimator->getTOA( VAVec3( 1, 0, 0 ), v3ClusteringDirectionPos );
double toaHRTFChL = m_pClusteringDirectionReceiver->pTimeOfArrivalEstimator->getTOA( VAVec3( -1, 0, 0 ), m_v3ClusteringDirectionPos );
double toaHRTFChR = m_pClusteringDirectionReceiver->pTimeOfArrivalEstimator->getTOA( VAVec3( 1, 0, 0 ), m_v3ClusteringDirectionPos );
// Process binaural sound sources connected to this clustering direction
// Process wave fronts connected to this clustering direction (binaurally)
std::map< int, IVABinauralWaveFront* >::const_iterator it;
for( it = m_mWaveFronts.begin(); it != m_mWaveFronts.end(); ++it )
{
......@@ -152,71 +152,67 @@ ITASampleFrame* CVABinauralClusteringDirection::GetOutput()
return m_psfOutput;
}
double CVABinauralClusteringDirection::GetDistError( IVABinauralWaveFront* source )
double CVABinauralClusteringDirection::GetDistError( IVABinauralWaveFront* pWaveFront )
{
VAVec3 sourceToListenerPos = source->GetPosition() - m_pClusteringDirectionReceiver->v3PredictedPosition;
VAVec3 dist;
sourceToListenerPos.Norm();
dist = sourceToListenerPos - v3ClusteringDirectionPos;
VAVec3 v3WaveFrontEmissionPoseToClusteringDirectionPos = pWaveFront->GetPosition() - m_pClusteringDirectionReceiver->v3PredictedPosition;
v3WaveFrontEmissionPoseToClusteringDirectionPos.Norm();
VAVec3 v3Distance;
v3Distance = v3WaveFrontEmissionPoseToClusteringDirectionPos - m_v3ClusteringDirectionPos;
return dist.Dot( dist );
return v3Distance.Dot( v3Distance ); // Error metric = squared distance
}
void CVABinauralClusteringDirection::AddWaveFront( int sourceID, IVABinauralWaveFront* source )
void CVABinauralClusteringDirection::AddWaveFront( int iWaveFrontID, IVABinauralWaveFront* pWaveFront )
{
VAVec3 sourceToListenerPos = source->GetPosition() - v3ReceiverPos;
double err = GetDistError( source );
VAVec3 v3WaveFrontEmssissionPosToReceiverPos = pWaveFront->GetPosition() - m_v3ReceiverPos;
v3WaveFrontEmssissionPosToReceiverPos.Norm();
sourceToListenerPos.Norm();
m_v3ClusteringDirectionPos = m_v3ClusteringDirectionPos + ( v3WaveFrontEmssissionPosToReceiverPos - m_v3ClusteringDirectionPos ) / ( iNumWaveFronts + 1 );
m_v3ClusteringDirectionPos.Norm();
v3ClusteringDirectionPos = v3ClusteringDirectionPos + ( sourceToListenerPos - v3ClusteringDirectionPos ) / ( iNumWaveFronts + 1 );
double dError = GetDistError( pWaveFront );
dMaxError = std::max( dError, dMaxError );
v3ClusteringDirectionPos.Norm();
dMaxError = std::max( err, dMaxError );
m_mWaveFronts.insert( std::pair<int, IVABinauralWaveFront*>( sourceID, source ) );
m_mWaveFronts.insert( std::pair<int, IVABinauralWaveFront*>( iWaveFrontID, pWaveFront ) );
// --
source->AddReference();
pWaveFront->AddReference();
++iNumWaveFronts;
}
void CVABinauralClusteringDirection::AddWaveFront( int sourceID, IVABinauralWaveFront* source, double error )
void CVABinauralClusteringDirection::AddWaveFront( int iWaveFrontID, IVABinauralWaveFront* pWaveFront, double dError )
{
VAVec3 sourceToListenerPos = source->GetPosition() - v3ReceiverPos;
double err = GetDistError( source );
sourceToListenerPos.Norm();
v3ClusteringDirectionPos = v3ClusteringDirectionPos + ( sourceToListenerPos - v3ClusteringDirectionPos ) / ( iNumWaveFronts + 1 );
VAVec3 v3WaveFrontEmittingPosToReceiverPos = pWaveFront->GetPosition() - m_v3ReceiverPos;
v3WaveFrontEmittingPosToReceiverPos.Norm();
double dDistanceError = GetDistError( pWaveFront );
dMaxError = std::max( dDistanceError, dMaxError );
v3ClusteringDirectionPos.Norm();
v3ClusteringDirectionToListenerPos = v3ClusteringDirectionPos - v3ReceiverPos;
m_v3ClusteringDirectionPos = m_v3ClusteringDirectionPos + ( v3WaveFrontEmittingPosToReceiverPos - m_v3ClusteringDirectionPos ) / ( iNumWaveFronts + 1 );
m_v3ClusteringDirectionPos.Norm(); // Projected to unity sphere ...
dMaxError = std::max( err, dMaxError );
m_v3ClusteringDirectionToReceiverPos = m_v3ClusteringDirectionPos - m_v3ReceiverPos;
m_mWaveFronts.insert( std::pair<int, IVABinauralWaveFront*>( sourceID, source ) );
m_mWaveFronts.insert( std::pair<int, IVABinauralWaveFront*>( iWaveFrontID, pWaveFront ) );
// --
source->AddReference();
pWaveFront->AddReference();
++iNumWaveFronts;
}
void CVABinauralClusteringDirection::RemoveWaveFront( int sourceID )
void CVABinauralClusteringDirection::RemoveWaveFront( int iWaveFrontID )
{
std::map< int, IVABinauralWaveFront* >::const_iterator it = m_mWaveFronts.find( sourceID );
IVABinauralWaveFront* source = it->second;
std::map< int, IVABinauralWaveFront* >::const_iterator it = m_mWaveFronts.find( iWaveFrontID );
IVABinauralWaveFront* pWaveFront = it->second;
m_mWaveFronts.erase( it );
source->RemoveReference();
pWaveFront->RemoveReference();
v3ClusteringDirectionPos = ( v3ClusteringDirectionPos * iNumWaveFronts - source->GetPosition() ) / ( iNumWaveFronts - 1 );
m_v3ClusteringDirectionPos = ( m_v3ClusteringDirectionPos * iNumWaveFronts - pWaveFront->GetPosition() ) / ( iNumWaveFronts - 1 );
//TODO: MaxError
--iNumWaveFronts;
......@@ -224,16 +220,15 @@ void CVABinauralClusteringDirection::RemoveWaveFront( int sourceID )
void CVABinauralClusteringDirection::PreRelease()
{
IVABinauralWaveFront* source;
IVABinauralWaveFront* pWaveFront;
std::map< int, IVABinauralWaveFront* >::const_iterator it;
// clear all references from this cluster
for( it = m_mWaveFronts.begin(); it != m_mWaveFronts.end(); )
{
source = it->second;
pWaveFront = it->second;
it = m_mWaveFronts.erase( it );
source->RemoveReference();
pWaveFront->RemoveReference();
}
}
......@@ -47,14 +47,14 @@ private:
ITASampleFrame* m_psfTempHRIR;
CVABinauralClusteringDirectionReceiver* m_pClusteringDirectionReceiver;
CVABinauralClusteringDirectionReceiver* m_pClusteringDirectionReceiver; // Receiver instance connected to this clustering direction (principle direction)
ITAUPConvolution* m_pFIRConvolverChL;
ITAUPConvolution* m_pFIRConvolverChR;
VAVec3 v3ReceiverPos;
VAVec3 v3ClusteringDirectionPos;
VAVec3 v3ClusteringDirectionToListenerPos;
VAVec3 m_v3ReceiverPos;
VAVec3 m_v3ClusteringDirectionPos; // Target position of the clustering direction projected to the unity sphere around receiver ( norm == 1 )
VAVec3 m_v3ClusteringDirectionToReceiverPos;
std::map< int, IVABinauralWaveFront* > m_mWaveFronts;
......@@ -64,4 +64,3 @@ private:
};
#endif // IW_VACORE_BINAURAL_CLUSTERING_DIRECTION
......@@ -38,7 +38,7 @@ public:
CVASharedMotionModel* pMotionModel;
IVADirectivity* pDirectivity;
VAVec3 v3PredictedPosition;
VAVec3 v3PredictedPosition; // @todo: remove and replace by a getter using the motion model.
VAVec3 predView;
VAVec3 predUp;
......@@ -46,7 +46,7 @@ public:
VABinauralTOAEstimator* pTimeOfArrivalEstimator;
CVABinauralClusteringDirectionReceiver( const CVACoreImpl* core, const Config& conf );
CVABinauralClusteringDirectionReceiver( const CVACoreImpl* pCore, const Config& oConf );
~CVABinauralClusteringDirectionReceiver();
void PreRequest();
......
......@@ -125,6 +125,7 @@ public:
return hasValidTrajectory;
};
// @todo jst: should be renamed to GetIncidenceDirection( v3TargetPos )
inline VAVec3 GetPosition()
{
return v3PredictedPos;
......
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