[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11777] branches/soc-2007-hcube/intern/ tinySND/intern/SND_DataCache.cpp: bugfix: fixed buffering routine.

Csaba Hruska csaba.hruska at gmail.com
Tue Aug 21 20:44:32 CEST 2007


Revision: 11777
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11777
Author:   hcube
Date:     2007-08-21 20:44:32 +0200 (Tue, 21 Aug 2007)

Log Message:
-----------
bugfix: fixed buffering routine.

Modified Paths:
--------------
    branches/soc-2007-hcube/intern/tinySND/intern/SND_DataCache.cpp

Modified: branches/soc-2007-hcube/intern/tinySND/intern/SND_DataCache.cpp
===================================================================
--- branches/soc-2007-hcube/intern/tinySND/intern/SND_DataCache.cpp	2007-08-21 18:43:45 UTC (rev 11776)
+++ branches/soc-2007-hcube/intern/tinySND/intern/SND_DataCache.cpp	2007-08-21 18:44:32 UTC (rev 11777)
@@ -3,6 +3,7 @@
 #include "SND_DataCache.h"
 #include "SND_Defines.h"
 
+#include <stdio.h>
 
 SND_DataCache::SND_DataCache( SND_DataProvider *dataProvider )
 {
@@ -73,191 +74,173 @@
 void SND_DataCache::seek( int frameNum )
 {
 	assert( mDataProvider != 0 );
+	assert( frameNum >= 0 && frameNum < getNumFrames() );
 
-	if( frameNum < 0 )
-	{
-		frameNum = 0;
-	}
-
-	if( frameNum > getNumFrames() )
-	{
-		frameNum = getNumFrames() - 1;
-	}
-
 	mFrameCounter = frameNum;
 }
 
 float* SND_DataCache::getPCMDataPtr( int framesNum, int channel )
 {
 	assert( mDataProvider != 0 );
+	assert( mFrameCounter + framesNum <= getNumFrames() );
 
 	// check if the wave buffer has enough data, load if it doesn't
-	
+
 	// check framesNum > mBufferSize, increase if necessary
 	if( framesNum > mBufferSize )
 	{
-		// new buffer structure:
-		// ----------------------------------------------------------------------------
-		// | new data (part A) | currently buffered data (part B) | new data (part C) |
-		// ----------------------------------------------------------------------------
-		
 		int numChannels = getNumChannels();
-		int copiedDataNum = 0;
-		int copyOldStart = 0;
-		int copyOldEnd = 0;
-		int copyNewStart = 0;
-		int copyNewEnd = 0;
+		int numFrames = getNumFrames();
+		int readNum;
+		int seekPos;
 		
-		// allocate new buffer
-		int newSize = (framesNum / SND_WAVE_BUFFER_FRAMES + 1) * SND_WAVE_BUFFER_FRAMES;
-		float *newBuffer = new float[ newSize * numChannels ];
+//		printf("SND_DataCache::getPCMDataPtr resize oldSize[%d]\n", mBufferSize);
 		
-		// copy datas from the old buffer if there is any usable
-		// calculate (part B) size
-		if( mFrameCounter <= mBufferPos + mBufferSize && mFrameCounter + mBufferSize > mBufferPos )
-		{
-			if( mFrameCounter <= mBufferPos )
-			{
-				copyOldStart = 0;
-				copyNewStart = mBufferPos - mFrameCounter;
-			}
-			else
-			{
-				copyOldStart = mFrameCounter - mBufferPos;
-				copyNewStart = 0;
-			}
-			
-			if( mFrameCounter + newSize > mBufferPos + mBufferSize )
-			{
-				copyOldEnd = mBufferSize;
-				copyNewEnd = copyNewStart + mBufferSize;
-			}
-			else
-			{
-				copyOldEnd = mBufferPos + mBufferSize - mFrameCounter - newSize;
-				copyNewEnd = newSize;
-			}
-			
-			// copy data
-			copiedDataNum = copyOldEnd - copyOldStart;
-			memcpy( &newBuffer[ copyNewStart*numChannels ], &mBuffer[ copyOldStart*numChannels ], copiedDataNum * numChannels * sizeof(float) );
-		}
+		// delete old buffer
+		delete mBuffer;
 		
-		// load new data
-		// (part A)
-		if( copyNewStart > 0 )
+		// allocate new buffer
+		mBufferSize = (framesNum / SND_WAVE_BUFFER_FRAMES + 1) * SND_WAVE_BUFFER_FRAMES;
+		if( mBufferSize > numFrames )
 		{
-			mDataProvider->seek( mFrameCounter );
-			mDataProvider->fillBuffer( newBuffer, copyNewStart );
+			mBufferSize = numFrames;
 		}
 
-		// (part C)
-		if( copyNewEnd < newSize )
+//		printf("SND_DataCache::getPCMDataPtr resize newSize[%d]\n", mBufferSize);
+		mBuffer = new float[ mBufferSize * numChannels ];
+		mBufferPos = mFrameCounter;
+
+		seekPos = mBufferPos;
+		mDataProvider->seek( seekPos );
+		
+		// prevent overread
+		readNum = mBufferSize;
+
+		if( readNum + seekPos > numFrames )
 		{
-			mDataProvider->seek( mFrameCounter + copyNewEnd );
-			mDataProvider->fillBuffer( &newBuffer[ copyNewEnd*numChannels ], newSize - copyNewEnd );
+			readNum = numFrames - seekPos;
 		}
-		
-		// delete old buffer
-		delete mBuffer;
-		
-		mBuffer = newBuffer;
-		mBufferSize = newSize;
-		mBufferPos = mFrameCounter;
+
+		mDataProvider->fillBuffer( mBuffer, readNum );
 	}
 	
 	// check underflow, load data if necessary
 	if( mFrameCounter < mBufferPos )
 	{
 		int offset;
+		int readNum;
+		int seekPos;
 		int dataOffset;
 		int newPos;
 		int i;
+		int numFrames = getNumFrames();
 		
-		if( mFrameCounter > mBufferPos - SND_WAVE_BUFFER_FRAMES )
+//		printf("SND_DataCache::getPCMDataPtr underflow mFrameCounter[%d] mBufferPos[%d] mBufferSize[%d]\n", mFrameCounter, mBufferPos, mBufferSize);
+		if( mFrameCounter > mBufferPos - SND_WAVE_BUFFER_STEP_FRAMES )
 		{
 			offset = SND_WAVE_BUFFER_STEP_FRAMES;
 			newPos = mBufferPos - offset;
 		}
 		else
 		{
-			offset = mBufferPos - mFrameCounter;
 			newPos = mFrameCounter;
+			offset = mBufferPos - newPos;
 		}
-
-		// prevent negative frame number
-		if( mBufferPos - offset < 0 )
+		
+		// prevent negative buffer positions
+		if( newPos < 0 )
 		{
+			newPos = 0;
 			offset = mBufferPos;
 		}
-		
+
+		dataOffset = offset * getNumChannels();
+
+		for( i = mBufferSize * getNumChannels() - 1 ; i >= dataOffset ; --i )
+		{
+			mBuffer[ i ] = mBuffer[ i - dataOffset ];
+		}
+			
 		// prevent buffer overflow
+		seekPos = newPos;
 		if( offset > mBufferSize )
 		{
 			offset = mBufferSize;
 		}
+
+		mDataProvider->seek( seekPos );
 			
-		dataOffset = offset * getNumChannels();
-			
-		for( i = mBufferSize * getNumChannels() - 1 ; i >= dataOffset ; --i )
+		// prevent overread
+		readNum = offset;
+		if( readNum + seekPos > numFrames )
 		{
-			mBuffer[ i ] = mBuffer[ i - dataOffset ];
+			readNum = numFrames - seekPos;
 		}
-			
+		
 		mBufferPos = newPos;
-		mDataProvider->seek( mBufferPos );
-		mDataProvider->fillBuffer( mBuffer, offset );
+		mDataProvider->fillBuffer( mBuffer, readNum );
 	}
 	
 	// check overflow, load data if necessary
 	if( mFrameCounter + framesNum > mBufferPos + mBufferSize )
 	{
 		int offset;
+		int readNum;
+		int seekPos;
 		int dataOffset;
 		int dataEnd;
 		int newPos;
 		int i;
+		int numFrames = getNumFrames();
 
-		if( mFrameCounter + framesNum < mBufferPos + mBufferSize + SND_WAVE_BUFFER_FRAMES )
+//		printf("SND_DataCache::getPCMDataPtr overflow mFrameCounter[%d] mBufferPos[%d] mBufferSize[%d]\n", mFrameCounter, mBufferPos, mBufferSize);
+		if( mFrameCounter + framesNum < mBufferPos + mBufferSize + SND_WAVE_BUFFER_STEP_FRAMES )
 		{
 			offset = SND_WAVE_BUFFER_STEP_FRAMES;
 			newPos = mBufferPos + offset;
 		}
 		else
 		{
-			offset = mFrameCounter - mBufferPos;
 			newPos = mFrameCounter;
+			offset = newPos - mBufferPos;
 		}
 
-		// prevent frame number overflow
-		if( newPos >= getNumFrames() - mBufferSize )
+		dataOffset = offset * getNumChannels();
+		dataEnd = mBufferSize * getNumChannels();
+
+		for( i = 0 ; dataOffset < dataEnd ; ++i, ++dataOffset )
 		{
-			newPos = getNumFrames() - mBufferSize - 1;
-			offset -= mFrameCounter - newPos;
+			mBuffer[ i ] = mBuffer[ dataOffset ];
 		}
-		
+
 		// prevent buffer overflow
 		if( offset > mBufferSize )
 		{
 			offset = mBufferSize;
+			seekPos = newPos;
 		}
-			
-		dataOffset = offset * getNumChannels();
-		dataEnd = mBufferSize * getNumChannels();
+		else
+		{
+			seekPos = mBufferPos + mBufferSize;
+		}
 		
-		for( i = 0 ; dataOffset < dataEnd ; ++i, ++dataOffset )
+		mDataProvider->seek( seekPos );
+
+		// prevent overread
+		readNum = offset;
+		if( readNum + seekPos > numFrames )
 		{
-			mBuffer[ i ] = mBuffer[ dataOffset ];
+			readNum = numFrames - seekPos;
 		}
-			
+		
 		mBufferPos = newPos;
-		mDataProvider->seek( mBufferPos + offset );
-
-		mDataProvider->fillBuffer( &mBuffer[ (mBufferSize - offset) * getNumChannels() ], offset );
+		mDataProvider->fillBuffer( &mBuffer[ (mBufferSize - offset) * getNumChannels() ], readNum );
 	}
-	
+
 	int index = (mFrameCounter - mBufferPos) * getNumChannels() + channel;
-	
+
+	assert( index < mBufferSize * getNumChannels() );
+
 	return &mBuffer[ index ];
 }
 





More information about the Bf-blender-cvs mailing list