Refactoring clustering renderer, moved some code to virtual methods of the wave front class

parent af276202
#define NOMINMAX
#include <stdlib.h>
#include <math.h>
#include "VABinauralCluster.h"
// VA includes
#include "../../../../../directivities/VADirectivityDAFFHRIR.h"
// ITA includes
#include <ITAUPFilter.h>
#include <ITAUPFilterPool.h>
#include <ITAConstants.h>
// Utils
#include "../Config/VAConfig.h"
#include "../RelationMetrics/VARelationMetrics.h"
#include "../BinauralTimeOfArrivalEstimator/VABinauralTOAEstimator.h"
VABinauralCluster::VABinauralCluster()
{
_output = new ITASampleFrame(2, VAConfig::blockLength, true);
_tempHRIR = new ITASampleFrame(2, VAConfig::hrirLength, true);
}
VABinauralCluster::~VABinauralCluster()
{}
void
VABinauralCluster::init(int sourceID, VABinauralSoundSource* source, VABinauralListener* listener, ITAUPConvolution* firL, ITAUPConvolution* firR)
{
_listener = listener;
_clusterSourcePos = source->predPos - listener->predPos;
_clusterSourcePos.Norm();
_FIRConvolverChL = firL;
_FIRConvolverChR = firR;
int outputLength = listener->output->GetLength();
if (_output->length() != outputLength) _output->init(2, outputLength, true);
if (_tmpChL.length() != outputLength){
_tmpChL.Init(outputLength, true);
_tmpChR.Init(outputLength, true);
}
maxError = getDistError(source);
_sources.insert(std::pair<int, VABinauralSoundSource*>(sourceID, source));
// --
source->AddReference();
++numSources;
}
void
VABinauralCluster::init(VABinauralCluster* cluster)
{
_listener = cluster->_listener;
_clusterSourcePos = cluster->_clusterSourcePos;
int outputLength = _listener->output->GetLength();
if (_output->length() != outputLength) _output->init(2, outputLength, true);
_tmpChL.Init(_listener->output->GetLength(), true);
_tmpChR.Init(_listener->output->GetLength(), true);
numSources = 0;
}
ITASampleFrame*
VABinauralCluster::getOutput()
{
// reset output Buffer
_output->zero();
// get cluster HRTF TOA
VARelationMetrics clusterSourceMetrics;
clusterSourceMetrics.calc(_listener->predPos, _listener->predView, _listener->predUp, _listener->predPos + _clusterSourcePos);
// 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 = _listener->toaEstimator->getTOA(VAVec3(-1, 0, 0), _clusterSourcePos);
double toaHRTFChR = _listener->toaEstimator->getTOA(VAVec3(1, 0, 0), _clusterSourcePos);
// set VDL Values
std::map<int, VABinauralSoundSource*>::const_iterator it;
for (it = _sources.begin(); it != _sources.end(); ++it)
{
VABinauralSoundSource* source = it->second;
const ITASampleBuffer* input = source->data->pSignalSourceInputBuf;
VARelationMetrics sourceMetrics;
sourceMetrics.calc(_listener->predPos, _listener->predView, _listener->predUp, source->predPos);
double toaDistance = sourceMetrics.dist / 343; // TODO: Medium Propagation....
//double toaSourceChL = _listener->toaEstimator->getTOALeft(sourceMetrics.phi, sourceMetrics.theta);
//double toSourceaChR = _listener->toaEstimator->getTOARight(sourceMetrics.phi, sourceMetrics.theta);
double toaSourceChL = _listener->toaEstimator->getTOA(VAVec3(-1, 0, 0), source->predPos -_listener->predPos);
double toaSourceChR = _listener->toaEstimator->getTOA(VAVec3(1, 0, 0), source->predPos - _listener->predPos);
float gain = float((1/sourceMetrics.dist) * source->state->GetVolume(VAConfig::amplitudeCalibration));
// @todo finalize and use TOA estimation
// source->vdlChL->SetDelayTime(std::max(0., toaDistance + toaSourceChL - toaHRTFChL));
// source->vdlChR->SetDelayTime(std::max(0., toaDistance + toaSourceChR - toaHRTFChR));
source->vdlChL->SetDelayTime(toaDistance);
source->vdlChR->SetDelayTime(toaDistance);
source->vdlChL->Process(input, &(_tmpChL));
source->vdlChR->Process(input, &(_tmpChR));
_tmpChL.mul_scalar(gain);
_tmpChR.mul_scalar(gain);
(*_output)[0] += _tmpChL;
(*_output)[1] += _tmpChR;
}
// convolve here!
CVADirectivityDAFFHRIR* HRIR = (CVADirectivityDAFFHRIR *)_listener->directivity;
ITAUPFilter* HRIRFilterChL = _FIRConvolverChL->GetFilterPool()->RequestFilter();
ITAUPFilter* HRIRFilterChR = _FIRConvolverChR->GetFilterPool()->RequestFilter();
HRIRFilterChL->Zeros();
HRIRFilterChR->Zeros();
if (HRIR){
int index = -1;
int filterLength = 0;
filterLength = HRIR->GetProperties()->iFilterLength;
// @todo remove, because getHRIR will override sample frame values!
_tempHRIR->init(2, filterLength, true);
if (_tempHRIR->length() != filterLength)
{
_tempHRIR->init(2, filterLength, false);
}
float phi = clusterSourceMetrics.phi * 180 / ITAConstants::PI_F;
float theta = clusterSourceMetrics.theta * 180 / ITAConstants::PI_F;
// @todo use index getter, compare with last index and only exchange if necessary
// HRIR->GetHRIRByIndex()
HRIR->GetHRIR(_tempHRIR, clusterSourceMetrics.phi * 180 / ITAConstants::PI_F, clusterSourceMetrics.theta * 180 / ITAConstants::PI_F, clusterSourceMetrics.dist);
HRIRFilterChL->Load((*_tempHRIR)[0].data(), filterLength);
HRIRFilterChR->Load((*_tempHRIR)[1].data(), filterLength);
_FIRConvolverChL->ExchangeFilter(HRIRFilterChL);
_FIRConvolverChR->ExchangeFilter(HRIRFilterChR);
_FIRConvolverChL->ReleaseFilter(HRIRFilterChL);
_FIRConvolverChR->ReleaseFilter(HRIRFilterChR);
_FIRConvolverChL->Process((*_output)[0].data(), (*_output)[0].data(), ITABase::MixingMethod::OVERWRITE);
_FIRConvolverChR->Process((*_output)[1].data(), (*_output)[1].data(), ITABase::MixingMethod::OVERWRITE);
}
return _output;
}
double
VABinauralCluster::getDistError(VABinauralSoundSource* source)
{
VAVec3 sourceToListenerPos = source->predPos - _listener->predPos;
VAVec3 dist;
sourceToListenerPos.Norm();
dist = sourceToListenerPos - _clusterSourcePos;
return dist.Dot(dist);
}
void
VABinauralCluster::addSource(int sourceID, VABinauralSoundSource* source)
{
VAVec3 sourceToListenerPos = source->predPos - _listenerPos;
double err = getDistError(source);
sourceToListenerPos.Norm();
_clusterSourcePos = _clusterSourcePos + (sourceToListenerPos - _clusterSourcePos) / (numSources + 1);
_clusterSourcePos.Norm();
maxError = std::max(err, maxError);
_sources.insert(std::pair<int, VABinauralSoundSource*>(sourceID, source));
// --
source->AddReference();
++numSources;
}
void
VABinauralCluster::addSource(int sourceID, VABinauralSoundSource* source, double error)
{
VAVec3 sourceToListenerPos = source->predPos - _listenerPos;
double err = getDistError(source);
sourceToListenerPos.Norm();
_clusterSourcePos = _clusterSourcePos + (sourceToListenerPos - _clusterSourcePos) / (numSources + 1);
_clusterSourcePos.Norm();
_clusterSourceToListenerPos = _clusterSourcePos - _listenerPos;
maxError = std::max(err, maxError);
_sources.insert(std::pair<int, VABinauralSoundSource*>(sourceID, source));
// --
source->AddReference();
++numSources;
}
void
VABinauralCluster::removeSource(int sourceID)
{
std::map<int, VABinauralSoundSource*>::const_iterator it = _sources.find(sourceID);
VABinauralSoundSource* source = it->second;
_sources.erase(it);
source->RemoveReference();
_clusterSourcePos = (_clusterSourcePos * numSources - source->predPos) / (numSources - 1);
//TODO: MaxError
--numSources;
}
void
VABinauralCluster::PreRelease()
{
VABinauralSoundSource* source;
std::map<int, VABinauralSoundSource*>::const_iterator it;
// clear all references from this cluster
for (it = _sources.begin(); it != _sources.end();)
{
source = it->second;
it = _sources.erase(it);
source->RemoveReference();
}
}
#ifndef IW_VACORE_BINAURALCLUSTER
#define IW_VACORE_BINAURALCLUSTER
// VA Includes
#include <VA.h>
// ITA includes
#include <ITAUPConvolution.h>
// Utils
#include "../BinauralSoundSource/VABinauralSoundSource.h"
#include "../BinauralListener/VABinauralListener.h"
class VABinauralCluster : public CVAPoolObject
{
public:
int numSources;
double maxError;
VABinauralCluster();
~VABinauralCluster();
void
init(int sourceID, VABinauralSoundSource* source, VABinauralListener* listener, ITAUPConvolution* firL, ITAUPConvolution* firR);
void
init(VABinauralCluster* cluster);
ITASampleFrame*
getOutput();
double
getDistError(VABinauralSoundSource* source);
void
addSource(int sourceID, VABinauralSoundSource* source);
void
addSource(int sourceID, VABinauralSoundSource* source, double error);
void
removeSource(int sourceID);
void
reset();
void
PreRelease();
private:
ITASampleBuffer _tmpChL;
ITASampleBuffer _tmpChR;
ITASampleFrame* _output;
ITASampleFrame* _tempHRIR;
VABinauralListener* _listener;
ITAUPConvolution* _FIRConvolverChL;
ITAUPConvolution* _FIRConvolverChR;
VAVec3 _listenerPos;
VAVec3 _clusterSourcePos;
VAVec3 _clusterSourceToListenerPos;
std::map<int, VABinauralSoundSource* > _sources;
double
cummulativeMovingAverage(int n, double average, double value);
};
#endif // IW_VACORE_BINAURALCLUSTER
\ No newline at end of file
......@@ -7,86 +7,80 @@
#include "./VABinauralClusteringPoolFactory.h">
VABinauralClusterEngine::VABinauralClusterEngine()
CVABinauralClusteringEngine::CVABinauralClusteringEngine()
{
IVAPoolObjectFactory* clusteringFactory = new VABinauralClusteringPoolFactory();
_clusteringPool = IVAObjectPool::Create(16, 2, clusteringFactory, true);
IVAPoolObjectFactory* clusteringFactory = new CVABinauralClusteringPoolFactory();
m_pClusteringPool = IVAObjectPool::Create( 16, 2, clusteringFactory, true );
}
VABinauralClusterEngine::~VABinauralClusterEngine()
CVABinauralClusteringEngine::~CVABinauralClusteringEngine()
{
}
void
VABinauralClusterEngine::update()
void CVABinauralClusteringEngine::Update()
{
for (auto const& clustering : _clusterings)
for( auto const& clustering : m_mClusteringInstances )
{
clustering.second->update();
clustering.second->Update();
}
}
VABinauralClustering*
VABinauralClusterEngine::getClustering(const int listenerID)
CVABinauralClustering* CVABinauralClusteringEngine::GetClustering( const int iReceiverID )
{
const int id = listenerID;
const int id = iReceiverID;
auto it = _clusterings.find(id);
auto it = m_mClusteringInstances.find( id );
return it->second;
}
void
VABinauralClusterEngine::addSource( int sourceID, VABinauralSoundSource* source )
void CVABinauralClusteringEngine::AddWaveFront( int sourceID, CVABinauralWaveFrontBase* source )
{
std::map< int, VABinauralClustering* >::iterator it;
for (it = _clusterings.begin(); it != _clusterings.end(); ++it)
std::map< int, CVABinauralClustering* >::iterator it;
for( it = m_mClusteringInstances.begin(); it != m_mClusteringInstances.end(); ++it )
{
it->second->addSource(sourceID, source);
it->second->AddWaveFront( sourceID, source );
}
_sources.insert(std::pair< int, VABinauralSoundSource* >(sourceID, source));
m_mCurrentWaveFronts.insert( std::pair< int, CVABinauralWaveFrontBase* >( sourceID, source ) );
}
void
VABinauralClusterEngine::removeSource(int sourceID)
CVABinauralClusteringEngine::RemoveWaveFront( int iID )
{
std::map< int, VABinauralClustering* >::iterator it;
for (it = _clusterings.begin(); it != _clusterings.end(); ++it)
std::map< int, CVABinauralClustering* >::iterator it;
for( it = m_mClusteringInstances.begin(); it != m_mClusteringInstances.end(); ++it )
{
it->second->removeSource(sourceID);
it->second->RemoveWaveFront( iID );
}
}
void
VABinauralClusterEngine::addListener(int listenerID, VABinauralListener* listener, clusterConfig_t& conf)
void CVABinauralClusteringEngine::AddReceiver( int listenerID, CVABinauralClusteringDirectionReceiver* listener, Config& conf )
{
VABinauralClustering* clustering = dynamic_cast< VABinauralClustering* >(_clusteringPool->RequestObject()); // Reference = 1
CVABinauralClustering* clustering = dynamic_cast< CVABinauralClustering* >( m_pClusteringPool->RequestObject() ); // Reference = 1
clustering->init(listenerID, listener, conf.numCluster);
clustering->Init( listenerID, listener, conf.iNumClusters );
// add local reference
_clusterings.insert(std::pair< int, VABinauralClustering* >(listenerID, clustering));
_listeners.insert(std::pair< int, VABinauralListener* >(listenerID, listener));
m_mClusteringInstances.insert( std::pair< int, CVABinauralClustering* >( listenerID, clustering ) );
m_mReceivers.insert( std::pair< int, CVABinauralClusteringDirectionReceiver* >( listenerID, listener ) );
// add preexisting sources
for (auto const& sourceIt : _sources)
for( auto const& sourceIt : m_mCurrentWaveFronts )
{
clustering->addSource(sourceIt.first, sourceIt.second);
clustering->AddWaveFront( sourceIt.first, sourceIt.second );
}
}
void
VABinauralClusterEngine::removeListener(int listenerID)
void CVABinauralClusteringEngine::RemoveReceiver( int listenerID )
{
std::map< int, VABinauralClustering* >::iterator it = _clusterings.find(listenerID);
VABinauralClustering* clustering = it->second;
_clusterings.erase(it);
std::map< int, CVABinauralClustering* >::iterator it = m_mClusteringInstances.find( listenerID );
CVABinauralClustering* clustering = it->second;
m_mClusteringInstances.erase( it );
clustering->RemoveReference();
/*
TODO: foreach cluster in CL delete cluster
*/
*/
}
#ifndef IW_VACORE_BINAURALCLUSTERENGINE
#define IW_VACORE_BINAURALCLUSTERENGINE
#ifndef IW_VACORE_BINAURAL_CLUSTERING_ENGINE
#define IW_VACORE_BINAURAL_CLUSTERING_ENGINE
// VA includes
#include <VA.h>
// ITA includes
// Utils
#include "../BinauralListener/VABinauralListener.h"
#include "../BinauralSoundSource/VABinauralSoundSource.h"
#include "./VABinauralClustering.h"
#include "./VABinauralCluster.h"
#include "./VABinauralClusteringDirection.h"
class VABinauralClusterEngine
//! Single managing instance that handles the entire clustering for all receivers
/**
* @todo rename source files
*/
class CVABinauralClusteringEngine
{
public:
struct clusterConfig_t {
int numCluster;
struct Config
{
int iNumClusters;
};
std::map< int, VABinauralClustering* > _clusterings;
//! Initialize clustering engine
~CVABinauralClusteringEngine();
CVABinauralClusteringEngine();
~VABinauralClusterEngine();
//! Managing instance that handles the entire clustering for all receivers
VABinauralClusterEngine();
// Handles scene updates
void Update();
void
update();
//! Returns pointer to clustering instance for a receiver
CVABinauralClustering* GetClustering( const int iReceiverID );
VABinauralClustering*
getClustering(const int listenerID);
//! Adds a new wave front
void AddWaveFront( int iWaveFrontID, CVABinauralWaveFrontBase* pWaveFront );
void
addSource( int sourceID, VABinauralSoundSource* source );
//! Removes a wave front
void RemoveWaveFront( int iWaveFrontID );
void
addListener( int listenerID, VABinauralListener* listener,clusterConfig_t& conf );
//! Adds a new receiver
void AddReceiver( int iListenerID, CVABinauralClusteringDirectionReceiver* pReceiver, Config& oConf );
void
removeListener( int listenerID );
//! Removes a receiver
void RemoveReceiver( int iListenerID );
void
removeSource( int sourceID );
std::map< int, CVABinauralClustering* > m_mClusteringInstances;
private:
std::map< int, VABinauralSoundSource* > _newSources;
IVAObjectPool* _sourcePool;
IVAObjectPool* _clusteringPool;
std::map< int, VABinauralSoundSource* > _sources;
std::map< int, VABinauralListener* > _listeners;
//IVAObjectPool* m_pWaveFrontPool;
IVAObjectPool* m_pClusteringPool;
std::map< int, CVABinauralWaveFrontBase* > m_mNewWaveFronts;
std::map< int, CVABinauralWaveFrontBase* > m_mCurrentWaveFronts;
std::map< int, CVABinauralClusteringDirectionReceiver* > m_mReceivers;
};
#endif // IW_VACORE_BINAURALCLUSTERENGINE
#endif // IW_VACORE_BINAURAL_CLUSTERING_ENGINE
#include "VABinauralClusterPoolFactory.h"
// Utils
#include "./VABinauralCluster.h"
#include "./VABinauralClusteringDirection.h"
VABinauralClusterPoolFactory::VABinauralClusterPoolFactory()
CVABinauralClusteringDirectionPoolFactory::CVABinauralClusteringDirectionPoolFactory()
{
}
VABinauralClusterPoolFactory::~VABinauralClusterPoolFactory()
CVABinauralClusteringDirectionPoolFactory::~CVABinauralClusteringDirectionPoolFactory()
{
}
CVAPoolObject*
VABinauralClusterPoolFactory::CreatePoolObject()
CVAPoolObject* CVABinauralClusteringDirectionPoolFactory::CreatePoolObject()
{