fix for ringbuffer problem on 64-bit macs. Also, this should make it possible to migrate away from using the long datatype on pa_ringbuffer.

This commit is contained in:
bjornroche 2009-11-18 16:09:05 +00:00
commit c55f47de78
3 changed files with 58 additions and 44 deletions

View file

@ -63,7 +63,7 @@
* Initialize FIFO.
* elementCount must be power of 2, returns -1 if not.
*/
long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long elementSizeBytes, long elementCount, void *dataPtr )
ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr )
{
if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */
rbuf->bufferSize = elementCount;
@ -77,14 +77,14 @@ long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long elementSizeBytes,
/***************************************************************************
** Return number of elements available for reading. */
long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf )
ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf )
{
PaUtil_ReadMemoryBarrier();
return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
}
/***************************************************************************
** Return number of elements available for writing. */
long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf )
ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf )
{
/* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
@ -103,19 +103,19 @@ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf )
** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or elementCount, whichever is smaller.
*/
long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount,
void **dataPtr1, long *sizePtr1,
void **dataPtr2, long *sizePtr2 )
ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
void **dataPtr1, ring_buffer_size_t *sizePtr1,
void **dataPtr2, ring_buffer_size_t *sizePtr2 )
{
long index;
long available = PaUtil_GetRingBufferWriteAvailable( rbuf );
ring_buffer_size_t index;
ring_buffer_size_t available = PaUtil_GetRingBufferWriteAvailable( rbuf );
if( elementCount > available ) elementCount = available;
/* Check to see if write is not contiguous. */
index = rbuf->writeIndex & rbuf->smallMask;
if( (index + elementCount) > rbuf->bufferSize )
{
/* Write data in two blocks that wrap the buffer. */
long firstHalf = rbuf->bufferSize - index;
ring_buffer_size_t firstHalf = rbuf->bufferSize - index;
*dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
*sizePtr1 = firstHalf;
*dataPtr2 = &rbuf->buffer[0];
@ -134,7 +134,7 @@ long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount
/***************************************************************************
*/
long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCount )
ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
{
/* we need to ensure that previous writes are seen before we update the write index */
PaUtil_WriteMemoryBarrier();
@ -147,19 +147,19 @@ long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCou
** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or elementCount, whichever is smaller.
*/
long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount,
void **dataPtr1, long *sizePtr1,
void **dataPtr2, long *sizePtr2 )
ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
void **dataPtr1, ring_buffer_size_t *sizePtr1,
void **dataPtr2, ring_buffer_size_t *sizePtr2 )
{
long index;
long available = PaUtil_GetRingBufferReadAvailable( rbuf );
ring_buffer_size_t index;
ring_buffer_size_t available = PaUtil_GetRingBufferReadAvailable( rbuf );
if( elementCount > available ) elementCount = available;
/* Check to see if read is not contiguous. */
index = rbuf->readIndex & rbuf->smallMask;
if( (index + elementCount) > rbuf->bufferSize )
{
/* Write data in two blocks that wrap the buffer. */
long firstHalf = rbuf->bufferSize - index;
ring_buffer_size_t firstHalf = rbuf->bufferSize - index;
*dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
*sizePtr1 = firstHalf;
*dataPtr2 = &rbuf->buffer[0];
@ -176,7 +176,7 @@ long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount,
}
/***************************************************************************
*/
long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long elementCount )
ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
{
/* we need to ensure that previous writes are always seen before updating the index. */
PaUtil_WriteMemoryBarrier();
@ -185,9 +185,9 @@ long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long elementCoun
/***************************************************************************
** Return elements written. */
long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elementCount )
ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount )
{
long size1, size2, numWritten;
ring_buffer_size_t size1, size2, numWritten;
void *data1, *data2;
numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 );
if( size2 > 0 )
@ -207,9 +207,9 @@ long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elem
/***************************************************************************
** Return elements read. */
long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long elementCount )
ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount )
{
long size1, size2, numRead;
ring_buffer_size_t size1, size2, numRead;
void *data1, *data2;
numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 );
if( size2 > 0 )

View file

