VABinauralOutdoorNoiseAudioRenderer.cpp 22.7 KB
Newer Older
1 2
#include "VABinauralOutdoorNoiseAudioRenderer.h"

3 4
#if VACORE_WITH_RENDERER_BINAURAL_OUTDOOR_NOISE

5
#include <atomic>
6 7 8 9 10
#include <iostream>
#include <fstream>
#include <ctime>
#include <chrono>
#include <time.h>
henryjandrew's avatar
wip  
henryjandrew committed
11 12 13 14 15 16 17
#include <vector>
#include <string>
#include <sstream>



#include <ITAThirdOctaveFilterbank.h>
18

19
// VA Includes
20 21
#include <VA.h>
#include <VAObjectPool.h>
22
#include "../../../core/core.h"
23 24 25 26
#include "../../../Utils/VAUtils.h"

// VA Core Includes
#include "../../../Scene/VAScene.h"
27
#include "../../../Scene/VASoundSourceDesc.h"
28 29

// ITA includes
30
#include <ITAException.h>
31
#include <ITAFastMath.h>
32 33
#include <ITAStreamInfo.h>
#include <ITAVariableDelayLine.h>
34
#include <ITASampleBuffer.h>
35 36 37 38 39 40

// Utils
#include "../Clustering/VAConfig.h"
#include "../Clustering/Receiver/VABinauralClusteringDirectionReceiverPoolFactory.h"
#include "VABinauralOutdoorWaveFront.h"
#include "VABinauralOutdoorWaveFrontPoolFactory.h"
henryjandrew's avatar
wip  
henryjandrew committed
41
#include "VABinauralOutdoorSource.h"
42 43 44 45 46 47 48 49 50 51 52

CVABinauralOutdoorNoiseRenderer::CVABinauralOutdoorNoiseRenderer( const CVAAudioRendererInitParams& oParams )
	: ITADatasourceRealization( 2, oParams.pCore->GetCoreConfig()->oAudioDriverConfig.dSampleRate, oParams.pCore->GetCoreConfig()->oAudioDriverConfig.iBuffersize )
	, m_oParams( oParams )
	, m_pCore( oParams.pCore )
	, m_pNewSceneState( NULL )
	, m_pCurSceneState( NULL )
	, m_bIndicateReset( false )
	, m_bResetAck( false )
{
	Init( *m_oParams.pConfig );
53

54 55
	IVAPoolObjectFactory* pReceiverFactory = new CVABinauralClusteringDirectionReceiverPoolFactory( m_pCore, m_oDefaultReceiverConf );
	m_pReceiverPool = IVAObjectPool::Create( 16, 2, pReceiverFactory, true );
56

57 58
	IVAPoolObjectFactory* pWaveFrontFactory = new CVABinauralOutdoorWaveFrontPoolFactory( m_oDefaultWaveFrontConf );
	m_pWaveFrontPool = IVAObjectPool::Create( 16, 2, pWaveFrontFactory, true );
59

60
	m_iCurGlobalAuralizationMode = IVAInterface::VA_AURAMODE_DEFAULT;
61 62
}

63
CVABinauralOutdoorNoiseRenderer::~CVABinauralOutdoorNoiseRenderer()
64 65 66
{
}

