diff --git a/include/ITABiquad.h b/include/ITABiquad.h
index 9e505f0f041dda5cf8cc0f9f201a76a0999bd1b6..dfe37cab87b33675af68f385c003da418647a1b6 100644
--- a/include/ITABiquad.h
+++ b/include/ITABiquad.h
@@ -57,73 +57,64 @@ public:
 
 	} oParams;
 
-	//! Überblendmodus der Ausgabe
+	//! Output write modes
 	enum
 	{
-		OUTPUT_OVERWRITE = 0, //!< Ausgabe überschreiben
-		OUTPUT_ADD = 1		  //!< Ausgabe addieren
-	} OutputFadeMode;
+		OUTPUT_OVERWRITE = 0, //!< Overwrites output
+		OUTPUT_ADD = 1		  //!< Adds to the output
+	};
 
-	//! Standardkonstruktor
-	/**
-	  * Setzt interne Werte und Koeffizienten für
-	  * einen idealen Übertrager
-	  */
 	CITABiquad();
 
-	//! Destruktor
 	virtual inline ~CITABiquad() {};
 
-	//! Löscht alle internen Puffer
-	/**
-	  * Setzt Akkumulatoren auf 0.
-	  */
+	//! Clears all accumulators
 	void Clear();
 
-	//! Filtert Samples, einfache Variante ohne Verstärkungsfaktoren
+	//! Filter samples, simple variant without any gain (factor)
 	/**
-	  * Filtert samples gemäß der Direkten Form 2 (Kanonische Form)
+	  * Direct second canonical form.
 	  *
-	  * \param in Eingabesamples
-	  * \param in Ausgabesamples
-	  * \param in Anzahl der Eingabe- und Ausgabesamples
+	  * @param[in] pfInputData Input samples
+	  * @param[out] pfOutputData Output samples
+	  * @param[in] iNumSamples Number of samples to be processed
 	  *
-	  * \note Eingabe- und Ausgabepuffer dürfen gleich sein
+	  * @note Input and output samples must have same length
 	  */
 	void Process( const float* pfInputData, float* pfOutputData, const int iNumSamples );
-
-	//! Filtert Samples, Variante mit Überlenden zu einer vorgegebenen Ausgabeverstärkung
+	
+	//! Filter samples, simple variant with given gain (factor)
 	/**
-	  * \param in Eingabesamples
-	  * \param out Ausgabesamples
-	  * \param nsamples Anzahl der Eingabe- und Ausgabesamples
-	  * \param outputGain Ausgabeverstärkung Ausgangsparameter
-	  * \param outputMode Überblendmodus, eines aus #OutputFadeMode
+	  * Direct second canonical form.
+	  *
+	  * @param[in] pfInputData Input samples
+	  * @param[out] pfOutputData Output samples
+	  * @param[in] iNumSamples Number of samples to be processed
+	  * @param[in] fOutputGain Gain (factor) for output
+	  * @param[in] iOutputMode Add to or overwrite output buffer
 	  *
-	  * \note Verändern nicht den internen Verstärkungsfaktor #g (Gain)
-	  * \note Eingabe- und Ausgabepuffer dürfen gleich sein
+	  * @note Input and output samples must have same length
 	  */
 	void Process( const float* pfInputData, float* pfOutputData, const int iNumSamples, const float fOutputGain, const int iOutputMode );
-
-	//! Filtert Samples. Fette Variante (Ausgabemodus, Überblendung der Gains)
+	
+	
+	//! Filter samples, simple variant with given gain (factor)
 	/**
-	  * Filtert Samples und setzt gleichzeitig eine Verstärkungsänderung um.
-	  * Interpoliert lineare zwischen Gain1 und Gain2 auf allen Samples.
+	  * Direct second canonical form.
 	  *
-	  * \param in Eingabesamples
-	  * \param out Ausgabesamples
-	  * \param nsamples Anzahl der Eingabe- und Ausgabesamples
-	  * \param outputGain1 Ausgabeverstärkung Ausgangsparameter
-	  * \param outputGain2 Ausgabeverstärkung Zielparameter
-	  * \param outputMode Überblendmodus, eines aus #OutputFadeMode
+	  * @param[in] pfInputData Input samples
+	  * @param[out] pfOutputData Output samples
+	  * @param[in] iNumSamples Number of samples to be processed
+	  * @param[in] fOutputGain1 Initial gain (factor) for output
+	  * @param[in] fOutputGain2 Target gain (factor) for output
+	  * @param[in] iOutputMode Add to or overwrite output buffer
 	  *
-	  * \note Verändern nicht den internen Verstärkungsfaktor #g (Gain)
-	  * \note Eingabe- und Ausgabepuffer dürfen gleich sein
+	  * @note Input and output samples must have same length
 	  */
 	void Process( const float* pfInputData, float* pfOutputData, const int iNumSamples, const float fOutputGain1, const float fOutputGain2, const int iOutputMode );
 
 private:
