[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