67
void CVABinauralOutdoorNoiseRenderer::Init( const CVAStruct& oArgs )
68
{
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
	CVAConfigInterpreter conf( oArgs );

	// set interpolation algorithm
	std::string vldInterpolationAlgorithm;
	conf.OptString( "SwitchingAlgorithm", vldInterpolationAlgorithm, "linear" );
	vldInterpolationAlgorithm = toLowercase( vldInterpolationAlgorithm );

	if( vldInterpolationAlgorithm == "switch" )
		m_iDefaultVDLSwitchingAlgorithm = CITAVariableDelayLine::SWITCH;
	else if( vldInterpolationAlgorithm == "crossfade" )
		m_iDefaultVDLSwitchingAlgorithm = CITAVariableDelayLine::CROSSFADE;
	else if( vldInterpolationAlgorithm == "linear" )
		m_iDefaultVDLSwitchingAlgorithm = CITAVariableDelayLine::LINEAR_INTERPOLATION;
	else if( vldInterpolationAlgorithm == "cubicspline" )
		m_iDefaultVDLSwitchingAlgorithm = CITAVariableDelayLine::CUBIC_SPLINE_INTERPOLATION;
	else if( vldInterpolationAlgorithm == "windowedsinc" )
		m_iDefaultVDLSwitchingAlgorithm = CITAVariableDelayLine::WINDOWED_SINC_INTERPOLATION;
	else
		ITA_EXCEPT1( INVALID_PARAMETER, "Unrecognized interpolation algorithm '" + vldInterpolationAlgorithm + "' in BinauralFreefieldAudioRendererConfig" );
88

89 90
	// HRTF filter length
	conf.OptInteger( "HRIRFilterLength", m_iHRIRFilterLength, 256 );
91

92 93
	// additional static delay
	conf.OptNumber( "AdditionalStaticDelaySeconds", m_dAdditionalStaticDelaySeconds, 0.0f );
94 95


96 97 98 99
	// default listener config, @todo rest
	m_oDefaultReceiverConf.motionModelLogEstimated = false;
	m_oDefaultReceiverConf.motionModelLogInput = false;
	conf.OptInteger( "MotionModelNumHistoryKeys", m_oDefaultReceiverConf.motionModelNumHistoryKeys, 1000 );
100

101 102
	if( m_oDefaultReceiverConf.motionModelNumHistoryKeys < 1 )
		VA_EXCEPT2( INVALID_PARAMETER, "Basic motion model history needs to be greater than zero" );
103

104 105
	conf.OptNumber( "MotionModelWindowSize", m_oDefaultReceiverConf.motionModelWindowSize, 0.1f );
	conf.OptNumber( "MotionModelWindowDelay", m_oDefaultReceiverConf.motionModelWindowDelay, 0.1f );
106

107 108
	if( ( m_oDefaultReceiverConf.motionModelWindowSize <= 0 ) || ( m_oDefaultReceiverConf.motionModelWindowDelay < 0 ) )
		VA_EXCEPT2( INVALID_PARAMETER, "Basic motion model window parameters parse error (zero or negative?)" );
109

110 111
	// default source config
	conf.OptInteger( "MotionModelNumHistoryKeys", m_oDefaultWaveFrontConf.motionModelNumHistoryKeys, 1000 );
112

113 114
	if( m_oDefaultWaveFrontConf.motionModelNumHistoryKeys < 1 )
		VA_EXCEPT2( INVALID_PARAMETER, "Basic motion model history needs to be greater than zero" );
115

116 117
	conf.OptNumber( "MotionModelWindowSize", m_oDefaultWaveFrontConf.motionModelWindowSize, 0.1f );
	conf.OptNumber( "MotionModelWindowDelay", m_oDefaultWaveFrontConf.motionModelWindowDelay, 0.1f );
118

119 120
	if( ( m_oDefaultWaveFrontConf.motionModelWindowSize <= 0 ) || ( m_oDefaultWaveFrontConf.motionModelWindowDelay < 0 ) )
		VA_EXCEPT2( INVALID_PARAMETER, "Basic motion model window parameters parse error (zero or negative?)" );
121

122 123
	m_oDefaultWaveFrontConf.blockLength = GetBlocklength();
	m_oDefaultWaveFrontConf.sampleRate = GetSampleRate();
124

125 126 127 128 129
	conf.OptInteger("FilterOrder", m_oDefaultWaveFrontConf.iFilterOrder, 4);
	conf.OptInteger("ImpulseResponseLength", m_oDefaultWaveFrontConf.IR_length, 1024);
	conf.OptInteger("BufferSize", m_oDefaultWaveFrontConf.BufferSize, 1124);

	m_oDefaultWaveFrontConf.FilterDesignAlgorithm = CVABinauralOutdoorWaveFront::BURG; //no other algorthms currently implemented
130

131 132 133 134 135 136
	VAConfig::blockLength = GetBlocklength();
	VAConfig::hrirLength = m_iHRIRFilterLength;
	VAConfig::amplitudeCalibration = m_pCore->GetCoreConfig()->dDefaultAmplitudeCalibration;

	// initialize after config
	m_pClusterEngine = new CVABinauralClusteringEngine();
137 138
}

139
void CVABinauralOutdoorNoiseRenderer::Reset()
140
{
141
	VA_ERROR( "BinauralClusteringRenderer", "Reset hast not yet been implemented" );
142 143
}

144
ITADatasource* CVABinauralOutdoorNoiseRenderer::GetOutputDatasource()
145
{
146 147
	return this;
}
148

henryjandrew's avatar
wip  
henryjandrew committed
149
void CVABinauralOutdoorNoiseRenderer::SetParameters(const CVAStruct& oInArgs)
150
{
151
 
henryjandrew's avatar
wip  
henryjandrew committed
152 153
	auto it = oInArgs.Begin();
	while (it != oInArgs.End()) {
154 155
		const CVAStructValue path_value = it->second; //extract data for the current path from the iterator in a useful form
		const CVAStruct path = path_value;
henryjandrew's avatar
wip  
henryjandrew committed
156

157
		//This is the unique string which identifies the current path for which data is being given (stored in "path")
158
		int path_ID = path["ID"]; //get path identifier from simulation engine. In future iterations, this will be generated within VA
henryjandrew's avatar
wip  
henryjandrew committed
159

160 161
		bool delete_path = path["delete"];
		if (delete_path ) {
162
			m_pClusterEngine->RemoveWaveFront(path_ID); //remove wavefront from the clustering engine
163 164 165 166
			m_mPaths.erase(path_ID); //delete the sound path from the map
		}
		else {
			auto path_pos = m_mPaths.find(path_ID); //find the position of "path_ID" in the map 
henryjandrew's avatar
wip  
henryjandrew committed
167

168 169
			if (path_pos == m_mPaths.end()) { //if the path ID is not found, create a new path with this ID
				CVABinauralOutdoorWaveFront* wave_front = dynamic_cast<CVABinauralOutdoorWaveFront*>(m_pWaveFrontPool->RequestObject()); //request a new path from the pool
170
				m_mPaths.insert(std::pair<int, CVABinauralOutdoorWaveFront*>(path_ID, wave_front)); //put that path into the map with the label path_ID
171
				//TODO: might need to add a reference to the new path here? *******************************************
172 173 174 175
				
				m_mPaths[path_ID]->hasValidTrajectory = true; //TODO: check if this should be checked in some fn rather than just alway set

				int path_source_ID = path["source"]; //get source ID from incoming data
176 177 178
				auto checksrc = m_mSources.find(path_source_ID);
				if (checksrc == m_mSources.end())
					VA_EXCEPT1("Source ID not found, make sure the source associated with each path exists.");
179 180 181
				m_mPaths[path_ID]->setSource(m_mSources[path_source_ID]); //set the source for this path

				int path_receiver_ID = path["receiver"];
182 183 184
				auto checkrec = m_mBinauralReceivers.find(path_receiver_ID);
				if( checkrec == m_mBinauralReceivers.end())
					VA_EXCEPT1("Receiver ID not found, make sure the Receiver associated with each path exists.");
185 186 187
				m_mPaths[path_ID]->setReceiver( m_mBinauralReceivers[path_receiver_ID] ); //set the sound receiver for this path

				//m_pClusterEngine->AddWaveFront(path_ID, m_mPaths[path_ID]); //add new wave front to the clustering engine
188
			}
henryjandrew's avatar
wip  
henryjandrew committed
189

190
			CVAStructValue sMags = path["frequency_magnitudes"]; //
191
			int num_values = sMags.GetDataSize() / sizeof(float); //currently only accepts third octave values, this is a safety check
henryjandrew's avatar
wip  
henryjandrew committed
192 193
			if (num_values != 31)
				VA_EXCEPT1("CVABinauralOutdoorNoiseRenderer: Expected 31 frequency magnitudes.");
194 195
			void *pvMags = sMags.GetData();
			const float* pfMags = (const float*)pvMags; //convert to float values
henryjandrew's avatar
wip  
henryjandrew committed
196

197
			ITABase::CThirdOctaveGainMagnitudeSpectrum Mags; //set third octave magnitudes
henryjandrew's avatar
wip  
henryjandrew committed
198
			for (int i = 0; i < 31; i++) {
199
				Mags.SetMagnitude(i, pfMags[i]);
henryjandrew's avatar
wip  
henryjandrew committed
200
			}
201

202 203
			m_mPaths[path_ID]->setFilterCoefficients(Mags); //update the filter coefficients internal to the path based on the target frequency magnitudes

204 205

			double delay = path["delay"];
206
			unsigned int idelay = (int)round(delay * m_oDefaultWaveFrontConf.sampleRate); //unsigned as can not have negative delay (causality)
207
			m_mPaths[path_ID]->setDelay(idelay); 
208

209

210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
			CVAStructValue position = path["position"]; //
			num_values = position.GetDataSize() / sizeof(float); //currently only accepts third octave values, this is a safety check
			if (num_values != 3)
				VA_EXCEPT1("CVABinauralOutdoorNoiseRenderer: Expected a position vector with 3 components.");
			void *pvposition = position.GetData();
			const float* pfposition = (const float*)pvposition; //convert to float values

			m_mPaths[path_ID]->v3PredictedPos.Set(pfposition[0], pfposition[1], pfposition[2]);

			//m_mPaths[path_ID]->setMotion(); //update the motion of the path **********METHOD NOT YET IMPLEMENTED (dont think needed)

			//TODO: add extra "setters" for wave front delay, position/motion e.t.c
			if (path_pos == m_mPaths.end()) { //if the path ID is not found, create a new path with this ID
				m_pClusterEngine->AddWaveFront(path_ID, m_mPaths[path_ID]); //add new wave front to the clustering engine
			}
henryjandrew's avatar
wip  
henryjandrew committed
225
		}
226
		it++; //increment iterator for the next path
henryjandrew's avatar
wip  
henryjandrew committed
227
	}
228

229 230 231 232 233 234 235 236 237 238
	VA_INFO( "BinauralOutdoorNoiseRenderer", "Received input arguments: " + oInArgs.ToString() );
}

