Changeset 1346 for portaudio/branches
- Timestamp:
- 02/20/08 05:09:20 (10 months ago)
- Location:
- portaudio/branches/v19-devel/src
- Files:
-
- 5 modified
-
common/pa_ringbuffer.c (modified) (8 diffs)
-
common/pa_ringbuffer.h (modified) (12 diffs)
-
hostapi/coreaudio/pa_mac_core.c (modified) (1 diff)
-
hostapi/coreaudio/pa_mac_core_blocking.c (modified) (2 diffs)
-
hostapi/jack/pa_jack.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
portaudio/branches/v19-devel/src/common/pa_ringbuffer.c
r1320 r1346 8 8 * modified for SMP safety on Linux by Leland Lucius 9 9 * also, allowed for const where possible 10 * modified for multiple-byte-sized data elements by Sven Fischer 11 * 10 12 * Note that this is safe only for a single-thread reader and a 11 13 * single-thread writer. … … 60 62 /*************************************************************************** 61 63 * Initialize FIFO. 62 * numBytesmust be power of 2, returns -1 if not.64 * elementCount must be power of 2, returns -1 if not. 63 65 */ 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;66 long 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; 68 70 rbuf->buffer = (char *)dataPtr; 69 71 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; 72 75 return 0; 73 76 } 74 77 75 78 /*************************************************************************** 76 ** Return number of bytes available for reading. */79 ** Return number of elements available for reading. */ 77 80 long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ) 78 81 { … … 81 84 } 82 85 /*************************************************************************** 83 ** Return number of bytes available for writing. */86 ** Return number of elements available for writing. */ 84 87 long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ) 85 88 { … … 99 102 ** If the region is contiguous, size2 will be zero. 100 103 ** 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 */ 106 long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount, 104 107 void **dataPtr1, long *sizePtr1, 105 108 void **dataPtr2, long *sizePtr2 ) … … 107 110 long index; 108 111 long available = PaUtil_GetRingBufferWriteAvailable( rbuf ); 109 if( numBytes > available ) numBytes= available;112 if( elementCount > available ) elementCount = available; 110 113 /* Check to see if write is not contiguous. */ 111 114 index = rbuf->writeIndex & rbuf->smallMask; 112 if( (index + numBytes) > rbuf->bufferSize )115 if( (index + elementCount) > rbuf->bufferSize ) 113 116 { 114 117 /* Write data in two blocks that wrap the buffer. */ 115 118 long firstHalf = rbuf->bufferSize - index; 116 *dataPtr1 = &rbuf->buffer[index ];119 *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 117 120 *sizePtr1 = firstHalf; 118 121 *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; 125 128 *dataPtr2 = NULL; 126 129 *sizePtr2 = 0; 127 130 } 128 return numBytes;129 } 130 131 132 /*************************************************************************** 133 */ 134 long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes)131 return elementCount; 132 } 133 134 135 /*************************************************************************** 136 */ 137 long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCount ) 135 138 { 136 139 /* we need to ensure that previous writes are seen before we update the write index */ 137 140 PaUtil_WriteMemoryBarrier(); 138 return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;141 return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask; 139 142 } 140 143 … … 143 146 ** If the region is contiguous, size2 will be zero. 144 147 ** 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 */ 150 long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount, 148 151 void **dataPtr1, long *sizePtr1, 149 152 void **dataPtr2, long *sizePtr2 ) … … 151 154 long index; 152 155 long available = PaUtil_GetRingBufferReadAvailable( rbuf ); 153 if( numBytes > available ) numBytes= available;156 if( elementCount > available ) elementCount = available; 154 157 /* Check to see if read is not contiguous. */ 155 158 index = rbuf->readIndex & rbuf->smallMask; 156 if( (index + numBytes) > rbuf->bufferSize )159 if( (index + elementCount) > rbuf->bufferSize ) 157 160 { 158 161 /* Write data in two blocks that wrap the buffer. */ 159 162 long firstHalf = rbuf->bufferSize - index; 160 *dataPtr1 = &rbuf->buffer[index ];163 *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; 161 164 *sizePtr1 = firstHalf; 162 165 *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; 169 172 *dataPtr2 = NULL; 170 173 *sizePtr2 = 0; 171 174 } 172 return numBytes;173 } 174 /*************************************************************************** 175 */ 176 long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes)175 return elementCount; 176 } 177 /*************************************************************************** 178 */ 179 long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long elementCount ) 177 180 { 178 181 /* we need to ensure that previous writes are always seen before updating the index. */ 179 182 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. */ 188 long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elementCount ) 186 189 { 187 190 long size1, size2, numWritten; 188 191 void *data1, *data2; 189 numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );192 numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); 190 193 if( size2 > 0 ) 191 194 { 192 195 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 ); 200 203 } 201 204 PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten ); … … 204 207 205 208 /*************************************************************************** 206 ** Return bytes read. */207 long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long numBytes)209 ** Return elements read. */ 210 long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long elementCount ) 208 211 { 209 212 long size1, size2, numRead; 210 213 void *data1, *data2; 211 numRead = PaUtil_GetRingBufferReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );214 numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); 212 215 if( size2 > 0 ) 213 216 { 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 ); 221 224 } 222 225 PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead ); -
portaudio/branches/v19-devel/src/common/pa_ringbuffer.h
r1151 r1346 9 9 * modified for SMP safety on OS X by Bjorn Roche. 10 10 * also allowed for const where possible. 11 * modified for multiple-byte-sized data elements by Sven Fischer 12 * 11 13 * Note that this is safe only for a single-thread reader 12 14 * and a single-thread writer. … … 58 60 typedef struct PaUtilRingBuffer 59 61 { 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. */ 65 68 char *buffer; 66 69 }PaUtilRingBuffer; … … 70 73 @param rbuf The ring buffer. 71 74 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. 73 76 74 77 @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 numBytesis 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 */ 82 long PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, long elementSizeBytes, long elementCount, void *dataPtr ); 80 83 81 84 /** Clear buffer. Should only be called when buffer is NOT being read. … … 85 88 void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ); 86 89 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. 92 95 */ 93 96 long PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ); 94 97 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. 100 103 */ 101 104 long PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ); … … 107 110 @param data The address of new data to write to the buffer. 108 111 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 */ 116 long PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, long elementCount ); 114 117 115 118 /** Read data from the ring buffer. … … 119 122 @param data The address where the data should be stored. 120 123 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 */ 128 long PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, long elementCount ); 126 129 127 130 /** Get address of region(s) to which we can write data. … … 129 132 @param rbuf The ring buffer. 130 133 131 @param numBytes The number of bytes desired.134 @param elementCount The number of elements desired. 132 135 133 136 @param dataPtr1 The address where the first (or only) region pointer will be … … 138 141 139 142 @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. 141 144 142 145 @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 */ 150 long PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, long elementCount, 148 151 void **dataPtr1, long *sizePtr1, 149 152 void **dataPtr2, long *sizePtr2 ); … … 153 156 @param rbuf The ring buffer. 154 157 155 @param numBytes The number of bytes to advance.158 @param elementCount The number of elements to advance. 156 159 157 160 @return The new position. 158 161 */ 159 long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long numBytes);162 long PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, long elementCount ); 160 163 161 164 /** Get address of region(s) from which we can write data. … … 163 166 @param rbuf The ring buffer. 164 167 165 @param numBytes The number of bytes desired.168 @param elementCount The number of elements desired. 166 169 167 170 @param dataPtr1 The address where the first (or only) region pointer will be … … 172 175 173 176 @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. 175 178 176 179 @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 */ 184 long PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, long elementCount, 182 185 void **dataPtr1, long *sizePtr1, 183 186 void **dataPtr2, long *sizePtr2 ); … … 187 190 @param rbuf The ring buffer. 188 191 189 @param numBytes The number of bytes to advance.192 @param elementCount The number of elements to advance. 190 193 191 194 @return The new position. 192 195 */ 193 long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long numBytes);196 long PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, long elementCount ); 194 197 195 198 #ifdef __cplusplus -
portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core.c
r1322 r1346 1537 1537 /* now we can initialize the ring buffer */ 1538 1538 PaUtil_InitializeRingBuffer( &stream->inputRingBuffer, 1539 ringSize*szfl, data ) ;1539 1, ringSize*szfl, data ) ; 1540 1540 /* advance the read point a little, so we are reading from the 1541 1541 middle of the buffer */ -
portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core_blocking.c
r1339 r1346 173 173 err = PaUtil_InitializeRingBuffer( 174 174 &blio->inputRingBuffer, 175 ringBufferSize*blio->inputSampleSizePow2*inChan,175 1, ringBufferSize*blio->inputSampleSizePow2*inChan, 176 176 data ); 177 177 assert( !err ); … … 187 187 err = PaUtil_InitializeRingBuffer( 188 188 &blio->outputRingBuffer, 189 ringBufferSize*blio->outputSampleSizePow2*outChan,189 1, ringBufferSize*blio->outputSampleSizePow2*outChan, 190 190 data ); 191 191 assert( !err ); -
portaudio/branches/v19-devel/src/hostapi/jack/pa_jack.c
r1306 r1346 255 255 if( buffer == NULL ) return paInsufficientMemory; 256 256 memset( buffer, 0, numBytes ); 257 return (PaError) PaUtil_InitializeRingBuffer( rbuf, numBytes, buffer );257 return (PaError) PaUtil_InitializeRingBuffer( rbuf, 1, numBytes, buffer ); 258 258 } 259 259
