VACoreImpl.cpp 142 KB
Newer Older
Jonas Stienen's avatar
Jonas Stienen committed
1
/*
2
 *  --------------------------------------------------------------------------------------------
Jonas Stienen's avatar
Jonas Stienen committed
3
 *
4
5
6
 *    VVV        VVV A           Virtual Acoustics (VA) | http://www.virtualacoustics.org
 *     VVV      VVV AAA          Licensed under the Apache License, Version 2.0
 *      VVV    VVV   AAA
7
 *       VVV  VVV     AAA        Copyright 2015-2018
8
9
10
11
 *        VVVVVV       AAA       Institute of Technical Acoustics (ITA)
 *         VVVV         AAA      RWTH Aachen University
 *
 *  --------------------------------------------------------------------------------------------
Jonas Stienen's avatar
Jonas Stienen committed
12
 */
13

Jonas Stienen's avatar
Jonas Stienen committed
14
15
16
#include "VACoreImpl.h"

// VA base
17
#include <VA.h>
Jonas Stienen's avatar
Jonas Stienen committed
18
19
20
21
22
23
24
25

// VA includes
#include "Audiosignals/VAAudioSignalSourceManager.h"
#include "Audiosignals/VAAudiofileSignalSource.h"
#include "Audiosignals/VAAudiofileSignalSource.h"
#include "Audiosignals/VAEngineSignalSource.h"
#include "Audiosignals/VAMachineSignalSource.h"
#include "Audiosignals/VASequencerSignalSource.h"
26
#include "directivities/VADirectivityManager.h"
Jonas Stienen's avatar
Jonas Stienen committed
27
28
#include "Rendering/VAAudioRenderer.h"
#include "Rendering/VAAudioRendererRegistry.h"
29
30
#include "Reproduction/VAAudioReproduction.h"
#include "Reproduction/VAAudioReproductionRegistry.h"
Jonas Stienen's avatar
Jonas Stienen committed
31
32
33
34
35
36
37
38
39
40
41
42
#include "Scene/VAScene.h"
#include "Scene/VASoundSourceDesc.h"
#include "Scene/VAListenerDesc.h"
#include "Utils/VADebug.h"
#include "Utils/VAUtils.h"
#include "VAAudiostreamTracker.h"
#include "VALog.h"
#include "VACoreEventManager.h"
#include "VACoreFactory.h"
#include "VACoreThread.h"
#include "VASourceListenerMetrics.h"

43
#include "Drivers/Audio/VAAudioDriverBackend.h"
44
#include "Drivers/Audio/VAAudioDriverConfig.h"
45
46
47
48
49
50
51
52

#ifdef VACORE_WITH_AUDIO_BACKEND_ASIO
#include "Drivers/Audio/VAASIOBackend.h"
#endif
#ifdef VACORE_WITH_AUDIO_BACKEND_PORTAUDIO
#include "Drivers/Audio/VAPortaudioBackend.h"
#endif

Jonas Stienen's avatar
Jonas Stienen committed
53
54
55
56
// ITA includes
#include <ITAASCIITable.h>
#include <ITAClock.h>
#include <ITAException.h>
57
#include <ITAFileSystemUtils.h>
Jonas Stienen's avatar
Jonas Stienen committed
58
#include <ITAFunctors.h>
59
#include <ITAStreamDetector.h>
Jonas Stienen's avatar
Jonas Stienen committed
60
61
62
63
#include <ITASoundSample.h>
#include <ITASoundSampler.h>
#include <ITASoundSamplePool.h>
#include <ITAStreamAmplifier.h>
64
#include <ITAStreamPatchBay.h>
Jonas Stienen's avatar
Jonas Stienen committed
65
66
67
68
69
70
71
72
73
74
75
76
#include <ITAStreamProbe.h>
#include <ITAStringUtils.h>

// Vista includes
#include <VistaTools/VistaFileSystemFile.h>
#include <VistaTools/VistaFileSystemDirectory.h>

// 3rdParty includes
#include <DAFF.h>

// STL includes
#include <algorithm>
77
#include <iomanip>
Jonas Stienen's avatar
Jonas Stienen committed
78
79
#include <iostream>

80
81
82
83

// We know about unreferenced formal parameters. There are a lot of unused methods for future use.
#pragma warning( disable : 4100 )

Jonas Stienen's avatar
Jonas Stienen committed
84
85
86
87
88
89
90
91
92
93
/*

	Informationen
	=-=-=-=-=-=-=

	Thread-safety & locking

	Alle durch die Schnittstelle nach aussen angebotenen Funktionen, werden
	gegen Reentrance grob-granular mittels eines kritischen Bereiches gesperrt.
	Damit sind auch parallele Calls auf unterschiedliche Methoden der Klasse
94
	unterbunden. Sollte dies zu Performance-Problemen fhren, kann ein
Jonas Stienen's avatar
Jonas Stienen committed
95
96
97
98
99
	verfeinerter Locking-Mechanismus entwickelt werden. Zunchst mal aber so.


	TODO: berall sicherstellen, das ITAExceptions zu VAExceptions umgebaut werden!!!

100
	*/
Jonas Stienen's avatar
Jonas Stienen committed
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125


// --= Hilfsmakros =--

// berprfung ob Initialisiert
#define VA_CHECK_INITIALIZED \
{ if (m_iState != VA_CORESTATE_READY) VA_EXCEPT2(MODAL_ERROR, "Core not initialized"); }

// Mutex-Lock welches parallelen Methoden-Mehrfracheintritt (reentrance) im Methoden-Scope verhindert
#define VA_NO_REENTRANCE \
ITACriticalSectionLock oReentranceLock(m_csReentrance)

// Manuelles das Lock gegen parallelen Methoden-Mehrfracheintritt (reentrance) holen
#define VA_LOCK_REENTRANCE \
m_csReentrance.enter()

// Manuelle das Lock gegen parallelen Methoden-Mehrfracheintritt (reentrance) freigeben 
#define VA_UNLOCK_REENTRANCE \
m_csReentrance.leave()

/*

	Sichere Ausnahmebehandlung

	Problem: Intern knnen auch andere Typen von Ausnahmen als
126
127
	CVAException geworfen werden. Nach aussen hin drfen
	aber NUR CVAExceptions geworfen werden (Konsistent)
Jonas Stienen's avatar
Jonas Stienen committed
128
129

	Lsung: TRY-/CATCH-Makros fr abgesicherte Bereiche in allen Methoden
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
	der externen Schnittstelle. Zweistufiger Aufbau.
	1. (innen) Fange alle Exception-Typen und konvertiere sie in CVAExceptions
	2. (aussen) Fange die einzig mgl. CVAExceptions und biete
	gemeinsamen Catch-Weg zur Problemlsung (Aufrumen) an

	try {
	try {
	// Code ...
	} catch (ITAException& e) {
	// Konvertiere zu CVAException
	} catch (VistaExceptionBase& e) {
	// Konvertiere zu CVAException
	} catch (...)
	// Generiere unerwartete CVAException
	}
	} catch (CVAException& e) {
	// Gemeinsames Aufrumen
	}
Jonas Stienen's avatar
Jonas Stienen committed
148
149

	Beispiel:
150
151
152
153
154
155

	VA_TRY {
	// Code ..
	} VA_CATCH {
	// Mach was ...
	}
Jonas Stienen's avatar
Jonas Stienen committed
156
157
158

	Hinweis: Initiale/finale Geschweifte Klammer fehlen, da diese hinter die Makros geschrieben werden

159
	*/