CVAStruct CVABinauralOutdoorNoiseRenderer::GetParameters( const CVAStruct& ) const
{
	CVAStruct oOutArgs;
	oOutArgs[ "info" ] = "Nothing meaningful to return, yet";
	return oOutArgs;
}

239 240 241 242
void CVABinauralOutdoorNoiseRenderer::UpdateGlobalAuralizationMode( int iGlobalAuralizationMode )
{
	if( m_iCurGlobalAuralizationMode == iGlobalAuralizationMode )
		return;
243

244
	m_iCurGlobalAuralizationMode = iGlobalAuralizationMode;
245

246
	return;
247 248
}

249 250
void
CVABinauralOutdoorNoiseRenderer::ProcessStream( const ITAStreamInfo* streamInfo )
251 252
{

253
#ifdef BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
254

255 256 257 258
	auto start = std::chrono::high_resolution_clock::now();
	LARGE_INTEGER frequency;        // ticks per second
	LARGE_INTEGER t1, t2;           // ticks
	double elapsedTime;
259

260 261
	// get ticks per second
	QueryPerformanceFrequency(&frequency);
262

263 264
	// start timer
	QueryPerformanceCounter(&t1);
265

266
#endif // BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
267

268 269 270 271
	/////
	ITASampleFrame* output;
	float* outputChL = GetWritePointer( 0 );
	float* outputChR = GetWritePointer( 1 );
272

273 274
	fm_zero( outputChL, GetBlocklength() );
	fm_zero( outputChR, GetBlocklength() );
275

276 277 278
	const CVAAudiostreamState* streamState = dynamic_cast< const CVAAudiostreamState* >( streamInfo );
	double time = streamState->dSysTime;
	//updateTrajectories(time); // @todo jst: why is this outcommented? Trajectories must be updated here for Doppler shifts ...
279

280 281 282 283 284 285 286 287 288 289

	// -- copy new samples from source' signal stream and feed the SIMO VDLs
	for (auto oSource : m_mSources)
	{
		CVABinauralOutdoorSource* pSource = oSource.second;
		CVASoundSourceDesc* pSourceDesc = pSource->pData;
		const ITASampleBuffer* pInBuf = pSourceDesc->pSignalSourceInputBuf;
		pSource->pVDL->Write(GetBlocklength(), pInBuf->GetData());
	}

290 291 292 293
	// -- create output for every listener
	for( auto const& clusteringIt : m_pClusterEngine->m_mClusteringInstances )
	{
		CVABinauralClustering* clustering = clusteringIt.second;
294

295
		output = clustering->GetOutput();
296

297 298 299
		fm_copy( outputChL, ( *output )[ 0 ].data(), m_uiBlocklength );
		fm_copy( outputChR, ( *output )[ 1 ].data(), m_uiBlocklength );
	}
300

301 302 303 304 305 306 307
	// -- copy new samples from source' signal stream and feed the SIMO VDLs
	for (auto oSource : m_mSources)
	{
		CVABinauralOutdoorSource* pSource = oSource.second;
		pSource->pVDL->Increment(GetBlocklength());
	}

308
#ifdef BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
309

310 311
	// stop timer
	QueryPerformanceCounter(&t2);
312

313 314
	// compute and print the elapsed time in millisec
	elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
315

316 317 318
	std::ofstream outfile("X:/Sciebo/master-thesis/data/benchmarks/Stream_128.txt", std::fstream::app);
	outfile << elapsedTime << std::endl;
	outfile.close();
319

320
#endif // BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
321

322
	IncrementWritePointer();
323

324
	return;
325 326
}