-	float z[ 2 ]; //!< Accumulators
+	float vfAccumulators[ 2 ]; //!< Accumulators
 };
 
 #endif // IW_ITA_BIQUAD
diff --git a/include/ITAThirdOctaveFilterbankFIR.h b/include/ITAThirdOctaveFilterbankFIR.h
index 24083dfa4e9c1c3abc7148d70f6d74b6c7d74eaa..2e8757557a2e6cbfcc4866d43dae365b8a0cfd58 100644
--- a/include/ITAThirdOctaveFilterbankFIR.h
+++ b/include/ITAThirdOctaveFilterbankFIR.h
@@ -70,9 +70,9 @@ public:
 		pFilter->Release();	// Auto-release
 	}
 
-	inline virtual void SetMagnitudes( const CITAThirdOctaveMagnitudeSpectrum& oGains, const bool bSmoothChangeover = true )
+	inline virtual void SetMagnitudes( const CITAThirdOctaveMagnitudeSpectrum& oMags, const bool bSmoothChangeover = true )
 	{
-		m_pGenerator->GenerateFilter( oGains, m_pfFilter );
+		m_pGenerator->GenerateFilter( oMags, m_pfFilter );
 		ITAUPFilter* pFilter = m_pConvolver->RequestFilter();
 		pFilter->Load( m_pfFilter, m_iFilterLength );
 		m_pConvolver->ExchangeFilter( pFilter, ( bSmoothChangeover ? ITAUPConvolution::AUTO : ITAUPConvolution::SWITCH ) );
diff --git a/include/ITAThirdOctaveFilterbankIIR.h b/include/ITAThirdOctaveFilterbankIIR.h
index 99125fcf9f6fb11f994c4ae219f07e86abd79ab9..cd6fb642464bc3ddf93f2fc324076b08f1a501b5 100644
--- a/include/ITAThirdOctaveFilterbankIIR.h
+++ b/include/ITAThirdOctaveFilterbankIIR.h
@@ -23,40 +23,38 @@
 #include <ITAThirdOctaveFilterbank.h>
 #include <ITAAmplitudeSpectrum.h>
 #include <ITABiquad.h>
+#include <ITASampleBuffer.h>
 
 #include <vector>
 #include <tbb/concurrent_queue.h>
 
-//! Terzfilterbank mittels Biquads (IIR Filter)
+//! Third octave magnitude filtering using Biquads (IIR filter)
 /**
-  * Diese Klasse realisiert eine Terzfilterbank (#CITAThirdOctaveFilterbank) mit der Methode der kaskadierten
-  * Biquads (#CITABiquad) für Verstärkungsfaktoren eines Terzbank-Betragsspektrums (#CITAThirdOctaveMagnitudeSpectrum).
   *
   */
 class ITA_DSP_API CITAThirdOctaveFilterbankIIR : public CITAThirdOctaveFilterbank
 {
 public:
-	//! Konstruktor mit Samplerate und Blocklänge
+	//! Constructor
 	/**
-	  * \param dSamplerate Samplingrate
-	  * \param iBlocklength Blocklänge
+	  * @param[in] dSampleRate Samplingrate
+	  * @param[in] iBlockLength Block length
 	  */
 	CITAThirdOctaveFilterbankIIR( const double dSampleRate, const int iBlockLength );
 
-	//! Destruktor
-	virtual ~CITAThirdOctaveFilterbankIIR();
+	virtual inline ~CITAThirdOctaveFilterbankIIR() {};
 
 	//! Filterlatenz in Samples zurückgeben
 	int GetLatency() const;
 
-	//! Verstärkungen (Gains) setzen
+	//! Set magnitudes (in decibel) of filter bank
 	/**
-	  * \param oGains Verstärkungsfaktoren
-	  * \param bSmoothChangeover Wenn true, dann überblenden (default), sonst sofort internen Gain umschalten
+	  * @param[in] oMagnitudes Filter magnitudes (dB)
+	  * @param[in] bSmoothChangeover If true, switching is smoothed
 	  */
-	void SetMagnitudes( const CITAThirdOctaveMagnitudeSpectrum& oGains, const bool bSmoothChangeover = true );
+	void SetMagnitudes( const CITAThirdOctaveMagnitudeSpectrum& oMagnitudes, const bool bSmoothChangeover = true );
 
-	//! Alle internen Zustände zurücksetzen (Akkumulatoren der Biquads)
+	//! Clear all internal accumulators
 	void Clear();
 
 	//! Verarbeite Samples (Filtern)
@@ -68,7 +66,7 @@ public:
 
 private:
 	//! Interne Datenklasse für das Verarbeiten eines neuen Gain Datensatzes
-	class GainUpdate
+	class MagnitudeUpdate
 	{
 	public:
 		CITAThirdOctaveMagnitudeSpectrum oMags; //! New magnitudes
@@ -79,11 +77,11 @@ private:
 	int m_iBlockLength;		  //!< Blocklänge
 	int m_nBandsInternal;	  //!< Anzahl der internen Bänder
 	int m_nBiquadsPerBand;	  //!< Anzahl von Biqads pro Band
-	std::vector< CITABiquad > m_vBiquads; //!< Biquads, Zugriff: [Band][BiquadNummer]
-	tbb::strict_ppl::concurrent_queue< CITAThirdOctaveFilterbankIIR::GainUpdate > m_qGains; //!< Liste von neuen Verstärkungsfaktoren
-	CITAThirdOctaveMagnitudeSpectrum m_oGainsInternal; //!< Interne Verstärkungsfaktoren
-	float* m_pfTempFilterBuf; //!< Zwischenpuffer für Filter
-	float* m_pfTempOutputBuf; //!< Zwischenpuffer für Ausgabe
+	std::vector< CITABiquad > m_vBiquads; //!< Biquads, access: [Band][BiquadNummer]
+	tbb::strict_ppl::concurrent_queue< CITAThirdOctaveFilterbankIIR::MagnitudeUpdate > m_vMagnitudesQueue; //!< Liste von neuen Verstärkungsfaktoren
+	CITAThirdOctaveMagnitudeSpectrum m_oMagnitudesInternal; //!< Interne Verstärkungsfaktoren
+	ITASampleBuffer m_sfTempFilterBuf; //!< Intermediate buffer for filter
+	ITASampleBuffer m_pfTempOutputBuf; //!< Intermediate buffer for output assembly
 };
 
 #endif // IW_ITA_THIRD_OCTAVE_FILTERBANK_IIR
diff --git a/src/ITABiquad.cpp b/src/ITABiquad.cpp
index b85594d35de3670820d8100ba3ff852de852557f..dccf0a33d7a10f8205f2fbc50500694fc608a3bc 100644
--- a/src/ITABiquad.cpp
+++ b/src/ITABiquad.cpp
@@ -1,4 +1,5 @@
 #include <ITABiquad.h>
+#include <ITAException.h>
 
 CITABiquad::CITABiquad()
 {
@@ -7,127 +8,131 @@ CITABiquad::CITABiquad()
 
 void CITABiquad::Clear()
 {
-	z[ 0 ] = z[ 1 ] = 0;
+	vfAccumulators[ 0 ] = vfAccumulators[ 1 ] = 0;
 }
 
 void CITABiquad::Process( const float* pfInputData, float* pfOutputData, const int iNumSamples )
 {
-	// Lokale Akkumulatoren erzeugen
-	float z0, z1, z2; // w[n], w[n-1], w[n-2]
+	// Local accumulators
+	float z0, z1, z2;
 
-	// Lokale Akkumulatoren mit gespeicherten Werten besetzen
-	z1 = z[ 0 ];
-	z2 = z[ 1 ];
+	z1 = vfAccumulators[ 0 ];
+	z2 = vfAccumulators[ 1 ];
 
 	for( int i = 0; i < iNumSamples; i++ )
 	{
 		// w[n] = x[n] - a_1*w[n-1] - a_2*w[n-2]
-		z0 = oParams.g*pfInputData[ i ] - oParams.a1*z1 - oParams.a2*z2;
+		z0 = oParams.g * pfInputData[ i ] - oParams.a1 * z1 - oParams.a2 * z2;
 
 		// y[n] = b_0*w[n] + b_1*w[n-1] + b_2*w[n-2]
-		pfOutputData[ i ] = oParams.b0*z0 + oParams.b1*z1 + oParams.b2*z2;
+		pfOutputData[ i ] = oParams.b0 * z0 + oParams.b1 * z1 + oParams.b2 * z2;
 
-		// Akkumulatoren schieben
+		// Shift accumulators
 		z2 = z1;
 		z1 = z0;
 	}
 
-	// Akkumulatoren für den nächsten Filterprozess speichern
-	z[ 0 ] = z1;
-	z[ 1 ] = z2;
+	// Store accumulators
+	vfAccumulators[ 0 ] = z1;
+	vfAccumulators[ 1 ] = z2;
 
 	return;
 }
 
-void CITABiquad::Process( const float* pfInputData, float* out, const int nsamples, const float outputGain, const int outputMode )
+void CITABiquad::Process( const float* pfInputData, float* pfOutputData, const int iNumSamples, const float fOutputGain, const int iOutputMode )
 {
-	// Lokale Akkumulatoren
+	// Local accumulators
 	float z0, z1, z2;
-	z1 = z[ 0 ];
-	z2 = z[ 1 ];
 
-	if( outputMode == OUTPUT_ADD )
+	z1 = vfAccumulators[ 0 ];
+	z2 = vfAccumulators[ 1 ];
+
+	if( iOutputMode == CITABiquad::OUTPUT_ADD )
 	{
-		// Modus: Addieren
-		for( int i = 0; i < nsamples; i++ )
+		for( int i = 0; i < iNumSamples; i++ )
 		{
-			z0 = oParams.g*pfInputData[ i ] - oParams.a1*z1 - oParams.a2*z2;
-			out[ i ] += ( oParams.b0*z0 + oParams.b1*z1 + oParams.b2*z2 ) * outputGain;
+			z0 = oParams.g * pfInputData[ i ] - oParams.a1*z1 - oParams.a2*z2;
+			pfOutputData[ i ] += ( oParams.b0*z0 + oParams.b1*z1 + oParams.b2*z2 ) * fOutputGain;
 
-			// Akkumulatoren schieben
+			// Shift accumulators
 			z2 = z1;
 			z1 = z0;
 		}
 	}
-	else
+	else if( iOutputMode == CITABiquad::OUTPUT_OVERWRITE )
 	{
-		// Modus: Überschreiben
-		for( int i = 0; i < nsamples; i++ )
+		for( int i = 0; i < iNumSamples; i++ )
 		{
 			z0 = oParams.g*pfInputData[ i ] - oParams.a1*z1 - oParams.a2*z2;
-			out[ i ] = ( oParams.b0*z0 + oParams.b1*z1 + oParams.b2*z2 ) * outputGain;
+			pfOutputData[ i ] = ( oParams.b0 * z0 + oParams.b1 * z1 + oParams.b2*z2 ) * fOutputGain;
 
-			// Akkumulatoren schieben
+			// Shift accumulators
 			z2 = z1;
 			z1 = z0;
 		}
 	}
+	else
+	{
+		ITA_EXCEPT1( INVALID_PARAMETER, "Unrecognized output write mode in CITABiquad" );
+	}
 
-	// Akkumulatoren global speichern
-	z[ 0 ] = z1;
-	z[ 1 ] = z2;
+	// Store accumulators
+	vfAccumulators[ 0 ] = z1;
+	vfAccumulators[ 1 ] = z2;
 
 	return;
 }
 
-void CITABiquad::Process( const float* pfInputData, float* out, const int nsamples, const float outputGain1, const float outputGain2, const int outputMode )
+void CITABiquad::Process( const float* pfInputData, float* out, const int iNumSamples, const float fOutputGain1, const float fOutputGain2, const int iOutputWriteMode )
 {
-	if( nsamples == 0 )
+	if( iNumSamples == 0 )
 		return;
 
-	// Lokale Akkumulatoren
+	// Local accumulators
 	float z0, z1, z2;
-	z1 = z[ 0 ];
-	z2 = z[ 1 ];
+	z1 = vfAccumulators[ 0 ];
+	z2 = vfAccumulators[ 1 ];
 
-	// Faktor für Linear-Interpolation des Gains
-	float c = ( outputGain2 - outputGain1 ) / nsamples; // @todo jst: integer rounding desired?
+	// Factor for linear gain
+	const float fLinearGainFactor = ( fOutputGain2 - fOutputGain1 ) / float( iNumSamples );
 
-	if( outputMode == OUTPUT_ADD )
+	if( iOutputWriteMode == OUTPUT_ADD )
 	{
-		// Modus: Addieren
-		for( int i = 0; i < nsamples; i++ )
+		for( int i = 0; i < iNumSamples; i++ )
 		{
-			float sampleGain = outputGain1 + i*c;
+			const float fSampleGain = fOutputGain1 + i * fLinearGainFactor;
 
 			z0 = oParams.g*pfInputData[ i ] - oParams.a1*z1 - oParams.a2*z2;
-			out[ i ] += ( oParams.b0*z0 + oParams.b1*z1 + oParams.b2*z2 ) * sampleGain;
+			out[ i ] += ( oParams.b0*z0 + oParams.b1*z1 + oParams.b2*z2 ) * fSampleGain;
 
-			// Akkumulatoren schieben
+			// Shift accumulators
 			z2 = z1;
 			z1 = z0;
 		}
 
 	}
-	else
+	else if( iOutputWriteMode == CITABiquad::OUTPUT_OVERWRITE )
 	{
-		// Modus: Überschreiben
-		for( int i = 0; i < nsamples; i++ )
+		for( int i = 0; i < iNumSamples; i++ )
 		{
-			float sampleGain = outputGain1 + i*c;
+			const float fSampleGain = fOutputGain1 + i * fLinearGainFactor;
 
 			z0 = oParams.g*pfInputData[ i ] - oParams.a1*z1 - oParams.a2*z2;
-			out[ i ] = ( oParams.b0*z0 + oParams.b1*z1 + oParams.b2*z2 ) * sampleGain;
+			out[ i ] = ( oParams.b0*z0 + oParams.b1*z1 + oParams.b2*z2 ) * fSampleGain;
 
-			// Akkumulatoren schieben
+			// Shift accumulators
 			z2 = z1;
 			z1 = z0;
 		}
 	}
+	else
+	{
+		ITA_EXCEPT1( INVALID_PARAMETER, "Unrecognized output write mode in CITABiquad" );
+	}
 
-	// Akkumulatoren global speichern
-	z[ 0 ] = z1;
-	z[ 1 ] = z2;
+	// Store accumulators
+	vfAccumulators[ 0 ] = z1;
+	vfAccumulators[ 1 ] = z2;
 }
 
 CITABiquad::CParams::CParams()
diff --git a/src/ITAThirdOctaveFilterbankCoefficients.h b/src/ITAThirdOctaveFilterbankCoefficients.h
index 2485b3460cfd2d29cbd2829dc54a65702edfec79..3ba248b0033cc609d76f048dc89736244ef1f829 100644
--- a/src/ITAThirdOctaveFilterbankCoefficients.h
+++ b/src/ITAThirdOctaveFilterbankCoefficients.h
@@ -1,12 +1,12 @@
 #ifndef IW_ITA_THIRD_OCTAVE_FILTERBANK_COEFFICIENTS
 #define IW_ITA_THIRD_OCTAVE_FILTERBANK_COEFFICIENTS
 
-const double FB_SAMPLINGRATE = 44100;   //!< Samplingrate
-const int FB_NUM_BANDS = 30;		   //!< Anzahl Frequenzb�nder
-const int FB_NUM_BIQUADS_PER_BAND = 5; //!< Anzahl Biquads pro Frequenzband
+const double ITA_BIQUAD_FILTER_SAMPLINGRATE = 44100;
+const int ITA_BIQUAD_FILTER_NUM_BANDS = 30;
+const int ITA_BIQUAD_FILTER_NUM_BIQUADS_PER_BAND = 5;
 
-//!< Parameters (g, b0, b1, b2, a0, a1) for biquad bandpasses, 10th order Buttworth design, Zugriff: [Band][Biquad][Param]
-const float FB_BIQUAD_PARAMS[ 30 ][ 5 ][ 6 ] =
+//!< Parameters (g, b0, b1, b2, a0, a1) for biquad bandpasses, 10th order Buttworth design, access: [Band][Biquad][Param]
+const float ITA_BIQUAD_FILTER_PARAMS[ 30 ][ 5 ][ 6 ] =
 {
 	{ // Band 1, center frequency 25.1 Hz
 		{ 0.000412886359F, 1.000000000000F, 0.000000000000F, -1.000000000000F, -1.999701032925F, 0.999716977654F },
diff --git a/src/ITAThirdOctaveFilterbankIIR.cpp b/src/ITAThirdOctaveFilterbankIIR.cpp
index 9db12332a35d1fb11f0f0ad82f6cb85a5acaf1d4..1b1ca6d4da4bc141c0d36ffed63223ca623fd42e 100644
--- a/src/ITAThirdOctaveFilterbankIIR.cpp
+++ b/src/ITAThirdOctaveFilterbankIIR.cpp
@@ -12,52 +12,40 @@
 CITAThirdOctaveFilterbankIIR::CITAThirdOctaveFilterbankIIR( const double dSampleRate, const int iBlockLength )
 	: m_dSampleRate( dSampleRate ),
 	m_iBlockLength( iBlockLength ),
-	m_nBandsInternal( FB_NUM_BANDS ),
-	m_nBiquadsPerBand( FB_NUM_BIQUADS_PER_BAND ),
-	m_pfTempFilterBuf( nullptr ),
-	m_pfTempOutputBuf( nullptr )
+	m_nBandsInternal( ITA_BIQUAD_FILTER_NUM_BANDS ),
+	m_nBiquadsPerBand( ITA_BIQUAD_FILTER_NUM_BIQUADS_PER_BAND )
 {
-	if( dSampleRate != FB_SAMPLINGRATE )
+	if( dSampleRate != ITA_BIQUAD_FILTER_SAMPLINGRATE )
 		ITA_EXCEPT1( INVALID_PARAMETER, "Filterbank does not support this samplingrate" );
 
 	// Initialize biquads
-	int nBiquads = m_nBandsInternal*m_nBiquadsPerBand;
+	int nBiquads = m_nBandsInternal * m_nBiquadsPerBand;
 	m_vBiquads.resize( nBiquads );
 	for( int i = 0; i < m_nBandsInternal; i++ )
-	{
 		for( int j = 0; j < m_nBiquadsPerBand; j++ )
-		{
-			m_vBiquads[ i*m_nBiquadsPerBand + j ].oParams.SetParameters( FB_BIQUAD_PARAMS[ i ][ j ] );
-		}
-	}
+			m_vBiquads[ i * m_nBiquadsPerBand + j ].oParams.SetParameters( ITA_BIQUAD_FILTER_PARAMS[ i ][ j ] );
 
-	m_pfTempFilterBuf = fm_falloc( m_iBlockLength, true );
-	m_pfTempOutputBuf = fm_falloc( m_iBlockLength, true );
-}
-
-CITAThirdOctaveFilterbankIIR::~CITAThirdOctaveFilterbankIIR()
-{
-	fm_free( m_pfTempFilterBuf );
-	fm_free( m_pfTempOutputBuf );
+	m_sfTempFilterBuf.Init( m_iBlockLength, true );
+	m_pfTempOutputBuf.Init( m_iBlockLength, true );
 }
 
 int CITAThirdOctaveFilterbankIIR::GetLatency() const
 {
-	return 0; // [stienen] sicher?
+	return 0; // @todo jst: really?
 }
 
-void CITAThirdOctaveFilterbankIIR::SetMagnitudes( const CITAThirdOctaveMagnitudeSpectrum& oMagnitudes, bool bSmoothChangeover )
+void CITAThirdOctaveFilterbankIIR::SetMagnitudes( const CITAThirdOctaveMagnitudeSpectrum& oMagnitudes, const bool bSmoothChangeover )
 {
-	CITAThirdOctaveFilterbankIIR::GainUpdate oUpdate;
+	CITAThirdOctaveFilterbankIIR::MagnitudeUpdate oUpdate;
 	oUpdate.oMags = oMagnitudes;
 	oUpdate.iBlendSamples = ( bSmoothChangeover ? 1 : 0 );
-	m_qGains.push( oUpdate );
+	m_vMagnitudesQueue.push( oUpdate );
 }
 
 void CITAThirdOctaveFilterbankIIR::Clear()
 {
-	for( int i = 0; i < ( int )
-		m_vBiquads.size(); i++ ) m_vBiquads[ i ].Clear();
+	for( size_t i = 0; i < m_vBiquads.size(); i++ )
+		m_vBiquads[ i ].Clear();
 }
 
 void CITAThirdOctaveFilterbankIIR::Process( const float* pfInputSamples, float* pfOutputSamples )
@@ -68,38 +56,33 @@ void CITAThirdOctaveFilterbankIIR::Process( const float* pfInputSamples, float*
 	// F�r Schleifen unten
 	assert( m_nBiquadsPerBand >= 2 );
 
-	// TODO: Fehler l�sen. Warum kommt aus den hohen B�ndern nix? Scheinen nicht stabil zu sein?!
 	const int iMaxBand = m_nBandsInternal - 1;
-	//const int iMaxBand = 10;
-	const int k = m_nBiquadsPerBand - 1;	// Index des letzten Biquads pro Band
-
-	if( m_nBandsInternal == 0 )
-		return; // [stienen] lieber assert? Filter ohne B�nder?
-
-	// Gains �bernehmen
-	CITAThirdOctaveFilterbankIIR::GainUpdate oUpdate;
+	const int iLastBandIndex = m_nBiquadsPerBand - 1;
+	
+	// Empty queue and use latest magnitude update
+	CITAThirdOctaveFilterbankIIR::MagnitudeUpdate oLatestMagnitudeUpdate;
 	bool bUpdateGains = false;
-	while( m_qGains.try_pop( oUpdate ) )
+	while( m_vMagnitudesQueue.try_pop( oLatestMagnitudeUpdate ) )
 		bUpdateGains = true;
 
+	// Processing will first work through the biquads per band and then add samples target buffer at last biquad of band
+
 	if( bUpdateGains )
 	{
-		bool bSwitchGains = ( oUpdate.iBlendSamples == 0 );
+		bool bSwitchGains = ( oLatestMagnitudeUpdate.iBlendSamples == 0 );
 
 		if( bSwitchGains )
 		{
 			for( int i = 0; i < iMaxBand; i++ )
 			{
-				// Erster Biquad in der Sequenz: input => tmp
-				m_vBiquads[ i*m_nBiquadsPerBand + 0 ].Process( pfInputSamples, m_pfTempFilterBuf, m_iBlockLength );
+				m_vBiquads[ i*m_nBiquadsPerBand + 0 ].Process( pfInputSamples, m_sfTempFilterBuf.GetData(), m_iBlockLength );
 
-				// Biquads dazwischen: tmp => tmp
-				for( int j = 1; j < k; j++ )
-					m_vBiquads[ i*m_nBiquadsPerBand + j ].Process( m_pfTempFilterBuf, m_pfTempFilterBuf, m_iBlockLength );
+				for( int j = 1; j < iLastBandIndex; j++ )
+					m_vBiquads[ i*m_nBiquadsPerBand + j ].Process( m_sfTempFilterBuf.GetData(), m_sfTempFilterBuf.GetData(), m_iBlockLength );
 
-				// Letztes Biquad mit Gain: tmp => output
-				const float fGain = float( db10_to_ratio( oUpdate.oMags[ i ] ) );
-				m_vBiquads[ i*m_nBiquadsPerBand + k ].Process( m_pfTempFilterBuf, m_pfTempOutputBuf, m_iBlockLength, fGain, ( i == 0 ? CITABiquad::OUTPUT_OVERWRITE : CITABiquad::OUTPUT_ADD ) );
+				const float fGain = float( db10_to_ratio( oLatestMagnitudeUpdate.oMags[ i ] ) );
+				const int iOutputWriteMode = ( i == 0 ? CITABiquad::OUTPUT_OVERWRITE : CITABiquad::OUTPUT_ADD );
+				m_vBiquads[ i*m_nBiquadsPerBand + iLastBandIndex ].Process( m_sfTempFilterBuf.GetData(), m_pfTempOutputBuf.GetData(), m_iBlockLength, fGain, iOutputWriteMode );
 			}
 		}
 		else
@@ -108,20 +91,20 @@ void CITAThirdOctaveFilterbankIIR::Process( const float* pfInputSamples, float*
 			for( int i = 0; i < iMaxBand; i++ )
 			{
 				// Erster Biquad in der Sequenz: input => tmp
-				m_vBiquads[ i*m_nBiquadsPerBand + 0 ].Process( pfInputSamples, m_pfTempFilterBuf, m_iBlockLength );
+				m_vBiquads[ i*m_nBiquadsPerBand + 0 ].Process( pfInputSamples, m_sfTempFilterBuf, m_iBlockLength );
 
 				// Biquads dazwischen: tmp => tmp
-				for( int j = 1; j < k; j++ )
-					m_vBiquads[ i*m_nBiquadsPerBand + j ].Process( m_pfTempFilterBuf, m_pfTempFilterBuf, m_iBlockLength );
+				for( int j = 1; j < iLastBandIndex; j++ )
+					m_vBiquads[ i*m_nBiquadsPerBand + j ].Process( m_sfTempFilterBuf, m_sfTempFilterBuf, m_iBlockLength );
 
 				// Letztes Biquad mit Gain: tmp => output
-				const float fGain1 = m_oGainsInternal[ i ];
-				const float fGain2 = float( db10_to_ratio( oUpdate.oMags[ i ] ) );
-				m_vBiquads[ i*m_nBiquadsPerBand + k ].Process( m_pfTempFilterBuf, m_pfTempOutputBuf, m_iBlockLength, fGain1, fGain2, ( i == 0 ? CITABiquad::OUTPUT_OVERWRITE : CITABiquad::OUTPUT_ADD ) );
+				const float fGain1 = m_oMagnitudesInternal[ i ];
+				const float fGain2 = float( db10_to_ratio( oLatestMagnitudeUpdate.oMags[ i ] ) );
+				m_vBiquads[ i*m_nBiquadsPerBand + iLastBandIndex ].Process( m_sfTempFilterBuf.GetData(), m_pfTempOutputBuf.GetData(), m_iBlockLength, fGain1, fGain2, ( i == 0 ? CITABiquad::OUTPUT_OVERWRITE : CITABiquad::OUTPUT_ADD ) );
 			}
 		}
 
-		m_oGainsInternal = oUpdate.oMags;
+		m_oMagnitudesInternal = oLatestMagnitudeUpdate.oMags;
 	}
 	else
 	{
@@ -129,17 +112,17 @@ void CITAThirdOctaveFilterbankIIR::Process( const float* pfInputSamples, float*
 		for( int i = 0; i < iMaxBand; i++ )
 		{
 			// Erster Biquad in der Sequenz: input => tmp
-			m_vBiquads[ i*m_nBiquadsPerBand + 0 ].Process( pfInputSamples, m_pfTempFilterBuf, m_iBlockLength );
+			m_vBiquads[ i*m_nBiquadsPerBand + 0 ].Process( pfInputSamples, m_sfTempFilterBuf.GetData(), m_iBlockLength );
 
 			// Biquads dazwischen: tmp => tmp
-			for( int j = 1; j < k; j++ )
-				m_vBiquads[ i*m_nBiquadsPerBand + j ].Process( m_pfTempFilterBuf, m_pfTempFilterBuf, m_iBlockLength );
+			for( int j = 1; j < iLastBandIndex; j++ )
+				m_vBiquads[ i*m_nBiquadsPerBand + j ].Process( m_sfTempFilterBuf.GetData(), m_sfTempFilterBuf.GetData(), m_iBlockLength );
 
 			// Letztes Biquad mit Gain: tmp => output
-			m_vBiquads[ i*m_nBiquadsPerBand + k ].Process( m_pfTempFilterBuf, m_pfTempOutputBuf, m_iBlockLength, m_oGainsInternal[ i ], ( i == 0 ? CITABiquad::OUTPUT_OVERWRITE : CITABiquad::OUTPUT_ADD ) );
+			m_vBiquads[ i*m_nBiquadsPerBand + iLastBandIndex ].Process( m_sfTempFilterBuf.GetData(), m_pfTempOutputBuf.GetData(), m_iBlockLength, m_oMagnitudesInternal[ i ], ( i == 0 ? CITABiquad::OUTPUT_OVERWRITE : CITABiquad::OUTPUT_ADD ) );
 		}
 	}
 
-	// Ausgabe bereitstellen
-	memcpy( pfOutputSamples, m_pfTempOutputBuf, m_iBlockLength*sizeof( float ) );
+	// Hand over output samples
+	fm_copy( pfOutputSamples, m_pfTempOutputBuf.GetData(), m_iBlockLength );
 }
diff --git a/tests/ITADSPThirdOctaveFilterbankTest.cpp b/tests/ITADSPThirdOctaveFilterbankTest.cpp
index 84e81447964d92c55e9e24147f2fc2e8eca05be0..83cca29595acf72235970e4c9113550331a734a4 100644
--- a/tests/ITADSPThirdOctaveFilterbankTest.cpp
+++ b/tests/ITADSPThirdOctaveFilterbankTest.cpp
@@ -31,7 +31,7 @@ void TestThirdOctaveFilterbankIIR()
 	CITAThirdOctaveMagnitudeSpectrum oMags;
 	oMags.SetIdentity();
 
-	pIIRFilterbank->SetMagnitudes( oMags );
+	pIIRFilterbank->SetMagnitudes( oMags, false );
 
 	ITASampleBuffer y( iSampleLength );
 
@@ -45,8 +45,7 @@ void TestThirdOctaveFilterbankIIR()
 	writeAudiofile( "ITADSPThirdOctaveFilterbankTest_IIR_Identity.wav", &y, g_dSampleRate );
 	y.Zero();
 
-	delete pIIRFilterbank;
-	pIIRFilterbank = CITAThirdOctaveFilterbank::Create( g_dSampleRate, iSampleLength, CITAThirdOctaveFilterbank::IIR_BIQUADS_ORDER10 );
+	pIIRFilterbank->Clear();
 	
 	oMags.SetZero();
 	pIIRFilterbank->SetMagnitudes( oMags );
@@ -59,8 +58,7 @@ void TestThirdOctaveFilterbankIIR()
 	y.Normalize();
 	writeAudiofile( "ITADSPThirdOctaveFilterbankTest_IIR_Zeros.wav", &y, g_dSampleRate );
 
-	delete pIIRFilterbank;
-	pIIRFilterbank = CITAThirdOctaveFilterbank::Create( g_dSampleRate, iSampleLength, CITAThirdOctaveFilterbank::IIR_BIQUADS_ORDER10 );
+	pIIRFilterbank->Clear();
 
 	// dB values
 	oMags[ 3 ] = 3.0f;