Jonas Stienen's avatar
Jonas Stienen committed
160
161

#define VA_TRY \
162
try { try
Jonas Stienen's avatar
Jonas Stienen committed
163
164

#define VA_CATCH(EXPR) \
165
166
167
168
169
catch( CVAException& e ) { throw e; } \
catch( ITAException& e ) { throw convert2VAException( e ); } \
catch( VistaExceptionBase& e ) { throw convert2VAException( e ); } \
catch( ... ) { throw getDefaultUnexpectedVAException(); } \
} catch( CVAException& EXPR )
Jonas Stienen's avatar
Jonas Stienen committed
170
171

#define VA_FINALLY \
172
173
174
175
176
catch( CVAException& e ) { throw e; } \
catch( ITAException& e ) { throw convert2VAException( e ); } \
catch( VistaExceptionBase& e ) { throw convert2VAException(e); } \
catch( ... ) { throw getDefaultUnexpectedVAException(); } \
} catch( ... )
Jonas Stienen's avatar
Jonas Stienen committed
177
178

#define VA_RETHROW \
179
180
181
182
183
catch( CVAException& e ) { throw e; } \
catch( ITAException& e ) { throw convert2VAException( e ); } \
catch( VistaExceptionBase& e ) { throw convert2VAException( e ); } \
catch( ... ) { throw getDefaultUnexpectedVAException(); } \
} catch( ... ) { throw; }
Jonas Stienen's avatar
Jonas Stienen committed
184
185


186
IVAInterface* VACore::CreateCoreInstance( const CVAStruct& oArgs, std::ostream* pOutputStream )
Jonas Stienen's avatar
Jonas Stienen committed
187
{
188
	VA_TRACE( "Config", oArgs );
189
	return new CVACoreImpl( oArgs, pOutputStream );
Jonas Stienen's avatar
Jonas Stienen committed
190
191
}

192
193
194
195
196
197
void VACore::StoreCoreConfigToFile( const CVAStruct& oConfig, const std::string& sConfigFilePath )
{
	StoreStructToINIFile( sConfigFilePath, oConfig );
}

CVAStruct VACore::LoadCoreConfigFromFile( const std::string& sConfigFilePath )
198
{
Jonas Stienen's avatar
Jonas Stienen committed
199
200
201
	CVAStruct oFinalCoreConfigStruct, oCurrentConfig;
	std::list< VistaFileSystemFile > voConfigFiles;
	std::vector< VistaFileSystemDirectory > voIncludePaths;
202
	voConfigFiles.push_back( VistaFileSystemFile( sConfigFilePath ) );
Jonas Stienen's avatar
Jonas Stienen committed
203

204
	VA_INFO( "Core", "Working directory: '" << VistaFileSystemDirectory::GetCurrentWorkingDirectory() << "'" );
205

Jonas Stienen's avatar
Jonas Stienen committed
206
207
208
209
210
211
212
	while( voConfigFiles.empty() == false )
	{
		VistaFileSystemFile oCurrentConfigFile( voConfigFiles.front() );
		voConfigFiles.pop_front();

		if( oCurrentConfigFile.Exists() == false )
		{
213
			for( size_t n = 0; n < voIncludePaths.size(); n++ )
Jonas Stienen's avatar
Jonas Stienen committed
214
			{
215
				std::string sCombinedFilePath = voIncludePaths[ n ].GetName() + PATH_SEPARATOR + oCurrentConfigFile.GetLocalName();
Jonas Stienen's avatar
Jonas Stienen committed
216
217
218
				oCurrentConfigFile.SetName( sCombinedFilePath );
				if( oCurrentConfigFile.Exists() && oCurrentConfigFile.IsFile() )
				{
219
					VA_INFO( "Config", "Including further configuration file '" + oCurrentConfigFile.GetLocalName() +
220
						"' from include path '" + voIncludePaths[ n ].GetName() + "'" );
Jonas Stienen's avatar
Jonas Stienen committed
221
222
223
224
225
					break;
				}
			}

			if( !oCurrentConfigFile.Exists() )
226
			{   
Jonas Stienen's avatar
Jonas Stienen committed
227
228
229
				VA_EXCEPT2( FILE_NOT_FOUND, "Configuration file '" + oCurrentConfigFile.GetLocalName() + "' not found, aborting." );
			}
		}
230

231
		VA_VERBOSE( "Config", std::string( "Reading INI file '" ) + oCurrentConfigFile.GetLocalName() + "'" );
232
		LoadStructFromINIFIle( oCurrentConfigFile.GetName(), oCurrentConfig );
233

Jonas Stienen's avatar
Jonas Stienen committed
234
235
236
237
238
239
		if( oCurrentConfig.HasKey( "paths" ) )
		{
			const CVAStruct& oPaths( oCurrentConfig[ "paths" ] );
			CVAStruct::const_iterator it = oPaths.Begin();
			while( it != oPaths.End() )
			{
240
				const CVAStructValue& oIncludePath( ( it++ )->second );
Jonas Stienen's avatar
Jonas Stienen committed
241
242
243
244
245
246
247
248
249
250
251
252
				VistaFileSystemDirectory oNewPathDir( oIncludePath );
				if( oNewPathDir.Exists() && oNewPathDir.IsDirectory() )
					voIncludePaths.push_back( oNewPathDir );
			}
		}

		if( oCurrentConfig.HasKey( "files" ) )
		{
			const CVAStruct& oPaths( oCurrentConfig[ "files" ] );
			CVAStruct::const_iterator it = oPaths.Begin();
			while( it != oPaths.End() )
			{
253
254
				const CVAStructValue& oIncludeFile( ( it++ )->second );

Jonas Stienen's avatar
Jonas Stienen committed
255
256
257
258
259
260
261
262
263
264
				voConfigFiles.push_back( VistaFileSystemFile( oIncludeFile ) );
			}
		}

		oCurrentConfig.RemoveKey( "files" );

		// Merge structs (check for uniqueness)
		oFinalCoreConfigStruct.Merge( oCurrentConfig, true );
	}

265
	return oFinalCoreConfigStruct;
Jonas Stienen's avatar
Jonas Stienen committed
266
267
}

268
#ifdef WIN32
Jonas Stienen's avatar
Jonas Stienen committed
269
270
// Trick um DLL-Pfad zu ermitteln
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
271
#endif
Jonas Stienen's avatar
Jonas Stienen committed
272