327
void CVABinauralOutdoorNoiseRenderer::UpdateScene( CVASceneState* pNewSceneState )
328
{
329
	assert( pNewSceneState );
330

331 332 333
	m_pNewSceneState = pNewSceneState;
	if( m_pNewSceneState == m_pCurSceneState )
		return;
334

335 336
	// get reference to new scene
	m_pNewSceneState->AddReference();
337

338 339 340
	// get difference between old scene state and current scene state
	CVASceneStateDiff diff;
	m_pNewSceneState->Diff( m_pCurSceneState, &diff );
341

342
#ifdef BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
343

344 345 346
	LARGE_INTEGER frequency;        // ticks per second
	LARGE_INTEGER t1, t2;           // ticks
	double elapsedTime;
347

348 349
	// get ticks per second
	QueryPerformanceFrequency(&frequency);
350

351 352
	// start timer
	QueryPerformanceCounter(&t1);
353

354
#endif // BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
355

356 357
	// Update receivers
	UpdateSoundReceivers( &diff );
358

359 360
	// Update wave fronts
	UpdateSoundSources( &diff );
361

362
	m_pClusterEngine->Update();
363

364
#ifdef BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
365

366 367
	// stop timer
	QueryPerformanceCounter(&t2);
368

369 370
	// compute and print the elapsed time in millisec
	elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
371

372 373 374
	std::ofstream outfile("X:/Sciebo/master-thesis/data/benchmarks/UpdateScene_128.txt", std::fstream::app);
	outfile << elapsedTime << std::endl;
	outfile.close();
375

376
#endif // BINAURAL_CLUSTERING_RENDERER_WITH_BENCHMARKING
377

378 379 380
	// Alte Szene freigeben (dereferenzieren)
	if( m_pCurSceneState )
		m_pCurSceneState->RemoveReference();
381

382 383
	m_pCurSceneState = m_pNewSceneState;
	m_pNewSceneState = nullptr;
384 385 386

}

