dos2unix
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@968 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
0232f398c7
commit
df1f3209d9
|
@ -55,10 +55,10 @@
|
|||
/************************************************************************/
|
||||
/******** Prototypes ****************************************************/
|
||||
/************************************************************************/
|
||||
static int blockingIOCallback(void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
|
||||
PaTimestamp outTime, void *userData);
|
||||
static PaError PABLIO_InitFIFO(RingBuffer * rbuf, long numFrames, long bytesPerFrame);
|
||||
static PaError PABLIO_TermFIFO(RingBuffer * rbuf);
|
||||
static int blockingIOCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
|
||||
PaTimestamp outTime, void *userData);
|
||||
static PaError PABLIO_InitFIFO(RingBuffer * rbuf, long numFrames, long bytesPerFrame);
|
||||
static PaError PABLIO_TermFIFO(RingBuffer * rbuf);
|
||||
|
||||
/************************************************************************/
|
||||
/******** Functions *****************************************************/
|
||||
|
@ -67,52 +67,52 @@
|
|||
/* Called from PortAudio.
|
||||
* Read and write data only if there is room in FIFOs.
|
||||
*/
|
||||
static int blockingIOCallback(void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
|
||||
PaTimestamp outTime, void *userData)
|
||||
static int blockingIOCallback(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer,
|
||||
PaTimestamp outTime, void *userData)
|
||||
{
|
||||
PABLIO_Stream * data = (PABLIO_Stream *) userData;
|
||||
long numBytes = data->bytesPerFrame * framesPerBuffer;
|
||||
(void) outTime;
|
||||
PABLIO_Stream * data = (PABLIO_Stream *) userData;
|
||||
long numBytes = data->bytesPerFrame * framesPerBuffer;
|
||||
(void) outTime;
|
||||
|
||||
/* This may get called with NULL inputBuffer during initial setup. */
|
||||
if (inputBuffer != NULL)
|
||||
{
|
||||
RingBuffer_Write(&data->inFIFO, inputBuffer, numBytes);
|
||||
}
|
||||
if (outputBuffer != NULL)
|
||||
{
|
||||
int i;
|
||||
int numRead = RingBuffer_Read(&data->outFIFO, outputBuffer, numBytes);
|
||||
{
|
||||
RingBuffer_Write(&data->inFIFO, inputBuffer, numBytes);
|
||||
}
|
||||
if (outputBuffer != NULL)
|
||||
{
|
||||
int i;
|
||||
int numRead = RingBuffer_Read(&data->outFIFO, outputBuffer, numBytes);
|
||||
|
||||
/* Zero out remainder of buffer if we run out of data. */
|
||||
for (i = numRead; i < numBytes; i++)
|
||||
{
|
||||
((char *) outputBuffer)[i] = 0;
|
||||
}
}
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
((char *) outputBuffer)[i] = 0;
|
||||
} }
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate buffer. */
|
||||
static PaError PABLIO_InitFIFO(RingBuffer * rbuf, long numFrames, long bytesPerFrame)
|
||||
{
|
||||
long numBytes = numFrames * bytesPerFrame;
|
||||
char *buffer = (char *) malloc(numBytes);
|
||||
if (buffer == NULL)
|
||||
long numBytes = numFrames * bytesPerFrame;
|
||||
char *buffer = (char *) malloc(numBytes);
|
||||
if (buffer == NULL)
|
||||
return paInsufficientMemory;
|
||||
memset(buffer, 0, numBytes);
|
||||
return (PaError) RingBuffer_Init(rbuf, numBytes, buffer);
|
||||
}
|
||||
memset(buffer, 0, numBytes);
|
||||
return (PaError) RingBuffer_Init(rbuf, numBytes, buffer);
|
||||
}
|
||||
|
||||
|
||||
/* Free buffer. */
|
||||
static PaError PABLIO_TermFIFO(RingBuffer * rbuf)
|
||||
{
|
||||
if (rbuf->buffer)
|
||||
if (rbuf->buffer)
|
||||
free(rbuf->buffer);
|
||||
rbuf->buffer = NULL;
|
||||
return paNoError;
|
||||
}
|
||||
rbuf->buffer = NULL;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
|
@ -121,19 +121,19 @@ static PaError PABLIO_TermFIFO(RingBuffer * rbuf)
|
|||
*/
|
||||
long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames)
|
||||
{
|
||||
long bytesWritten;
|
||||
char *p = (char *) data;
|
||||
long numBytes = aStream->bytesPerFrame * numFrames;
|
||||
while (numBytes > 0)
|
||||
{
|
||||
bytesWritten = RingBuffer_Write(&aStream->outFIFO, p, numBytes);
|
||||
numBytes -= bytesWritten;
|
||||
p += bytesWritten;
|
||||
if (numBytes > 0)
|
||||
long bytesWritten;
|
||||
char *p = (char *) data;
|
||||
long numBytes = aStream->bytesPerFrame * numFrames;
|
||||
while (numBytes > 0)
|
||||
{
|
||||
bytesWritten = RingBuffer_Write(&aStream->outFIFO, p, numBytes);
|
||||
numBytes -= bytesWritten;
|
||||
p += bytesWritten;
|
||||
if (numBytes > 0)
|
||||
Pa_Sleep(10);
|
||||
}
|
||||
return numFrames;
|
||||
}
|
||||
}
|
||||
return numFrames;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
|
@ -142,19 +142,19 @@ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames)
|
|||
*/
|
||||
long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames)
|
||||
{
|
||||
long bytesRead;
|
||||
char *p = (char *) data;
|
||||
long numBytes = aStream->bytesPerFrame * numFrames;
|
||||
while (numBytes > 0)
|
||||
{
|
||||
bytesRead = RingBuffer_Read(&aStream->inFIFO, p, numBytes);
|
||||
numBytes -= bytesRead;
|
||||
p += bytesRead;
|
||||
if (numBytes > 0)
|
||||
long bytesRead;
|
||||
char *p = (char *) data;
|
||||
long numBytes = aStream->bytesPerFrame * numFrames;
|
||||
while (numBytes > 0)
|
||||
{
|
||||
bytesRead = RingBuffer_Read(&aStream->inFIFO, p, numBytes);
|
||||
numBytes -= bytesRead;
|
||||
p += bytesRead;
|
||||
if (numBytes > 0)
|
||||
Pa_Sleep(10);
|
||||
}
|
||||
return numFrames;
|
||||
}
|
||||
}
|
||||
return numFrames;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
|
@ -163,9 +163,9 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames)
|
|||
*/
|
||||
long GetAudioStreamWriteable(PABLIO_Stream * aStream)
|
||||
{
|
||||
int bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
|
||||
return bytesEmpty / aStream->bytesPerFrame;
|
||||
}
|
||||
int bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
|
||||
return bytesEmpty / aStream->bytesPerFrame;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
|
@ -174,24 +174,24 @@ long GetAudioStreamWriteable(PABLIO_Stream * aStream)
|
|||
*/
|
||||
long GetAudioStreamReadable(PABLIO_Stream * aStream)
|
||||
{
|
||||
int bytesFull = RingBuffer_GetReadAvailable(&aStream->inFIFO);
|
||||
return bytesFull / aStream->bytesPerFrame;
|
||||
}
|
||||
int bytesFull = RingBuffer_GetReadAvailable(&aStream->inFIFO);
|
||||
return bytesFull / aStream->bytesPerFrame;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************/
|
||||
static unsigned long RoundUpToNextPowerOf2(unsigned long n)
|
||||
{
|
||||
long numBits = 0;
|
||||
if (((n - 1) & n) == 0)
|
||||
long numBits = 0;
|
||||
if (((n - 1) & n) == 0)
|
||||
return n; /* Already Power of two. */
|
||||
while (n > 0)
|
||||
{
|
||||
n = n >> 1;
|
||||
numBits++;
|
||||
}
|
||||
return (1 << numBits);
|
||||
}
|
||||
while (n > 0)
|
||||
{
|
||||
n = n >> 1;
|
||||
numBits++;
|
||||
}
|
||||
return (1 << numBits);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
|
@ -202,132 +202,132 @@ static unsigned long RoundUpToNextPowerOf2(unsigned long n)
|
|||
* PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
|
||||
* and either PABLIO_MONO or PABLIO_STEREO
|
||||
*/
|
||||
PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, double sampleRate,
PaSampleFormat format, long flags, int indev,
|
||||
PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, double sampleRate, PaSampleFormat format, long flags, int indev,
|
||||
int outdev)
|
||||
{
|
||||
long bytesPerSample;
|
||||
long doRead = 0;
|
||||
long doWrite = 0;
|
||||
PaError err;
|
||||
PABLIO_Stream * aStream;
|
||||
long minNumBuffers;
|
||||
long numFrames;
|
||||
long bytesPerSample;
|
||||
long doRead = 0;
|
||||
long doWrite = 0;
|
||||
PaError err;
|
||||
PABLIO_Stream * aStream;
|
||||
long minNumBuffers;
|
||||
long numFrames;
|
||||
|
||||
/* Allocate PABLIO_Stream structure for caller. */
|
||||
aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream));
|
||||
if (aStream == NULL)
|
||||
if (aStream == NULL)
|
||||
return paInsufficientMemory;
|
||||
memset(aStream, 0, sizeof(PABLIO_Stream));
|
||||
memset(aStream, 0, sizeof(PABLIO_Stream));
|
||||
|
||||
/* Determine size of a sample. */
|
||||
bytesPerSample = Pa_GetSampleSize(format);
|
||||
if (bytesPerSample < 0)
|
||||
{
|
||||
err = (PaError) bytesPerSample;
|
||||
goto error;
|
||||
}
|
||||
aStream->samplesPerFrame = ((flags & PABLIO_MONO) != 0) ? 1 : 2;
|
||||
aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;
|
||||
if (bytesPerSample < 0)
|
||||
{
|
||||
err = (PaError) bytesPerSample;
|
||||
goto error;
|
||||
}
|
||||
aStream->samplesPerFrame = ((flags & PABLIO_MONO) != 0) ? 1 : 2;
|
||||
aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;
|
||||
|
||||
/* Initialize PortAudio */
|
||||
err = Pa_Initialize();
|
||||
if (err != paNoError)
|
||||
if (err != paNoError)
|
||||
goto error;
|
||||
|
||||
/* Warning: numFrames must be larger than amount of data processed per interrupt
|
||||
* inside PA to prevent glitches. Just to be safe, adjust size upwards.
|
||||
*/
|
||||
minNumBuffers = 2 * Pa_GetMinNumBuffers(FRAMES_PER_BUFFER, sampleRate);
|
||||
numFrames = minNumBuffers * FRAMES_PER_BUFFER;
|
||||
numFrames = minNumBuffers * FRAMES_PER_BUFFER;
|
||||
|
||||
/* The PortAudio callback runs in a high priority thread. But PABLIO
|
||||
* runs in a normal foreground thread. So we may have much worse
|
||||
* latency in PABLIO. So adjust latency to a safe level.
|
||||
*/
|
||||
{
|
||||
const int safeLatencyMSec = 200;
|
||||
int minLatencyMSec = (int) ((1000 * numFrames) / sampleRate);
|
||||
if (minLatencyMSec < safeLatencyMSec)
|
||||
{
|
||||
numFrames = (int) ((safeLatencyMSec * sampleRate) / 1000);
|
||||
}
|
||||
}
numFrames = RoundUpToNextPowerOf2(numFrames);
|
||||
const int safeLatencyMSec = 200;
|
||||
int minLatencyMSec = (int) ((1000 * numFrames) / sampleRate);
|
||||
if (minLatencyMSec < safeLatencyMSec)
|
||||
{
|
||||
numFrames = (int) ((safeLatencyMSec * sampleRate) / 1000);
|
||||
}
|
||||
} numFrames = RoundUpToNextPowerOf2(numFrames);
|
||||
|
||||
/* Initialize Ring Buffers */
|
||||
doRead = ((flags & PABLIO_READ) != 0);
|
||||
doWrite = ((flags & PABLIO_WRITE) != 0);
|
||||
if (doRead)
|
||||
{
|
||||
err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
|
||||
if (err != paNoError)
|
||||
doWrite = ((flags & PABLIO_WRITE) != 0);
|
||||
if (doRead)
|
||||
{
|
||||
err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
|
||||
if (err != paNoError)
|
||||
goto error;
|
||||
}
|
||||
if (doWrite)
|
||||
{
|
||||
long numBytes;
|
||||
err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
|
||||
if (err != paNoError)
|
||||
}
|
||||
if (doWrite)
|
||||
{
|
||||
long numBytes;
|
||||
err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
|
||||
if (err != paNoError)
|
||||
goto error;
|
||||
|
||||
/* Make Write FIFO appear full initially. */
|
||||
numBytes = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
|
||||
RingBuffer_AdvanceWriteIndex(&aStream->outFIFO, numBytes);
|
||||
}
|
||||
RingBuffer_AdvanceWriteIndex(&aStream->outFIFO, numBytes);
|
||||
}
|
||||
|
||||
/* Open a PortAudio stream that we will use to communicate with the underlying
|
||||
* audio drivers. */
|
||||
err = Pa_OpenStream(
&aStream->stream,
|
||||
err = Pa_OpenStream(&aStream->stream,
|
||||
(doRead ? (indev > -1) ? indev : Pa_GetDefaultInputDeviceID() : paNoDevice),
|
||||
(doRead ? aStream->samplesPerFrame : 0),
format,
NULL,
|
||||
(doRead ? aStream->samplesPerFrame : 0), format, NULL,
|
||||
(doWrite ? (outdev > -1) ? outdev : Pa_GetDefaultOutputDeviceID() : paNoDevice),
|
||||
(doWrite ? aStream->samplesPerFrame : 0),
format,
NULL,
sampleRate,
FRAMES_PER_BUFFER,
|
||||
minNumBuffers,
paClipOff,
|
||||
(doWrite ? aStream->samplesPerFrame : 0), format, NULL, sampleRate, FRAMES_PER_BUFFER,
|
||||
minNumBuffers, paClipOff,
|
||||
/* we won't output out of range samples so don't bother clipping them */
|
||||
blockingIOCallback,
aStream);
|
||||
if (err != paNoError)
|
||||
blockingIOCallback, aStream);
|
||||
if (err != paNoError)
|
||||
goto error;
|
||||
err = Pa_StartStream(aStream->stream);
|
||||
if (err != paNoError)
|
||||
err = Pa_StartStream(aStream->stream);
|
||||
if (err != paNoError)
|
||||
goto error;
|
||||
*rwblPtr = aStream;
|
||||
return paNoError;
|
||||
error:
CloseAudioStream(aStream);
|
||||
*rwblPtr = NULL;
|
||||
return err;
|
||||
}
|
||||
*rwblPtr = aStream;
|
||||
return paNoError;
|
||||
error:CloseAudioStream(aStream);
|
||||
*rwblPtr = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************/
|
||||
PaError CloseAudioStream(PABLIO_Stream * aStream)
|
||||
{
|
||||
PaError err = paNoError;
|
||||
int bytesEmpty;
|
||||
int byteSize = aStream->outFIFO.bufferSize;
|
||||
if (aStream->stream != NULL) /* Make sure stream was opened. PLB021214 */
|
||||
{
|
||||
PaError err = paNoError;
|
||||
int bytesEmpty;
|
||||
int byteSize = aStream->outFIFO.bufferSize;
|
||||
if (aStream->stream != NULL) /* Make sure stream was opened. PLB021214 */
|
||||
{
|
||||
|
||||
/* If we are writing data, make sure we play everything written. */
|
||||
if (byteSize > 0)
|
||||
{
|
||||
int timeOutMSec = 2000;
|
||||
bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
|
||||
while ((bytesEmpty < byteSize) && (timeOutMSec > 0))
|
||||
{
|
||||
Pa_Sleep(20);
|
||||
timeOutMSec -= 20;
|
||||
bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
|
||||
}
|
||||
}
|
||||
err = Pa_StopStream(aStream->stream);
|
||||
if (err != paNoError)
|
||||
{
|
||||
int timeOutMSec = 2000;
|
||||
bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
|
||||
while ((bytesEmpty < byteSize) && (timeOutMSec > 0))
|
||||
{
|
||||
Pa_Sleep(20);
|
||||
timeOutMSec -= 20;
|
||||
bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
|
||||
}
|
||||
}
|
||||
err = Pa_StopStream(aStream->stream);
|
||||
if (err != paNoError)
|
||||
goto error;
|
||||
err = Pa_CloseStream(aStream->stream);
|
||||
}
|
||||
error:
Pa_Terminate();
|
||||
PABLIO_TermFIFO(&aStream->inFIFO);
|
||||
PABLIO_TermFIFO(&aStream->outFIFO);
|
||||
free(aStream);
|
||||
return err;
|
||||
}
|
||||
err = Pa_CloseStream(aStream->stream);
|
||||
}
|
||||
error:Pa_Terminate();
|
||||
PABLIO_TermFIFO(&aStream->inFIFO);
|
||||
PABLIO_TermFIFO(&aStream->outFIFO);
|
||||
free(aStream);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,39 +45,39 @@
|
|||
*/
|
||||
long RingBuffer_Init(RingBuffer * rbuf, long numBytes, void *dataPtr)
|
||||
{
|
||||
if (((numBytes - 1) & numBytes) != 0)
|
||||
if (((numBytes - 1) & numBytes) != 0)
|
||||
return -1; /* Not Power of two. */
|
||||
rbuf->bufferSize = numBytes;
|
||||
rbuf->buffer = (char *) dataPtr;
|
||||
RingBuffer_Flush(rbuf);
|
||||
rbuf->bigMask = (numBytes * 2) - 1;
|
||||
rbuf->smallMask = (numBytes) - 1;
|
||||
return 0;
|
||||
}
|
||||
rbuf->bufferSize = numBytes;
|
||||
rbuf->buffer = (char *) dataPtr;
|
||||
RingBuffer_Flush(rbuf);
|
||||
rbuf->bigMask = (numBytes * 2) - 1;
|
||||
rbuf->smallMask = (numBytes) - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** Return number of bytes available for reading. */
|
||||
long RingBuffer_GetReadAvailable(RingBuffer * rbuf)
|
||||
{
|
||||
return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask);
|
||||
}
|
||||
return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** Return number of bytes available for writing. */
|
||||
long RingBuffer_GetWriteAvailable(RingBuffer * rbuf)
|
||||
{
|
||||
return (rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
|
||||
}
|
||||
return (rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** Clear buffer. Should only be called when buffer is NOT being read. */
|
||||
void RingBuffer_Flush(RingBuffer * rbuf)
|
||||
{
|
||||
rbuf->writeIndex = rbuf->readIndex = 0;
|
||||
}
|
||||
rbuf->writeIndex = rbuf->readIndex = 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
** Get address of region(s) to which we can write data.
|
||||
|
@ -85,44 +85,44 @@ void RingBuffer_Flush(RingBuffer * rbuf)
|
|||
** If non-contiguous, size2 will be the size of second region.
|
||||
** Returns room available to be written or numBytes, whichever is smaller.
|
||||
*/
|
||||
long RingBuffer_GetWriteRegions(RingBuffer * rbuf, long numBytes,
void **dataPtr1, long *sizePtr1,
void **dataPtr2,
|
||||
long RingBuffer_GetWriteRegions(RingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2,
|
||||
long *sizePtr2)
|
||||
{
|
||||
long index;
|
||||
long available = RingBuffer_GetWriteAvailable(rbuf);
|
||||
if (numBytes > available)
|
||||
long index;
|
||||
long available = RingBuffer_GetWriteAvailable(rbuf);
|
||||
if (numBytes > available)
|
||||
numBytes = available;
|
||||
|
||||
/* Check to see if write is not contiguous. */
|
||||
index = rbuf->writeIndex & rbuf->smallMask;
|
||||
if ((index + numBytes) > rbuf->bufferSize)
|
||||
{
|
||||
if ((index + numBytes) > rbuf->bufferSize)
|
||||
{
|
||||
|
||||
/* Write data in two blocks that wrap the buffer. */
|
||||
long firstHalf = rbuf->bufferSize - index;
|
||||
*dataPtr1 = &rbuf->buffer[index];
|
||||
*sizePtr1 = firstHalf;
|
||||
*dataPtr2 = &rbuf->buffer[0];
|
||||
*sizePtr2 = numBytes - firstHalf;
|
||||
}
|
||||
*dataPtr1 = &rbuf->buffer[index];
|
||||
*sizePtr1 = firstHalf;
|
||||
*dataPtr2 = &rbuf->buffer[0];
|
||||
*sizePtr2 = numBytes - firstHalf;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
*dataPtr1 = &rbuf->buffer[index];
|
||||
*sizePtr1 = numBytes;
|
||||
*dataPtr2 = NULL;
|
||||
*sizePtr2 = 0;
|
||||
}
|
||||
return numBytes;
|
||||
}
|
||||
{
|
||||
*dataPtr1 = &rbuf->buffer[index];
|
||||
*sizePtr1 = numBytes;
|
||||
*dataPtr2 = NULL;
|
||||
*sizePtr2 = 0;
|
||||
}
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*/
|
||||
long RingBuffer_AdvanceWriteIndex(RingBuffer * rbuf, long numBytes)
|
||||
{
|
||||
return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
|
||||
}
|
||||
return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -131,89 +131,89 @@ long RingBuffer_AdvanceWriteIndex(RingBuffer * rbuf, long numBytes)
|
|||
** If non-contiguous, size2 will be the size of second region.
|
||||
** Returns room available to be written or numBytes, whichever is smaller.
|
||||
*/
|
||||
long RingBuffer_GetReadRegions(RingBuffer * rbuf, long numBytes,
void **dataPtr1, long *sizePtr1,
void **dataPtr2,
|
||||
long RingBuffer_GetReadRegions(RingBuffer * rbuf, long numBytes, void **dataPtr1, long *sizePtr1, void **dataPtr2,
|
||||
long *sizePtr2)
|
||||
{
|
||||
long index;
|
||||
long available = RingBuffer_GetReadAvailable(rbuf);
|
||||
if (numBytes > available)
|
||||
long index;
|
||||
long available = RingBuffer_GetReadAvailable(rbuf);
|
||||
if (numBytes > available)
|
||||
numBytes = available;
|
||||
|
||||
/* Check to see if read is not contiguous. */
|
||||
index = rbuf->readIndex & rbuf->smallMask;
|
||||
if ((index + numBytes) > rbuf->bufferSize)
|
||||
{
|
||||
if ((index + numBytes) > rbuf->bufferSize)
|
||||
{
|
||||
|
||||
/* Write data in two blocks that wrap the buffer. */
|
||||
long firstHalf = rbuf->bufferSize - index;
|
||||
*dataPtr1 = &rbuf->buffer[index];
|
||||
*sizePtr1 = firstHalf;
|
||||
*dataPtr2 = &rbuf->buffer[0];
|
||||
*sizePtr2 = numBytes - firstHalf;
|
||||
}
|
||||
*dataPtr1 = &rbuf->buffer[index];
|
||||
*sizePtr1 = firstHalf;
|
||||
*dataPtr2 = &rbuf->buffer[0];
|
||||
*sizePtr2 = numBytes - firstHalf;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
*dataPtr1 = &rbuf->buffer[index];
|
||||
*sizePtr1 = numBytes;
|
||||
*dataPtr2 = NULL;
|
||||
*sizePtr2 = 0;
|
||||
}
|
||||
return numBytes;
|
||||
}
|
||||
{
|
||||
*dataPtr1 = &rbuf->buffer[index];
|
||||
*sizePtr1 = numBytes;
|
||||
*dataPtr2 = NULL;
|
||||
*sizePtr2 = 0;
|
||||
}
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*/
|
||||
long RingBuffer_AdvanceReadIndex(RingBuffer * rbuf, long numBytes)
|
||||
{
|
||||
return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
|
||||
}
|
||||
return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** Return bytes written. */
|
||||
long RingBuffer_Write(RingBuffer * rbuf, void *data, long numBytes)
|
||||
{
|
||||
long size1, size2, numWritten;
|
||||
void *data1, *data2;
|
||||
numWritten = RingBuffer_GetWriteRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
|
||||
if (size2 > 0)
|
||||
{
|
||||
memcpy(data1, data, size1);
|
||||
data = ((char *) data) + size1;
|
||||
memcpy(data2, data, size2);
|
||||
}
|
||||
long size1, size2, numWritten;
|
||||
void *data1, *data2;
|
||||
numWritten = RingBuffer_GetWriteRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
|
||||
if (size2 > 0)
|
||||
{
|
||||
memcpy(data1, data, size1);
|
||||
data = ((char *) data) + size1;
|
||||
memcpy(data2, data, size2);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
memcpy(data1, data, size1);
|
||||
}
|
||||
RingBuffer_AdvanceWriteIndex(rbuf, numWritten);
|
||||
return numWritten;
|
||||
}
|
||||
{
|
||||
memcpy(data1, data, size1);
|
||||
}
|
||||
RingBuffer_AdvanceWriteIndex(rbuf, numWritten);
|
||||
return numWritten;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** Return bytes read. */
|
||||
long RingBuffer_Read(RingBuffer * rbuf, void *data, long numBytes)
|
||||
{
|
||||
long size1, size2, numRead;
|
||||
void *data1, *data2;
|
||||
numRead = RingBuffer_GetReadRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
|
||||
if (size2 > 0)
|
||||
{
|
||||
memcpy(data, data1, size1);
|
||||
data = ((char *) data) + size1;
|
||||
memcpy(data, data2, size2);
|
||||
}
|
||||
long size1, size2, numRead;
|
||||
void *data1, *data2;
|
||||
numRead = RingBuffer_GetReadRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
|
||||
if (size2 > 0)
|
||||
{
|
||||
memcpy(data, data1, size1);
|
||||
data = ((char *) data) + size1;
|
||||
memcpy(data, data2, size2);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
memcpy(data, data1, size1);
|
||||
}
|
||||
RingBuffer_AdvanceReadIndex(rbuf, numRead);
|
||||
return numRead;
|
||||
}
|
||||
{
|
||||
memcpy(data, data1, size1);
|
||||
}
|
||||
RingBuffer_AdvanceReadIndex(rbuf, numRead);
|
||||
return numRead;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue