ITAUPFilter.h 4 KB
Newer Older
1
2
3
4
5
/*
 * ----------------------------------------------------------------
 *
 *		ITA core libs
 *		(c) Copyright Institute of Technical Acoustics (ITA)
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
6
 *		RWTH Aachen University, Germany, 2015-2020
7
8
9
10
11
12
13
14
15
16
17
18
 *
 * ----------------------------------------------------------------
 *				    ____  __________  _______
 *				   //  / //__   ___/ //  _   |
 *				  //  /    //  /    //  /_|  |
 *				 //  /    //  /    //  ___   |
 *				//__/    //__/    //__/   |__|
 *
 * ----------------------------------------------------------------
 *
 */

19
20
#ifndef INCLUDE_WATCHER_ITA_UP_FILTER
#define INCLUDE_WATCHER_ITA_UP_FILTER
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

#include <ITAConvolutionDefinitions.h>

#include <ITACriticalSection.h>
#include <ITATypes.h>
#include <ITAUncopyable.h>

#include <atomic>
#include <vector>

// Vorwärtsdeklarationen
class ITAUPFilterPool;
class ITAFFT;

/**
 * Diese Klasse realisiert Filter (d.h. Representationen von Impulsantworten im Frequenzbereich)
37
 * für DSMBCConvolver. Solche Filter haben einen Zustand: 1) unbenutzt oder 2) momentan in einem
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 * Falter in Benutzung. Generell kann 1 Filter in beliebig vielen Faltern verwendet werden.
 * Seine Daten dürfen aber nur modifiziert werden, wenn es nicht in Benutzung ist.
 *
 * Eine neue Impulsantwort wird mittels der Methode load geladen und intern transformiert.
 *
 * Nebenläufigkeit & Synchronisation:
 *
 * Instanzen der Klasse sollen nur von einem Thread zu einer Zeit benutzt werden
 * (üblicherweise der Thread der die Filterdaten generiert hat). Im Sinne der Anwendung
 * macht es keinen Sinn das mehrere Threads um beispielsweise die load-Methode konkurrieren.
 * Deshalb unternimmt die Klasse keine Maßnahmen zur Synchronisation.
 */

class ITA_CONVOLUTION_API ITAUPFilter : public ITAUncopyable
{
public:
	//! Konstruktor
	ITAUPFilter( const int iBlocklength, const int iMaxFilterLength );

	//! Destruktor
	/**
	 * Hinweis: Das Objekt kann nur freigegeben werden, wenn es nicht mehr benutzt wird!
	 */
	virtual ~ITAUPFilter();

	//! Gibt zurück ob der Filter aktuell in Benutzung ist
64
	bool IsInUse() const;
65
66
67
68
69

	//! übergeordneten Filterpool zurückgeben (falls nicht vorhanden NULL)
	ITAUPFilterPool* getParentFilterPool() const;

	//! Filter übergeordneten Filterpool freigeben (falls Teil eines Filterpools)
70
	void Release();
71
72
73
74
75
76
77
78

	//! Filterdaten laden
	/**
	 * \param pfFilterData Array mit den Filterkoeffizienten
	 * \param iFilterLength Anzahl Filterkoeffizienten in pfFilterData (maximal iMaxFilterLength)
	 *
	 * \note Falls das Filter in Benutzung ist wird eine ITAException geworfen!
	 */
79
	void Load( const float* pfFilterData, const int iFilterLength );
80
81

	//! Nullen setzen
82
	void Zeros();
83
84
85
86
87
88
89
90
91
92
93

	//! Einheitsimpuls (Dirac) setzen
	void identity();

	// Interne Zustandklasse, welche Referenzzähler enthält.
	// Es werden immer zwei Zähler benötigt: Prep und Use.
	class State
	{
	public:
		State( ITAUPFilter* pParent );

94
95
96
97
98
		bool IsInUse() const;
		void AddPrep();
		void RemovePrep();
		void ExchangePrep2Use();
		void RemoveUse();
99
100
101
102
103
104
105
106
107
108
109
110
111
112

		// Damit auf älteren Windows-System, welche keine DCAS-Operationen bereistellen,
		// dieser zwei-elementige Zustand atomar verändert werden kann,
		// muss eine Datenstruktur von 32-Bit realisiert werden.
		// 16-Bit für die Zähler ist immer noch ausreichend
		typedef struct
		{
			std::atomic< int16_t > iPrepRefCount;
			std::atomic< int16_t > iUseRefCount;
		} StateStruct;

		ITAUPFilter* m_pParent;
		StateStruct m_oState;

113
		void ModifyState( const int16_t iPrepDelta, const int16_t iUseDelta );
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
	};

	ITAUPFilterPool* m_pParent;				// Übergeordneter Filterpool
	int m_iBlocklength;						// Blocklänge (Zeitbereich)
	int m_iNumFilterParts;					// Anzahl Filterteile
	int m_iNumEffectiveFilterParts;			// Anzahl effektiver Filterteile mit Filterkoeff. != 0
	std::vector<float*> m_vpfFreqData;		// Filterdaten im Frequenzbereich (DFT-Spektren der Teile)
	ITAFFT* m_pFFT;
	ITACriticalSection m_csReentrance;		// Reentrance-Lock für die Load-Methode
	State m_oState;							// Zustand

	friend class ITAUPConvolution;
	friend class ITAUPFilterPool;
};

129
#endif // INCLUDE_WATCHER_ITA_UP_FILTER