387
void CVABinauralOutdoorNoiseRenderer::UpdateSoundSources( CVASceneStateDiff* diff )
388
{
389
	typedef std::vector< int >::const_iterator icit_t;
390

391 392
	// Delete sources
	for( icit_t it = diff->viDelSoundSourceIDs.begin(); it != diff->viDelSoundSourceIDs.end(); )
393
	{
394 395
		const int& iID( *it++ );
		DeleteSoundSource( iID );
396 397
	}

398 399
	// Add sources
	for( icit_t it = diff->viNewSoundSourceIDs.begin(); it != diff->viNewSoundSourceIDs.end(); )
400
	{
401 402
		const int& iID( *it++ );
		CreateSoundSource( iID, m_pNewSceneState->GetSoundSourceState( iID ) );
403 404
	}

405
	// Update wave front trajectories
henryjandrew's avatar
wip  
henryjandrew committed
406
	std::map< int, CVABinauralOutdoorSource* >::iterator it;
407

henryjandrew's avatar
wip  
henryjandrew committed
408
	for( it = m_mSources.begin(); it != m_mSources.end(); ++it )
409
	{
henryjandrew's avatar
wip  
henryjandrew committed
410 411
		int iSourceID = it->first;
		CVABinauralOutdoorSource* source = it->second;
412

henryjandrew's avatar
wip  
henryjandrew committed
413 414
		CVASoundSourceState* sourceCur = ( m_pCurSceneState ? m_pCurSceneState->GetSoundSourceState(iSourceID) : nullptr );
		CVASoundSourceState* sourceNew = ( m_pNewSceneState ? m_pNewSceneState->GetSoundSourceState(iSourceID) : nullptr );
415

416
		if( sourceNew && ( sourceNew != sourceCur ) )
417
		{
418
			source->pState = sourceNew;
419 420
		}

421 422
		const CVAMotionState* motionCur = ( sourceCur ? sourceCur->GetMotionState() : nullptr );
		const CVAMotionState* motionNew = ( sourceNew ? sourceNew->GetMotionState() : nullptr );
423

424 425 426 427
		if( motionNew && ( motionNew != motionCur ) )
		{
			source->pMotionModel->InputMotionKey( motionNew );
			// Dirty Hack
428

429
			VAVec3 pos = motionNew->GetPosition();
430

431 432 433 434
			if( pos != VAVec3( 0, 0, 0 ) )
			{
				VAVec3 view = motionNew->GetView();
				VAVec3 up = motionNew->GetUp();
435

henryjandrew's avatar
wip  
henryjandrew committed
436
				/*
437 438 439 440
				source->v3PredictedPos = pos;
				source->predView = view;
				source->predUp = up;
				source->hasValidTrajectory = true;
henryjandrew's avatar
wip  
henryjandrew committed
441 442 443

				todo : in future impl trigger propagation simulation
				*/
444 445 446
			}
		}
	}
447 448
}

449
void CVABinauralOutdoorNoiseRenderer::UpdateSoundReceivers( CVASceneStateDiff* diff )
450
{
451
	typedef std::vector< int >::const_iterator icit_t;
452

453 454
	// Delete listeners
	for( icit_t it = diff->viDelReceiverIDs.begin(); it != diff->viDelReceiverIDs.end(); )
455
	{
456 457
		const int& iID( *it++ );
		DeleteSoundReceiver( iID );
458 459
	}

460 461
	// Add listeners
	for( icit_t it = diff->viNewReceiverIDs.begin(); it != diff->viNewReceiverIDs.end(); )
462
	{
463 464
		const int& iID( *it++ );
		CreateSoundReceiver( iID, m_pNewSceneState->GetReceiverState( iID ) );
465 466
	}

467 468 469 470 471
	// Update receiver trajectories and directivity
	for( std::map< int, CVABinauralClusteringDirectionReceiver* >::iterator it = m_mBinauralReceivers.begin(); it != m_mBinauralReceivers.end(); ++it )
	{
		int iListenerID = it->first;
		CVABinauralClusteringDirectionReceiver* listener = it->second;
472

473 474
		CVAReceiverState* listenerCur = ( m_pCurSceneState ? m_pCurSceneState->GetReceiverState( iListenerID ) : nullptr );
		CVAReceiverState* listenerNew = ( m_pNewSceneState ? m_pNewSceneState->GetReceiverState( iListenerID ) : nullptr );
475

476 477
		const CVAMotionState* motionCur = ( listenerCur ? listenerCur->GetMotionState() : nullptr );
		const CVAMotionState* motionNew = ( listenerNew ? listenerNew->GetMotionState() : nullptr );
478

479 480 481 482
		if( motionNew && ( motionNew != motionCur ) )
		{
			listener->pMotionModel->InputMotionKey( motionNew );
			// Dirty Hack
483

484
			VAVec3 pos = motionNew->GetPosition();
485

486 487 488 489
			if( pos != VAVec3( 0, 0, 0 ) )
			{
				VAVec3 view = motionNew->GetView();
				VAVec3 up = motionNew->GetUp();
490

491 492 493 494 495
				listener->v3PredictedPosition = pos;
				listener->predView = view;
				listener->predUp = up;
				listener->hasValidTrajectory = true;
			}
496 497
		}

498 499 500
		if( listenerNew != nullptr )
		{
			listener->pDirectivity = ( IVADirectivity* ) listenerNew->GetDirectivity();
501 502 503 504
		}
	}
}

