Interfaces.h 11.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 *		RAVEN Interface
 *
 *		(c) Copyright Institut fr Technische Akustik (ITA)
 *			RWTH Aachen (http://www.akustik.rwth-aachen.de)
 *
 *  ---------------------------------------------------------------------------------
 *
 *    Datei:			R_Raven.h
 *
 *    Zweck:			Interface to RAVEN
 *
 *    Autor(en):		Jonas Stienen (stienen@akustik.rwth-aachen.de)
 *						Frank Wefers (fwe@akustik.rwth-aachen.de)
 *						Snke Pelzer (spe@akustik.rwth-aachen.de)
 *
 *  ---------------------------------------------------------------------------------
 */
  
// $Id: R_Raven.h 2732 2012-06-26 13:38:17Z stienen $

#ifndef __R_RAVEN_H__
#define __R_RAVEN_H__

// API includes
Pascal Palenda's avatar
Pascal Palenda committed
26
#include <ITASimulationScheduler/Definitions.h>
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

// Raven includes
#include <RG_Vector.h>
#include <ITASimulationScheduler/Raven/R_RavenScene.h>
#include <ITASimulationScheduler/Raven/R_RavenConfig.h>

// ITA includes
#include <ITAException.h>
#include <ITASampleFrame.h>

// STL includes
#include <map>
#include <stdio.h>
#include <vector>

42
namespace ITASimulationScheduler
43
44
{

45
46
47
48
49
	//! Statistics class
	/**
	  * This class holds information on statistical values such as
	  * average and deviation.
	  */
Pascal Palenda's avatar
Pascal Palenda committed
50
	class ITA_SIMULATION_SCHEDULER_API CStatistics
51
	{
52
53
	public:
		//! Constructor, sets internal values to zero
Pascal Palenda's avatar
Pascal Palenda committed
54
		CStatistics()
55
56
57
		{
			Reset();
		};
58

59
60
61
62
63
64
65
66
67
		//! Set all internal values to zero
		void Reset()
		{
			dMean = 0;
			dStdDev = 0;
			dMin = 0;
			dMax = 0;
			uiCycles = 0;
		};
68

69
70
71
72
73
74
75
		double dMean;				//!< Mean/Average
		double dStdDev;				//!< Standard deviation	
		double dMin;				//!< Maximum
		double dMax;				//!< Minimum
		unsigned long int uiCycles;	//!< Number of cycles/elements
		std::string sName;	//!< Short name
	};
76
	
77
78
	//! Simulation task
	/**
79
80
81
82
		* Enthlt Informationen ber Auftragstyp, virtuelle Szene und Konfiguration der Simulation.
		* Datenpfade sollten mit dem Makro $(RavenDataBasePath) beginnen, um den (entfernten) Simulator
		* anzuweisen, den fr sich eingestellten Datenpfad zu verwenden.
		*/
Pascal Palenda's avatar
Pascal Palenda committed
83
	class ITA_SIMULATION_SCHEDULER_API CSimulationTask
84
	{
85
86
	public:
		//!< Simulation types
87
88
		enum
		{
89
90
91
92
			SIM_DS = 1 << 0, //!< Direct sound
			SIM_ER_IS = 1 << 1, //!< Early reflections using Image Sources
			SIM_DD_RT = 1 << 2, //!< Diffuse decay using Ray Tracing
			SIM_DD_AR = 1 << 3, //!< Diffuse decay using Artificial Reverberation
93
94
		};

Pascal Palenda's avatar
Pascal Palenda committed
95
96
		CSimulationTask() {};
		virtual ~CSimulationTask() {};
97

98
99
		unsigned long int uiID;				//!< Unique Identifier fr diesen Task
		unsigned long int uiReferenceID;	//!< Referenz-Identifier (fr den Benutzer)
100

101
		int iSimulationType;	//!< Type of simulation, one of 'simulation types'
102

Pascal Palenda's avatar
Pascal Palenda committed
103
104
		RAVEN::CScene oScene;		//!< Scene, die komplett simuliert wird (smtliche Quellen, Portale und Empfnger)
		RAVEN::CConfig oConfig;	//!< Konfiguration fr den Simulationsauftrag
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
		//! Task profiler status
		struct CProfiler
		{
			//! Discard reasons
			enum
			{
				UNSPECIFIED = 0,		//!< Unkown or unspecified reason
				RESET_INDICATED,		//!< Discarded due to reset request
				REPLACED_BY_NEWER,		//!< Task was replaced by a newer task with same reference id
				REPLACED_BY_PREFERRED,	//!< Task was replaced by a preferred task
				UNHANDABLE,				//!< Task could not be handled by scheduler
			};

			double dCreationTime;
			double dSchedulerEnqueTime;
			double dSchedulerTurnaroundTime;
			double dComputeTime;
			int iDiscardReason;
		};
125

126
		CProfiler oProfiler; //!< Task Profiler
127

128
129
		//! Perform some sanity checks
		inline bool IsValid() const
130
		{
131
132
133
134
			if (iSimulationType < 0)
				return false;
			if (oConfig.Validate() != 0)
				return false;
135

136
137
			return true;
		};
138
139
	};

140
	//! Container for simulation results
Pascal Palenda's avatar
Pascal Palenda committed
141
	class ITA_SIMULATION_SCHEDULER_API CSimulationResult
142
143
	{
	public:
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
		//! Complex sound path of a sender-receiver-pair
		class ComplexSimulationSoundPath
		{
		public:
			ComplexSimulationSoundPath();
			virtual ~ComplexSimulationSoundPath();

			//! Art des komplexen Schallpfades
			enum
			{
				S2R = 0,	//!< Quelle zu Empfnger
				P2R,	//!< Portal zu Empfnger
				S2P,	//!< Quelle zu Portal
				P2P,	//!< Portal zu Portal
			};

			int iType;					//!< Art des komplexen Schallpfades
			int iReceiverID;			//!< ID des Empfngerobjekts (Hrer oder Portal)
			int iSenderID;				//!< ID des Senderobjekts (Quelle oder Portal)
			int iNumChannels;			//!< Anzahl der Kanle
			bool bDirectSoundAudible;	//!< True, wenn Direktschall hrbar ist (nicht verdeckt)
			bool bEntitiesInSameRoom;	//!< True, if source and receiver are in sme room
			bool bEmpty;				//!< True, wenn die Impulsantwort leer ist
			int iLeadingZeros;			//!< Anzahl an Null-Samples am Anfang der eigentlichen Impulsantwort
			int iTailingZeros;			//!< Anzahl an Null-Samples am Ende der generierten Impulsantwort
			bool bZerosStripped;		//!< Indicated, if zeros are stripped from result container (true) or still included (false)
			ITASampleFrame* psfResult;	//!< Zeiger auf Impulsantwort des komplexen Schallpfades
		};
173

174
		//! Constructor
Pascal Palenda's avatar
Pascal Palenda committed
175
		CSimulationResult();
176

177
		//! Destructor
Pascal Palenda's avatar
Pascal Palenda committed
178
		virtual ~CSimulationResult();
179

180
181
		//! Deletes all accumulated complex simulation sound paths
		virtual void Clear();
182

183
184
		std::vector< ComplexSimulationSoundPath* > vcspResult; //!< Result container
	};
185

186
	//! Abstract RAVEN simulation interface
187
	/**
188
189
190
	  * This abstract Interface to RAVEN embraces the
	  * functional methods that every Raven simulator
	  * has to implement.
191
192
	  *
	  */
Pascal Palenda's avatar
Pascal Palenda committed
193
	class ITA_SIMULATION_SCHEDULER_API ISimulationInterface
194
	{
195
	public:
196

Pascal Palenda's avatar
Pascal Palenda committed
197
		virtual ~ISimulationInterface() {};
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

		//! Reset
		/**
		  * Perform an entire reset of the RAVEN instance, i.e. clear all objects and geometry (scene)
		  */
		virtual void Reset() = 0;

		//! Load a scene (RPF) 
		/**
		  * \param sFileName Path to the Raven Project File (RPF), use with macro $(RavenDataBasePath)
		  *
		  * \note will become irrelevant one day ... load via special task
		  */
		virtual void LoadScene(const std::string& sFileName) = 0;

		//! Perform a simulation of a task and provide result
		/**
		  * This call will perform a simulation of the required task and will present the result.
		  * This call is blocking, i.e. depending on the complexity of the scene and the geometry,
		  * the computation might take a couple of seconds.
		  *
		  * \param pTask Simulation task with a scene and a configuration, profiler status will be modified
		  * \param pResult Pointer to an existing simulation result container. Results will initialized and appended to the container.
		  */
Pascal Palenda's avatar
Pascal Palenda committed
222
		virtual void Compute(CSimulationTask* pTask, CSimulationResult* pResult) = 0;
223
224
225
226
227
228
229

		//! Simulator profiler
		struct CProfiler
		{
			unsigned int uiNumLoadScenes;	//!< Number of (forced) scene reloads
			unsigned int uiNumResets;		//!< Number of (forced) resets

Pascal Palenda's avatar
Pascal Palenda committed
230
231
232
233
234
			CStatistics oCompute;		//!< Statistics on overall compute (incl. config and scene adaption and simulation)
			CStatistics oSimulateDS;	//!< Statistics on simulation of DS
			CStatistics oSimulateIS;	//!< Statistics on simulation of IS
			CStatistics oSimulateRT;	//!< Statistics on simulation of RT
			CStatistics oSimulateAR;	//!< Statistics on simulation of AR
235
		};
236

237
238
239
240
241
242
243
244
245
246
		//! Return current profiler status
		/**
		  * \param oStatus Status information, only if profile availabele
		  *
		  * \return TRUE, if profile information available, false otherwise (check this!)
		  */
		virtual bool GetProfilerStatus(CProfiler& oStatus) = 0;

	protected:
		//! Protected standard constructor
Pascal Palenda's avatar
Pascal Palenda committed
247
		ISimulationInterface() {};
248
	};
249
250


251
	// Forward declaration of result handler
Pascal Palenda's avatar
Pascal Palenda committed
252
	class ISimulationSchedulerResultHandler;
253

254
	//! Abstract RAVEN simulation scheduler interface
255
	/**
256
257
258
259
260
261
262
	  * This abstract Interface to a RAVEN scheduler embraces the
	  * functional methods that every RAVEN scheduler has to implement.
	  *
	  * A Raven simulation scheduler receives tasks and either
	  * discards the computation or accepts and in latter case
	  * returns a simulation result.
	  *
263
	  */
Pascal Palenda's avatar
Pascal Palenda committed
264
	class ITA_SIMULATION_SCHEDULER_API ISimulationSchedulerInterface
265
266
	{
	public:
267
		//! Destructor
Pascal Palenda's avatar
Pascal Palenda committed
268
		virtual ~ISimulationSchedulerInterface() {};
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

		// stienen: vielleicht brauchen wir den fr Handle-Hooks, i.e. fr RavenNet
		//virtual void SetTaskHandler(IRavenSimulationSchedulerTaskHandler*)=0;

		//! Reset the Scheduler and its simulators
		/**
		  * \note	This call will go into a blocking wait until all nodes have
		  *			signaled that they sucessfully performed a reset. In worst case
		  *			this means, that the scheduler will wait for an entire simulation task
		  *			to be performed (i.e. up to some hundred milliseconds, if Ray Tracing is used)
		  */
		virtual void Reset() = 0;

		//! Add a task to the scheduler queue
		/**
		  * \param pTask Simulation task with a scene and a configuration, task profiler status will be modified
		  */
Pascal Palenda's avatar
Pascal Palenda committed
286
		virtual void AddTask(CSimulationTask* pTask) = 0;
287
288
289
290
291
292
293
294
295
296
297

		//! Advise the scheduler to load a geometry file
		/**
		  * \param sFileName Path to the geometry file (.ac), use with macro $(RavenDataBasePath)
		  */
		virtual void LoadScene(const std::string& sFileName) = 0;

		//! Attach a Simulation Result Handler that will be called when Task is finished or discarded
		/**
		  * \return True, if attach possible, false if already present in internal list
		  */
Pascal Palenda's avatar
Pascal Palenda committed
298
		virtual bool AttachSimulationResultHandler(ISimulationSchedulerResultHandler*) = 0;
299
300
301
302
303

		//! Detach a Simulation Result Handler
		/**
		  * \return True, if detach possible, false if already present in internal list
		  */
Pascal Palenda's avatar
Pascal Palenda committed
304
		virtual bool DetachSimulationResultHandler(ISimulationSchedulerResultHandler*) = 0;
305
306
307

		//! Scheduler profiler
		struct CProfiler
308
		{
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
		public:
			// Tasks
			struct CProfilerSimType
			{
				unsigned long int uiTasksAdded;		//!< Total number of added tasks
				unsigned long int uiTasksDiscarded;	//!< Total number of discarded tasks
				unsigned long int uiTasksFinished;	//!< Total number of finished tasks
				unsigned long int uiTasksPending;	//!< Total number of pending tasks
				double dTaskTurnaroundDiscarded;	//!< Average time for turnaround if task was discarded
				double dTaskTurnaroundFinished;		//!< Average time for turnaround if task was finished
				double dTaskComputeAvrg;			//!< Average time that has been spend on compute
			};

			CProfilerSimType oAll;
			CProfilerSimType oDS;
			CProfilerSimType oER_IS;
			CProfilerSimType oDD_RT;
			CProfilerSimType oDD_AR;
327
328
		};

329
330
331
332
333
334
335
336
337
338
		//! Return current profiler status
		/**
		  * \param oStatus Status information, only if profile availabele
		  *
		  * \return TRUE, if profile information available, false otherwise (check this!)
		  */
		virtual bool GetProfilerStatus(CProfiler& oStatus) = 0;

	protected:
		//! Protected standard constructor
Pascal Palenda's avatar
Pascal Palenda committed
339
		ISimulationSchedulerInterface() {};
340
341
342
	};


343
	//! Abstracter Handler, der einem Scheduler hinzugefgt werden kann und welcher dann mit Resultaten bedient wird
Pascal Palenda's avatar
Pascal Palenda committed
344
	class ITA_SIMULATION_SCHEDULER_API ISimulationSchedulerResultHandler
345
	{
346
347
348
349
350
351
	public:
		enum
		{
			COMPUTE_TASK = 0,
			DISCARD_TASK = 1,
		};
352

353
354
355
356
357
		enum
		{
			DELETE_TASK = 0,
			PRESERVE_TASK = 1,
		};
358

Pascal Palenda's avatar
Pascal Palenda committed
359
		virtual ~ISimulationSchedulerResultHandler() {};
360
361
362
363
364
365
366
367
368
369

		//! Hook: Wird aufgerufen nachdem ein Task dem Scheduler hinzugefgt wurde
		// VIELLEICHT: virtual void PostTaskAdded(Scheduler*, Task*) {};

		//! Hook: Wird vor der tatschlichen Ausfhrung des Task aufgerufen
		/**
		  * Der Handler kann den Aufruf dazu nutzen den Task zu verndern
		  * (z.B. zwischenzeitlich aktualisierte Positionsdaten) oder diesen
		  * zu verwerfen (hierzu wird der Rckgabewert genutzt, COMPUTE_TASK|DISCARD_TASK).
		  */
Pascal Palenda's avatar
Pascal Palenda committed
370
		virtual int PreTaskStart(ISimulationSchedulerInterface*, CSimulationTask*) = 0;
371
372
373
374
375

		//! Hook: Wird aufgerufen nachdem ein Task abgeschlossen wurde
		/**
		  * \return Ein Wert aus #TaskDeletion
		  */
Pascal Palenda's avatar
Pascal Palenda committed
376
		virtual int PostTaskFinished(ISimulationSchedulerInterface*, const CSimulationTask*, CSimulationResult*) = 0;
377
378
379
380
381

		//! Hook: wird aufgerufen, nachdem ein Task abgewiesen/ersetzt wurde
		/**
		  * \return Ein Wert aus #TaskDeletion
		  */
Pascal Palenda's avatar
Pascal Palenda committed
382
		virtual int PostTaskDiscarded(ISimulationSchedulerInterface*, const CSimulationTask*) = 0;
383
384
385

	protected:
		//! Protected standard constructor
Pascal Palenda's avatar
Pascal Palenda committed
386
		ISimulationSchedulerResultHandler() {};
387
	};
388

389
}
390
391

#endif // __R_RAVEN_H__