Commit ffeae456 authored by Lucas Moesch's avatar Lucas Moesch

Added TOAEstimator and implemented ITD in clusters.

parent 2ab5d6f6
#define NOMINMAX
#include <math.h>
#include "VABinauralCluster.h"
// Utils
#include "../BinauralTimeOfArrivalEstimator/VABinauralTOAEstimator.h"
VABinauralCluster::VABinauralCluster()
{
}
......@@ -15,25 +21,87 @@ VABinauralCluster::VABinauralCluster(const VABinauralCluster& cluster) :
VABinauralCluster::~VABinauralCluster()
{
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();
}
}
void
VABinauralCluster::init(int sourceID, VABinauralSoundSource* source)
VABinauralCluster::init(int sourceID, VABinauralSoundSource* source, VABinauralListener* listener)
{
_listener = listener;
_listenerPos = listener->predPos;
_clusterSourcePos = _clusterSourcePos + source->predPos;
_clusterSourceToListenerPos = _clusterSourcePos - _listenerPos;
_output = new ITASampleFrame(2, listener->output->GetLength(), true);
_tmpChL.Init(listener->output->GetLength(), true);
_tmpChR.Init(listener->output->GetLength(), true);
maxError = getDistError(source);
_sources.insert(std::pair<int, VABinauralSoundSource*>(sourceID, source));
// --
source->AddReference();
++_numSources;
}
ITASampleFrame*
VABinauralCluster::getOutput()
{
// reset output Buffer
_output->zero();
// 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;
VAVec3 sourceToListenerPos = source->predPos - _listenerPos;
sourceToListenerPos.Norm();
double phi = atan2(sourceToListenerPos.y, sourceToListenerPos.x);
double theta = acos(sourceToListenerPos.z);
// add general distance VDL
double toaChL = _listener->toaEstimator->getTOALeft(phi, theta);
double toaChR = _listener->toaEstimator->getTOARight(phi, theta);
source->vdlChL->SetDelayTime(toaChL);
source->vdlChR->SetDelayTime(toaChR);
source->vdlChL->Process(input, &(_tmpChL));
source->vdlChR->Process(input, &(_tmpChR));
(*_output)[0] += _tmpChL;
(*_output)[1] += _tmpChR;
}
// convolve
return _output;
}
double
VABinauralCluster::getDistError(VABinauralSoundSource* source)
{
double dotp = _clusterSourcePos.Dot(source->predPos);
VAVec3 sourceToListenerPos = source->predPos - _listenerPos;
double dotp = _clusterSourceToListenerPos.Dot(sourceToListenerPos);
return ((dotp * dotp) / (_clusterSourcePos.Dot(_clusterSourcePos)) * (source->predPos.Dot(source->predPos)));
return (dotp * dotp) / (_clusterSourcePos.Dot(_clusterSourcePos) * sourceToListenerPos.Dot(sourceToListenerPos));
}
void
......@@ -42,19 +110,30 @@ VABinauralCluster::addSource(int sourceID, VABinauralSoundSource* source)
double err = getDistError(source);
_clusterSourcePos = (source->predPos + _clusterSourcePos * _numSources) / (_numSources + 1);
_clusterSourceToListenerPos = _clusterSourcePos - _listenerPos;
maxError = std::max(err, maxError);
_sources.insert(std::pair<int, VABinauralSoundSource*>(sourceID, source));
// --
source->AddReference();
++_numSources;
}
void
VABinauralCluster::addSource(VABinauralSoundSource* source, double error)
VABinauralCluster::addSource(int sourceID, VABinauralSoundSource* source, double error)
{
_clusterSourcePos = (source->predPos + _clusterSourcePos * _numSources) / (_numSources + 1);
_clusterSourceToListenerPos = _clusterSourcePos - _listenerPos;
maxError = std::max(error, maxError);
_sources.insert(std::pair<int, VABinauralSoundSource*>(sourceID, source));
// --
source->AddReference();
++_numSources;
}
......@@ -6,6 +6,7 @@
// Utils
#include "../BinauralSoundSource/VABinauralSoundSource.h"
#include "../BinauralListener/VABinauralListener.h"
class VABinauralCluster : public CVAPoolObject
......@@ -20,7 +21,10 @@ public:
~VABinauralCluster();
void
init(int sourceID, VABinauralSoundSource* source);
init(int sourceID, VABinauralSoundSource* source, VABinauralListener* listener);
ITASampleFrame*
getOutput();
double
getDistError(VABinauralSoundSource* source);
......@@ -29,7 +33,7 @@ public:
addSource(int sourceID, VABinauralSoundSource* source);
void
addSource(VABinauralSoundSource* source, double error);
addSource(int sourceID, VABinauralSoundSource* source, double error);
void
removeSource();
......@@ -39,9 +43,20 @@ public:
private:
int _numSources;
std::map<int, VABinauralSoundSource* > _sources;
ITASampleBuffer _tmpChL;
ITASampleBuffer _tmpChR;
ITASampleFrame* _output;
VABinauralListener* _listener;
VAVec3 _listenerPos;
VAVec3 _clusterSourcePos;
VAVec3 _clusterSourceToListenerPos;
std::map<int, VABinauralSoundSource* > _sources;
double
cummulativeMovingAverage(int n, double average, double value);
......
......@@ -24,6 +24,14 @@ VABinauralClusterEngine::update()
}
}
VABinauralClustering*
VABinauralClusterEngine::getClustering(int listenerID)
{
std::map< int, VABinauralClustering* >::iterator it = _clusterings.find(listenerID);
return it->second;
}
void
VABinauralClusterEngine::addSource( int sourceID, VABinauralSoundSource* source )
{
......@@ -50,9 +58,11 @@ void
VABinauralClusterEngine::removeListener(int listenerID)
{
std::map< int, VABinauralClustering* >::iterator it = _clusterings.find(listenerID);
VABinauralClustering* listener = it->second;
VABinauralClustering* clustering = it->second;
_clusterings.erase(it);
clustering->RemoveReference();
/*
TODO: foreach cluster in CL delete cluster
*/
......
......@@ -28,6 +28,9 @@ public:
void
update();
VABinauralClustering*
getClustering(int listenerID);
void
addSource( int sourceID, VABinauralSoundSource* source );
......
......@@ -12,13 +12,13 @@
#include "./VABinauralClustering.h"
#include "./VABinauralClusterPoolFactory.h"
VABinauralClustering::~VABinauralClustering()
VABinauralClustering::VABinauralClustering()
{
IVAPoolObjectFactory* clusterFactory = new VABinauralClusterPoolFactory();
_clusterPool = IVAObjectPool::Create(16, 2, clusterFactory, true);
};
VABinauralClustering::VABinauralClustering(){};
VABinauralClustering::~VABinauralClustering(){};
void
VABinauralClustering::addSource(int sourceID, VABinauralSoundSource* source)
......@@ -33,12 +33,31 @@ VABinauralClustering::init(int listenerID, VABinauralListener* listener, int num
_listener = listener;
_numClusters = numClusters;
_threshold = cos(180. / numClusters) * cos(180. / numClusters);
_output = new ITASampleFrame(2, listener->output->GetLength(), true);
_curState.reset(new VABinauralClusteringState(_numClusters, _listener));
}
VABinauralClustering::binauralOutput_t
ITASampleFrame*
VABinauralClustering::getOutput()
{
_curState.reset(_nextState.release());
{
// --
_output->zero();
// swap out clustering state
_curState.reset(_nextState.release()); //TODO: only if next State is not null!
std::map< int, VABinauralCluster*>::const_iterator it;
for (it = _curState->clusters.begin(); it != _curState->clusters.end(); ++it)
{
ITASampleFrame* clusterOutput = it->second->getOutput();
(*_output)[0] += (*clusterOutput)[0];
(*_output)[1] += (*clusterOutput)[1];
}
return _output;
}
void
......@@ -56,6 +75,7 @@ VABinauralClustering::update()
}
// TODO: refinement
for (it = _unassignedSources.begin(); it != _unassignedSources.end(); ++it)
{
_assignedSources.insert(std::pair< int, VABinauralSoundSource* >(it->first, it->second));
......
......@@ -12,15 +12,13 @@
#include "VABinauralClusteringState.h"
#include "../BinauralListener/VABinauralListener.h"
#include "../BinauralSoundSource/VABinauralSoundSource.h"
#include "../BinauralTimeOfArrivalEstimator/VABinauralTOAEstimator.h"
class VABinauralClustering : public CVAPoolObject
{
public:
struct binauralOutput_t {
ITASampleBuffer outputChL;
ITASampleBuffer outputChR;
};
// friend VABinauralClusteringState;
public:
~VABinauralClustering();
VABinauralClustering();
......@@ -28,7 +26,7 @@ public:
void
init(int listenerID, VABinauralListener* listener, int numClusters);
binauralOutput_t
ITASampleFrame*
getOutput();
void
......@@ -43,6 +41,8 @@ private:
int _numClusters;
double _threshold;
ITASampleFrame* _output;
std::unique_ptr<VABinauralClusteringState> _curState;
std::unique_ptr<VABinauralClusteringState> _nextState;
......
......@@ -10,7 +10,9 @@
#include "./VABinauralClusterPoolFactory.h"
VABinauralClusteringState::VABinauralClusteringState(int numClusters)
VABinauralClusteringState::VABinauralClusteringState(int numClusters, VABinauralListener* listener) :
numClusters(numClusters),
listener(listener)
{
for (int i = numClusters - 1; i >= 0; --i)
{
......@@ -25,6 +27,7 @@ VABinauralClusteringState::~VABinauralClusteringState()
VABinauralClusteringState::VABinauralClusteringState(const VABinauralClusteringState& state) :
numClusters(state.numClusters),
listener(state.listener),
sourceClusterReference(state.sourceClusterReference)
{
std::map< int, VABinauralCluster* >::const_iterator it;
......@@ -68,7 +71,7 @@ VABinauralClusteringState::addSource(int sourceID, VABinauralSoundSource* source
nearestCluster = p.second;
}
nearestCluster->addSource(source, minerr);
nearestCluster->addSource(sourceID, source, minerr);
sourceClusterReference.insert(std::pair< int, int >(sourceID, nearestClusterID));
}
......@@ -78,7 +81,7 @@ VABinauralClusteringState::createCluster(int sourceID, VABinauralSoundSource* s
int clusterID = freeClusterIDs.back();
VABinauralCluster* cluster = dynamic_cast< VABinauralCluster* >(_clusterPool->RequestObject()); // Reference = 1
cluster->init(sourceID, source);
cluster->init(sourceID, source, listener);
clusters.insert(std::pair< int, VABinauralCluster* >(clusterID, cluster));
freeClusterIDs.pop();
......
......@@ -10,6 +10,7 @@
// Utils
#include "VABinauralCluster.h"
#include "../BinauralSoundSource/VABinauralSoundSource.h"
#include "../BinauralListener/VABinauralListener.h"
class VABinauralClusteringState
{
......@@ -20,7 +21,9 @@ public:
std::map< int, int> sourceClusterReference;
std::map< int, VABinauralCluster* > clusters;
VABinauralClusteringState(int numClusters);
VABinauralListener* listener;
VABinauralClusteringState(int numClusters, VABinauralListener* listener);
VABinauralClusteringState(const VABinauralClusteringState& state);
......
......@@ -22,13 +22,16 @@ VABinauralListener::PreRequest()
listenerMotionConf.dWindowSize = _conf.motionModelWindowSize;
listenerMotionConf.iNumHistoryKeys = _conf.motionModelNumHistoryKeys;
sfOutput = new ITASampleFrame(
output = new ITASampleFrame(
2,
_core->GetCoreConfig()->oAudioDriverConfig.iBuffersize,
true
);
motionModel = new CVASharedMotionModel(new CVABasicMotionModel(listenerMotionConf), true);
// TODO: load HRTF from some kind of config
toaEstimator = new VABinauralTOAEstimator();
data = nullptr;
}
......
......@@ -13,6 +13,9 @@
// ITA includes
#include <ITASampleFrame.h>
// Utils
#include "../BinauralTimeOfArrivalEstimator/VABinauralTOAEstimator.h"
class VABinauralListener : public CVAPoolObject
{
public:
......@@ -33,7 +36,9 @@ public:
VAVec3 prefView;
VAVec3 predUp;
ITASampleFrame* sfOutput;
ITASampleFrame* output;
VABinauralTOAEstimator* toaEstimator;
VABinauralListener(const CVACoreImpl* core, const config_t& conf);
......
......@@ -2,10 +2,10 @@
VABinauralSoundSource::VABinauralSoundSource(const config_t& conf) :
_conf( conf )
conf( conf )
{
vdlChL = new CITAVariableDelayLine(_conf.sampleRate, _conf.blockLength, 3. * _conf.sampleRate, CITAVariableDelayLine::CUBIC_SPLINE_INTERPOLATION);
vdlChR = new CITAVariableDelayLine(_conf.sampleRate, _conf.blockLength, 3. * _conf.sampleRate, CITAVariableDelayLine::CUBIC_SPLINE_INTERPOLATION);
vdlChL = new CITAVariableDelayLine(conf.sampleRate, conf.blockLength, 3. * conf.sampleRate, CITAVariableDelayLine::CUBIC_SPLINE_INTERPOLATION);
vdlChR = new CITAVariableDelayLine(conf.sampleRate, conf.blockLength, 3. * conf.sampleRate, CITAVariableDelayLine::CUBIC_SPLINE_INTERPOLATION);
}
......@@ -18,11 +18,11 @@ VABinauralSoundSource::PreRequest()
{
CVABasicMotionModel::Config sourceMotionConf;
sourceMotionConf.bLogEstimatedOutputEnabled = _conf.motionModelLogEstimated;
sourceMotionConf.bLogInputEnabled = _conf.motionModelLogInput;
sourceMotionConf.dWindowDelay = _conf.motionModelWindowDelay;
sourceMotionConf.dWindowSize = _conf.motionModelWindowSize;
sourceMotionConf.iNumHistoryKeys = _conf.motionModelNumHistoryKeys;
sourceMotionConf.bLogEstimatedOutputEnabled = conf.motionModelLogEstimated;
sourceMotionConf.bLogInputEnabled = conf.motionModelLogInput;
sourceMotionConf.dWindowDelay = conf.motionModelWindowDelay;
sourceMotionConf.dWindowSize = conf.motionModelWindowSize;
sourceMotionConf.iNumHistoryKeys = conf.motionModelNumHistoryKeys;
motionModel = new CVASharedMotionModel(new CVABasicMotionModel(sourceMotionConf), true);
data = nullptr;
......
......@@ -28,6 +28,8 @@ public:
int blockLength;
};
const config_t conf;
CVASoundSourceDesc* data;
CVASharedMotionModel* motionModel;
CITAVariableDelayLine* vdlChL;
......@@ -47,7 +49,6 @@ public:
PreRelease();
private:
const config_t _conf;
double _dCreationTimeStamp;
};
......
#define _USE_MATH_DEFINES
#define SPEEDOFSOUND 343
#define HEADRADIUS 0.06
#define DELAY HEADRADIUS / SPEEDOFSOUND
#include "VABinauralTOAEstimator.h"
#include <math.h>
VABinauralTOAEstimator::VABinauralTOAEstimator()
{
}
VABinauralTOAEstimator::~VABinauralTOAEstimator()
{
}
double
VABinauralTOAEstimator::getTOALeft(double phi, double theta)
{
return DELAY * ((sin(phi) * cos(theta) / 2) + 1);
}
double
VABinauralTOAEstimator::getTOARight(double phi, double theta)
{
return DELAY * ((sin(phi - M_PI) * cos(theta) / 2) + 1);
}
#ifndef IW_VACORE_BINAURALTIMEOFARRIVALESTIMATOR
#define IW_VACORE_BINAURALTIMEOFARRIVALESTIMATOR
class VABinauralTOAEstimator
{
public:
VABinauralTOAEstimator();
~VABinauralTOAEstimator();
double
getTOALeft(double phi, double theta);
double
getTOARight(double phi, double theta);
};
#endif // IW_VACORE_BINAURALTIMEOFARRIVALESTIMATOR
\ No newline at end of file
# $Id:$
set( RelativeDir "src/Rendering/Binaural/RealTime/Utils/BinauralTimeOfArrivalEstimator" )
set( RelativeSourceGroup "Source Files\\Rendering\\Binaural\\Realtime\\Utils\\BinauralTimeOfArrivalEstimator" )
set( DirFiles
VABinauralTOAEstimator.cpp
VABinauralTOAEstimator.h
_SourceFiles.cmake
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
set( LocalSourceGroupFiles )
foreach( File ${DirFiles} )
list( APPEND LocalSourceGroupFiles "${RelativeDir}/${File}" )
list( APPEND ProjectSources "${RelativeDir}/${File}" )
endforeach()
source_group( ${DirFiles_SourceGroup} FILES ${LocalSourceGroupFiles} )
......@@ -2,7 +2,7 @@
set( RelativeDir "src/Rendering/Binaural/Realtime/Utils" )
set( RelativeSourceGroup "Source Files\\Rendering\\Binaural\\Realtime\\Utils" )
set( SubDirs BinauralListener BinauralClusterEngine BinauralSoundSource)
set( SubDirs BinauralListener BinauralClusterEngine BinauralSoundSource BinauralTimeOfArrivalEstimator)
set( DirFiles
_SourceFiles.cmake
......
......@@ -19,7 +19,8 @@
#include "./Utils/BinauralListener/VABinauralListenerPoolFactory.h"
#include "./Utils/BinauralSoundSource/VABinauralSoundSourcePoolFactory.h"
VABinauralRealTimeRenderer::VABinauralRealTimeRenderer( const CVAAudioRendererInitParams& params ) :
VABinauralRealTimeRenderer::VABinauralRealTimeRenderer( const CVAAudioRendererInitParams& params ) :
ITADatasourceRealization(2, params.pCore->GetCoreConfig()->oAudioDriverConfig.dSampleRate, params.pCore->GetCoreConfig()->oAudioDriverConfig.iBuffersize),
_params(params),
_core(params.pCore),
_newSceneState(NULL),
......@@ -102,6 +103,7 @@ VABinauralRealTimeRenderer::init( const CVAStruct& oArgs )
void
VABinauralRealTimeRenderer::processStream(const ITAStreamInfo* streamInfo)
{
ITASampleFrame* output;
float* outputChL = GetWritePointer(0);
float* outputChR = GetWritePointer(1);
......@@ -111,6 +113,16 @@ VABinauralRealTimeRenderer::processStream(const ITAStreamInfo* streamInfo)
const CVAAudiostreamState* streamState = dynamic_cast< const CVAAudiostreamState* >(streamInfo);
double dListenerTime = streamState->dSysTime;
// -- create output for every listener
std::map< int, VABinauralListener* >::const_iterator it;
for (it = _listeners.begin(); it != _listeners.end(); ++it)
{
VABinauralClustering* clustering = _clusterEngine.getClustering(it->first);
output = clustering->getOutput();
fm_copy(outputChL, (*output)[0].data(), m_uiBlocklength);
fm_copy(outputChR, (*output)[1].data(), m_uiBlocklength);
}
IncrementWritePointer();
......@@ -140,11 +152,12 @@ VABinauralRealTimeRenderer::updateScene(CVASceneState* newSceneState)
updateSources(&diff);
}
/*
ITADatasource* VABinauralRealTimeRenderer::GetOutputDatasource()
{
return this;
}
*/
void
......
......@@ -52,7 +52,7 @@ private:
VABinauralListener::config_t _defaultListenerConf; //!< Default listener config for factory object creation
VABinauralSoundSource::config_t _defaultSourceConf;
CVABFFUpdateMessage* _updateMessage;
// CVABFFUpdateMessage* _updateMessage;
int _defaultVDLSwitchingAlgorithm;
int _hrirFilterLength;
......
......@@ -152,6 +152,13 @@ void CVADirectivityDAFFHRIR::GetNearestNeighbour( const float fAzimuthDeg, const
if( pbOutOfBounds ) *pbOutOfBounds = bOutOfBounds;
}