Changeset 1346

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

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

Location:
portaudio/branches/v19-devel/src
Files:
5 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 ); 
  • portaudio/branches/v19-devel/src/common/pa_ringbuffer.h

    r1151 r1346  
    99 * modified for SMP safety on OS X by Bjorn Roche. 
    1010 * also allowed for const where possible. 
     11 * modified for multiple-byte-sized data elements by Sven Fischer  
     12 * 
    1113 * Note that this is safe only for a single-thread reader 
    1214 * and a single-thread writer. 
     
    5860typedef struct PaUtilRingBuffer 
    5961{ 
    60     long   bufferSize; /* Number of bytes in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */ 
    61     long   writeIndex; /* Index of next writable byte. Set by PaUtil_AdvanceRingBufferWriteIndex. */ 
    62     long   readIndex;  /* Index of next readable byte. Set by PaUtil_AdvanceRingBufferReadIndex. */ 
    63     long   bigMask;    /* Used for wrapping indices with extra bit to distinguish full/empty. */ 
    64     long   smallMask;  /* Used for fitting indices to buffer. */ 
     62    long  bufferSize;   /* Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */ 
     63    long  writeIndex;   /* Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */ 
     64    long  readIndex;    /* Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */ 
     65    long  bigMask;    /* Used for wrapping indices with extra bit to distinguish full/empty. */ 
     66    long  smallMask;  /* Used for fitting indices to buffer. */ 
     67    long  elementSizeBytes; /* Number of bytes per element. */ 
    6568    char  *buffer; 
    6669}PaUtilRingBuffer; 
     
    7073 @param rbuf The ring buffer. 
    7174 
    72  @param numBytes The number of bytes in the buffer and must be power of 2. 
     75 @param elementCount The number of elements in the buffer and must be power of 2. 
    7376 
    7477 @param dataPtr A pointer to a previously allocated area where the data 
    75  will be maintained.  It must be numBytes long. 
    76  
    77  @return -1 if numBytes is not a power of 2, otherwise 0. 
    78 */ 
    79 long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long numBytes, void *dataPtr ); 
     78 will be maintained.  It must be elementCount*elementSizeBytes long. 
     79 
     80 @return -1 if elementCount is not a power of 2, otherwise 0. 
     81*/ 
     82long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long elementSizeBytes, long elementCount, void *dataPtr ); 
    8083 
    8184/** Clear buffer. Should only be called when buffer is NOT being read. 
     
    8588void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ); 
    8689 
    87 /** Retrieve the number of bytes available in the ring buffer for writing. 
    88  
    89  @param rbuf The ring buffer. 
    90  
    91  @return The number of bytes available for writing. 
     90/** Retrieve the number of elements available in the ring buffer for writing. 
     91 
     92 @param rbuf The ring buffer. 
     93 
     94 @return The number of elements available for writing. 
    9295*/ 
    9396long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ); 
    9497 
    95 /** Retrieve the number of bytes available in the ring buffer for reading. 
    96  
    97  @param rbuf The ring buffer. 
    98  
    99  @return The number of bytes available for reading. 
     98/** Retrieve the number of elements available in the ring buffer for reading. 
     99 
     100 @param rbuf The ring buffer. 
     101 
     102 @return The number of elements available for reading. 
    100103*/ 
    101104long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ); 
     
    107110 @param data The address of new data to write to the buffer. 
    108111 
    109  @param numBytes The number of bytes to be written. 
    110  
    111  @return The number of bytes written. 
    112 */ 
    113 long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long numBytes ); 
     112 @param elementCount The number of elements to be written. 
     113 
     114 @return The number of elements written. 
     115*/ 
     116long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elementCount ); 
    114117 
    115118/** Read data from the ring buffer. 
     
    119122 @param data The address where the data should be stored. 
    120123 
    121  @param numBytes The number of bytes to be read. 
    122  
    123  @return The number of bytes read. 
    124 */ 
    125 long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes ); 
     124 @param elementCount The number of elements to be read. 
     125 
     126 @return The number of elements read. 
     127*/ 
     128long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long elementCount ); 
    126129 
    127130/** Get address of region(s) to which we can write data. 
     
    129132 @param rbuf The ring buffer. 
    130133 
    131  @param numBytes The number of bytes desired. 
     134 @param elementCount The number of elements desired. 
    132135 
    133136 @param dataPtr1 The address where the first (or only) region pointer will be 
     
    138141 
    139142 @param dataPtr2 The address where the second region pointer will be stored if 
    140  the first region is too small to satisfy numBytes. 
     143 the first region is too small to satisfy elementCount. 
    141144 
    142145 @param sizePtr2 The address where the second region length will be stored if 
    143  the first region is too small to satisfy numBytes. 
    144  
    145  @return The room available to be written or numBytes, whichever is smaller. 
    146 */ 
    147 long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long numBytes, 
     146 the first region is too small to satisfy elementCount. 
     147 
     148 @return The room available to be written or elementCount, whichever is smaller. 
     149*/ 
     150long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount, 
    148151                                       void **dataPtr1, long *sizePtr1, 
    149152                                       void **dataPtr2, long *sizePtr2 ); 
     
    153156 @param rbuf The ring buffer. 
    154157 
    155  @param numBytes The number of bytes to advance. 
     158 @param elementCount The number of elements to advance. 
    156159 
    157160 @return The new position. 
    158161*/ 
    159 long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes ); 
     162long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCount ); 
    160163 
    161164/** Get address of region(s) from which we can write data. 
     
    163166 @param rbuf The ring buffer. 
    164167 
    165  @param numBytes The number of bytes desired. 
     168 @param elementCount The number of elements desired. 
    166169 
    167170 @param dataPtr1 The address where the first (or only) region pointer will be 
     
    172175 
    173176 @param dataPtr2 The address where the second region pointer will be stored if 
    174  the first region is too small to satisfy numBytes. 
     177 the first region is too small to satisfy elementCount. 
    175178 
    176179 @param sizePtr2 The address where the second region length will be stored if 
    177  the first region is too small to satisfy numBytes. 
    178  
    179  @return The number of bytes available for reading. 
    180 */ 
    181 long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long numBytes, 
     180 the first region is too small to satisfy elementCount. 
     181 
     182 @return The number of elements available for reading. 
     183*/ 
     184long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount, 
    182185                                      void **dataPtr1, long *sizePtr1, 
    183186                                      void **dataPtr2, long *sizePtr2 ); 
     
    187190 @param rbuf The ring buffer. 
    188191 
    189  @param numBytes The number of bytes to advance. 
     192 @param elementCount The number of elements to advance. 
    190193 
    191194 @return The new position. 
    192195*/ 
    193 long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes ); 
     196long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long elementCount ); 
    194197 
    195198#ifdef __cplusplus 
  • portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core.c

    r1322 r1346  
    15371537          /* now we can initialize the ring buffer */ 
    15381538          PaUtil_InitializeRingBuffer( &stream->inputRingBuffer, 
    1539                                    ringSize*szfl, data ) ; 
     1539                                   1, ringSize*szfl, data ) ; 
    15401540          /* advance the read point a little, so we are reading from the 
    15411541             middle of the buffer */ 
  • portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core_blocking.c

    r1339 r1346  
    173173      err = PaUtil_InitializeRingBuffer( 
    174174            &blio->inputRingBuffer, 
    175             ringBufferSize*blio->inputSampleSizePow2*inChan, 
     175            1, ringBufferSize*blio->inputSampleSizePow2*inChan, 
    176176            data ); 
    177177      assert( !err ); 
     
    187187      err = PaUtil_InitializeRingBuffer( 
    188188            &blio->outputRingBuffer, 
    189             ringBufferSize*blio->outputSampleSizePow2*outChan, 
     189            1, ringBufferSize*blio->outputSampleSizePow2*outChan, 
    190190            data ); 
    191191      assert( !err ); 
  • portaudio/branches/v19-devel/src/hostapi/jack/pa_jack.c

    r1306 r1346  
    255255    if( buffer == NULL ) return paInsufficientMemory; 
    256256    memset( buffer, 0, numBytes ); 
    257     return (PaError) PaUtil_InitializeRingBuffer( rbuf, numBytes, buffer ); 
     257    return (PaError) PaUtil_InitializeRingBuffer( rbuf, 1, numBytes, buffer ); 
    258258} 
    259259