VABinauralClusteringState.cpp 3.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#define NOMINMAX

#include <algorithm> 

// VA
#include <VAObjectPool.h>

// Utils
#include "VABinauralClusteringState.h"
#include "./VABinauralClusterPoolFactory.h"


Lucas Moesch's avatar
Lucas Moesch committed
13
VABinauralClusteringState::VABinauralClusteringState(int numClusters, VABinauralListener* listener, IVAObjectPool* clusterPool) :
14
	numClusters(numClusters),
15
	listener(listener),
Lucas Moesch's avatar
Lucas Moesch committed
16
	_clusterPool(clusterPool)
17
{
18
	
19 20 21 22 23 24 25 26
	for (int i = numClusters - 1; i >= 0; --i)
	{
		freeClusterIDs.push(i);
	}
}

VABinauralClusteringState::VABinauralClusteringState(const VABinauralClusteringState& state) : 
	numClusters(state.numClusters),
27
	listener(state.listener),
Lucas Moesch's avatar
Lucas Moesch committed
28
	sourceClusterReference(state.sourceClusterReference),
29
	freeClusterIDs(state.freeClusterIDs),
Lucas Moesch's avatar
Lucas Moesch committed
30
	_clusterPool(state._clusterPool)
31
{
Lucas Moesch's avatar
Lucas Moesch committed
32

33 34 35
	std::map< int, VABinauralCluster* >::const_iterator it;
	for (it = state.clusters.begin(); it != state.clusters.end(); ++it)
	{
Lucas Moesch's avatar
Lucas Moesch committed
36
		createCluster(it->first, it->second);
37 38 39
	}
}

Lucas Moesch's avatar
Lucas Moesch committed
40 41 42 43 44 45 46 47
VABinauralClusteringState::~VABinauralClusteringState()
{
	for (auto &const clusterIt : clusters)
	{
		clusterIt.second->RemoveReference();
	}
}

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
void
VABinauralClusteringState::addSource(int sourceID, VABinauralSoundSource* source, double threshold, int numBlockedClusters)
{
	int numFreeClusters = numClusters - numBlockedClusters - clusters.size();
	double err = 0, minerr = std::numeric_limits<double>::infinity();

	int nearestClusterID = -1;
	VABinauralCluster* nearestCluster = nullptr;

	std::map< int, VABinauralCluster* >::iterator it;

	for (it = clusters.begin(); it != clusters.end(); ++it)
	{
		err = it->second->getDistError(source);
		if (err < minerr)
		{
			minerr = err;
			nearestClusterID = it->first;
			nearestCluster = it->second;
		}
	}

	if ((minerr > threshold) && (numFreeClusters > 0))
	{
		std::pair< int, VABinauralCluster*> p;
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
73
		p = createCluster(sourceID, source);
74 75 76 77 78

		nearestClusterID = p.first;
		nearestCluster = p.second;
	}

79
	nearestCluster->addSource(sourceID, source, minerr);
80 81 82
	sourceClusterReference.insert(std::pair< int, int >(sourceID, nearestClusterID));
}

Lucas Moesch's avatar
wip  
Lucas Moesch committed
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
void
VABinauralClusteringState::removeSource(int sourceID)
{
	std::map<int, int>::const_iterator itSource = sourceClusterReference.find(sourceID);
	std::map<int, VABinauralCluster*>::const_iterator itCluster = clusters.find(itSource->second);
	VABinauralCluster* cluster = itCluster->second;

	cluster->removeSource(sourceID);

	if (cluster->numSources <= 0)
	{
		clusters.erase(itCluster);
		freeClusterIDs.push(itSource->second);

		cluster->RemoveReference();
	}
}

101
std::pair< int, VABinauralCluster*>
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
102
VABinauralClusteringState::createCluster(int sourceID,  VABinauralSoundSource* source)
103
{
104
	int clusterID = freeClusterIDs.front();
105 106
	VABinauralCluster* cluster = dynamic_cast< VABinauralCluster* >(_clusterPool->RequestObject()); // Reference = 1

Lucas Moesch's avatar
Lucas Moesch committed
107
	cluster->init(sourceID, source, listener);
108 109 110 111 112 113 114
	clusters.insert(std::pair< int, VABinauralCluster* >(clusterID, cluster));

	freeClusterIDs.pop();

	return std::pair< int, VABinauralCluster* >(clusterID, cluster);
}

Lucas Moesch's avatar
Lucas Moesch committed
115 116 117 118 119 120 121 122 123 124 125
std::pair< int, VABinauralCluster*>
VABinauralClusteringState::createCluster(int clusterID, VABinauralCluster* cluster)
{
	VABinauralCluster* _cluster = dynamic_cast< VABinauralCluster* >(_clusterPool->RequestObject());
	
	_cluster->init(cluster);
	clusters.insert(std::pair<int, VABinauralCluster* >(clusterID, _cluster));

	return std::pair< int, VABinauralCluster* >(clusterID, _cluster);
}

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140

double
VABinauralClusteringState::getMaxError()
{
	double max = 0;
	std::map< int, VABinauralCluster* >::iterator it;

	for (it = clusters.begin(); it != clusters.end(); ++it)
	{
		max = std::max(max, it->second->maxError);
	}

	return max;
}