diff --git a/include/ITASIMOVariableDelayLine.h b/include/ITASIMOVariableDelayLine.h
index e28110e0181543665cbcc1f6ef44fd6f04ee4a69..a11f27d18661f1e3f9c3f64a0b185cd53c02eed5 100644
--- a/include/ITASIMOVariableDelayLine.h
+++ b/include/ITASIMOVariableDelayLine.h
@@ -268,11 +268,32 @@ public:
 	void Clear();
 
 	//! Pushes a block of samples at front of delay line
+	/**
+	  * Writes a block of samples to the input of the VDL.
+	  * Does not increment block, has to be done manually (i.e. after read)
+	  *
+	  * @note block-oriented VDL usage is usually a three-step process: write-read-increment.
+	  *
+	  * @param[in] psbInput Buffer source for incoming samples
+	  */
 	void WriteBlock( const ITASampleBuffer* psbInput );
 
 	//! Reads a block of samples for a read cursor and switches to new delay
+	/**
+	  * @note Incremet block processing after all cursors have benn processed / read.
+	  *
+	  * @param[in] iID Cursor identifier
+	  * @param[out] psbOutput Buffer target for processed samples (must be initialized)
+	  */
 	void ReadBlock( const int iID, ITASampleBuffer* psbOutput );
 
+	//! Increments processing to next block
+	/**
+	  * @note Make sure that all cursors have been processed, i.e. have read a block from
+	  *       the delay line. Otherwise, dropouts occur.
+	  */
+	void Increment();
+
 	//! Reads a block of samples at all cursors (switches to new delay)
 	/**
 	  * The order of the channels in the sample frame will be linear over the
@@ -281,13 +302,13 @@ public:
 	  * @param[in] psfOutput Initialized sample frame
 	  *
 	  */
-	void ReadBlock( ITASampleFrame* psfOutput );
+	void ReadBlockAndIncrement( ITASampleFrame* psfOutput );
 
 private:
 	double m_dSampleRate;				//!< Audio-Abtastrate
 	int m_iBlockLength;					//!< Audio-Blockgr��e
 	int m_iVDLBufferSize;				//!< Gr��e des Puffers zum Speichern verz�gerter Samples
-	ITASampleBuffer* m_psbVDLBuffer;	//!< Puffer zum Speichern verz�gerter Samples (variable Gr��e, mindestens 2xBlockl�nge)
+	ITASampleBuffer* m_psbVDLBuffer;	//!< Buffer for samples (variable size at multiples of block leng, but minimum is 2 blocks)
 	ITASampleBuffer* m_psbTemp;			//!< Tempor�rer Puffer zum Arbeiten mit Samples (Gr��e: 2xBlockl�nge) (das k�nnte evtl. knapp sein)
 	ITACriticalSection m_csBuffer;		//!< Zugriff auf Puffer sch�tzen
 
@@ -302,6 +323,7 @@ private:
 
 	bool m_bStarted;					//!< Statusvariable zur Initialisierung
 
+	bool m_bBenchmark;
 	ITAStopWatch m_swProcess;			//!< StopWatch zur �berwachung der Berechnungsschleife
 
 	IITASampleInterpolationRoutine* m_pInterpolationRoutine; //!< Zeiger auf Interpolationsroutine
