Show
Ignore:
Timestamp:
02/20/08 05:09:20 (10 months ago)
Author:
rossb
Message:

added support for multi-byte elements in pa_ringbuffer.c/h thanks to Sven Fischer

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • portaudio/branches/v19-devel/src/common/pa_ringbuffer.c

    r1320 r1346  
    88 * modified for SMP safety on Linux by Leland Lucius 
    99 * also, allowed for const where possible 
     10 * modified for multiple-byte-sized data elements by Sven Fischer  
     11 * 
    1012 * Note that this is safe only for a single-thread reader and a 
    1113 * single-thread writer. 
     
    6062/*************************************************************************** 
    6163 * Initialize FIFO. 
    62  * numBytes must be power of 2, returns -1 if not. 
     64 * elementCount must be power of 2, returns -1 if not. 
    6365 */ 
    64 long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr ) 
    65 { 
    66     if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */ 
    67     rbuf->bufferSize = numBytes; 
     66long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long elementSizeBytes, long elementCount, void *dataPtr ) 
     67{ 
     68    if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */ 
     69    rbuf->bufferSize = elementCount; 
    6870    rbuf->buffer = (char *)dataPtr; 
    6971    PaUtil_FlushRingBuffer( rbuf ); 
    70     rbuf->bigMask = (numBytes*2)-1; 
    71     rbuf->smallMask = (numBytes)-1; 
     72    rbuf->bigMask = (elementCount*2)-1; 
     73    rbuf->smallMask = (elementCount)-1; 
     74    rbuf->elementSizeBytes = elementSizeBytes; 
    7275    return 0; 
    7376} 
    7477 
    7578/*************************************************************************** 
    76 ** Return number of bytes available for reading. */ 
     79** Return number of elements available for reading. */ 
    7780long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ) 
    7881{ 
     
    8184} 
    8285/*************************************************************************** 
    83 ** Return number of bytes available for writing. */ 
     86** Return number of elements available for writing. */ 
    8487long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ) 
    8588{ 
     
    99102** If the region is contiguous, size2 will be zero. 
    100103** If non-contiguous, size2 will be the size of second region. 
    101 ** Returns room available to be written or numBytes, whichever is smaller. 
    102 */ 
    103 long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes, 
     104** Returns room available to be written or elementCount, whichever is smaller. 
     105*/ 
     106long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount, 
    104107                                       void **dataPtr1, long *sizePtr1, 
    105108                                       void **dataPtr2, long *sizePtr2 ) 
     
    107110    long   index; 
    108111    long   available = PaUtil_GetRingBufferWriteAvailable( rbuf ); 
    109     if( numBytes > available ) numBytes = available; 
     112    if( elementCount > available ) elementCount = available; 
    110113    /* Check to see if write is not contiguous. */ 
    111114    index = rbuf->writeIndex & rbuf->smallMask; 
    112     if( (index + numBytes) > rbuf->bufferSize ) 
     115    if( (index + elementCount) > rbuf->bufferSize ) 
    113116    { 
    114117        /* Write data in two blocks that wrap the buffer. */ 
    115118        long   firstHalf = rbuf->bufferSize - index; 
    116         *dataPtr1 = &rbuf->buffer[index]; 
     119        *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 
    117120        *sizePtr1 = firstHalf; 
    118121        *dataPtr2 = &rbuf->buffer[0]; 
    119         *sizePtr2 = numBytes - firstHalf; 
    120     } 
    121     else 
    122     { 
    123         *dataPtr1 = &rbuf->buffer[index]; 
    124         *sizePtr1 = numBytes; 
     122        *sizePtr2 = elementCount - firstHalf; 
     123    } 
     124    else 
     125    { 
     126        *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 
     127        *sizePtr1 = elementCount; 
    125128        *dataPtr2 = NULL; 
    126129        *sizePtr2 = 0; 
    127130    } 
    128     return numBytes; 
    129 } 
    130  
    131  
    132 /*************************************************************************** 
    133 */ 
    134 long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes ) 
     131    return elementCount; 
     132} 
     133 
     134 
     135/*************************************************************************** 
     136*/ 
     137long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCount ) 
    135138{ 
    136139    /* we need to ensure that previous writes are seen before we update the write index */ 
    137140    PaUtil_WriteMemoryBarrier(); 
    138     return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask; 
     141    return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask; 
    139142} 
    140143 
     
    143146** If the region is contiguous, size2 will be zero. 
    144147** If non-contiguous, size2 will be the size of second region. 
    145 ** Returns room available to be written or numBytes, whichever is smaller. 
    146 */ 
    147 long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes, 
     148** Returns room available to be written or elementCount, whichever is smaller. 
     149*/ 
     150long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount, 
    148151                                void **dataPtr1, long *sizePtr1, 
    149152                                void **dataPtr2, long *sizePtr2 ) 
     
    151154    long   index; 
    152155    long   available = PaUtil_GetRingBufferReadAvailable( rbuf ); 
    153     if( numBytes > available ) numBytes = available; 
     156    if( elementCount > available ) elementCount = available; 
    154157    /* Check to see if read is not contiguous. */ 
    155158    index = rbuf->readIndex & rbuf->smallMask; 
    156     if( (index + numBytes) > rbuf->bufferSize ) 
     159    if( (index + elementCount) > rbuf->bufferSize ) 
    157160    { 
    158161        /* Write data in two blocks that wrap the buffer. */ 
    159162        long firstHalf = rbuf->bufferSize - index; 
    160         *dataPtr1 = &rbuf->buffer[index]; 
     163        *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 
    161164        *sizePtr1 = firstHalf; 
    162165        *dataPtr2 = &rbuf->buffer[0]; 
    163         *sizePtr2 = numBytes - firstHalf; 
    164     } 
    165     else 
    166     { 
    167         *dataPtr1 = &rbuf->buffer[index]; 
    168         *sizePtr1 = numBytes; 
     166        *sizePtr2 = elementCount - firstHalf; 
     167    } 
     168    else 
     169    { 
     170        *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 
     171        *sizePtr1 = elementCount; 
    169172        *dataPtr2 = NULL; 
    170173        *sizePtr2 = 0; 
    171174    } 
    172     return numBytes; 
    173 } 
    174 /*************************************************************************** 
    175 */ 
    176 long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes ) 
     175    return elementCount; 
     176} 
     177/*************************************************************************** 
     178*/ 
     179long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long elementCount ) 
    177180{ 
    178181    /* we need to ensure that previous writes are always seen before updating the index. */ 
    179182    PaUtil_WriteMemoryBarrier(); 
    180     return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask; 
    181 } 
    182  
    183 /*************************************************************************** 
    184 ** Return bytes written. */ 
    185 long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes ) 
     183    return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask; 
     184} 
     185 
     186/*************************************************************************** 
     187** Return elements written. */ 
     188long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elementCount ) 
    186189{ 
    187190    long size1, size2, numWritten; 
    188191    void *data1, *data2; 
    189     numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 ); 
     192    numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); 
    190193    if( size2 > 0 ) 
    191194    { 
    192195 
    193         memcpy( data1, data, size1 ); 
    194         data = ((char *)data) + size1; 
    195         memcpy( data2, data, size2 ); 
    196     } 
    197     else 
    198     { 
    199         memcpy( data1, data, size1 ); 
     196        memcpy( data1, data, size1*rbuf->elementSizeBytes ); 
     197        data = ((char *)data) + size1*rbuf->elementSizeBytes; 
     198        memcpy( data2, data, size2*rbuf->elementSizeBytes ); 
     199    } 
     200    else 
     201    { 
     202        memcpy( data1, data, size1*rbuf->elementSizeBytes ); 
    200203    } 
    201204    PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten ); 
     
    204207 
    205208/*************************************************************************** 
    206 ** Return bytes read. */ 
    207 long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes ) 
     209** Return elements read. */ 
     210long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long elementCount ) 
    208211{ 
    209212    long size1, size2, numRead; 
    210213    void *data1, *data2; 
    211     numRead = PaUtil_GetRingBufferReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 ); 
     214    numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); 
    212215    if( size2 > 0 ) 
    213216    { 
    214         memcpy( data, data1, size1 ); 
    215         data = ((char *)data) + size1; 
    216         memcpy( data, data2, size2 ); 
    217     } 
    218     else 
    219     { 
    220         memcpy( data, data1, size1 ); 
     217        memcpy( data, data1, size1*rbuf->elementSizeBytes ); 
     218        data = ((char *)data) + size1*rbuf->elementSizeBytes; 
     219        memcpy( data, data2, size2*rbuf->elementSizeBytes ); 
     220    } 
     221    else 
     222    { 
     223        memcpy( data, data1, size1*rbuf->elementSizeBytes ); 
    221224    } 
    222225    PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead );