VABinauralClustering.cpp 4.23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
#define NOMINMAX

#include <limits>
#include <algorithm>

#include <math.h>

// VA
#include <VAObjectPool.h>

11 12 13
// ITA includes
#include <ITAUPFilter.h>

14 15 16 17
// Utils
#include "./VABinauralClustering.h"
#include "./VABinauralClusterPoolFactory.h"

18 19
VABinauralClustering::VABinauralClustering(int blocklength) : 
_blocklength(blocklength)
20 21
{
	IVAPoolObjectFactory* clusterFactory = new VABinauralClusterPoolFactory();
22
	clusterPool = IVAObjectPool::Create(16, 2, clusterFactory, true);
23 24
};

25
VABinauralClustering::~VABinauralClustering(){};
26 27 28 29 30 31 32

void
VABinauralClustering::addSource(int sourceID, VABinauralSoundSource* source)
{
	_unassignedSources.insert(std::pair< int, VABinauralSoundSource* >(sourceID, source));
};

Lucas Moesch's avatar
WIP  
Lucas Moesch committed
33 34 35 36 37 38
void 
VABinauralClustering::removeSource(int sourceID)
{
	_delSourceIDs.insert(sourceID);
}

39
void
40
VABinauralClustering::init(int listenerID, VABinauralListener* listener, int numClusters, int HRIRFilterLength)
41
{
42
	_HRIRFilterLength = HRIRFilterLength;
43 44 45 46
	_listenerID = listenerID;
	_listener = listener;
	_numClusters = numClusters;
	_threshold = cos(180. / numClusters) * cos(180. / numClusters);
47 48 49

	_output = new ITASampleFrame(2, listener->output->GetLength(), true);

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
	// initialize left channel convolver for each cluster
	for (int i = 0; i < _numClusters; ++i)
	{
		ITAUPConvolution* convChL = new ITAUPConvolution(_blocklength, _HRIRFilterLength);

		convChL->SetFilterExchangeFadingFunction(ITABase::FadingFunction::COSINE_SQUARE);
		convChL->SetFilterCrossfadeLength((std::min)(_blocklength, 32));
		convChL->SetGain(0.0f, true);

		ITAUPFilter* HRIRFilterChL = convChL->RequestFilter();
		HRIRFilterChL->identity();

		convChL->ExchangeFilter(HRIRFilterChL);

		FIRConvolverChL.insert(std::pair< int, ITAUPConvolution* >(i, convChL));
	}

	// initialize right channel convolver for each cluster
	for (int i = 0; i < _numClusters; ++i)
	{
		ITAUPConvolution* convChR = new ITAUPConvolution(_blocklength, _HRIRFilterLength);

		convChR->SetFilterExchangeFadingFunction(ITABase::FadingFunction::COSINE_SQUARE);
		convChR->SetFilterCrossfadeLength((std::min)(_blocklength, 32));
		convChR->SetGain(0.0f, true);

		ITAUPFilter* HRIRFilterChR = convChR->RequestFilter();
		HRIRFilterChR->identity();

		convChR->ExchangeFilter(HRIRFilterChR);

		FIRConvolverChR.insert(std::pair< int, ITAUPConvolution* >(i, convChR));
	}

	_curState.reset(new VABinauralClusteringState(_numClusters, _listener, clusterPool, &FIRConvolverChL, &FIRConvolverChR));
85 86
}

87
ITASampleFrame*
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
88
VABinauralClustering::getOutput()
89 90 91 92 93
{	
	// --
	_output->zero();

	// swap out clustering state
Lucas Moesch's avatar
Lucas Moesch committed
94
	if (_nextState != nullptr) _curState.reset(_nextState.release());
95 96 97 98 99 100 101 102 103 104 105

	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;
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
106 107
}

108 109 110
void
VABinauralClustering::update()
{
Lucas Moesch's avatar
Lucas Moesch committed
111
	//TODO: DIRTY HACK
112

Lucas Moesch's avatar
Lucas Moesch committed
113
	if (_nextState == nullptr)
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
114 115
	{

Lucas Moesch's avatar
Lucas Moesch committed
116
		VABinauralClusteringState* state = new VABinauralClusteringState(*_curState);
Lucas Moesch's avatar
wip  
Lucas Moesch committed
117

Lucas Moesch's avatar
Lucas Moesch committed
118 119
		// remove removed sources 
		std::set< int >::const_iterator it;
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
120

Lucas Moesch's avatar
Lucas Moesch committed
121 122 123 124 125
		for (it = _delSourceIDs.begin(); it != _delSourceIDs.end(); ++it)
		{
			// remove if in unassigned sources
			std::map< int, VABinauralSoundSource* >::iterator delIt = _unassignedSources.find(*it);
			VABinauralSoundSource* source = delIt->second;
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
126

Lucas Moesch's avatar
Lucas Moesch committed
127
			state->removeSource(*it);
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
128

Lucas Moesch's avatar
Lucas Moesch committed
129
			_unassignedSources.erase(delIt);
130

Lucas Moesch's avatar
Lucas Moesch committed
131 132 133
			// remove if in assigned sources
			delIt = _assignedSources.find(*it);
			source = delIt->second;
134

Lucas Moesch's avatar
Lucas Moesch committed
135 136
			_assignedSources.erase(delIt);
		}
137

Lucas Moesch's avatar
Lucas Moesch committed
138 139
		// add unassigned sources
		std::map< int, VABinauralSoundSource* >::iterator sourceIt;
140

Lucas Moesch's avatar
Lucas Moesch committed
141 142 143 144
		for (sourceIt = _unassignedSources.begin(); sourceIt != _unassignedSources.end(); ++sourceIt)
		{
			state->addSource(sourceIt->first, sourceIt->second, _threshold, 0);
		}
145

Lucas Moesch's avatar
Lucas Moesch committed
146
		// TODO: refinement
Lucas Moesch's avatar
WIP  
Lucas Moesch committed
147

Lucas Moesch's avatar
Lucas Moesch committed
148 149 150 151 152 153 154 155 156 157 158 159 160
		// update source status
		for (auto const& assignedSources : _assignedSources)
		{
			_assignedSources.insert(std::pair< int, VABinauralSoundSource* >(assignedSources.first, assignedSources.second));
		}

		_unassignedSources.clear();

		_nextState.reset(state);

		// TODO: update fixed clustertrajectories

	}
161 162 163 164 165 166 167
}

void
VABinauralClustering::PreRequest(){};

void
VABinauralClustering::PreRelease(){};