diff --git a/src/ITASIMOVariableDelayLine.cpp b/src/ITASIMOVariableDelayLine.cpp
index acf3b4aff9875ab39a787c89259cda93333b1dca..7ff05283f93116a08e9e4b33120e6914a7fbba02 100644
--- a/src/ITASIMOVariableDelayLine.cpp
+++ b/src/ITASIMOVariableDelayLine.cpp
@@ -22,7 +22,8 @@ CITASIMOVariableDelayLine::CITASIMOVariableDelayLine( const double dSamplerate,
 	m_iSwitchingAlgorithm( iAlgorithm ),
 	m_psbVDLBuffer( nullptr ),
 	m_psbTemp( nullptr ),
-	m_pInterpolationRoutine( nullptr )
+	m_pInterpolationRoutine( nullptr ),
+	m_bBenchmark( false )
 {
 	assert( dSamplerate > 0 );
 	assert( iBlocklength > 0 );
@@ -49,7 +50,7 @@ CITASIMOVariableDelayLine::CITASIMOVariableDelayLine( const double dSamplerate,
 
 void CITASIMOVariableDelayLine::Clear()
 {
-	m_psbVDLBuffer->Zero();
+	m_psbVDLBuffer->Zero(); // Very important, because on small delays the potentially unititialized end of VDL is also read
 	m_psbTemp->Zero();
 
 	m_iWriteCursor = 0;
@@ -59,16 +60,6 @@ void CITASIMOVariableDelayLine::Clear()
 	m_swProcess.reset();
 }
 
-void CITASIMOVariableDelayLine::WriteBlock( const ITASampleBuffer* psbInput )
-{
-	if( !m_bStarted )
-		m_bStarted = true;
-
-	assert( m_iWriteCursor % m_iBlockLength == 0 );
-	m_psbVDLBuffer->write( psbInput, m_iBlockLength, 0, m_iWriteCursor );
-	m_iWriteCursor = ( m_iWriteCursor + m_iBlockLength ) % m_iVDLBufferSize;
-}
-
 CITASIMOVariableDelayLine::~CITASIMOVariableDelayLine()
 {
 	delete m_psbVDLBuffer;
@@ -132,7 +123,7 @@ void CITASIMOVariableDelayLine::ReserveMaximumDelaySamples( float fMaxDelaySampl
 		 *  nur durch den Konstruktor aufgerufen wird
 		 */
 
-		m_psbVDLBuffer = new ITASampleBuffer( iNewBufferSize, true );
+		m_psbVDLBuffer = new ITASampleBuffer( iNewBufferSize, true ); // Important! set all samples to zero.
 		m_iVDLBufferSize = iNewBufferSize;
 		m_iWriteCursor = 0;
 
@@ -152,7 +143,7 @@ void CITASIMOVariableDelayLine::ReserveMaximumDelaySamples( float fMaxDelaySampl
 		int iOldBufferSize = m_psbVDLBuffer->length();
 
 		// Vorhandene Daten zyklisch Kopieren (aktuelle Schreibposition => Anfang abrollen)
-		ITASampleBuffer* psbNewBuffer = new ITASampleBuffer( iNewBufferSize, true );
+		ITASampleBuffer* psbNewBuffer = new ITASampleBuffer( iNewBufferSize, true ); // Important! set all samples to zero.
 		psbNewBuffer->cyclic_write( m_psbVDLBuffer, iNewBufferSize, m_iWriteCursor, 0 );
 
 		// Alten Puffer freigeben, neuen zuweisen
@@ -241,7 +232,7 @@ void CITASIMOVariableDelayLine::SetDelaySamples( const int iID, const float fDel
 	CITAVDLReadCursor& oReadCursor( m_lUserCursors[ iID ] );
 	oReadCursor.fNewReadCursorSamples = fDelaySamples;
 
-	// If not started, set both
+	// If not started, set both to avoid artifact on first block
 	if( !m_bStarted )
 		oReadCursor.fOldReadCursorSamples = fDelaySamples;
 }
@@ -251,7 +242,16 @@ void CITASIMOVariableDelayLine::SetDelayTime( const int iCursorID, const float f
 	SetDelaySamples( iCursorID, fDelaySeconds * ( float ) m_dSampleRate );
 }
 
-void CITASIMOVariableDelayLine::ReadBlock( ITASampleFrame* psfOutput )
+void CITASIMOVariableDelayLine::WriteBlock( const ITASampleBuffer* psbInput )
+{
+	if( !m_bStarted )
+		m_bStarted = true;
+
+	assert( m_iWriteCursor % m_iBlockLength == 0 );
+	m_psbVDLBuffer->write( psbInput, m_iBlockLength, 0, m_iWriteCursor );
+}
+
+void CITASIMOVariableDelayLine::ReadBlockAndIncrement( ITASampleFrame* psfOutput )
 {
 	assert( psfOutput );
 	const std::vector< int > viIDs = GetCursorIDs();
@@ -261,6 +261,8 @@ void CITASIMOVariableDelayLine::ReadBlock( ITASampleFrame* psfOutput )
 
 	for( int i = 0; i < GetNumCursors(); i++ )
 		ReadBlock( viIDs[ i ], &( *psfOutput )[ i ] );
+
+	Increment();
 }
 
 void CITASIMOVariableDelayLine::ReadBlock( const int iCursorID, ITASampleBuffer* psbOutput )
@@ -270,23 +272,18 @@ void CITASIMOVariableDelayLine::ReadBlock( const int iCursorID, ITASampleBuffer*
 
 	m_swProcess.start();
 
-	// Lokale Kopie des gew�nschten Algorithmus (Atomare Membervariable)
-	int iAlgorithm = m_iSwitchingAlgorithm;
-
-	// Lokale Kopie der neuen Verz�gerung
-	float fCurrentDelay = m_lUserCursors[ iCursorID ].fOldReadCursorSamples;
-	float fNewDelay = m_lUserCursors[ iCursorID ].fNewReadCursorSamples;
+	int iAlgorithmLocalCopy = m_iSwitchingAlgorithm;
 
-	// --= Keine �nderung der Verz�gerung (f�r rasant schnelle statische Szenen) =--
-
-	if( fNewDelay == fCurrentDelay ) {
-		// Keine �nderung der Verz�gerung. Einfach Anfang der VDL in den Ausgang kopieren.
-		int iReadCursor = ( m_iWriteCursor + m_iVDLBufferSize - ( int ) ceil( fCurrentDelay ) ) % m_iVDLBufferSize;
+	float fCurrentDelayLocalCopy = m_lUserCursors[ iCursorID ].fOldReadCursorSamples;
+	float fNewDelayLocalCopy = m_lUserCursors[ iCursorID ].fNewReadCursorSamples;
+	
+	// Use a fast-forward copy in case of no new delay (static situation)
+	if( fNewDelayLocalCopy == fCurrentDelayLocalCopy )
+	{
+		// No change of delay, simply copy samples from read cursor
+		int iReadCursor = ( m_iWriteCursor - ( int ) ceil( fCurrentDelayLocalCopy ) + m_iVDLBufferSize ) % m_iVDLBufferSize;
 		psbOutput->cyclic_write( m_psbVDLBuffer, m_iBlockLength, iReadCursor, 0 );
 
-		// Schreibzeiger um Blockl�nge vergr��ern (BlockPointerIncrement)
-		m_iWriteCursor = ( m_iWriteCursor + m_iBlockLength ) % m_iVDLBufferSize;
-
 		return;
 	}
 
@@ -294,18 +291,18 @@ void CITASIMOVariableDelayLine::ReadBlock( const int iCursorID, ITASampleBuffer*
 	// --= �nderung der Verz�gerung =--
 
 	// Zerlegen in Ganzzahl und Kommazahl
-	int iCurrentIntDelay = ( int ) ceil( fCurrentDelay );
-	float fCurrentFracDelay = ( float ) iCurrentIntDelay - fCurrentDelay;
+	int iCurrentIntDelay = ( int ) ceil( fCurrentDelayLocalCopy );
+	float fCurrentFracDelay = ( float ) iCurrentIntDelay - fCurrentDelayLocalCopy;
 	assert( fCurrentFracDelay >= 0.0f );  // Subsample darf nicht negativ sein
-	int iNewIntDelay = ( int ) ceil( fNewDelay );
-	float fNewFracDelay = ( float ) iNewIntDelay - fNewDelay;
+	int iNewIntDelay = ( int ) ceil( fNewDelayLocalCopy );
+	float fNewFracDelay = ( float ) iNewIntDelay - fNewDelayLocalCopy;
 	assert( fNewFracDelay >= 0.0f ); // Subsample darf nicht negativ sein
 	int iDeltaDelay = iNewIntDelay - iCurrentIntDelay;
 
 	// Falls Interpolation gew�nscht ist, Grenzen pr�fen
-	if( ( iAlgorithm == LINEAR_INTERPOLATION ) ||
-		( iAlgorithm == WINDOWED_SINC_INTERPOLATION ) ||
-		( iAlgorithm == CUBIC_SPLINE_INTERPOLATION ) )
+	if( ( iAlgorithmLocalCopy == LINEAR_INTERPOLATION ) ||
+		( iAlgorithmLocalCopy == WINDOWED_SINC_INTERPOLATION ) ||
+		( iAlgorithmLocalCopy == CUBIC_SPLINE_INTERPOLATION ) )
 	{
 
 		/*
@@ -335,7 +332,7 @@ void CITASIMOVariableDelayLine::ReadBlock( const int iCursorID, ITASampleBuffer*
 		// Wenn Voraussetzungen verletzt werden, f�r diesen Bearbeitungsschritt auf weiches Umschalten wechseln
 		if( ( fResamplingFactor <= MIN_RESAMPLING_FACTOR ) || ( fResamplingFactor > MAX_RESAMPLING_FACTOR ) )
 		{
-			iAlgorithm = CROSSFADE;
+			iAlgorithmLocalCopy = CROSSFADE;
 		}
 	}
 
@@ -350,24 +347,24 @@ void CITASIMOVariableDelayLine::ReadBlock( const int iCursorID, ITASampleBuffer*
 
 
 	// --= Umschaltverfahren =--
-
-	// TODO:  - vermutlich sehen die R�mpfe f�r jede andere Interpolation �hnlich aus, sodass man mit getOverlap() vereinheitlichen kann. 
-	//			(LinInterp schon fertig, aber erst Erfahrungen mit den anderen Verfahren sammeln...)
-
+	
 	int iSize;
 	int iLeft, iRight; // �berlappung an den Grenzen
-	switch( iAlgorithm )
+	switch( iAlgorithmLocalCopy )
 	{
 
 		// o Hartes Umschalten
 	case SWITCH:
+	{
 		// Direkt neue Verz�gerung nehmen. Einfach kopieren. Keine R�cksicht nehmen.
 		psbOutput->cyclic_write( m_psbVDLBuffer, m_iBlockLength, iReadCursorNew, 0 );
 
 		break;
+	}
 
 		// o Umschalten mittels Kreuzblende
 	case CROSSFADE:
+	{
 		// Kreuzblende mittels tempor�rem Puffer
 		assert( m_iFadeLength <= m_psbTemp->length() ); // Zu gro�e Blende f�r diesen Puffer
 		m_psbTemp->cyclic_write( m_psbVDLBuffer, m_iFadeLength, iReadCursorCurrent, 0 );
@@ -376,11 +373,11 @@ void CITASIMOVariableDelayLine::ReadBlock( const int iCursorID, ITASampleBuffer*
 		psbOutput->Crossfade( m_psbTemp, 0, m_iFadeLength, ITASampleBuffer::CROSSFADE_FROM_SOURCE, ITASampleBuffer::COSINE_SQUARE );
 
 		break;
-
+	}
 
 		// o Umschalten durch Stauchen oder Strecken: Lineare Interpolation, Kubische Spline-Interpolation oder gefensterte Sinc-Interpolation
 	default:
-
+	{
 		/* Zur Erkl�rung:
 
 			Verringerung der Verz�gerung => Samples stauchen
@@ -423,18 +420,24 @@ void CITASIMOVariableDelayLine::ReadBlock( const int iCursorID, ITASampleBuffer*
 		m_pInterpolationRoutine->Interpolate( m_psbTemp, iInputLength, iInputStartOffset, psbOutput, m_iBlockLength );
 
 		break;
-
+	}
 
 	} // end case switch
 
 	// Neue Verz�gerung speichern
-	m_lUserCursors[ iCursorID ].fOldReadCursorSamples = fNewDelay;
-
-	// Schreibzeiger inkrementieren
-	// (Hinweis: Der Schreibzeiger ist immer Vielfaches der Blockl�nge)
-	m_iWriteCursor = ( m_iWriteCursor + m_iBlockLength ) % m_iVDLBufferSize;
-
+	m_lUserCursors[ iCursorID ].fOldReadCursorSamples = fNewDelayLocalCopy;
+	
 	// Zeitnahme
 	double t = m_swProcess.stop();
+
+	if( m_bBenchmark && t > double( m_iBlockLength ) / m_dSampleRate )
+		std::cerr << "[ SIMOVDL ] Stream processing panic, reading block for cursor " << iCursorID << " took too long: " << t << std::endl;
+
 	return;
 }
+
+void CITASIMOVariableDelayLine::Increment()
+{
+	// Increment write cursor by one block (BlockPointerIncrement)
+	m_iWriteCursor = ( m_iWriteCursor + m_iBlockLength ) % m_iVDLBufferSize;
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 052b0a3c2ddfde89ae4a3628a9c79ca688a66eb5..4acfdd62a077897f3d43fd571c52767255c61e92 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -59,6 +59,16 @@ vista_create_default_info_file( ITADSPThirdOctaveFilterGeneratorTest )
 set_property( TARGET ITADSPThirdOctaveFilterGeneratorTest PROPERTY FOLDER "ITACoreLibs/Tests/ITADSP" )
 
 
+add_executable( ITADSPSIMOVDLSourceInShoebox ITADSPSIMOVDLSourceInShoebox.cpp )
+target_link_libraries( ITADSPSIMOVDLSourceInShoebox ${VISTA_USE_PACKAGE_LIBRARIES} )
+
+vista_configure_app( ITADSPSIMOVDLSourceInShoebox )
+vista_install( ITADSPSIMOVDLSourceInShoebox )
+vista_create_default_info_file( ITADSPSIMOVDLSourceInShoebox )
+
+set_property( TARGET ITADSPSIMOVDLSourceInShoebox PROPERTY FOLDER "ITACoreLibs/Tests/ITADSP" )
+
+
 add_executable( ITADSPThirdOctaveFilterbankTest ITADSPThirdOctaveFilterbankTest.cpp )
 target_link_libraries( ITADSPThirdOctaveFilterbankTest ${VISTA_USE_PACKAGE_LIBRARIES} )
 
diff --git a/tests/ITADSPBiquadTest.cpp b/tests/ITADSPBiquadTest.cpp
index 1be610933a949094fa14166bd28680b226e42565..87cc3dc107d1f0d0a7073ce2b462a7a53246edf3 100644
--- a/tests/ITADSPBiquadTest.cpp
+++ b/tests/ITADSPBiquadTest.cpp
@@ -1,4 +1,22 @@
-#include <ITAThirdOctaveFIRFilterGenerator.h>
+/*
+ * ----------------------------------------------------------------
+ *
+ *		ITA core libs
+ *		(c) Copyright Institute of Technical Acoustics (ITA)
+ *		RWTH Aachen University, Germany, 2015-2017
+ *
+ * ----------------------------------------------------------------
+ *				    ____  __________  _______
+ *				   //  / //__   ___/ //  _   |
+ *				  //  /    //  /    //  /_|  |
+ *				 //  /    //  /    //  ___   |
+ *				//__/    //__/    //__/   |__|
+ *
+ * ----------------------------------------------------------------
+ *
+ */
+
+#include <ITABiquad.h>
 #include <ITAThirdOctaveFilterbank.h>
 
 #include <ITAAudiofileWriter.h>
diff --git a/tests/ITADSPSIMOVDLSourceInShoebox.cpp b/tests/ITADSPSIMOVDLSourceInShoebox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..707e8fd6608b4e49be344a6bbc72eeabea8da87b
--- /dev/null
+++ b/tests/ITADSPSIMOVDLSourceInShoebox.cpp
@@ -0,0 +1,170 @@
+/*
+ * ----------------------------------------------------------------
+ *
+ *		ITA core libs
+ *		(c) Copyright Institute of Technical Acoustics (ITA)
+ *		RWTH Aachen University, Germany, 2015-2017
+ *
+ * ----------------------------------------------------------------
+ *				    ____  __________  _______
+ *				   //  / //__   ___/ //  _   |
+ *				  //  /    //  /    //  /_|  |
+ *				 //  /    //  /    //  ___   |
+ *				//__/    //__/    //__/   |__|
+ *
+ * ----------------------------------------------------------------
+ *
+ * Circulates a sound source in a shoebox room including specular
+ * reflections off walls (perfectly hard).
+ *
+ */
+
+#include <ITASIMOVariableDelayLine.h>
+
+#include <ITAStringUtils.h>
+#include <ITAAudiofileWriter.h>
+#include <ITASampleBuffer.h>
+#include <ITASampleFrame.h>
+
+#include <ITAStreamFunctionGenerator.h>
+#include <ITAFileDataSource.h>
+#include <ITAStreamInfo.h>
+
+#include <iostream>
+#include <cmath>
+#include <vector>
+
+using namespace std;
+
+const float fSimulateSeconds = 20; // s
+const float fShoeboxLength = 10.0f; // m
+const float fShoeboxWidth = 7.0f; // m
+const float fShoeboxHeight = 3.0f; // m
+
+const float fCircleRadiusHorizontal = 3.0f; // m
+const float fCircleDuration = 3.0f; // s
+
+const float fSpeedOfSound = 343.0f; // m/s
+
+const string sInFilePath = "CirculatingSource_Signal.wav";
+const string sOutFilePath = "CirculatingSource_ShoeboxRoom.wav";
+
+const unsigned int iBlockLength = 128;
+const double dSampleRate = 44.1e3;
+
+float DistanceToPropagationTime( const float fDistanceMeter )
+{
+	return fDistanceMeter / fSpeedOfSound;
+}
+
+int main( int, char** )
+{
+	assert( fCircleRadiusHorizontal * 2 < fShoeboxLength );
+	assert( fCircleRadiusHorizontal * 2 < fShoeboxWidth );
+	assert( 1.7f < fShoeboxHeight );
+
+	ITAStreamFunctionGenerator sinesignal( 1, dSampleRate, iBlockLength, ITAStreamFunctionGenerator::SINE, 500.0f, 0.5f, true );
+	ITAFileDatasource filesignal( "cl-mod-bb-piece-32.wav", iBlockLength, true );
+	ITADatasource* pIntputStream = &filesignal;
+
+	assert( fShoeboxLength > fShoeboxWidth );
+	const float fMaxReservedDelaySamples = float( fShoeboxLength * pow( 2, 1 ) / double( fSpeedOfSound ) * dSampleRate );
+	CITASIMOVariableDelayLine* pSIMOVDL = new CITASIMOVariableDelayLine( dSampleRate, iBlockLength, fMaxReservedDelaySamples, CITASIMOVariableDelayLine::CUBIC_SPLINE_INTERPOLATION );
+
+	unsigned int uiNumberOfFrames = ( unsigned int ) ceil( dSampleRate * fSimulateSeconds / ( float ) iBlockLength );
+
+	// OpenGL coordinates
+	const int iCursorDirect = pSIMOVDL->AddCursor();
+	const int iCursorPositiveX = pSIMOVDL->AddCursor();
+	const int iCursorNegativeX = pSIMOVDL->AddCursor();
+	const int iCursorPositiveY = pSIMOVDL->AddCursor();
+	const int iCursorNegativeY = pSIMOVDL->AddCursor();
+	const int iCursorPositiveZ = pSIMOVDL->AddCursor();
+	const int iCursorNegativeZ = pSIMOVDL->AddCursor();
+
+	ITAAudiofileProperties props_in;
+	props_in.iChannels = 1;
+	props_in.dSampleRate = dSampleRate;
+	props_in.eQuantization = ITAQuantization::ITA_FLOAT;
+	props_in.eDomain = ITADomain::ITA_TIME_DOMAIN;
+	props_in.iLength = ( unsigned int ) uiNumberOfFrames * iBlockLength;
+	ITAAudiofileWriter* writer_in = ITAAudiofileWriter::create( sInFilePath, props_in );
+	ITAAudiofileProperties props_out( props_in );
+	props_out.iChannels = pSIMOVDL->GetNumCursors();
+	ITAAudiofileWriter* writer_out = ITAAudiofileWriter::create( sOutFilePath, props_out );
+
+	ITAStreamInfo oState;
+
+	ITASampleBuffer* psbInput = new ITASampleBuffer( iBlockLength, true );
+	ITASampleFrame* psfOutput = new ITASampleFrame( pSIMOVDL->GetNumCursors(), iBlockLength, true );
+
+	cout << "Input file: " << sInFilePath << endl;
+	cout << "Processing ";
+
+	unsigned int n = 0;
+	while( n < uiNumberOfFrames )
+	{
+		// Set new delays
+		const double dT = double( n ) * double( iBlockLength ) / dSampleRate;
+
+		const float fX = fCircleRadiusHorizontal * float( sin( dT / fCircleDuration ) );
+		const float fY = 1.7f;
+		const float fZ = -fCircleRadiusHorizontal * float( cos( dT / fCircleDuration ) );
+
+		// Direct
+		const float fDelay = DistanceToPropagationTime( sqrt( fX * fX + fZ * fZ ) );
+		pSIMOVDL->SetDelayTime( iCursorDirect, fDelay );
+
+		// Reflection positive X (right wall)
+		const float fX_ReflectionPositiveX = fShoeboxWidth - fX;
+		pSIMOVDL->SetDelayTime( iCursorPositiveX, DistanceToPropagationTime( sqrt( fX_ReflectionPositiveX * fX_ReflectionPositiveX + fZ * fZ ) ) );
+
+		// Reflection negative X (left wall)
+		const float fX_ReflectionNegativeX = -fShoeboxWidth + fX;
+		pSIMOVDL->SetDelayTime( iCursorNegativeX, DistanceToPropagationTime( sqrt( fX_ReflectionNegativeX * fX_ReflectionNegativeX + fZ * fZ ) ) );
+
+		// Reflection positive Y (ceiling)
+		const float fY_ReflectionPositiveY = fShoeboxHeight - fY;
+		pSIMOVDL->SetDelayTime( iCursorPositiveY, DistanceToPropagationTime( sqrt( fX * fX + fY_ReflectionPositiveY * fY_ReflectionPositiveY + fZ * fZ ) ) );
+
+		// Reflection negative Y (floor)
+		const float fY_ReflectionNegativeY = -fShoeboxHeight + fY;
+		pSIMOVDL->SetDelayTime( iCursorNegativeY, DistanceToPropagationTime( sqrt( fX * fX + fY_ReflectionNegativeY * fY_ReflectionNegativeY + fZ * fZ ) ) );
+
+		// Reflection positive Z (rear wall)
+		const float fZ_ReflectionPositiveZ = fShoeboxLength - fZ;
+		pSIMOVDL->SetDelayTime( iCursorPositiveZ, DistanceToPropagationTime( sqrt( fX * fX + fZ_ReflectionPositiveZ * fZ_ReflectionPositiveZ ) ) );
+
+		// Reflection negative Z (front wall)
+		const float fZ_ReflectionNegativeZ = -fShoeboxLength + fZ;
+		pSIMOVDL->SetDelayTime( iCursorNegativeZ, DistanceToPropagationTime( sqrt( fX * fX + fZ_ReflectionNegativeZ * fZ_ReflectionNegativeZ ) ) );
+
+
+		// Process
+		psbInput->write( pIntputStream->GetBlockPointer( 0, &oState ), iBlockLength );
+		pSIMOVDL->WriteBlock( psbInput );
+		pSIMOVDL->ReadBlockAndIncrement( psfOutput );
+
+		std::vector< float* > pIn;
+		pIn.push_back( psbInput->data() );
+		writer_in->write( iBlockLength, pIn );
+		writer_out->write( psfOutput, iBlockLength );
+		n++;
+
+		pIntputStream->IncrementBlockPointer();
+
+		if( n % ( uiNumberOfFrames / 40 ) == 0 )
+			cout << ".";
+	}
+
+	cout << " done." << endl;
+	cout << "Output file: " << sOutFilePath << endl;
+
+	delete writer_in;
+	delete writer_out;
+
+	delete psbInput;
+	delete psfOutput;
+
+	return 255;
+}
diff --git a/tests/ITADSPSIMOVDLSourceInShoebox.m b/tests/ITADSPSIMOVDLSourceInShoebox.m
new file mode 100644
index 0000000000000000000000000000000000000000..c95b3a569b24a6d50fb05bd2253268abd4bb191f
--- /dev/null
+++ b/tests/ITADSPSIMOVDLSourceInShoebox.m
@@ -0,0 +1,24 @@
+%% load
+simo_i = ita_read( 'CirculatingSource_Signal.wav' );
+simo_o = ita_read( 'CirculatingSource_ShoeboxRoom.wav' );
+simo_io = ita_merge( simo_i, simo_o );
+
+%% prepare
+simo_io_snipped = ita_time_crop( simo_io, [ 2 2.1 ], 'time' );
+simo_io_snipped.comment = 'Circulating source in a shoebox room (10x7x3)';
+simo_io_snipped.channelNames = { 'Input signal', ...
+    'Direct sound', ...
+    'Reflection right wall', ...
+    'Reflection left wall', ...
+    'Reflection ceiling', ...
+    'Reflection floor', ...
+    'Reflection rear wall', ...
+    'Reflection front wall', ...
+    };
+
+%% plot
+simo_io_snipped.pt
+
+%% merge
+source_shoebox_auralization_mono = ita_sum( simo_o );
+ita_write( ita_normalize_dat( source_shoebox_auralization_mono ), 'CirculatingSource_ShoeboxRoom_Mono.wav', 'overwrite' );
diff --git a/tests/ITADSPSIMOVDLTest.cpp b/tests/ITADSPSIMOVDLTest.cpp
index f482665a494c9fddeaa96e79f86102c663414ef7..cca062de41de94352ac0294a9b79e1876e1054ce 100644
--- a/tests/ITADSPSIMOVDLTest.cpp
+++ b/tests/ITADSPSIMOVDLTest.cpp
@@ -1,3 +1,25 @@
+/*
+ * ----------------------------------------------------------------
+ *
+ *		ITA core libs
+ *		(c) Copyright Institute of Technical Acoustics (ITA)
+ *		RWTH Aachen University, Germany, 2015-2017
+ *
+ * ----------------------------------------------------------------
+ *				    ____  __________  _______
+ *				   //  / //__   ___/ //  _   |
+ *				  //  /    //  /    //  /_|  |
+ *				 //  /    //  /    //  ___   |
+ *				//__/    //__/    //__/   |__|
+ *
+ * ----------------------------------------------------------------
+ *
+ * Processes a sine signal through single-input multiple-output 
+ * variable delay line with two cursors at different delays and
+ * exports the i/o streams to hard drive.
+ * 
+ */
+
 #include <ITASIMOVariableDelayLine.h>
 
 #include <ITAStringUtils.h>
@@ -6,6 +28,7 @@
 #include <ITASampleFrame.h>
 
 #include <ITAStreamFunctionGenerator.h>
+#include <ITAFileDataSource.h>
 #include <ITAStreamInfo.h>
 
 #include <iostream>
@@ -20,23 +43,35 @@ const float fMaxReservedDelaySamples = 5 * iBlockLength;
 const float fSimulateSeconds = 10;
 const float fInitialDelaySamples = 10 * 2 * iBlockLength - 1;
 
+const string sInFilePath = "SIMOVDL_in.wav";
+const string sOutFilePath = "SIMOVDL_out.wav";
+
 int main( int, char** )
 {
 
 	ITAStreamFunctionGenerator sinesignal( 1, dSampleRate, iBlockLength, ITAStreamFunctionGenerator::SINE, 500.0f, 0.9f, true );
+	//ITAFileDatasource filesignal( "cl-mod-bb-piece-32.wav", iBlockLength, true );
 
-	CITASIMOVariableDelayLine* pSIMOVDL = new CITASIMOVariableDelayLine( dSampleRate, iBlockLength, fMaxReservedDelaySamples, CITASIMOVariableDelayLine::SWITCH );
+	ITADatasource* pIntputStream = &sinesignal;
+
+	CITASIMOVariableDelayLine* pSIMOVDL = new CITASIMOVariableDelayLine( dSampleRate, iBlockLength, fMaxReservedDelaySamples, CITASIMOVariableDelayLine::CUBIC_SPLINE_INTERPOLATION );
 
 
 	double dSamplerate = dSampleRate;
 	unsigned int uiBlocklength = iBlockLength;
 	unsigned int uiNumberOfFrames = ( unsigned int ) std::ceil( dSamplerate * fSimulateSeconds / ( float ) uiBlocklength );
 
+	int iCursor0 = pSIMOVDL->AddCursor();
+	pSIMOVDL->SetDelaySamples( iCursor0, .0f );
+
 	int iCursor1 = pSIMOVDL->AddCursor();
-	pSIMOVDL->SetDelaySamples( iCursor1, float( uiBlocklength * 2 ) );
+	pSIMOVDL->SetDelaySamples( iCursor1, 11.0f );
 
 	int iCursor2 = pSIMOVDL->AddCursor();
-	pSIMOVDL->SetDelaySamples( iCursor2, float( uiBlocklength * 3 ) );
+	pSIMOVDL->SetDelaySamples( iCursor2, float( uiBlocklength * 2 ) );
+
+	int iCursor3 = pSIMOVDL->AddCursor();
+	pSIMOVDL->SetDelaySamples( iCursor3, float( uiBlocklength * 3 ) );
 
 	ITAAudiofileProperties props_in;
 	props_in.iChannels = 1;
@@ -44,34 +79,43 @@ int main( int, char** )
 	props_in.eQuantization = ITAQuantization::ITA_FLOAT;
 	props_in.eDomain = ITADomain::ITA_TIME_DOMAIN;
 	props_in.iLength = uiNumberOfFrames * uiBlocklength;
-	ITAAudiofileWriter* writer_in = ITAAudiofileWriter::create( "SIMOVDL_in.wav", props_in );
+	ITAAudiofileWriter* writer_in = ITAAudiofileWriter::create( sInFilePath, props_in );
 	ITAAudiofileProperties props_out( props_in );
 	props_out.iChannels = pSIMOVDL->GetNumCursors();
-	ITAAudiofileWriter* writer_out = ITAAudiofileWriter::create( "SIMOVDL_out.wav", props_out );
+	ITAAudiofileWriter* writer_out = ITAAudiofileWriter::create( sOutFilePath, props_out );
 
 	ITAStreamInfo oState;
 
 	ITASampleBuffer* psbInput = new ITASampleBuffer( uiBlocklength, true );
 	ITASampleFrame* psfOutput = new ITASampleFrame( pSIMOVDL->GetNumCursors(), uiBlocklength, true );
 
+	cout << "Input file: " << sInFilePath << endl;
+	cout << "Processing ";
+
 	unsigned int n = 0;
 	while( n < uiNumberOfFrames )
 	{
 		// Add new samples
-		psbInput->write( sinesignal.GetBlockPointer( 0, &oState ), uiBlocklength );
+		psbInput->write( pIntputStream->GetBlockPointer( 0, &oState ), uiBlocklength );
 		pSIMOVDL->WriteBlock( psbInput );
 
-		pSIMOVDL->ReadBlock( psfOutput );
+		pSIMOVDL->ReadBlockAndIncrement( psfOutput );
 
-		std::vector<float*> pIn;
+		std::vector< float* > pIn;
 		pIn.push_back( psbInput->data() );
 		writer_in->write( uiBlocklength, pIn );
 		writer_out->write( psfOutput, uiBlocklength );
 		n++;
 
-		sinesignal.IncrementBlockPointer();
+		pIntputStream->IncrementBlockPointer();
+
+		if( n % ( uiNumberOfFrames / 40 ) == 0 )
+			cout << ".";
 	}
 
+	cout << " done." << endl;
+	cout << "Output file: " << sOutFilePath << endl;
+
 	delete writer_in;
 	delete writer_out;
 
diff --git a/tests/ITADSPSIMOVDLTest.m b/tests/ITADSPSIMOVDLTest.m
new file mode 100644
index 0000000000000000000000000000000000000000..90716d9a51636601cd3e632a57f106973e48d105
--- /dev/null
+++ b/tests/ITADSPSIMOVDLTest.m
@@ -0,0 +1,14 @@
+%% load
+simo_io = ita_merge( ita_read( 'SIMOVDL_in.wav' ), ita_read( 'SIMOVDL_out.wav' ) );
+
+%% prepare
+simo_io_snipped = ita_time_crop( simo_io, [ 1 512 ], 'samples' );
+simo_io_snipped.comment = 'Single-Input Multiple-Output Variable Delay Line';
+simo_io_snipped.channelNames = { 'Sine signal in', ...
+    'Read cursor 1 out (no delay)', ...
+    'Read cursor 2 out (11 samples delay)', ...
+    'Read cursor 3 out (2 blocks delay)', ...
+    'Read cursor 4 out (3 blocks delay)' };
+
+%% plot
+simo_io_snipped.pt
\ No newline at end of file
diff --git a/tests/ITADSPThirdOctaveFilterbankTest.cpp b/tests/ITADSPThirdOctaveFilterbankTest.cpp
index a5c334371ed62a74ce81d4d9c275df543955501c..69046bc4df3b3e9f745725dce548b871674d2700 100644
--- a/tests/ITADSPThirdOctaveFilterbankTest.cpp
+++ b/tests/ITADSPThirdOctaveFilterbankTest.cpp
@@ -26,7 +26,7 @@ void TestThirdOctaveFilterbankIIR()
 	const int iSampleLength = ( 1 << 17 );
 	CITAThirdOctaveFilterbank* pIIRFilterbank = CITAThirdOctaveFilterbank::Create( g_dSampleRate, iSampleLength, CITAThirdOctaveFilterbank::IIR_BIQUADS_ORDER10 );
 
-	ITASampleBuffer x( iSampleLength );
+	ITASampleBuffer x( iSampleLength, true );
 	x[ 0 ] = 1.0f;
 
 	CITAThirdOctaveGainMagnitudeSpectrum oMags;