273
std::string VACore::GetCoreLibFilePath()
Jonas Stienen's avatar
Jonas Stienen committed
274
{
275
#ifdef WIN32
Jonas Stienen's avatar
Jonas Stienen committed
276
	CHAR pszPath[ MAX_PATH + 1 ] = { 0 };
277
	GetModuleFileNameA( ( HINSTANCE ) &__ImageBase, pszPath, _countof( pszPath ) );
Jonas Stienen's avatar
Jonas Stienen committed
278
	return std::string( pszPath );
279
280
#else
	VA_EXCEPT2( NOT_IMPLEMENTED, "This function is not implemented for your platform. Sorry." );
Jonas Stienen's avatar
Jonas Stienen committed
281
	return "";
282
#endif // WIN32
Jonas Stienen's avatar
Jonas Stienen committed
283
284
}

285
CVACoreImpl::CVACoreImpl( const CVAStruct& oArgs, std::ostream* pOutputStream )
286
287
288
	: m_pAudioDriverBackend( nullptr ),
	m_pGlobalSamplePool( nullptr ),
	m_pGlobalSampler( nullptr ),
289
290
291
	m_pSignalSourceManager( nullptr ),
	m_pDirectivityManager( nullptr ),
	m_pSceneManager( nullptr ),
292
	m_pNewSceneState( nullptr ),
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
293
294
295
	m_iCurActiveSoundReceiver( -1 ),
	m_iNewActiveSoundReceiver( -1 ),
	m_iUpdActiveSoundReceiver( -1 ),
296
	m_pEventManager( nullptr ),
297
298
299
300
	m_pCoreThread( nullptr ),
	m_pInputAmp( nullptr ),
	m_pR2RPatchbay( nullptr ),
	m_pOutputPatchbay( nullptr ),
301
302
	m_pInputStreamDetector( nullptr ),
	m_pOutputStreamDetector( nullptr ),
303
304
305
306
307
308
309
310
311
312
313
	m_pOutputTracker( nullptr ),
	m_pStreamProbeDeviceInput( nullptr ),
	m_pStreamProbeFinal( nullptr ),
	m_pCurSceneState( nullptr ),
	m_pClock( ITAClock::getDefaultClock() ),
	m_pTicker( NULL ),
	m_lSyncModOwner( -1 ),
	m_lSyncModSpinCount( 0 ),
	m_iState( VA_CORESTATE_CREATED ),

	// TODO: Welche Default-Wert mssen erst in Initialize gesetzt werden?
314
	m_iGlobalAuralizationMode( IVAInterface::VA_AURAMODE_ALL ),
315
316
317
318
319
320
	m_dOutputGain( 1 ), m_dInputGain( 1 ),
	m_bOutputMuted( false ), m_bInputMuted( false ),
	m_dStreamClockOffset( 0 ), m_fCoreClockOffset( 0 ),

	// --= Profiling =--
	m_pmCoreThreadLoopTotalDuration( "Core thread loop" )
Jonas Stienen's avatar
Jonas Stienen committed
321
322
323
{
	VA_NO_REENTRANCE;

324
325
326
	if( pOutputStream )
		SetOutputStream( pOutputStream );

327
328
329
330
	VA_TRY
	{
		// read configuration
		m_oCoreConfig.Init( oArgs );
Jonas Stienen's avatar
Jonas Stienen committed
331

332
		// register core itself as a module
Jonas Stienen's avatar
Jonas Stienen committed
333
334
		SetObjectName( "VACore" );
		m_oModules.RegisterObject( this );
335
		VA_VERBOSE( "Core", "Registered core module with name '" << GetObjectName() << "'" );
Jonas Stienen's avatar
Jonas Stienen committed
336
337
338

		// Der Event-Manager muss immer verfgbar sein,
		// unabhnging davon ob der Core initialisiert wurde oder nicht.
339
		m_pEventManager = new CVACoreEventManager;
340

Jonas Stienen's avatar
Jonas Stienen committed
341
342
		m_iState = VA_CORESTATE_CREATED;

343
		VA_TRACE( "Core", "CVACoreImpl instance created [" << this << "]" );
Jonas Stienen's avatar
Jonas Stienen committed
344

345
346
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
347
348
}

349
350
CVACoreImpl::~CVACoreImpl()
{
Jonas Stienen's avatar
Jonas Stienen committed
351
352
353
	VA_NO_REENTRANCE;

	// Implizit finalisieren, falls dies nicht durch den Benutzer geschah
354
355
356
357
	if( m_iState == VA_CORESTATE_READY )
	{
		VA_TRY
		{
Jonas Stienen's avatar
Jonas Stienen committed
358
			Finalize();
359
		}
360
			VA_FINALLY
361
		{
Jonas Stienen's avatar
Jonas Stienen committed
362
363
364
365
366
			// Fehler beim Finalisieren ignorieren
		};
	}

	// Nachricht senden [blocking], das die Kerninstanz gelscht wird.
367
	CVAEvent ev;
368
	ev.iEventType = CVAEvent::DESTROY;
Jonas Stienen's avatar
Jonas Stienen committed
369
	ev.pSender = this;
370
	m_pEventManager->BroadcastEvent( ev );
Jonas Stienen's avatar
Jonas Stienen committed
371
372
373
374
375

	// Module deregistrieren
	m_oModules.Clear();

	// Nachrichten-Manager freigeben
376
377
	VA_TRY
	{
378
		delete m_pEventManager;
379
380
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
381

382
	VA_TRACE( "Core", "CVACoreImpl instance deleted [" << this << "]" );
Jonas Stienen's avatar
Jonas Stienen committed
383
384

	// Profiling ausgeben
385
	VA_VERBOSE( "Core", m_pmCoreThreadLoopTotalDuration.ToString() );
Jonas Stienen's avatar
Jonas Stienen committed
386
387
}

388
void CVACoreImpl::SetOutputStream( std::ostream* posDebug )
389
{
390
391
	VALog_setOutputStream( posDebug );
	VALog_setErrorStream( posDebug );
Jonas Stienen's avatar
Jonas Stienen committed
392
393
}

394
void CVACoreImpl::GetVersionInfo( CVAVersionInfo* pVersionInfo ) const
Jonas Stienen's avatar
Jonas Stienen committed
395
396
397
398
399
{
	if( !pVersionInfo )
		return;

	std::stringstream ss;
400
	ss << VACORE_VERSION_MAJOR << "." << VACORE_VERSION_MINOR;
Jonas Stienen's avatar
Jonas Stienen committed
401
	pVersionInfo->sVersion = ss.str();
402
403
404
405
	ss.clear();
#ifdef VACORE_CMAKE_DATE
	ss << VACORE_CMAKE_DATE;
#else
406
	ss << "Unkown date";
407
408
#endif
	pVersionInfo->sDate = ss.str();
Jonas Stienen's avatar
Jonas Stienen committed
409
	pVersionInfo->sFlags = "";
410

Jonas Stienen's avatar
Jonas Stienen committed
411
#ifdef DEBUG
412
	pVersionInfo->sComments = "debug";
Jonas Stienen's avatar
Jonas Stienen committed
413
#else
414
	pVersionInfo->sComments = "release";
Jonas Stienen's avatar
Jonas Stienen committed
415
416
417
#endif
}

418
419
void CVACoreImpl::AttachEventHandler( IVAEventHandler* pCoreEventHandler )
{
Jonas Stienen's avatar
Jonas Stienen committed
420
421
422
	VA_TRY
	{
		// Immer mglich. Unabhngig vom Zustand. Thread-safety wird im Manager geregelt.
423
		m_pEventManager->AttachHandler( pCoreEventHandler );
424
425
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
426
427
}

428
429
430
431
void CVACoreImpl::DetachEventHandler( IVAEventHandler* pCoreEventHandler )
{
	VA_TRY
	{
Jonas Stienen's avatar
Jonas Stienen committed
432
		// Immer mglich. Unabhngig vom Zustand. Thread-safety wird im Manager geregelt.
433
		m_pEventManager->DetachHandler( pCoreEventHandler );
434
435
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
436
437
}

438
439
440
int CVACoreImpl::GetState() const
{
	VA_VERBOSE( "Core", "Core state requested, current state is " << m_iState );
Jonas Stienen's avatar
Jonas Stienen committed
441
442
443
444
445
446
447
448
	return m_iState;
}

void CVACoreImpl::Initialize() {
	VA_NO_REENTRANCE;

	// TODO: Prfen ob im Fehlerfall zurck in den sauberen Grundzustand [WICHTIG!]

449
	VA_VERBOSE( "Core", "Initializing core" );
Jonas Stienen's avatar
Jonas Stienen committed
450

451
452
	VA_TRY
	{
453
454
		if( m_iState == VA_CORESTATE_READY )
		VA_EXCEPT2( MODAL_ERROR, "Core already initialized." );
Jonas Stienen's avatar
Jonas Stienen committed
455

456
457
		if( m_iState == VA_CORESTATE_FAIL )
			VA_EXCEPT2( MODAL_ERROR, "Core corrupted, reinitialization impossible" );
Jonas Stienen's avatar
Jonas Stienen committed
458

459
		m_pCoreThread = new CVACoreThread( this );
Jonas Stienen's avatar
Jonas Stienen committed
460

461
		SetProgress( "Setting up audio hardware", "", 1 );
Jonas Stienen's avatar
Jonas Stienen committed
462
463
		InitializeAudioDriver();

464
		m_pR2RPatchbay = new ITAStreamPatchbay( m_oCoreConfig.oAudioDriverConfig.dSampleRate, m_oCoreConfig.oAudioDriverConfig.iBuffersize );
Jonas Stienen's avatar
Jonas Stienen committed
465
466

		// Create output patch bay with a single output that uses all available physical audio outputs from sound card
467
		m_pOutputPatchbay = new ITAStreamPatchbay( m_oCoreConfig.oAudioDriverConfig.dSampleRate, m_oCoreConfig.oAudioDriverConfig.iBuffersize );
Jonas Stienen's avatar
Jonas Stienen committed
468
469
470
471
472
		int iPhysicalHardwareOutput = m_pOutputPatchbay->AddOutput( m_oCoreConfig.oAudioDriverConfig.iOutputChannels );
		m_pOutputPatchbay->SetOutputGain( iPhysicalHardwareOutput, m_dOutputGain );

		m_iGlobalAuralizationMode = VA_AURAMODE_ALL;

473
		// Set up input stream network
Jonas Stienen's avatar
Jonas Stienen committed
474
		ITADatasource* pInputTail = nullptr;
475
476
		if( m_oCoreConfig.oAudioDriverConfig.iInputChannels > 0 )
		{
Jonas Stienen's avatar
Jonas Stienen committed
477
			pInputTail = m_pAudioDriverBackend->getInputStreamDatasource();
478
479
			if( pInputTail )
			{
480
				m_pInputAmp = new ITAStreamAmplifier( pInputTail, ( float ) m_dInputGain );
481
				m_pInputStreamDetector = new ITAStreamDetector( m_pInputAmp );
482
				m_pInputStreamDetector->SetProfilerEnabled( true );
483
				pInputTail = m_pInputStreamDetector;
Jonas Stienen's avatar
Jonas Stienen committed
484

485
486
487
488
489
				if( m_oCoreConfig.bRecordDeviceInputEnabled )
				{
					m_pStreamProbeDeviceInput = new ITAStreamProbe( pInputTail, m_oCoreConfig.sRecordDeviceInputFilePath );
					pInputTail = m_pStreamProbeDeviceInput;
				}
Jonas Stienen's avatar
Jonas Stienen committed
490
491
492
			}
		}

493
		SetProgress( "Setting up resource managers", "", 2 );
Jonas Stienen's avatar
Jonas Stienen committed
494

495
		m_pSignalSourceManager = new CVAAudioSignalSourceManager( this, m_oCoreConfig.oAudioDriverConfig, pInputTail );
496
497
		m_pGlobalSamplePool = ITASoundSamplePool::Create( 1, m_oCoreConfig.oAudioDriverConfig.dSampleRate );
		m_pGlobalSampler = ITASoundSampler::Create( 1, m_oCoreConfig.oAudioDriverConfig.dSampleRate, m_oCoreConfig.oAudioDriverConfig.iBuffersize, m_pGlobalSamplePool );
Jonas Stienen's avatar
Jonas Stienen committed
498
		m_pGlobalSampler->AddMonoTrack();
499

500
501
		m_pDirectivityManager = new CVADirectivityManager( this, m_oCoreConfig.oAudioDriverConfig.dSampleRate );
		m_pDirectivityManager->Initialize();
Jonas Stienen's avatar
Jonas Stienen committed
502
503


504
		SetProgress( "Setting up scene management", "", 3 );
Jonas Stienen's avatar
Jonas Stienen committed
505

506
507
508
		m_pSceneManager = new CVASceneManager( m_pClock );
		m_pSceneManager->Initialize();
		m_pCurSceneState = m_pSceneManager->GetHeadSceneState();
509

510
511
512
513
514
515
		SetProgress( "Setting up medium environment", "", 4 );

		oHomogeneousMedium = m_oCoreConfig.oInitialHomogeneousMedium;


		SetProgress( "Initializing rendering modules", "", 5 );
Jonas Stienen's avatar
Jonas Stienen committed
516

517
		// Register all renderers and initialize
518
		CVAAudioRendererRegistry::GetInstance()->RegisterInternalCoreFactoryMethods();
Jonas Stienen's avatar
Jonas Stienen committed
519
520
		InitializeAudioRenderers();

521
		if( m_voRenderers.empty() )
Jonas Stienen's avatar
Jonas Stienen committed
522
523
			VA_EXCEPT1( "No audio renderers created" );

524

525
		SetProgress( "Initializing reproduction modules", "", 6 );
526

527
		// Register all reproductions and initialize
528
		CVAAudioReproductionRegistry::GetInstance()->RegisterInternalCoreFactoryMethods();
Jonas Stienen's avatar
Jonas Stienen committed
529
530
		InitializeReproductionModules();

531
		if( m_voReproductionModules.empty() )
Jonas Stienen's avatar
Jonas Stienen committed
532
			VA_EXCEPT1( "No audio reproduction modules created" );
533

534
535
536

		SetProgress( "Patching audio i/o of rendering and reproduction modules", "", 7 );

Jonas Stienen's avatar
Jonas Stienen committed
537
538
539
540
541
542
543
544
		// Patch renderer and reproduction modules
		PatchRendererToReproductionModules();

		// Patch audio reproduction to output
		PatchReproductionModulesToOutput();


		// Create output peak detector that uses patch bay output stream
Michael Kohnen's avatar
merging    
Michael Kohnen committed
545

546
		m_pOutputStreamDetector = new ITAStreamDetector( m_pOutputPatchbay->GetOutputDatasource( iPhysicalHardwareOutput ) );
547
		m_pOutputStreamDetector->SetProfilerEnabled( true );
548
549


Jonas Stienen's avatar
Jonas Stienen committed
550
		// Setup output dump (if set)
551
		ITADatasource* pOutputTail = m_pOutputStreamDetector;
552
		if( m_oCoreConfig.bRecordDeviceOutputEnabled )
Jonas Stienen's avatar
Jonas Stienen committed
553
		{
554
			m_pStreamProbeFinal = new ITAStreamProbe( pOutputTail, m_oCoreConfig.sRecordFinalOutputFilePath );
Jonas Stienen's avatar
Jonas Stienen committed
555
556
557
558
			pOutputTail = m_pStreamProbeFinal;
		}

		// Attach the stream tracker
559
		m_pOutputTracker = new CVAAudiostreamTracker( pOutputTail, m_pClock, &m_fCoreClockOffset, &m_lSyncModOwner, m_pSignalSourceManager );
Jonas Stienen's avatar
Jonas Stienen committed
560
561
562
563
564
565
566
		pOutputTail = m_pOutputTracker;

		// Give output stream datasource to audio driver
		m_pAudioDriverBackend->setOutputStreamDatasource( pOutputTail );

		// Core-Clock auf 0 initialisieren
		double dNow = m_pClock->getTime();
567
		m_fCoreClockOffset = ( float ) dNow;
Jonas Stienen's avatar
Jonas Stienen committed
568
569
570
		m_dStreamClockOffset = -1;

		// Timer erzeugen und konfigurieren (wird fr Peak-Events benutzt)
571
		m_pTicker = new VistaTicker();
572
		m_pTicker->AddTrigger( new VistaTicker::TriggerContext( m_oCoreConfig.iTriggerUpdateMilliseconds, true ) );
573
		m_pTicker->SetAfterPulseFunctor( this );
Jonas Stienen's avatar
Jonas Stienen committed
574
575

		// Audio-Streaming starten
576
		SetProgress( "Starting audio streaming", "", 8 );
Jonas Stienen's avatar
Jonas Stienen committed
577
578
579
		m_pAudioDriverBackend->startStreaming();

		// Timer fr Peak-Events starten
580
		m_pTicker->StartTicker();
Jonas Stienen's avatar
Jonas Stienen committed
581
582
583
584

		// Initialisierung erfolgreich!
		m_iState = VA_CORESTATE_READY;

585
		SetProgress( "Initialization finished", "", 9 );
Jonas Stienen's avatar
Jonas Stienen committed
586
587
		FinishProgress();

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
588
	}
589
		VA_FINALLY
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
590
	{
Jonas Stienen's avatar
Jonas Stienen committed
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
		// Aufrumen und Exception weiterwerfen
		Tidyup();
		throw;
	}
}

void CVACoreImpl::Reset()
{
	VA_CHECK_INITIALIZED;

	// Wait for core thread
	while( !m_pCoreThread->TryBreak() )
		VASleep( 20 );

	VA_NO_REENTRANCE;

607
	if( GetUpdateLocked() )
Jonas Stienen's avatar
Jonas Stienen committed
608
	{
609
		VA_WARN( "Core", "Encountered locked scene during reset. Please unlock before resetting, skipping." );
Jonas Stienen's avatar
Jonas Stienen committed
610
611
612
613
614
		m_pCoreThread->Continue();
	}

	VA_TRY
	{
615
		VA_INFO( "Core", "Resetting core" );
Jonas Stienen's avatar
Jonas Stienen committed
616
617

		// Reset audio renderers
618
619
		std::vector< CVAAudioRendererDesc >::iterator it = m_voRenderers.begin();
		while( it != m_voRenderers.end() )
Jonas Stienen's avatar
Jonas Stienen committed
620
621
622
623
		{
			CVAAudioRendererDesc& oRend( *it++ );
			oRend.pInstance->Reset();
		}
624

Jonas Stienen's avatar
Jonas Stienen committed
625
626
627
		if( m_pCurSceneState )
		{
			// Referenz entfernen welche in CoreThreadLoop hinzugefgt wurde
628
			m_pCurSceneState->RemoveReference();
Jonas Stienen's avatar
Jonas Stienen committed
629
630
631
632
			m_pCurSceneState = nullptr;
		}

		// Alle Szenenobjekte lschen
633
634
635
		m_pSceneManager->Reset();
		m_pSignalSourceManager->Reset();
		m_pDirectivityManager->Reset();
Jonas Stienen's avatar
Jonas Stienen committed
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

		// TODO: Check if the pool and sampler must really be recreated
		/*
		delete m_pGlobalSamplePool;
		m_pGlobalSamplePool = nullptr;
		m_pGlobalSamplePool = ITASoundSamplePool::Create(1, m_oCoreConfig.oAudioDriverConfig.dSamplerate);

		// This causes a crash in patch bay
		delete m_pGlobalSampler;
		m_pGlobalSampler = nullptr;
		m_pGlobalSampler = ITASoundSampler::Create(1, m_oCoreConfig.oAudioDriverConfig.dSamplerate, m_oCoreConfig.oAudioDriverConfig.iBuffersize, m_pGlobalSamplePool);
		m_pGlobalSampler->AddMonoTrack();
		*/
		//m_pGlobalSampler->RemoveAllPlaybacks();

		// Werte neusetzen
652
		m_pCurSceneState = m_pSceneManager->GetHeadSceneState();
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
653
654
		m_iCurActiveSoundReceiver = -1;
		m_iNewActiveSoundReceiver = -1;
Jonas Stienen's avatar
Jonas Stienen committed
655
656
657
658
659
660
661

		m_pCoreThread;

		// Core-Thread fortsetzen
		m_pCoreThread->Continue();

		// Ereignis generieren, wenn Operation erfolgreich
662
		CVAEvent ev;
663
		ev.iEventType = CVAEvent::RESET;
Jonas Stienen's avatar
Jonas Stienen committed
664
		ev.pSender = this;
665
		m_pEventManager->BroadcastEvent( ev );
Jonas Stienen's avatar
Jonas Stienen committed
666
667

	}
668
		VA_FINALLY
Jonas Stienen's avatar
Jonas Stienen committed
669
670
671
672
673
674
675
676
	{
		Tidyup();
		throw;
	}
}

void CVACoreImpl::Tidyup() {
	/*
677
	 *  Hinweis: Diese Hilfsmethode wird nur innerhalb des Reentrance-Locks
Jonas Stienen's avatar
Jonas Stienen committed
678
679
	 *           aufgerufen - daher keine weiter Absicherung ntig.
	 */
680

Jonas Stienen's avatar
Jonas Stienen committed
681
682
	VA_TRY
	{
683
684
685
686
687
		if( m_pTicker )
		{
			m_pTicker->StopTicker();
			m_pTicker->SetAfterPulseFunctor( NULL );
		}
Jonas Stienen's avatar
Jonas Stienen committed
688
689

		FinalizeAudioDriver();
690
691
		FinalizeRenderingModules();
		FinalizeReproductionModules();
Jonas Stienen's avatar
Jonas Stienen committed
692

693
694
		delete m_pTicker;
		m_pTicker = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
695
696
697
698
699
700
701

		delete m_pCoreThread;
		m_pCoreThread = nullptr;

		delete m_pInputAmp;
		m_pInputAmp = nullptr;

702
703
		delete m_pInputStreamDetector;
		m_pInputStreamDetector = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
704
705
706
707
708
709
710

		delete m_pR2RPatchbay;
		m_pR2RPatchbay = nullptr;

		delete m_pOutputPatchbay;
		m_pOutputPatchbay = nullptr;

711
712
		delete m_pOutputStreamDetector;
		m_pOutputStreamDetector = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
713
714
715

		delete m_pOutputTracker;
		m_pOutputTracker = nullptr;
716

Jonas Stienen's avatar
Jonas Stienen committed
717
718
719
720
721
722
		delete m_pStreamProbeDeviceInput;
		m_pStreamProbeDeviceInput = nullptr;

		delete m_pStreamProbeFinal;
		m_pStreamProbeFinal = nullptr;

723
724
		delete m_pSignalSourceManager;
		m_pSignalSourceManager = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
725
726
727
728
729
730
731

		delete m_pGlobalSampler;
		m_pGlobalSampler = nullptr;

		delete m_pGlobalSamplePool;
		m_pGlobalSamplePool = nullptr;

732
733
734
735
		if( m_pDirectivityManager )
			m_pDirectivityManager->Finalize();
		delete m_pDirectivityManager;
		m_pDirectivityManager = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
736
737


738
739
740
741
		if( m_pSceneManager )
			m_pSceneManager->Finalize();
		delete m_pSceneManager;
		m_pSceneManager = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
742
743
744
745

		m_iState = VA_CORESTATE_CREATED;

	}
746
		VA_FINALLY
Jonas Stienen's avatar
Jonas Stienen committed
747
748
749
750
751
	{
		m_iState = VA_CORESTATE_FAIL;
	}
}

752
753
void CVACoreImpl::Finalize()
{
Jonas Stienen's avatar
Jonas Stienen committed
754
755
756
	VA_NO_REENTRANCE;

	//VA_TRACE("Core", __FUNCTION__ << " entry");
757
	VA_INFO( "Core", "Finalizing core" );
Jonas Stienen's avatar
Jonas Stienen committed
758

759
760
	VA_TRY
	{
Jonas Stienen's avatar
Jonas Stienen committed
761
		// Mehrfaches Finialisieren fhrt nicht zu Fehlern
762
763
764
765
		if( m_iState == VA_CORESTATE_CREATED ) return;

		if( m_iState == VA_CORESTATE_FAIL )
			VA_EXCEPT2( MODAL_ERROR, "Core corrupted, finalization impossible" );
Jonas Stienen's avatar
Jonas Stienen committed
766
767
768
769
770
771
772
773

		// Core-Thread anhalten (wenn frei ist)
		while( !m_pCoreThread->TryBreak() )
			VASleep( 10 );
		//m_pCoreThread->Break(); << deadlock

		// Alle Filterketten lschen und warten bis Zustand sicher bernommen
		// Wichtig: Dies muss vor dem Beenden des Streamings geschehen
774

Jonas Stienen's avatar
Jonas Stienen committed
775
		// Reset audio renderers
776
		for( std::vector<CVAAudioRendererDesc>::iterator it = m_voRenderers.begin(); it != m_voRenderers.end(); ++it )
Jonas Stienen's avatar
Jonas Stienen committed
777
778
779
			it->pInstance->Reset();

		// Peak-Nachrichten stoppen
780
		m_pTicker->StopTicker();
Jonas Stienen's avatar
Jonas Stienen committed
781
782
783
784

		// Audio-Streaming beenden
		m_pAudioDriverBackend->stopStreaming();

785
		InitProgress( "Stopping auralization threads", "", 2 );
Jonas Stienen's avatar
Jonas Stienen committed
786

787
788
789
790
		// Stop and delete ticker
		m_pTicker->SetAfterPulseFunctor( NULL );
		delete m_pTicker;
		m_pTicker = NULL;
Jonas Stienen's avatar
Jonas Stienen committed
791
792
793
794
795

		// Hauptthread beenden und freigeben
		delete m_pCoreThread;
		m_pCoreThread = nullptr;

796
		SetProgress( "Releasing audio hardware", "", 1 );
Jonas Stienen's avatar
Jonas Stienen committed
797
		FinalizeAudioDriver();
798
799
		FinalizeRenderingModules();
		FinalizeReproductionModules();
Jonas Stienen's avatar
Jonas Stienen committed
800

801
		SetProgress( "Cleaning up resources", "", 2 );
Jonas Stienen's avatar
Jonas Stienen committed
802
803
804
		delete m_pInputAmp;
		m_pInputAmp = nullptr;

805
806
807
		if( m_pInputStreamDetector )
			if( m_pInputStreamDetector->GetProfilerEnabled() )
				VA_VERBOSE( "Core", "Input stream detector profiler: " << m_pInputStreamDetector->GetProfilerResult() );
808
809
		delete m_pInputStreamDetector;
		m_pInputStreamDetector = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
810

811
		m_voReproductionModules.clear();
Jonas Stienen's avatar
Jonas Stienen committed
812
813
814
815
816
817
818

		delete m_pR2RPatchbay;
		m_pR2RPatchbay = nullptr;

		delete m_pOutputPatchbay;
		m_pOutputPatchbay = nullptr;

819
820
		if( m_pOutputStreamDetector->GetProfilerEnabled() )
			VA_VERBOSE( "Core", "Output stream detector profiler: " << m_pOutputStreamDetector->GetProfilerResult() );
821
822
		delete m_pOutputStreamDetector;
		m_pOutputStreamDetector = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
823
824
825
826
827
828
829
830
831
832

		delete m_pOutputTracker;
		m_pOutputTracker = nullptr;

		delete m_pStreamProbeDeviceInput;
		m_pStreamProbeDeviceInput = nullptr;

		delete m_pStreamProbeFinal;
		m_pStreamProbeFinal = nullptr;

833
834
		delete m_pSignalSourceManager;
		m_pSignalSourceManager = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
835
836
837
838
839
840
841

		delete m_pGlobalSampler;
		m_pGlobalSampler = nullptr;

		delete m_pGlobalSamplePool;
		m_pGlobalSamplePool = nullptr;

842
843
844
		m_pDirectivityManager->Finalize();
		delete m_pDirectivityManager;
		m_pDirectivityManager = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
845

846
847
848
		m_pSceneManager->Finalize();
		delete m_pSceneManager;
		m_pSceneManager = nullptr;
Jonas Stienen's avatar
Jonas Stienen committed
849
850
851
852
853
854

		// Finalisierung erfolgreich. Nun wieder im Grundzustand!
		m_iState = VA_CORESTATE_CREATED;

		FinishProgress();

855
856
857
	}
		VA_FINALLY
	{
Jonas Stienen's avatar
Jonas Stienen committed
858
859
860
861
862
863
864
865
866
867
868
869
		// Nochmals versuchen aufzurumen
		Tidyup();

		// Allgemein: Fehler beim Finalisieren? => Core im Sack
		m_iState = VA_CORESTATE_FAIL;

		// VAExceptions unverndert nach aussen leiten
		throw;
	}
}


870
void CVACoreImpl::RegisterModule( CVAObject* pModule )
Jonas Stienen's avatar
Jonas Stienen committed
871
{
872
	m_oModules.RegisterObject( pModule );
Jonas Stienen's avatar
Jonas Stienen committed
873
874
}

875
void CVACoreImpl::GetModules( std::vector< CVAModuleInfo >& viModuleInfos ) const
876
{
Jonas Stienen's avatar
Jonas Stienen committed
877
878
879
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

880
#ifdef VACORE_MODULE_INTERFACE_ENABLED
881
882
	VA_TRY
	{
Jonas Stienen's avatar
Jonas Stienen committed
883
		std::vector<CVAObjectInfo> v;
884
		m_oModules.GetObjectInfos( v );
Jonas Stienen's avatar
Jonas Stienen committed
885

886
		VA_PRINT( "Available modules (" << v.size() << ")" );
Jonas Stienen's avatar
Jonas Stienen committed
887
888
889

		viModuleInfos.clear();
		viModuleInfos.resize( v.size() );
890
891
892
893
894
		for( size_t i = 0; i < v.size(); i++ )
		{
			VA_PRINT( "'" << v[ i ].sName << "'\t\t\t" << v[ i ].sDesc );
			viModuleInfos[ i ].sName = v[ i ].sName;
			viModuleInfos[ i ].sDesc = v[ i ].sDesc;
Jonas Stienen's avatar
Jonas Stienen committed
895
		}
896
		}
897
898
	VA_RETHROW;

899
#else // VACORE_MODULE_INTERFACE_ENABLED
900

901
902
	VA_EXCEPT1( "This VACore version does not provide modules" );

903
#endif // VACORE_MODULE_INTERFACE_ENABLED
904

905
	}
Jonas Stienen's avatar
Jonas Stienen committed
906

907
CVAStruct CVACoreImpl::CallModule( const std::string& sModuleName, const CVAStruct& oArgs )
908
{
Jonas Stienen's avatar
Jonas Stienen committed
909
910
911
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

912
#ifdef VACORE_MODULE_INTERFACE_ENABLED
913
914
915

	VA_TRY
	{
916
		CVAObject* pModule = m_oModules.FindObjectByName( sModuleName );
917
		if( !pModule )
918
		{
919
			VA_EXCEPT2( INVALID_PARAMETER, "Module '" + sModuleName + "' not found" );
920
		}
921
922
923

#ifdef VACORE_MODULE_INTERFACE_MECHANISM_EVENT_BASED

924
		CVAEvent ev;
925
		ev.iEventType = CVAEvent::SIGNALSOURCE_STATE_CHANGED;
926
927
928
		ev.pSender = this;
		ev.sObjectID = sModuleName;
		ev;
929
930
		m_pEventManager->BroadcastEvent( ev );
		m_pEventManager->
931
932
933

#else // not VACORE_MODULE_INTERFACE_MECHANISM_EVENT_BASED

934
		return pModule->CallObject( oArgs );
935
936

#endif // VACORE_MODULE_INTERFACE_MECHANISM_EVENT_BASED
Jonas Stienen's avatar
Jonas Stienen committed
937

938
939
	}
	VA_RETHROW;
940

941
#else // VACORE_MODULE_INTERFACE_ENABLED
942

943
#ifdef VACORE_NO_MODULE_INTERFACE_THROW_EXCEPTION
944
	VA_EXCEPT1( "This VACore version does not provide modules" );
945
946
#endif // VACORE_NO_MODULE_INTERFACE_THROW_EXCEPTION

947
#endif // VACORE_MODULE_INTERFACE_ENABLED
Jonas Stienen's avatar
Jonas Stienen committed
948
949
}

950
951
952
953
CVAStruct CVACoreImpl::GetSearchPaths() const
{
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;
Jonas Stienen's avatar
Jonas Stienen committed
954

955
956
957
958
959
960
961
	CVAStruct oSearchPaths;
	for( size_t i = 0; i < m_oCoreConfig.vsSearchPaths.size(); i++ )
		oSearchPaths[ "path_" + std::to_string( long( i ) ) ] = m_oCoreConfig.vsSearchPaths[ i ];

	return oSearchPaths;
}

962
CVAStruct CVACoreImpl::GetCoreConfiguration( const bool bFilterEnabled ) const
Jonas Stienen's avatar
Jonas Stienen committed
963
964
965
966
{
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

967
968
	CVAStruct oCoreConfig;

969
970
971
972
973
	if( bFilterEnabled )
	{
		CVAStruct::const_iterator cit = m_oCoreConfig.GetStruct().Begin();
		while( cit != m_oCoreConfig.GetStruct().End() )
		{
974
975
976
977
			const std::string sKey( cit->first );
			const CVAStructValue& oVal( cit->second );
			++cit;

978
979
980
981
982
983
			if( oVal.IsStruct() )
			{
				const CVAStruct& oSection( oVal.GetStruct() );
				if( oSection.HasKey( "enabled" ) )
					if( bool( oSection[ "enabled" ] ) == false )
						continue; // Only skip if explicitly not enabled
984
				oCoreConfig[ sKey ] = oVal;
985
986
			}
		}
987

988
989
990
	}
	else
	{
991
		oCoreConfig = m_oCoreConfig.GetStruct();
992
	}
993
994

	return oCoreConfig;
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
}

CVAStruct CVACoreImpl::GetHardwareConfiguration() const
{
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;
	return m_oCoreConfig.oHardwareSetup.GetStruct();
}

CVAStruct CVACoreImpl::GetFileList( const bool bRecursive, const std::string& sFileSuffixFilter ) const
{
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

	CVAStruct oFileList;
	for( size_t i = 0; i < m_oCoreConfig.vsSearchPaths.size(); i++ )
Jonas Stienen's avatar
Jonas Stienen committed
1011
	{
1012
1013
1014
1015
1016
1017
1018
1019
		if( bRecursive )
		{
			RecursiveFileList( m_oCoreConfig.vsSearchPaths[ i ], oFileList, sFileSuffixFilter );
		}
		else
		{
			std::vector< std::string > vsFileList;
			FileList( m_oCoreConfig.vsSearchPaths[ i ], vsFileList, sFileSuffixFilter );
Jonas Stienen's avatar
Jonas Stienen committed
1020

1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
			CVAStruct oMoreFiles;
			for( size_t j = 0; j < vsFileList.size(); j++ )
				oMoreFiles[ std::to_string( long( j ) ) ] = vsFileList[ j ];

			oFileList[ m_oCoreConfig.vsSearchPaths[ i ] ] = oMoreFiles;
		}
	}
	return oFileList;
}

1031
int CVACoreImpl::CreateDirectivityFromParameters( const CVAStruct& oParams, const std::string& sName )
Jonas Stienen's avatar
Jonas Stienen committed
1032
1033
1034
1035
1036
1037
{
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

	VA_TRY
	{
1038
		int iDirID = m_pDirectivityManager->CreateDirectivity( oParams, sName );
Jonas Stienen's avatar
Jonas Stienen committed
1039
1040
1041

		assert( iDirID != -1 );

1042
		CVAEvent ev;
1043
		ev.iEventType = CVAEvent::DIRECTIVITY_LOADED;
Jonas Stienen's avatar
Jonas Stienen committed
1044
1045
		ev.pSender = this;
		ev.iObjectID = iDirID;
1046
		m_pEventManager->BroadcastEvent( ev );
Jonas Stienen's avatar
Jonas Stienen committed
1047

1048
		VA_INFO( "Core", "Directivity successfully loaded, assigned directivity ID " << iDirID );
Jonas Stienen's avatar
Jonas Stienen committed
1049
1050
1051
1052
1053
1054

		return iDirID;

	} VA_RETHROW;
}

1055
1056
bool CVACoreImpl::DeleteDirectivity( const int iDirID )
{
Jonas Stienen's avatar
Jonas Stienen committed
1057
1058
1059
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

1060
1061
	VA_TRY
	{
1062
		bool bSuccess = m_pDirectivityManager->DeleteDirectivity( iDirID );
Jonas Stienen's avatar
Jonas Stienen committed
1063
1064
1065
		//assert( bSuccess );

		// Ereignis generieren, wenn Operation erfolgreich
1066
		CVAEvent ev;
1067
		ev.iEventType = CVAEvent::DIRECTIVITY_DELETED;
Jonas Stienen's avatar
Jonas Stienen committed
1068
1069
		ev.pSender = this;
		ev.iObjectID = iDirID;
1070
		m_pEventManager->BroadcastEvent( ev );
Jonas Stienen's avatar
Jonas Stienen committed
1071

1072
		VA_INFO( "Core", "FreeDirectivity successful, freed directivity " << iDirID );
Jonas Stienen's avatar
Jonas Stienen committed
1073
1074
1075
1076
1077
1078

		return bSuccess;

	} VA_RETHROW;
}

1079
CVADirectivityInfo CVACoreImpl::GetDirectivityInfo( int iDirID ) const {
Jonas Stienen's avatar
Jonas Stienen committed
1080
1081
1082
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

1083
	VA_TRY{
1084
		return m_pDirectivityManager->GetDirectivityInfo( iDirID );
Jonas Stienen's avatar
Jonas Stienen committed
1085
1086
1087
	} VA_RETHROW;
}

1088
1089
void CVACoreImpl::GetDirectivityInfos( std::vector<CVADirectivityInfo>& vdiDest ) const
{
Jonas Stienen's avatar
Jonas Stienen committed
1090
1091
1092
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

1093
1094
	VA_TRY
	{
1095
		m_pDirectivityManager->GetDirectivityInfos( vdiDest );
1096
1097
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
1098
1099
}

1100
void CVACoreImpl::SetDirectivityName( const int iID, const std::string& sName )
Jonas Stienen's avatar
Jonas Stienen committed
1101
1102
1103
1104
1105
1106
{
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

	VA_TRY
	{
1107
1108
1109
1110
		VA_EXCEPT_NOT_IMPLEMENTED_NEXT_VERSION;
		//m_pDirectivityManager->SetName( iID, sName );
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
1111
1112
}

1113
std::string CVACoreImpl::GetDirectivityName( const int iID ) const
1114
{
Jonas Stienen's avatar
Jonas Stienen committed
1115
1116
1117
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

1118
	VA_TRY
1119
	{
1120
1121
		CVADirectivityInfo oInfo = m_pDirectivityManager->GetDirectivityInfo( iID );
		return oInfo.sName;
1122
1123
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
1124
1125
}

1126
void CVACoreImpl::SetDirectivityParameters( const int iID, const CVAStruct& oParams )
1127
{
Jonas Stienen's avatar
Jonas Stienen committed
1128
1129
1130
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

1131
1132
	VA_TRY
	{
1133
1134
		VA_EXCEPT_NOT_IMPLEMENTED_NEXT_VERSION;
		//m_pDirectivityManager->SetParameters( iID, oParams );
1135
1136
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
1137
1138
}

1139
CVAStruct CVACoreImpl::GetDirectivityParameters( const int iID, const CVAStruct& ) const
1140
{
Jonas Stienen's avatar
Jonas Stienen committed
1141
1142
1143
	VA_NO_REENTRANCE;
	VA_CHECK_INITIALIZED;

1144
1145
1146
1147
1148
1149
1150
1151
1152
	VA_TRY
	{
		CVADirectivityInfo oInfo = m_pDirectivityManager->GetDirectivityInfo( iID );
		return oInfo.oParams;

		// @todo
		//return m_pDirectivityManager->GetDirectivityParameters( iID, oParams );
	}
	VA_RETHROW;
Jonas Stienen's avatar
Jonas Stienen committed
1153
1154
}

1155
1156
int CVACoreImpl::CreateAcousticMaterial( const CVAAcousticMaterial& oMaterial, const std::string& sName )
{