@ -67,6 +67,21 @@
the use of the ring buffer.
*/
#if defined(__APPLE__)
#include <sys/types.h>
typedef int32_t ring_buffer_size_t;
#elif defined( __GNUC__ )
typedef long ring_buffer_size_t;
#elif (_MSC_VER >= 1400)
typedef long ring_buffer_size_t;
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef long ring_buffer_size_t;
#else
typedef long ring_buffer_size_t;
#endif
#ifdef __cplusplus
extern "C"
{
@ -74,12 +89,12 @@ extern "C"
typedef struct PaUtilRingBuffer
{
long bufferSize; /**< Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
long writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */
long readIndex; /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */
long bigMask; /**< Used for wrapping indices with extra bit to distinguish full/empty. */
long smallMask; /**< Used for fitting indices to buffer. */
long elementSizeBytes; /**< Number of bytes per element. */
ring_buffer_size_t bufferSize; /**< Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */
ring_buffer_size_t writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */
ring_buffer_size_t readIndex; /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */
ring_buffer_size_t bigMask; /**< Used for wrapping indices with extra bit to distinguish full/empty. */
ring_buffer_size_t smallMask; /**< Used for fitting indices to buffer. */
ring_buffer_size_t elementSizeBytes; /**< Number of bytes per element. */
char *buffer; /**< Pointer to the buffer containing the actual data. */
}PaUtilRingBuffer;
@ -96,7 +111,7 @@ typedef struct PaUtilRingBuffer
@return -1 if elementCount is not a power of 2, otherwise 0.
*/
long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long elementSizeBytes, long elementCount, void *dataPtr );
ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr );
/** Clear buffer. Should only be called when buffer is NOT being read.
@ -110,7 +125,7 @@ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf );
@return The number of elements available for writing.
*/
long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf );
ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf );
/** Retrieve the number of elements available in the ring buffer for reading.
@ -118,7 +133,7 @@ long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf );
@return The number of elements available for reading.
*/
long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf );
ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf );
/** Write data to the ring buffer.
@ -130,7 +145,7 @@ long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf );
@return The number of elements written.
*/
long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elementCount );
ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount );
/** Read data from the ring buffer.
@ -142,7 +157,7 @@ long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elem
@return The number of elements read.
*/
long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long elementCount );
ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount );
/** Get address of region(s) to which we can write data.
@ -164,9 +179,9 @@ long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long elementCoun
@return The room available to be written or elementCount, whichever is smaller.
*/
long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount,
void **dataPtr1, long *sizePtr1,
void **dataPtr2, long *sizePtr2 );
ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
void **dataPtr1, ring_buffer_size_t *sizePtr1,
void **dataPtr2, ring_buffer_size_t *sizePtr2 );
/** Advance the write index to the next location to be written.
@ -176,7 +191,7 @@ long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount
@return The new position.
*/
long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCount );
ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount );
/** Get address of region(s) from which we can write data.
@ -198,9 +213,9 @@ long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCou
@return The number of elements available for reading.
*/
long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount,
void **dataPtr1, long *sizePtr1,
void **dataPtr2, long *sizePtr2 );
ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
void **dataPtr1, ring_buffer_size_t *sizePtr1,
void **dataPtr2, ring_buffer_size_t *sizePtr2 );
/** Advance the read index to the next location to be read.
@ -210,7 +225,7 @@ long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount,
@return The new position.
*/
long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long elementCount );
ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount );
#ifdef __cplusplus
}

View file

@ -1714,19 +1714,18 @@ static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter,
void*inUserData )
{
void *dummyData;
long dummySize;
ring_buffer_size_t dummySize;
PaUtilRingBuffer *rb = (PaUtilRingBuffer *) inUserData;
VVDBUG(("ringBufferIOProc()\n"));
assert( sizeof( UInt32 ) == sizeof( long ) );
if( PaUtil_GetRingBufferReadAvailable( rb ) == 0 ) {
*outData = NULL;
*ioDataSize = 0;
return RING_BUFFER_EMPTY;
}
PaUtil_GetRingBufferReadRegions( rb, *ioDataSize,
outData, (long *)ioDataSize,
outData, (ring_buffer_size_t *)ioDataSize,
&dummyData, &dummySize );
assert( *ioDataSize );
@ -1938,7 +1937,7 @@ static OSStatus AudioIOProc( void *inRefCon,
because we have to do a little buffer processing that the
AudioConverter would otherwise handle for us. */
void *data1, *data2;
long size1, size2;
ring_buffer_size_t size1, size2;
PaUtil_GetRingBufferReadRegions( &stream->inputRingBuffer,
inChan*frames*flsz,
&data1, &size1,