ITAUPFilter.h 4 KB
Newer Older
1 2 3 4 5
/*
 * ----------------------------------------------------------------
 *
 *		ITA core libs
 *		(c) Copyright Institute of Technical Acoustics (ITA)
6
 *		RWTH Aachen University, Germany, 2015-2019
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