diff options
Diffstat (limited to 'pd/portaudio/src/common/pa_ringbuffer.h')
-rw-r--r-- | pd/portaudio/src/common/pa_ringbuffer.h | 90 |
1 files changed, 55 insertions, 35 deletions
diff --git a/pd/portaudio/src/common/pa_ringbuffer.h b/pd/portaudio/src/common/pa_ringbuffer.h index b3808898..fd92882a 100644 --- a/pd/portaudio/src/common/pa_ringbuffer.h +++ b/pd/portaudio/src/common/pa_ringbuffer.h @@ -1,13 +1,15 @@ #ifndef PA_RINGBUFFER_H #define PA_RINGBUFFER_H /* - * $Id: pa_ringbuffer.h 1151 2006-11-29 02:11:16Z leland_lucius $ + * $Id: pa_ringbuffer.h 1347 2008-02-21 04:54:36Z rossb $ * Portable Audio I/O Library * Ring Buffer utility. * * Author: Phil Burk, http://www.softsynth.com * modified for SMP safety on OS X by Bjorn Roche. * also allowed for const where possible. + * modified for multiple-byte-sized data elements by Sven Fischer + * * Note that this is safe only for a single-thread reader * and a single-thread writer. * @@ -48,6 +50,21 @@ /** @file @ingroup common_src + @brief Single-reader single-writer lock-free ring buffer + + PaUtilRingBuffer is a ring buffer used to transport samples between + different execution contexts (threads, OS callbacks, interrupt handlers) + without requiring the use of any locks. This only works when there is + a single reader and a single writer (ie. one thread or callback writes + to the ring buffer, another thread or callback reads from it). + + The PaUtilRingBuffer structure manages a ring buffer containing N + elements, where N must be a power of two. An element may be any size + (specified in bytes). + + The memory area used to store the buffer elements must be allocated by + the client prior to calling PaUtil_InitializeRingBuffer() and must outlive + the use of the ring buffer. */ #ifdef __cplusplus @@ -57,26 +74,29 @@ extern "C" typedef struct PaUtilRingBuffer { - long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */ - long writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */ - long readIndex; /* Index of next readable byte. 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. */ - char *buffer; + 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. */ + char *buffer; /**< Pointer to the buffer containing the actual data. */ }PaUtilRingBuffer; /** Initialize Ring Buffer. @param rbuf The ring buffer. - @param numBytes The number of bytes in the buffer and must be power of 2. + @param elementSizeBytes The size of a single data element in bytes. + + @param elementCount The number of elements in the buffer (must be power of 2). @param dataPtr A pointer to a previously allocated area where the data - will be maintained. It must be numBytes long. + will be maintained. It must be elementCount*elementSizeBytes long. - @return -1 if numBytes is not a power of 2, otherwise 0. + @return -1 if elementCount is not a power of 2, otherwise 0. */ -long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr ); +long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long elementSizeBytes, long elementCount, void *dataPtr ); /** Clear buffer. Should only be called when buffer is NOT being read. @@ -84,19 +104,19 @@ long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *d */ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ); -/** Retrieve the number of bytes available in the ring buffer for writing. +/** Retrieve the number of elements available in the ring buffer for writing. @param rbuf The ring buffer. - @return The number of bytes available for writing. + @return The number of elements available for writing. */ long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ); -/** Retrieve the number of bytes available in the ring buffer for reading. +/** Retrieve the number of elements available in the ring buffer for reading. @param rbuf The ring buffer. - @return The number of bytes available for reading. + @return The number of elements available for reading. */ long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ); @@ -106,11 +126,11 @@ long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ); @param data The address of new data to write to the buffer. - @param numBytes The number of bytes to be written. + @param elementCount The number of elements to be written. - @return The number of bytes written. + @return The number of elements written. */ -long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes ); +long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elementCount ); /** Read data from the ring buffer. @@ -118,17 +138,17 @@ long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numB @param data The address where the data should be stored. - @param numBytes The number of bytes to be read. + @param elementCount The number of elements to be read. - @return The number of bytes read. + @return The number of elements read. */ -long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes ); +long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long elementCount ); /** Get address of region(s) to which we can write data. @param rbuf The ring buffer. - @param numBytes The number of bytes desired. + @param elementCount The number of elements desired. @param dataPtr1 The address where the first (or only) region pointer will be stored. @@ -137,14 +157,14 @@ long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes ); stored. @param dataPtr2 The address where the second region pointer will be stored if - the first region is too small to satisfy numBytes. + the first region is too small to satisfy elementCount. @param sizePtr2 The address where the second region length will be stored if - the first region is too small to satisfy numBytes. + the first region is too small to satisfy elementCount. - @return The room available to be written or numBytes, whichever is smaller. + @return The room available to be written or elementCount, whichever is smaller. */ -long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes, +long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2 ); @@ -152,17 +172,17 @@ long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes, @param rbuf The ring buffer. - @param numBytes The number of bytes to advance. + @param elementCount The number of elements to advance. @return The new position. */ -long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes ); +long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCount ); /** Get address of region(s) from which we can write data. @param rbuf The ring buffer. - @param numBytes The number of bytes desired. + @param elementCount The number of elements desired. @param dataPtr1 The address where the first (or only) region pointer will be stored. @@ -171,14 +191,14 @@ long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes ) stored. @param dataPtr2 The address where the second region pointer will be stored if - the first region is too small to satisfy numBytes. + the first region is too small to satisfy elementCount. @param sizePtr2 The address where the second region length will be stored if - the first region is too small to satisfy numBytes. + the first region is too small to satisfy elementCount. - @return The number of bytes available for reading. + @return The number of elements available for reading. */ -long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes, +long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount, void **dataPtr1, long *sizePtr1, void **dataPtr2, long *sizePtr2 ); @@ -186,11 +206,11 @@ long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes, @param rbuf The ring buffer. - @param numBytes The number of bytes to advance. + @param elementCount The number of elements to advance. @return The new position. */ -long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes ); +long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long elementCount ); #ifdef __cplusplus } |