505
void CVABinauralOutdoorNoiseRenderer::CreateSoundSource( const int sourceID, const CVASoundSourceState* sourceState )
506
{
henryjandrew's avatar
wip  
henryjandrew committed
507 508
	//CVABinauralOutdoorWaveFront* source = dynamic_cast< CVABinauralOutdoorWaveFront* >( m_pWaveFrontPool->RequestObject() ); // Reference = 1
	auto pSource = new CVABinauralOutdoorSource();
509

510
	// set state
henryjandrew's avatar
wip  
henryjandrew committed
511
	pSource->pState = ( CVASoundSourceState* ) sourceState;
512
	// set internal data
henryjandrew's avatar
wip  
henryjandrew committed
513 514
	pSource->pData = m_pCore->GetSceneManager()->GetSoundSourceDesc( sourceID );
	pSource->pData->AddReference();
515

henryjandrew's avatar
wip  
henryjandrew committed
516 517 518
	CVABasicMotionModel::Config sourceMotionConf;
	sourceMotionConf.SetDefaults();
	pSource->pMotionModel = new CVASharedMotionModel(new CVABasicMotionModel(sourceMotionConf), true);
519
	// set motion model
henryjandrew's avatar
wip  
henryjandrew committed
520 521
	CVABasicMotionModel* motionInstance = dynamic_cast< CVABasicMotionModel* >( pSource->pMotionModel->GetInstance() ); // Problem HERE***
	motionInstance->SetName( std::string( "bfrend_mm_source_" + pSource->pData->sName ) );
522
	motionInstance->Reset();
523

524
	// add local reference
henryjandrew's avatar
wip  
henryjandrew committed
525
	m_mSources.insert( std::pair< int, CVABinauralOutdoorSource* >( sourceID, pSource ) );
526 527 528

}

529
void CVABinauralOutdoorNoiseRenderer::DeleteSoundSource( int sourceID )
530
{
531
	// remove local source reference
henryjandrew's avatar
wip  
henryjandrew committed
532 533 534
	std::map< int, CVABinauralOutdoorSource* >::iterator it = m_mSources.find( sourceID );
	auto source = it->second;
	m_mSources.erase( it );
535

536
	// todo henry: how to remove path from  this source?**** Done (I think) ****
537
	// remove listener reference from clustering
henryjandrew's avatar
wip  
henryjandrew committed
538 539
	//m_pClusterEngine->RemoveWaveFront( sourceID );
	//source->RemoveReference();
540 541
}

542
void CVABinauralOutdoorNoiseRenderer::CreateSoundReceiver( int listenerID, const CVAReceiverState* recevierState )
543
{
544
	CVABinauralClusteringDirectionReceiver* listener = dynamic_cast< CVABinauralClusteringDirectionReceiver* >( m_pReceiverPool->RequestObject() ); // Reference = 1
545

546 547 548
	// set internal data
	listener->pData = m_pCore->GetSceneManager()->GetListenerDesc( listenerID );
	listener->pData->AddReference();
549

550
	// set motion model
henryjandrew's avatar
wip  
henryjandrew committed
551
	CVABasicMotionModel* motionInstance = dynamic_cast< CVABasicMotionModel* >( listener->pMotionModel->GetInstance() ); //foo possible error Get Instance
552 553
	motionInstance->SetName( std::string( "bfrend_mm_listener_" + listener->pData->sName ) );
	motionInstance->Reset();
554

555 556
	//set directivity
	listener->pDirectivity = ( IVADirectivity* ) recevierState->GetDirectivity();
557

558 559
	// add local reference
	m_mBinauralReceivers.insert( std::pair< int, CVABinauralClusteringDirectionReceiver* >( listenerID, listener ) );
560

561 562 563 564
	// add listener to clustering
	CVABinauralClusteringEngine::Config config = { /*numClusters=*/ 12 }; // @todo use configuranble number of clusters -> config
	m_pClusterEngine->AddReceiver( listenerID, listener, config );
}
565

