Update portaudio to the latest

Previous version uses OSMemoryBarrier() on Apple but this is deprecated
in macOS 10.12.

Also, modify PRESUBMIT.py so that this patch is not blocked by
CheckLongLines.

Bug: chromium:1322548
Change-Id: I02c6b7682730abf718e88fc7f1bd4dcd7d347da6
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/256580
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Daniel.L (Byoungchan) Lee <daniel.l@hpcnt.com>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36873}
This commit is contained in:
Byoungchan Lee 2022-05-12 22:48:05 +09:00 committed by WebRTC LUCI CQ
parent fbe667298a
commit 81d65fcf7d
6 changed files with 146 additions and 119 deletions

View file

@ -953,7 +953,7 @@ def CommonChecks(input_api, output_api):
# Skip long-lines check for DEPS and GN files. # Skip long-lines check for DEPS and GN files.
build_file_filter_list = (r'.+\.gn$', r'.+\.gni$', 'DEPS') build_file_filter_list = (r'.+\.gn$', r'.+\.gni$', 'DEPS')
# Also we will skip most checks for third_party directory. # Also we will skip most checks for third_party directory.
third_party_filter_list = (r'^third_party[\\\/].+', ) third_party_filter_list = (r'(^|.*[\\\/])third_party[\\\/].+', )
eighty_char_sources = lambda x: input_api.FilterSourceFile( eighty_char_sources = lambda x: input_api.FilterSourceFile(
x, x,
files_to_skip=build_file_filter_list + objc_filter_list + files_to_skip=build_file_filter_list + objc_filter_list +

View file

@ -227,7 +227,7 @@ AudioDeviceGeneric::InitStatus AudioDeviceMac::Init() {
if (_paRenderBuffer == NULL) { if (_paRenderBuffer == NULL) {
_paRenderBuffer = new PaUtilRingBuffer; _paRenderBuffer = new PaUtilRingBuffer;
PaRingBufferSize bufSize = -1; ring_buffer_size_t bufSize = -1;
bufSize = PaUtil_InitializeRingBuffer( bufSize = PaUtil_InitializeRingBuffer(
_paRenderBuffer, sizeof(SInt16), _renderBufSizeSamples, _renderBufData); _paRenderBuffer, sizeof(SInt16), _renderBufSizeSamples, _renderBufData);
if (bufSize == -1) { if (bufSize == -1) {
@ -247,7 +247,7 @@ AudioDeviceGeneric::InitStatus AudioDeviceMac::Init() {
if (_paCaptureBuffer == NULL) { if (_paCaptureBuffer == NULL) {
_paCaptureBuffer = new PaUtilRingBuffer; _paCaptureBuffer = new PaUtilRingBuffer;
PaRingBufferSize bufSize = -1; ring_buffer_size_t bufSize = -1;
bufSize = bufSize =
PaUtil_InitializeRingBuffer(_paCaptureBuffer, sizeof(Float32), PaUtil_InitializeRingBuffer(_paCaptureBuffer, sizeof(Float32),
_captureBufSizeSamples, _captureBufData); _captureBufSizeSamples, _captureBufData);
@ -2219,7 +2219,7 @@ OSStatus AudioDeviceMac::implDeviceIOProc(const AudioBufferList* inputData,
} }
} }
PaRingBufferSize bufSizeSamples = ring_buffer_size_t bufSizeSamples =
PaUtil_GetRingBufferReadAvailable(_paRenderBuffer); PaUtil_GetRingBufferReadAvailable(_paRenderBuffer);
int32_t renderDelayUs = int32_t renderDelayUs =
@ -2237,7 +2237,7 @@ OSStatus AudioDeviceMac::implDeviceIOProc(const AudioBufferList* inputData,
OSStatus AudioDeviceMac::implOutConverterProc(UInt32* numberDataPackets, OSStatus AudioDeviceMac::implOutConverterProc(UInt32* numberDataPackets,
AudioBufferList* data) { AudioBufferList* data) {
RTC_DCHECK(data->mNumberBuffers == 1); RTC_DCHECK(data->mNumberBuffers == 1);
PaRingBufferSize numSamples = ring_buffer_size_t numSamples =
*numberDataPackets * _outDesiredFormat.mChannelsPerFrame; *numberDataPackets * _outDesiredFormat.mChannelsPerFrame;
data->mBuffers->mNumberChannels = _outDesiredFormat.mChannelsPerFrame; data->mBuffers->mNumberChannels = _outDesiredFormat.mChannelsPerFrame;
@ -2288,7 +2288,7 @@ OSStatus AudioDeviceMac::implInDeviceIOProc(const AudioBufferList* inputData,
return 0; return 0;
} }
PaRingBufferSize bufSizeSamples = ring_buffer_size_t bufSizeSamples =
PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer); PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer);
int32_t captureDelayUs = int32_t captureDelayUs =
@ -2301,9 +2301,9 @@ OSStatus AudioDeviceMac::implInDeviceIOProc(const AudioBufferList* inputData,
_captureDelayUs = captureDelayUs; _captureDelayUs = captureDelayUs;
RTC_DCHECK(inputData->mNumberBuffers == 1); RTC_DCHECK(inputData->mNumberBuffers == 1);
PaRingBufferSize numSamples = inputData->mBuffers->mDataByteSize * ring_buffer_size_t numSamples = inputData->mBuffers->mDataByteSize *
_inStreamFormat.mChannelsPerFrame / _inStreamFormat.mChannelsPerFrame /
_inStreamFormat.mBytesPerPacket; _inStreamFormat.mBytesPerPacket;
PaUtil_WriteRingBuffer(_paCaptureBuffer, inputData->mBuffers->mData, PaUtil_WriteRingBuffer(_paCaptureBuffer, inputData->mBuffers->mData,
numSamples); numSamples);
@ -2318,7 +2318,7 @@ OSStatus AudioDeviceMac::implInDeviceIOProc(const AudioBufferList* inputData,
OSStatus AudioDeviceMac::implInConverterProc(UInt32* numberDataPackets, OSStatus AudioDeviceMac::implInConverterProc(UInt32* numberDataPackets,
AudioBufferList* data) { AudioBufferList* data) {
RTC_DCHECK(data->mNumberBuffers == 1); RTC_DCHECK(data->mNumberBuffers == 1);
PaRingBufferSize numSamples = ring_buffer_size_t numSamples =
*numberDataPackets * _inStreamFormat.mChannelsPerFrame; *numberDataPackets * _inStreamFormat.mChannelsPerFrame;
while (PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer) < numSamples) { while (PaUtil_GetRingBufferReadAvailable(_paCaptureBuffer) < numSamples) {
@ -2341,7 +2341,7 @@ OSStatus AudioDeviceMac::implInConverterProc(UInt32* numberDataPackets,
// Pass the read pointer directly to the converter to avoid a memcpy. // Pass the read pointer directly to the converter to avoid a memcpy.
void* dummyPtr; void* dummyPtr;
PaRingBufferSize dummySize; ring_buffer_size_t dummySize;
PaUtil_GetRingBufferReadRegions(_paCaptureBuffer, numSamples, PaUtil_GetRingBufferReadRegions(_paCaptureBuffer, numSamples,
&data->mBuffers->mData, &numSamples, &data->mBuffers->mData, &numSamples,
&dummyPtr, &dummySize); &dummyPtr, &dummySize);
@ -2356,7 +2356,7 @@ OSStatus AudioDeviceMac::implInConverterProc(UInt32* numberDataPackets,
} }
bool AudioDeviceMac::RenderWorkerThread() { bool AudioDeviceMac::RenderWorkerThread() {
PaRingBufferSize numSamples = ring_buffer_size_t numSamples =
ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * _outDesiredFormat.mChannelsPerFrame; ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * _outDesiredFormat.mChannelsPerFrame;
while (PaUtil_GetRingBufferWriteAvailable(_paRenderBuffer) - while (PaUtil_GetRingBufferWriteAvailable(_paRenderBuffer) -
_renderDelayOffsetSamples < _renderDelayOffsetSamples <

View file

@ -1,8 +1,8 @@
Name: Portaudio library for mac Name: Portaudio library for mac
Short Name: portaudio Short Name: portaudio
URL: https://app.assembla.com/spaces/portaudio/git/source/master/src/common URL: https://github.com/PortAudio/portaudio/tree/master/src/common
Version: 0 Version: 9d8563100d841300f1689b186d131347ad43a0f6
Date: 2018-02-01 Date: 2022-04-12
License: Custom license License: Custom license
License File: LICENSE License File: LICENSE
Security Critical: yes Security Critical: yes
@ -10,3 +10,5 @@ Security Critical: yes
Description: Description:
Part of portaudio library to operate with memory barriers and ring buffer. Part of portaudio library to operate with memory barriers and ring buffer.
Local changes:
- Minor formatting to make 'git cl format' happy.

View file

@ -64,13 +64,23 @@
#define MODULES_THIRD_PARTY_PORTAUDIO_PA_MEMORYBARRIER_H_ #define MODULES_THIRD_PARTY_PORTAUDIO_PA_MEMORYBARRIER_H_
#if defined(__APPLE__) #if defined(__APPLE__)
/* Support for the atomic library was added in C11.
*/
#if (__STDC_VERSION__ < 201112L) || defined(__STDC_NO_ATOMICS__)
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
/* Here are the memory barrier functions. Mac OS X only provides /* Here are the memory barrier functions. Mac OS X only provides
full memory barriers, so the three types of barriers are the same, full memory barriers, so the three types of barriers are the same,
however, these barriers are superior to compiler-based ones. */ however, these barriers are superior to compiler-based ones.
These were deprecated in MacOS 10.12. */
#define PaUtil_FullMemoryBarrier() OSMemoryBarrier() #define PaUtil_FullMemoryBarrier() OSMemoryBarrier()
#define PaUtil_ReadMemoryBarrier() OSMemoryBarrier() #define PaUtil_ReadMemoryBarrier() OSMemoryBarrier()
#define PaUtil_WriteMemoryBarrier() OSMemoryBarrier() #define PaUtil_WriteMemoryBarrier() OSMemoryBarrier()
#else
#include <stdatomic.h>
#define PaUtil_FullMemoryBarrier() atomic_thread_fence(memory_order_seq_cst)
#define PaUtil_ReadMemoryBarrier() atomic_thread_fence(memory_order_acquire)
#define PaUtil_WriteMemoryBarrier() atomic_thread_fence(memory_order_release)
#endif
#elif defined(__GNUC__) #elif defined(__GNUC__)
/* GCC >= 4.1 has built-in intrinsics. We'll use those */ /* GCC >= 4.1 has built-in intrinsics. We'll use those */
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
@ -98,7 +108,7 @@
#define PaUtil_ReadMemoryBarrier() #define PaUtil_ReadMemoryBarrier()
#define PaUtil_WriteMemoryBarrier() #define PaUtil_WriteMemoryBarrier()
#else #else
# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. # error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
#endif #endif
#endif #endif
#elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE) #elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE)
@ -106,6 +116,8 @@
#pragma intrinsic(_ReadWriteBarrier) #pragma intrinsic(_ReadWriteBarrier)
#pragma intrinsic(_ReadBarrier) #pragma intrinsic(_ReadBarrier)
#pragma intrinsic(_WriteBarrier) #pragma intrinsic(_WriteBarrier)
/* note that MSVC intrinsics _ReadWriteBarrier(), _ReadBarrier(),
* _WriteBarrier() are just compiler barriers *not* memory barriers */
#define PaUtil_FullMemoryBarrier() _ReadWriteBarrier() #define PaUtil_FullMemoryBarrier() _ReadWriteBarrier()
#define PaUtil_ReadMemoryBarrier() _ReadBarrier() #define PaUtil_ReadMemoryBarrier() _ReadBarrier()
#define PaUtil_WriteMemoryBarrier() _WriteBarrier() #define PaUtil_WriteMemoryBarrier() _WriteBarrier()
@ -125,7 +137,7 @@
#define PaUtil_ReadMemoryBarrier() #define PaUtil_ReadMemoryBarrier()
#define PaUtil_WriteMemoryBarrier() #define PaUtil_WriteMemoryBarrier()
#else #else
# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. # error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
#endif #endif
#endif #endif

View file

@ -1,5 +1,5 @@
/* /*
* $Id: pa_ringbuffer.c 1421 2009-11-18 16:09:05Z bjornroche $ * $Id$
* Portable Audio I/O Library * Portable Audio I/O Library
* Ring Buffer utility. * Ring Buffer utility.
* *
@ -52,21 +52,19 @@
@ingroup common_src @ingroup common_src
*/ */
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include "pa_ringbuffer.h"
#include <string.h> #include <string.h>
#include "modules/third_party/portaudio/pa_memorybarrier.h" #include "pa_memorybarrier.h"
#include "modules/third_party/portaudio/pa_ringbuffer.h"
/*************************************************************************** /***************************************************************************
* Initialize FIFO. * Initialize FIFO.
* elementCount must be power of 2, returns -1 if not. * elementCount must be power of 2, returns -1 if not.
*/ */
PaRingBufferSize PaUtil_InitializeRingBuffer(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr )
PaRingBufferSize elementSizeBytes, {
PaRingBufferSize elementCount,
void* dataPtr) {
if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */ if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */
rbuf->bufferSize = elementCount; rbuf->bufferSize = elementCount;
rbuf->buffer = (char *)dataPtr; rbuf->buffer = (char *)dataPtr;
@ -79,21 +77,19 @@ PaRingBufferSize PaUtil_InitializeRingBuffer(PaUtilRingBuffer* rbuf,
/*************************************************************************** /***************************************************************************
** Return number of elements available for reading. */ ** Return number of elements available for reading. */
PaRingBufferSize PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf ) ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf )
{ {
PaUtil_ReadMemoryBarrier();
return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask ); return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
} }
/*************************************************************************** /***************************************************************************
** Return number of elements available for writing. */ ** Return number of elements available for writing. */
PaRingBufferSize PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf ) ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf )
{ {
/* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf)); return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
} }
/*************************************************************************** /***************************************************************************
** Clear buffer. Should only be called when buffer is NOT being read. */ ** Clear buffer. Should only be called when buffer is NOT being read or written. */
void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ) void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf )
{ {
rbuf->writeIndex = rbuf->readIndex = 0; rbuf->writeIndex = rbuf->readIndex = 0;
@ -105,21 +101,19 @@ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf )
** If non-contiguous, size2 will be the size of second region. ** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or elementCount, whichever is smaller. ** Returns room available to be written or elementCount, whichever is smaller.
*/ */
PaRingBufferSize PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
PaRingBufferSize elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1,
void** dataPtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 )
PaRingBufferSize* sizePtr1, {
void** dataPtr2, ring_buffer_size_t index;
PaRingBufferSize* sizePtr2) { ring_buffer_size_t available = PaUtil_GetRingBufferWriteAvailable( rbuf );
PaRingBufferSize index;
PaRingBufferSize available = PaUtil_GetRingBufferWriteAvailable( rbuf );
if( elementCount > available ) elementCount = available; if( elementCount > available ) elementCount = available;
/* Check to see if write is not contiguous. */ /* Check to see if write is not contiguous. */
index = rbuf->writeIndex & rbuf->smallMask; index = rbuf->writeIndex & rbuf->smallMask;
if( (index + elementCount) > rbuf->bufferSize ) if( (index + elementCount) > rbuf->bufferSize )
{ {
/* Write data in two blocks that wrap the buffer. */ /* Write data in two blocks that wrap the buffer. */
PaRingBufferSize firstHalf = rbuf->bufferSize - index; ring_buffer_size_t firstHalf = rbuf->bufferSize - index;
*dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
*sizePtr1 = firstHalf; *sizePtr1 = firstHalf;
*dataPtr2 = &rbuf->buffer[0]; *dataPtr2 = &rbuf->buffer[0];
@ -132,16 +126,21 @@ PaRingBufferSize PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer* rbuf,
*dataPtr2 = NULL; *dataPtr2 = NULL;
*sizePtr2 = 0; *sizePtr2 = 0;
} }
if( available )
PaUtil_FullMemoryBarrier(); /* (write-after-read) => full barrier */
return elementCount; return elementCount;
} }
/*************************************************************************** /***************************************************************************
*/ */
PaRingBufferSize PaUtil_AdvanceRingBufferWriteIndex( ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
PaUtilRingBuffer* rbuf, {
PaRingBufferSize elementCount) { /* ensure that previous writes are seen before we update the write index
/* we need to ensure that previous writes are seen before we update the write index */ (write after write)
*/
PaUtil_WriteMemoryBarrier(); PaUtil_WriteMemoryBarrier();
return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask; return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask;
} }
@ -150,23 +149,21 @@ PaRingBufferSize PaUtil_AdvanceRingBufferWriteIndex(
** Get address of region(s) from which we can read data. ** Get address of region(s) from which we can read data.
** If the region is contiguous, size2 will be zero. ** If the region is contiguous, size2 will be zero.
** If non-contiguous, size2 will be the size of second region. ** If non-contiguous, size2 will be the size of second region.
** Returns room available to be written or elementCount, whichever is smaller. ** Returns room available to be read or elementCount, whichever is smaller.
*/ */
PaRingBufferSize PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount,
PaRingBufferSize elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1,
void** dataPtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 )
PaRingBufferSize* sizePtr1, {
void** dataPtr2, ring_buffer_size_t index;
PaRingBufferSize* sizePtr2) { ring_buffer_size_t available = PaUtil_GetRingBufferReadAvailable( rbuf ); /* doesn't use memory barrier */
PaRingBufferSize index;
PaRingBufferSize available = PaUtil_GetRingBufferReadAvailable( rbuf );
if( elementCount > available ) elementCount = available; if( elementCount > available ) elementCount = available;
/* Check to see if read is not contiguous. */ /* Check to see if read is not contiguous. */
index = rbuf->readIndex & rbuf->smallMask; index = rbuf->readIndex & rbuf->smallMask;
if( (index + elementCount) > rbuf->bufferSize ) if( (index + elementCount) > rbuf->bufferSize )
{ {
/* Write data in two blocks that wrap the buffer. */ /* Write data in two blocks that wrap the buffer. */
PaRingBufferSize firstHalf = rbuf->bufferSize - index; ring_buffer_size_t firstHalf = rbuf->bufferSize - index;
*dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
*sizePtr1 = firstHalf; *sizePtr1 = firstHalf;
*dataPtr2 = &rbuf->buffer[0]; *dataPtr2 = &rbuf->buffer[0];
@ -179,24 +176,28 @@ PaRingBufferSize PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer* rbuf,
*dataPtr2 = NULL; *dataPtr2 = NULL;
*sizePtr2 = 0; *sizePtr2 = 0;
} }
if( available )
PaUtil_ReadMemoryBarrier(); /* (read-after-read) => read barrier */
return elementCount; return elementCount;
} }
/*************************************************************************** /***************************************************************************
*/ */
PaRingBufferSize PaUtil_AdvanceRingBufferReadIndex( ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
PaUtilRingBuffer* rbuf, {
PaRingBufferSize elementCount) { /* ensure that previous reads (copies out of the ring buffer) are always completed before updating (writing) the read index.
/* we need to ensure that previous writes are always seen before updating the index. */ (write-after-read) => full barrier
PaUtil_WriteMemoryBarrier(); */
PaUtil_FullMemoryBarrier();
return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask; return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask;
} }
/*************************************************************************** /***************************************************************************
** Return elements written. */ ** Return elements written. */
PaRingBufferSize PaUtil_WriteRingBuffer(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount )
const void* data, {
PaRingBufferSize elementCount) { ring_buffer_size_t size1, size2, numWritten;
PaRingBufferSize size1, size2, numWritten;
void *data1, *data2; void *data1, *data2;
numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 );
if( size2 > 0 ) if( size2 > 0 )
@ -216,10 +217,9 @@ PaRingBufferSize PaUtil_WriteRingBuffer(PaUtilRingBuffer* rbuf,
/*************************************************************************** /***************************************************************************
** Return elements read. */ ** Return elements read. */
PaRingBufferSize PaUtil_ReadRingBuffer(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount )
void* data, {
PaRingBufferSize elementCount) { ring_buffer_size_t size1, size2, numRead;
PaRingBufferSize size1, size2, numRead;
void *data1, *data2; void *data1, *data2;
numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 );
if( size2 > 0 ) if( size2 > 0 )

View file

@ -1,7 +1,7 @@
#ifndef MODULES_THIRD_PARTY_PORTAUDIO_PA_RINGBUFFER_H_ #ifndef MODULES_THIRD_PARTY_PORTAUDIO_PA_RINGBUFFER_H_
#define MODULES_THIRD_PARTY_PORTAUDIO_PA_RINGBUFFER_H_ #define MODULES_THIRD_PARTY_PORTAUDIO_PA_RINGBUFFER_H_
/* /*
* $Id: pa_ringbuffer.h 1421 2009-11-18 16:09:05Z bjornroche $ * $Id$
* Portable Audio I/O Library * Portable Audio I/O Library
* Ring Buffer utility. * Ring Buffer utility.
* *
@ -65,19 +65,23 @@
The memory area used to store the buffer elements must be allocated by The memory area used to store the buffer elements must be allocated by
the client prior to calling PaUtil_InitializeRingBuffer() and must outlive the client prior to calling PaUtil_InitializeRingBuffer() and must outlive
the use of the ring buffer. the use of the ring buffer.
@note The ring buffer functions are not normally exposed in the PortAudio
libraries. If you want to call them then you will need to add pa_ringbuffer.c
to your application source code.
*/ */
#if defined(__APPLE__) #if defined(__APPLE__)
#include <sys/types.h> #include <sys/types.h>
typedef int32_t PaRingBufferSize; typedef int32_t ring_buffer_size_t;
#elif defined(__GNUC__) #elif defined(__GNUC__)
typedef long PaRingBufferSize; typedef long ring_buffer_size_t;
#elif (_MSC_VER >= 1400) #elif (_MSC_VER >= 1400)
typedef long PaRingBufferSize; typedef long ring_buffer_size_t;
#elif defined(_MSC_VER) || defined(__BORLANDC__) #elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef long PaRingBufferSize; typedef long ring_buffer_size_t;
#else #else
typedef long PaRingBufferSize; typedef long ring_buffer_size_t;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -85,38 +89,43 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
typedef struct PaUtilRingBuffer { typedef struct PaUtilRingBuffer {
PaRingBufferSize bufferSize; /**< Number of elements in FIFO. Power of 2. Set ring_buffer_size_t bufferSize; /**< Number of elements in FIFO. Power of 2.
by PaUtil_InitRingBuffer. */ Set by PaUtil_InitRingBuffer. */
PaRingBufferSize writeIndex; /**< Index of next writable element. Set by volatile ring_buffer_size_t
PaUtil_AdvanceRingBufferWriteIndex. */ writeIndex; /**< Index of next writable element. Set by
PaRingBufferSize readIndex; /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */
PaUtil_AdvanceRingBufferReadIndex. */ volatile ring_buffer_size_t
PaRingBufferSize bigMask; /**< Used for wrapping indices with extra bit to readIndex; /**< Index of next readable element. Set by
distinguish full/empty. */ PaUtil_AdvanceRingBufferReadIndex. */
PaRingBufferSize smallMask; /**< Used for fitting indices to buffer. */ ring_buffer_size_t bigMask; /**< Used for wrapping indices with extra bit to
PaRingBufferSize elementSizeBytes; /**< Number of bytes per element. */ 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. */ char* buffer; /**< Pointer to the buffer containing the actual data. */
} PaUtilRingBuffer; } PaUtilRingBuffer;
/** Initialize Ring Buffer. /** Initialize Ring Buffer to empty state ready to have elements written to it.
@param rbuf The ring buffer. @param rbuf The ring buffer.
@param elementSizeBytes The size of a single data element in bytes. @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 elementCount The number of elements in the buffer (must be a power of
2).
@param dataPtr A pointer to a previously allocated area where the data @param dataPtr A pointer to a previously allocated area where the data
will be maintained. It must be elementCount*elementSizeBytes long. will be maintained. It must be elementCount*elementSizeBytes long.
@return -1 if elementCount is not a power of 2, otherwise 0. @return -1 if elementCount is not a power of 2, otherwise 0.
*/ */
PaRingBufferSize PaUtil_InitializeRingBuffer(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_InitializeRingBuffer(
PaRingBufferSize elementSizeBytes, PaUtilRingBuffer* rbuf,
PaRingBufferSize elementCount, ring_buffer_size_t elementSizeBytes,
void* dataPtr); ring_buffer_size_t elementCount,
void* dataPtr);
/** Clear buffer. Should only be called when buffer is NOT being read. /** Reset buffer to empty. Should only be called when buffer is NOT being read
or written.
@param rbuf The ring buffer. @param rbuf The ring buffer.
*/ */
@ -128,7 +137,8 @@ void PaUtil_FlushRingBuffer(PaUtilRingBuffer* rbuf);
@return The number of elements available for writing. @return The number of elements available for writing.
*/ */
PaRingBufferSize PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer* rbuf); ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable(
const PaUtilRingBuffer* rbuf);
/** Retrieve the number of elements available in the ring buffer for reading. /** Retrieve the number of elements available in the ring buffer for reading.
@ -136,7 +146,8 @@ PaRingBufferSize PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer* rbuf);
@return The number of elements available for reading. @return The number of elements available for reading.
*/ */
PaRingBufferSize PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer* rbuf); ring_buffer_size_t PaUtil_GetRingBufferReadAvailable(
const PaUtilRingBuffer* rbuf);
/** Write data to the ring buffer. /** Write data to the ring buffer.
@ -148,9 +159,9 @@ PaRingBufferSize PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer* rbuf);
@return The number of elements written. @return The number of elements written.
*/ */
PaRingBufferSize PaUtil_WriteRingBuffer(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_WriteRingBuffer(PaUtilRingBuffer* rbuf,
const void* data, const void* data,
PaRingBufferSize elementCount); ring_buffer_size_t elementCount);
/** Read data from the ring buffer. /** Read data from the ring buffer.
@ -162,9 +173,9 @@ PaRingBufferSize PaUtil_WriteRingBuffer(PaUtilRingBuffer* rbuf,
@return The number of elements read. @return The number of elements read.
*/ */
PaRingBufferSize PaUtil_ReadRingBuffer(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_ReadRingBuffer(PaUtilRingBuffer* rbuf,
void* data, void* data,
PaRingBufferSize elementCount); ring_buffer_size_t elementCount);
/** Get address of region(s) to which we can write data. /** Get address of region(s) to which we can write data.
@ -186,12 +197,13 @@ PaRingBufferSize PaUtil_ReadRingBuffer(PaUtilRingBuffer* rbuf,
@return The room available to be written or elementCount, whichever is smaller. @return The room available to be written or elementCount, whichever is smaller.
*/ */
PaRingBufferSize PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_GetRingBufferWriteRegions(
PaRingBufferSize elementCount, PaUtilRingBuffer* rbuf,
void** dataPtr1, ring_buffer_size_t elementCount,
PaRingBufferSize* sizePtr1, void** dataPtr1,
void** dataPtr2, ring_buffer_size_t* sizePtr1,
PaRingBufferSize* sizePtr2); void** dataPtr2,
ring_buffer_size_t* sizePtr2);
/** Advance the write index to the next location to be written. /** Advance the write index to the next location to be written.
@ -201,11 +213,11 @@ PaRingBufferSize PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer* rbuf,
@return The new position. @return The new position.
*/ */
PaRingBufferSize PaUtil_AdvanceRingBufferWriteIndex( ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex(
PaUtilRingBuffer* rbuf, PaUtilRingBuffer* rbuf,
PaRingBufferSize elementCount); ring_buffer_size_t elementCount);
/** Get address of region(s) from which we can write data. /** Get address of region(s) from which we can read data.
@param rbuf The ring buffer. @param rbuf The ring buffer.
@ -225,12 +237,13 @@ PaRingBufferSize PaUtil_AdvanceRingBufferWriteIndex(
@return The number of elements available for reading. @return The number of elements available for reading.
*/ */
PaRingBufferSize PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer* rbuf, ring_buffer_size_t PaUtil_GetRingBufferReadRegions(
PaRingBufferSize elementCount, PaUtilRingBuffer* rbuf,
void** dataPtr1, ring_buffer_size_t elementCount,
PaRingBufferSize* sizePtr1, void** dataPtr1,
void** dataPtr2, ring_buffer_size_t* sizePtr1,
PaRingBufferSize* sizePtr2); void** dataPtr2,
ring_buffer_size_t* sizePtr2);
/** Advance the read index to the next location to be read. /** Advance the read index to the next location to be read.
@ -240,9 +253,9 @@ PaRingBufferSize PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer* rbuf,
@return The new position. @return The new position.
*/ */
PaRingBufferSize PaUtil_AdvanceRingBufferReadIndex( ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex(
PaUtilRingBuffer* rbuf, PaUtilRingBuffer* rbuf,
PaRingBufferSize elementCount); ring_buffer_size_t elementCount);
#ifdef __cplusplus #ifdef __cplusplus
} }