566 567 568 569 570 571
void CVABinauralOutdoorNoiseRenderer::DeleteSoundReceiver( int listenerID )
{
	// remove local listener reference
	std::map< int, CVABinauralClusteringDirectionReceiver* >::iterator it = m_mBinauralReceivers.find( listenerID );
	CVABinauralClusteringDirectionReceiver* listener = it->second;
	m_mBinauralReceivers.erase( it );
572

573 574 575
	//listener->bDeleted = true;
	//listener->pData->RemoveReference();
	listener->RemoveReference();
576

577 578
	// remove listener reference from clustering
	m_pClusterEngine->RemoveReceiver( listenerID );
579 580 581

}

582
void CVABinauralOutdoorNoiseRenderer::UpdateMotionStates()
583
{
584
	// Neue Quellendaten bernehmen
henryjandrew's avatar
wip  
henryjandrew committed
585
	for( std::map< int, CVABinauralOutdoorSource* >::iterator it = m_mSources.begin(); it != m_mSources.end(); ++it )
586
	{
587
		int sourceID = it->first;
henryjandrew's avatar
wip  
henryjandrew committed
588
		auto source = it->second;
589

590 591
		CVASoundSourceState* sourceCur = ( m_pCurSceneState ? m_pCurSceneState->GetSoundSourceState( sourceID ) : nullptr );
		CVASoundSourceState* sourceNew = ( m_pNewSceneState ? m_pNewSceneState->GetSoundSourceState( sourceID ) : nullptr );
592

593 594
		const CVAMotionState* motionCur = ( sourceCur ? sourceCur->GetMotionState() : nullptr );
		const CVAMotionState* motionNew = ( sourceNew ? sourceNew->GetMotionState() : nullptr );
595

596
		if( motionNew && ( motionNew != motionCur ) )
597
		{
598 599
			//VA_TRACE("BinauralFreeFieldAudioRenderer", "Source " << iSourceID << " new motion state");
			source->pMotionModel->InputMotionKey( motionNew );
600 601 602 603
		}
	}
}

604
void CVABinauralOutdoorNoiseRenderer::UpdateTrajectories( double time )
605
{
henryjandrew's avatar
wip  
henryjandrew committed
606
	for( auto const& sourceIt : m_mSources )
607
	{
608
		bool isValid = true;
henryjandrew's avatar
wip  
henryjandrew committed
609
		auto source = sourceIt.second;
610

611
		source->pMotionModel->HandleMotionKeys();
henryjandrew's avatar
wip  
henryjandrew committed
612
		/* todo trigger simulation in C++ ...
613 614 615
		isValid &= source->pMotionModel->EstimatePosition( time, source->v3PredictedPos );
		isValid &= source->pMotionModel->EstimateOrientation( time, source->predView, source->predUp );
		source->hasValidTrajectory = isValid;
henryjandrew's avatar
wip  
henryjandrew committed
616
		*/
617 618
	}

619
	for( auto const& listenerIt : m_mBinauralReceivers )
620
	{
621 622
		bool isValid = true;
		CVABinauralClusteringDirectionReceiver* listener = listenerIt.second;
623

624 625 626 627
		listener->pMotionModel->HandleMotionKeys();
		isValid &= listener->pMotionModel->EstimatePosition( time, listener->v3PredictedPosition );
		isValid &= listener->pMotionModel->EstimateOrientation( time, listener->predView, listener->predUp );
		listener->hasValidTrajectory = isValid;
628 629
	}
}
630 631

#endif // VACORE_WITH_RENDERER_BINAURAL_OUTDOOR_NOISE