-/*\r
- * $Id: pablio.c,v 1.1.1.1.4.4 2003/03/13 17:28:33 philburk Exp $\r
- * pablio.c\r
- * Portable Audio Blocking Input/Output utility.\r
- *\r
- * Author: Phil Burk, http://www.softsynth.com\r
- *\r
- * This program uses the PortAudio Portable Audio Library.\r
- * For more information see: http://www.audiomulch.com/portaudio/\r
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files\r
- * (the "Software"), to deal in the Software without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Software,\r
- * and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * Any person wishing to distribute modifications to the Software is\r
- * requested to send the modifications to the original developer so that\r
- * they can be incorporated into the canonical version.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */ \r
- \r
-/* History:\r
- * PLB021214 - check for valid stream in CloseAudioStream() to prevent hang.\r
- * add timeOutMSec to CloseAudioStream() to prevent hang.\r
- */ \r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <math.h>\r
-#include "portaudio.h"\r
-#include "ringbuffer.h"\r
-#include "pablio.h"\r
-#include <string.h>\r
- \r
-/************************************************************************/ \r
-/******** Constants *****************************************************/ \r
-/************************************************************************/ \r
- \r
-#define FRAMES_PER_BUFFER (256)\r
- \r
-/************************************************************************/ \r
-/******** Prototypes ****************************************************/ \r
-/************************************************************************/ \r
-\rstatic int blockingIOCallback(void *inputBuffer, void *outputBuffer, \runsigned long framesPerBuffer,
- \rPaTimestamp outTime, void *userData);
-\rstatic PaError PABLIO_InitFIFO(RingBuffer * rbuf, long numFrames, long bytesPerFrame);
-\rstatic PaError PABLIO_TermFIFO(RingBuffer * rbuf);
-\r\r
-/************************************************************************/ \r
-/******** Functions *****************************************************/ \r
-/************************************************************************/ \r
- \r
-/* Called from PortAudio.\r
- * Read and write data only if there is room in FIFOs.\r
- */ \r
-static int blockingIOCallback(void *inputBuffer, void *outputBuffer, \runsigned long framesPerBuffer,
- \rPaTimestamp outTime, void *userData) \r
+/*
+ * $Id: pablio.c,v 1.1.1.1.4.4 2003/03/13 17:28:33 philburk Exp $
+ * pablio.c
+ * Portable Audio Blocking Input/Output utility.
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/* History:
+ * PLB021214 - check for valid stream in CloseAudioStream() to prevent hang.
+ * add timeOutMSec to CloseAudioStream() to prevent hang.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "portaudio.h"
+#include "ringbuffer.h"
+#include "pablio.h"
+#include <string.h>
+
+/************************************************************************/
+/******** Constants *****************************************************/
+/************************************************************************/
+
+#define FRAMES_PER_BUFFER (256)
+
+/************************************************************************/
+/******** 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);
+
+/************************************************************************/
+/******** Functions *****************************************************/
+/************************************************************************/
+
+/* 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)
{
- \rPABLIO_Stream * data = (PABLIO_Stream *) userData;
- \rlong numBytes = data->bytesPerFrame * framesPerBuffer;
- \r(void) outTime;
- \r\r
- /* This may get called with NULL inputBuffer during initial setup. */ \r
+ 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)
- \r {
- \rRingBuffer_Write(&data->inFIFO, inputBuffer, numBytes);
- \r}
- \rif (outputBuffer != NULL)
- \r {
- \rint i;
- \rint numRead = RingBuffer_Read(&data->outFIFO, outputBuffer, numBytes);
- \r
- /* Zero out remainder of buffer if we run out of data. */ \r
+ {
+ 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++)
- \r {
- \r((char *) outputBuffer)[i] = 0;
- \r} \r}
- \r\rreturn 0;
-\r}
+ {
+ ((char *) outputBuffer)[i] = 0;
+ } }
+ return 0;
+}
+
-\r\r
-/* Allocate buffer. */ \r
-static PaError PABLIO_InitFIFO(RingBuffer * rbuf, long numFrames, long bytesPerFrame) \r
+/* Allocate buffer. */
+static PaError PABLIO_InitFIFO(RingBuffer * rbuf, long numFrames, long bytesPerFrame)
{
- \rlong numBytes = numFrames * bytesPerFrame;
- \rchar *buffer = (char *) malloc(numBytes);
- \rif (buffer == NULL)
+ long numBytes = numFrames * bytesPerFrame;
+ char *buffer = (char *) malloc(numBytes);
+ if (buffer == NULL)
return paInsufficientMemory;
- \rmemset(buffer, 0, numBytes);
- \rreturn (PaError) RingBuffer_Init(rbuf, numBytes, buffer);
-\r}
+ memset(buffer, 0, numBytes);
+ return (PaError) RingBuffer_Init(rbuf, numBytes, buffer);
+}
+
-\r\r
-/* Free buffer. */ \r
-static PaError PABLIO_TermFIFO(RingBuffer * rbuf) \r
+/* Free buffer. */
+static PaError PABLIO_TermFIFO(RingBuffer * rbuf)
{
- \rif (rbuf->buffer)
+ if (rbuf->buffer)
free(rbuf->buffer);
- \rrbuf->buffer = NULL;
- \rreturn paNoError;
-\r}
+ rbuf->buffer = NULL;
+ return paNoError;
+}
-\r\r
-/************************************************************\r
- * Write data to ring buffer.\r
- * Will not return until all the data has been written.\r
- */ \r
-long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames) \r
+
+/************************************************************
+ * Write data to ring buffer.
+ * Will not return until all the data has been written.
+ */
+long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames)
{
- \rlong bytesWritten;
- \rchar *p = (char *) data;
- \rlong numBytes = aStream->bytesPerFrame * numFrames;
- \rwhile (numBytes > 0)
- \r {
- \rbytesWritten = RingBuffer_Write(&aStream->outFIFO, p, numBytes);
- \rnumBytes -= bytesWritten;
- \rp += bytesWritten;
- \rif (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);
- \r}
- \rreturn numFrames;
-\r}
+ }
+ return numFrames;
+}
+
-\r\r
-/************************************************************\r
- * Read data from ring buffer.\r
- * Will not return until all the data has been read.\r
- */ \r
-long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames) \r
+/************************************************************
+ * Read data from ring buffer.
+ * Will not return until all the data has been read.
+ */
+long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames)
{
- \rlong bytesRead;
- \rchar *p = (char *) data;
- \rlong numBytes = aStream->bytesPerFrame * numFrames;
- \rwhile (numBytes > 0)
- \r {
- \rbytesRead = RingBuffer_Read(&aStream->inFIFO, p, numBytes);
- \rnumBytes -= bytesRead;
- \rp += bytesRead;
- \rif (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);
- \r}
- \rreturn numFrames;
-\r}
+ }
+ return numFrames;
+}
+
-\r\r
-/************************************************************\r
- * Return the number of frames that could be written to the stream without\r
- * having to wait.\r
- */ \r
-long GetAudioStreamWriteable(PABLIO_Stream * aStream) \r
+/************************************************************
+ * Return the number of frames that could be written to the stream without
+ * having to wait.
+ */
+long GetAudioStreamWriteable(PABLIO_Stream * aStream)
{
- \rint bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
- \rreturn bytesEmpty / aStream->bytesPerFrame;
-\r}
+ int bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
+ return bytesEmpty / aStream->bytesPerFrame;
+}
-\r\r
-/************************************************************\r
- * Return the number of frames that are available to be read from the\r
- * stream without having to wait.\r
- */ \r
-long GetAudioStreamReadable(PABLIO_Stream * aStream) \r
+
+/************************************************************
+ * Return the number of frames that are available to be read from the
+ * stream without having to wait.
+ */
+long GetAudioStreamReadable(PABLIO_Stream * aStream)
{
- \rint bytesFull = RingBuffer_GetReadAvailable(&aStream->inFIFO);
- \rreturn bytesFull / aStream->bytesPerFrame;
-\r}
+ int bytesFull = RingBuffer_GetReadAvailable(&aStream->inFIFO);
+ return bytesFull / aStream->bytesPerFrame;
+}
+
-\r\r
-/************************************************************/ \r
-static unsigned long RoundUpToNextPowerOf2(unsigned long n) \r
+/************************************************************/
+static unsigned long RoundUpToNextPowerOf2(unsigned long n)
{
- \rlong numBits = 0;
- \rif (((n - 1) & n) == 0)
+ long numBits = 0;
+ if (((n - 1) & n) == 0)
return n; /* Already Power of two. */
- \rwhile (n > 0)
- \r {
- \rn = n >> 1;
- \rnumBits++;
- \r}
- \rreturn (1 << numBits);
-\r}
+ while (n > 0)
+ {
+ n = n >> 1;
+ numBits++;
+ }
+ return (1 << numBits);
+}
+
-\r\r
-/************************************************************\r
- * Opens a PortAudio stream with default characteristics.\r
- * Allocates PABLIO_Stream structure.\r
- *\r
- * flags parameter can be an ORed combination of:\r
- * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,\r
- * and either PABLIO_MONO or PABLIO_STEREO\r
- */ \r
- PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, double sampleRate, \rPaSampleFormat format, long flags, int indev,
- int outdev) \r
+/************************************************************
+ * Opens a PortAudio stream with default characteristics.
+ * Allocates PABLIO_Stream structure.
+ *
+ * flags parameter can be an ORed combination of:
+ * 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,
+ int outdev)
{
- \rlong bytesPerSample;
- \rlong doRead = 0;
- \rlong doWrite = 0;
- \rPaError err;
- \rPABLIO_Stream * aStream;
- \rlong minNumBuffers;
- \rlong numFrames;
- \r\r
- /* Allocate PABLIO_Stream structure for caller. */ \r
+ 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));
- \rif (aStream == NULL)
+ if (aStream == NULL)
return paInsufficientMemory;
- \rmemset(aStream, 0, sizeof(PABLIO_Stream));
- \r\r
- /* Determine size of a sample. */ \r
+ memset(aStream, 0, sizeof(PABLIO_Stream));
+
+ /* Determine size of a sample. */
bytesPerSample = Pa_GetSampleSize(format);
- \rif (bytesPerSample < 0)
- \r {
- \rerr = (PaError) bytesPerSample;
- \rgoto error;
- \r}
- \raStream->samplesPerFrame = ((flags & PABLIO_MONO) != 0) ? 1 : 2;
- \raStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;
- \r\r
- /* Initialize PortAudio */ \r
+ 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();
- \rif (err != paNoError)
+ if (err != paNoError)
goto error;
- \r\r
- /* Warning: numFrames must be larger than amount of data processed per interrupt\r
- * inside PA to prevent glitches. Just to be safe, adjust size upwards.\r
- */ \r
+
+ /* 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);
- \rnumFrames = minNumBuffers * FRAMES_PER_BUFFER;
- \r
- /* The PortAudio callback runs in a high priority thread. But PABLIO\r
- * runs in a normal foreground thread. So we may have much worse\r
- * latency in PABLIO. So adjust latency to a safe level.\r
- */ \r
+ 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.
+ */
{
- \rconst int safeLatencyMSec = 200;
- \rint minLatencyMSec = (int) ((1000 * numFrames) / sampleRate);
- \rif (minLatencyMSec < safeLatencyMSec)
- \r {
- \rnumFrames = (int) ((safeLatencyMSec * sampleRate) / 1000);
- \r}
- \r} \rnumFrames = RoundUpToNextPowerOf2(numFrames);
- \r\r
- /* Initialize Ring Buffers */ \r
+ 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);
- \rdoWrite = ((flags & PABLIO_WRITE) != 0);
- \rif (doRead)
- \r {
- \rerr = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
- \rif (err != paNoError)
+ doWrite = ((flags & PABLIO_WRITE) != 0);
+ if (doRead)
+ {
+ err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
+ if (err != paNoError)
goto error;
- \r}
- \rif (doWrite)
- \r {
- \rlong numBytes;
- \rerr = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
- \rif (err != paNoError)
+ }
+ if (doWrite)
+ {
+ long numBytes;
+ err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
+ if (err != paNoError)
goto error;
- \r
- /* Make Write FIFO appear full initially. */ \r
+
+ /* Make Write FIFO appear full initially. */
numBytes = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
- \rRingBuffer_AdvanceWriteIndex(&aStream->outFIFO, numBytes);
- \r}
- \r\r
- /* Open a PortAudio stream that we will use to communicate with the underlying\r
- * audio drivers. */ \r
- err = Pa_OpenStream(\r&aStream->stream, \r
- (doRead ? (indev > -1) ? indev : Pa_GetDefaultInputDeviceID() : paNoDevice), \r
- (doRead ? aStream->samplesPerFrame : 0), \rformat, \rNULL, \r
- (doWrite ? (outdev > -1) ? outdev : Pa_GetDefaultOutputDeviceID() : paNoDevice), \r
- (doWrite ? aStream->samplesPerFrame : 0), \rformat, \rNULL, \rsampleRate, \rFRAMES_PER_BUFFER,
- \rminNumBuffers, \rpaClipOff,
- /* we won't output out of range samples so don't bother clipping them */ \r
- blockingIOCallback, \raStream);
- \rif (err != paNoError)
+ 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,
+ (doRead ? (indev > -1) ? indev : Pa_GetDefaultInputDeviceID() : paNoDevice),
+ (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,
+ /* we won't output out of range samples so don't bother clipping them */
+ blockingIOCallback, aStream);
+ if (err != paNoError)
goto error;
- \r\rerr = Pa_StartStream(aStream->stream);
- \rif (err != paNoError)
+ err = Pa_StartStream(aStream->stream);
+ if (err != paNoError)
goto error;
- \r\r*rwblPtr = aStream;
- \rreturn paNoError;
- \r\rerror:\rCloseAudioStream(aStream);
- \r*rwblPtr = NULL;
- \rreturn err;
-\r}
+ *rwblPtr = aStream;
+ return paNoError;
+ error:CloseAudioStream(aStream);
+ *rwblPtr = NULL;
+ return err;
+}
+
-\r\r
-/************************************************************/ \r
- PaError CloseAudioStream(PABLIO_Stream * aStream) \r
+/************************************************************/
+ PaError CloseAudioStream(PABLIO_Stream * aStream)
{
- \rPaError err = paNoError;
- \rint bytesEmpty;
- \rint byteSize = aStream->outFIFO.bufferSize;
- \r\rif (aStream->stream != NULL) /* Make sure stream was opened. PLB021214 */
- \r {
- \r
- /* If we are writing data, make sure we play everything written. */ \r
+ 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)
- \r {
- \rint timeOutMSec = 2000;
- \rbytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
- \rwhile ((bytesEmpty < byteSize) && (timeOutMSec > 0))
- \r {
- \rPa_Sleep(20);
- \rtimeOutMSec -= 20;
- \rbytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO);
- \r}
- \r}
- \rerr = Pa_StopStream(aStream->stream);
- \rif (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;
- \rerr = Pa_CloseStream(aStream->stream);
- \r}
- \r\rerror:\rPa_Terminate();
- \rPABLIO_TermFIFO(&aStream->inFIFO);
- \rPABLIO_TermFIFO(&aStream->outFIFO);
- \rfree(aStream);
- \rreturn err;
-\r}
+ err = Pa_CloseStream(aStream->stream);
+ }
+ error:Pa_Terminate();
+ PABLIO_TermFIFO(&aStream->inFIFO);
+ PABLIO_TermFIFO(&aStream->outFIFO);
+ free(aStream);
+ return err;
+}
+
-\r
-#ifndef _PABLIO_H\r
-#define _PABLIO_H\r
-\r
-#ifdef __cplusplus\r
-extern "C"\r
-{\r
-#endif /* __cplusplus */\r
-\r
-/*\r
- * $Id: pablio.h,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $\r
- * PABLIO.h\r
- * Portable Audio Blocking read/write utility.\r
- *\r
- * Author: Phil Burk, http://www.softsynth.com/portaudio/\r
- *\r
- * Include file for PABLIO, the Portable Audio Blocking I/O Library.\r
- * PABLIO is built on top of PortAudio, the Portable Audio Library.\r
- * For more information see: http://www.audiomulch.com/portaudio/\r
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files\r
- * (the "Software"), to deal in the Software without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Software,\r
- * and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * Any person wishing to distribute modifications to the Software is\r
- * requested to send the modifications to the original developer so that\r
- * they can be incorporated into the canonical version.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <math.h>\r
-#include "portaudio.h"\r
-#include "ringbuffer.h"\r
-#include <string.h>\r
-\r
-typedef struct\r
-{\r
- RingBuffer inFIFO;\r
- RingBuffer outFIFO;\r
- PortAudioStream *stream;\r
- int bytesPerFrame;\r
- int samplesPerFrame;\r
-}\r
-PABLIO_Stream;\r
-\r
-/* Values for flags for OpenAudioStream(). */\r
-#define PABLIO_READ (1<<0)\r
-#define PABLIO_WRITE (1<<1)\r
-#define PABLIO_READ_WRITE (PABLIO_READ|PABLIO_WRITE)\r
-#define PABLIO_MONO (1<<2)\r
-#define PABLIO_STEREO (1<<3)\r
-\r
-/************************************************************\r
- * Write data to ring buffer.\r
- * Will not return until all the data has been written.\r
- */\r
-long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );\r
-\r
-/************************************************************\r
- * Read data from ring buffer.\r
- * Will not return until all the data has been read.\r
- */\r
-long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );\r
-\r
-/************************************************************\r
- * Return the number of frames that could be written to the stream without\r
- * having to wait.\r
- */\r
-long GetAudioStreamWriteable( PABLIO_Stream *aStream );\r
-\r
-/************************************************************\r
- * Return the number of frames that are available to be read from the\r
- * stream without having to wait.\r
- */\r
-long GetAudioStreamReadable( PABLIO_Stream *aStream );\r
-\r
-/************************************************************\r
- * Opens a PortAudio stream with default characteristics.\r
- * Allocates PABLIO_Stream structure.\r
- *\r
- * flags parameter can be an ORed combination of:\r
- * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,\r
- * and either PABLIO_MONO or PABLIO_STEREO\r
- */\r
-PaError OpenAudioStream( PABLIO_Stream **aStreamPtr, double sampleRate,\r
- PaSampleFormat format, long flags, int indev, int outdev );\r
-\r
-PaError CloseAudioStream( PABLIO_Stream *aStream );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif /* __cplusplus */\r
-#endif /* _PABLIO_H */\r
+#ifndef _PABLIO_H
+#define _PABLIO_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * $Id: pablio.h,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $
+ * PABLIO.h
+ * Portable Audio Blocking read/write utility.
+ *
+ * Author: Phil Burk, http://www.softsynth.com/portaudio/
+ *
+ * Include file for PABLIO, the Portable Audio Blocking I/O Library.
+ * PABLIO is built on top of PortAudio, the Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "portaudio.h"
+#include "ringbuffer.h"
+#include <string.h>
+
+typedef struct
+{
+ RingBuffer inFIFO;
+ RingBuffer outFIFO;
+ PortAudioStream *stream;
+ int bytesPerFrame;
+ int samplesPerFrame;
+}
+PABLIO_Stream;
+
+/* Values for flags for OpenAudioStream(). */
+#define PABLIO_READ (1<<0)
+#define PABLIO_WRITE (1<<1)
+#define PABLIO_READ_WRITE (PABLIO_READ|PABLIO_WRITE)
+#define PABLIO_MONO (1<<2)
+#define PABLIO_STEREO (1<<3)
+
+/************************************************************
+ * Write data to ring buffer.
+ * Will not return until all the data has been written.
+ */
+long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+
+/************************************************************
+ * Read data from ring buffer.
+ * Will not return until all the data has been read.
+ */
+long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+
+/************************************************************
+ * Return the number of frames that could be written to the stream without
+ * having to wait.
+ */
+long GetAudioStreamWriteable( PABLIO_Stream *aStream );
+
+/************************************************************
+ * Return the number of frames that are available to be read from the
+ * stream without having to wait.
+ */
+long GetAudioStreamReadable( PABLIO_Stream *aStream );
+
+/************************************************************
+ * Opens a PortAudio stream with default characteristics.
+ * Allocates PABLIO_Stream structure.
+ *
+ * flags parameter can be an ORed combination of:
+ * PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
+ * and either PABLIO_MONO or PABLIO_STEREO
+ */
+PaError OpenAudioStream( PABLIO_Stream **aStreamPtr, double sampleRate,
+ PaSampleFormat format, long flags, int indev, int outdev );
+
+PaError CloseAudioStream( PABLIO_Stream *aStream );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _PABLIO_H */
-/*\r
- * $Id: ringbuffer.c,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $\r
- * ringbuffer.c\r
- * Ring Buffer utility..\r
- *\r
- * Author: Phil Burk, http://www.softsynth.com\r
- *\r
- * This program uses the PortAudio Portable Audio Library.\r
- * For more information see: http://www.audiomulch.com/portaudio/\r
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files\r
- * (the "Software"), to deal in the Software without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Software,\r
- * and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * Any person wishing to distribute modifications to the Software is\r
- * requested to send the modifications to the original developer so that\r
- * they can be incorporated into the canonical version.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */ \r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <math.h>\r
-#include "ringbuffer.h"\r
-#include <string.h>\r
- \r
-/***************************************************************************\r
- * Initialize FIFO.\r
- * numBytes must be power of 2, returns -1 if not.\r
- */ \r
-long RingBuffer_Init(RingBuffer * rbuf, long numBytes, void *dataPtr) \r
+/*
+ * $Id: ringbuffer.c,v 1.1.1.1 2002/01/22 00:52:53 phil Exp $
+ * ringbuffer.c
+ * Ring Buffer utility..
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "ringbuffer.h"
+#include <string.h>
+
+/***************************************************************************
+ * Initialize FIFO.
+ * numBytes must be power of 2, returns -1 if not.
+ */
+long RingBuffer_Init(RingBuffer * rbuf, long numBytes, void *dataPtr)
{
- \rif (((numBytes - 1) & numBytes) != 0)
+ if (((numBytes - 1) & numBytes) != 0)
return -1; /* Not Power of two. */
- \rrbuf->bufferSize = numBytes;
- \rrbuf->buffer = (char *) dataPtr;
- \rRingBuffer_Flush(rbuf);
- \rrbuf->bigMask = (numBytes * 2) - 1;
- \rrbuf->smallMask = (numBytes) - 1;
- \rreturn 0;
-\r}
-
-\r
-/***************************************************************************\r
-** Return number of bytes available for reading. */ \r
-long RingBuffer_GetReadAvailable(RingBuffer * rbuf) \r
+ 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)
{
- \rreturn ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask);
-\r}
+ return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask);
+}
-\r
-/***************************************************************************\r
-** Return number of bytes available for writing. */ \r
-long RingBuffer_GetWriteAvailable(RingBuffer * rbuf) \r
+
+/***************************************************************************
+** Return number of bytes available for writing. */
+long RingBuffer_GetWriteAvailable(RingBuffer * rbuf)
{
- \rreturn (rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
-\r}
+ return (rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
+}
+
-\r\r
-/***************************************************************************\r
-** Clear buffer. Should only be called when buffer is NOT being read. */ \r
-void RingBuffer_Flush(RingBuffer * rbuf) \r
+/***************************************************************************
+** Clear buffer. Should only be called when buffer is NOT being read. */
+void RingBuffer_Flush(RingBuffer * rbuf)
{
- \rrbuf->writeIndex = rbuf->readIndex = 0;
-\r} \r\r
-
-/***************************************************************************\r
-** Get address of region(s) to which we can write data.\r
-** If the region is contiguous, size2 will be zero.\r
-** If non-contiguous, size2 will be the size of second region.\r
-** Returns room available to be written or numBytes, whichever is smaller.\r
-*/ \r
-long RingBuffer_GetWriteRegions(RingBuffer * rbuf, long numBytes, \rvoid **dataPtr1, long *sizePtr1, \rvoid **dataPtr2,
- long *sizePtr2) \r
+ rbuf->writeIndex = rbuf->readIndex = 0;
+}
+
+/***************************************************************************
+** Get address of region(s) to which we can write data.
+** If the region is contiguous, size2 will be zero.
+** 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 *sizePtr2)
{
- \rlong index;
- \rlong available = RingBuffer_GetWriteAvailable(rbuf);
- \rif (numBytes > available)
+ long index;
+ long available = RingBuffer_GetWriteAvailable(rbuf);
+ if (numBytes > available)
numBytes = available;
- \r
- /* Check to see if write is not contiguous. */ \r
+
+ /* Check to see if write is not contiguous. */
index = rbuf->writeIndex & rbuf->smallMask;
- \rif ((index + numBytes) > rbuf->bufferSize)
- \r {
- \r
- /* Write data in two blocks that wrap the buffer. */ \r
+ if ((index + numBytes) > rbuf->bufferSize)
+ {
+
+ /* Write data in two blocks that wrap the buffer. */
long firstHalf = rbuf->bufferSize - index;
- \r*dataPtr1 = &rbuf->buffer[index];
- \r*sizePtr1 = firstHalf;
- \r*dataPtr2 = &rbuf->buffer[0];
- \r*sizePtr2 = numBytes - firstHalf;
- \r}
- \r
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = firstHalf;
+ *dataPtr2 = &rbuf->buffer[0];
+ *sizePtr2 = numBytes - firstHalf;
+ }
+
else
- \r {
- \r*dataPtr1 = &rbuf->buffer[index];
- \r*sizePtr1 = numBytes;
- \r*dataPtr2 = NULL;
- \r*sizePtr2 = 0;
- \r}
- \rreturn numBytes;
-\r}
-
-\r\r\r
-/***************************************************************************\r
-*/ \r
-long RingBuffer_AdvanceWriteIndex(RingBuffer * rbuf, long numBytes) \r
+ {
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = numBytes;
+ *dataPtr2 = NULL;
+ *sizePtr2 = 0;
+ }
+ return numBytes;
+}
+
+
+/***************************************************************************
+*/
+long RingBuffer_AdvanceWriteIndex(RingBuffer * rbuf, long numBytes)
{
- \rreturn rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
-\r}
-
-\r\r
-/***************************************************************************\r
-** Get address of region(s) from which we can read data.\r
-** If the region is contiguous, size2 will be zero.\r
-** If non-contiguous, size2 will be the size of second region.\r
-** Returns room available to be written or numBytes, whichever is smaller.\r
-*/ \r
-long RingBuffer_GetReadRegions(RingBuffer * rbuf, long numBytes, \rvoid **dataPtr1, long *sizePtr1, \rvoid **dataPtr2,
- long *sizePtr2) \r
+ return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
+}
+
+
+/***************************************************************************
+** Get address of region(s) from which we can read data.
+** If the region is contiguous, size2 will be zero.
+** 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 *sizePtr2)
{
- \rlong index;
- \rlong available = RingBuffer_GetReadAvailable(rbuf);
- \rif (numBytes > available)
+ long index;
+ long available = RingBuffer_GetReadAvailable(rbuf);
+ if (numBytes > available)
numBytes = available;
- \r
- /* Check to see if read is not contiguous. */ \r
+
+ /* Check to see if read is not contiguous. */
index = rbuf->readIndex & rbuf->smallMask;
- \rif ((index + numBytes) > rbuf->bufferSize)
- \r {
- \r
- /* Write data in two blocks that wrap the buffer. */ \r
+ if ((index + numBytes) > rbuf->bufferSize)
+ {
+
+ /* Write data in two blocks that wrap the buffer. */
long firstHalf = rbuf->bufferSize - index;
- \r*dataPtr1 = &rbuf->buffer[index];
- \r*sizePtr1 = firstHalf;
- \r*dataPtr2 = &rbuf->buffer[0];
- \r*sizePtr2 = numBytes - firstHalf;
- \r}
- \r
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = firstHalf;
+ *dataPtr2 = &rbuf->buffer[0];
+ *sizePtr2 = numBytes - firstHalf;
+ }
+
else
- \r {
- \r*dataPtr1 = &rbuf->buffer[index];
- \r*sizePtr1 = numBytes;
- \r*dataPtr2 = NULL;
- \r*sizePtr2 = 0;
- \r}
- \rreturn numBytes;
-\r}
-
-\r
-/***************************************************************************\r
-*/ \r
-long RingBuffer_AdvanceReadIndex(RingBuffer * rbuf, long numBytes) \r
+ {
+ *dataPtr1 = &rbuf->buffer[index];
+ *sizePtr1 = numBytes;
+ *dataPtr2 = NULL;
+ *sizePtr2 = 0;
+ }
+ return numBytes;
+}
+
+
+/***************************************************************************
+*/
+long RingBuffer_AdvanceReadIndex(RingBuffer * rbuf, long numBytes)
{
- \rreturn rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
-\r}
+ return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
+}
+
-\r\r
-/***************************************************************************\r
-** Return bytes written. */ \r
-long RingBuffer_Write(RingBuffer * rbuf, void *data, long numBytes) \r
+/***************************************************************************
+** Return bytes written. */
+long RingBuffer_Write(RingBuffer * rbuf, void *data, long numBytes)
{
- \rlong size1, size2, numWritten;
- \rvoid *data1, *data2;
- \rnumWritten = RingBuffer_GetWriteRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
- \rif (size2 > 0)
- \r {
- \r\rmemcpy(data1, data, size1);
- \rdata = ((char *) data) + size1;
- \rmemcpy(data2, data, size2);
- \r}
- \r
+ 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
- \r {
- \rmemcpy(data1, data, size1);
- \r}
- \rRingBuffer_AdvanceWriteIndex(rbuf, numWritten);
- \rreturn numWritten;
-\r}
-
-\r\r
-/***************************************************************************\r
-** Return bytes read. */ \r
-long RingBuffer_Read(RingBuffer * rbuf, void *data, long numBytes) \r
+ {
+ memcpy(data1, data, size1);
+ }
+ RingBuffer_AdvanceWriteIndex(rbuf, numWritten);
+ return numWritten;
+}
+
+
+/***************************************************************************
+** Return bytes read. */
+long RingBuffer_Read(RingBuffer * rbuf, void *data, long numBytes)
{
- \rlong size1, size2, numRead;
- \rvoid *data1, *data2;
- \rnumRead = RingBuffer_GetReadRegions(rbuf, numBytes, &data1, &size1, &data2, &size2);
- \rif (size2 > 0)
- \r {
- \rmemcpy(data, data1, size1);
- \rdata = ((char *) data) + size1;
- \rmemcpy(data, data2, size2);
- \r}
- \r
+ 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
- \r {
- \rmemcpy(data, data1, size1);
- \r}
- \rRingBuffer_AdvanceReadIndex(rbuf, numRead);
- \rreturn numRead;
-\r}
-
-\r
+ {
+ memcpy(data, data1, size1);
+ }
+ RingBuffer_AdvanceReadIndex(rbuf, numRead);
+ return numRead;
+}
+
+
-#ifndef _RINGBUFFER_H\r
-#define _RINGBUFFER_H\r
-#ifdef __cplusplus\r
-extern "C"\r
-{\r
-#endif /* __cplusplus */\r
-\r
-/*\r
- * $Id: ringbuffer.h,v 1.1.1.1.4.2 2003/04/28 17:45:34 philburk Exp $\r
- * ringbuffer.h\r
- * Ring Buffer utility..\r
- *\r
- * Author: Phil Burk, http://www.softsynth.com\r
- *\r
- * This program is distributed with the PortAudio Portable Audio Library.\r
- * For more information see: http://www.audiomulch.com/portaudio/\r
- * Copyright (c) 1999-2000 Ross Bencina and Phil Burk\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining\r
- * a copy of this software and associated documentation files\r
- * (the "Software"), to deal in the Software without restriction,\r
- * including without limitation the rights to use, copy, modify, merge,\r
- * publish, distribute, sublicense, and/or sell copies of the Software,\r
- * and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be\r
- * included in all copies or substantial portions of the Software.\r
- *\r
- * Any person wishing to distribute modifications to the Software is\r
- * requested to send the modifications to the original developer so that\r
- * they can be incorporated into the canonical version.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
- * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- */\r
-#define PortAudioStream PaStream\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <math.h>\r
-#include "ringbuffer.h"\r
-#include <string.h>\r
-\r
-typedef struct\r
-{\r
- long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */\r
-/* These are declared volatile because they are written by a different thread than the reader. */\r
- volatile long writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */\r
- volatile long readIndex; /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */\r
- long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */\r
- long smallMask; /* Used for fitting indices to buffer. */\r
- char *buffer;\r
-}\r
-RingBuffer;\r
-/*\r
- * Initialize Ring Buffer.\r
- * numBytes must be power of 2, returns -1 if not.\r
- */\r
-long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr );\r
-\r
-/* Clear buffer. Should only be called when buffer is NOT being read. */\r
-void RingBuffer_Flush( RingBuffer *rbuf );\r
-\r
-/* Return number of bytes available for writing. */\r
-long RingBuffer_GetWriteAvailable( RingBuffer *rbuf );\r
-/* Return number of bytes available for read. */\r
-long RingBuffer_GetReadAvailable( RingBuffer *rbuf );\r
-/* Return bytes written. */\r
-long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes );\r
-/* Return bytes read. */\r
-long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes );\r
-\r
-/* Get address of region(s) to which we can write data.\r
-** If the region is contiguous, size2 will be zero.\r
-** If non-contiguous, size2 will be the size of second region.\r
-** Returns room available to be written or numBytes, whichever is smaller.\r
-*/\r
-long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,\r
- void **dataPtr1, long *sizePtr1,\r
- void **dataPtr2, long *sizePtr2 );\r
-long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes );\r
-\r
-/* Get address of region(s) from which we can read data.\r
-** If the region is contiguous, size2 will be zero.\r
-** If non-contiguous, size2 will be the size of second region.\r
-** Returns room available to be read or numBytes, whichever is smaller.\r
-*/\r
-long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,\r
- void **dataPtr1, long *sizePtr1,\r
- void **dataPtr2, long *sizePtr2 );\r
-\r
-long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes );\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif /* __cplusplus */\r
-#endif /* _RINGBUFFER_H */\r
+#ifndef _RINGBUFFER_H
+#define _RINGBUFFER_H
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * $Id: ringbuffer.h,v 1.1.1.1.4.2 2003/04/28 17:45:34 philburk Exp $
+ * ringbuffer.h
+ * Ring Buffer utility..
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ *
+ * This program is distributed with the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#define PortAudioStream PaStream
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "ringbuffer.h"
+#include <string.h>
+
+typedef struct
+{
+ long bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */
+/* These are declared volatile because they are written by a different thread than the reader. */
+ volatile long writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */
+ volatile long readIndex; /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */
+ long bigMask; /* Used for wrapping indices with extra bit to distinguish full/empty. */
+ long smallMask; /* Used for fitting indices to buffer. */
+ char *buffer;
+}
+RingBuffer;
+/*
+ * Initialize Ring Buffer.
+ * numBytes must be power of 2, returns -1 if not.
+ */
+long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr );
+
+/* Clear buffer. Should only be called when buffer is NOT being read. */
+void RingBuffer_Flush( RingBuffer *rbuf );
+
+/* Return number of bytes available for writing. */
+long RingBuffer_GetWriteAvailable( RingBuffer *rbuf );
+/* Return number of bytes available for read. */
+long RingBuffer_GetReadAvailable( RingBuffer *rbuf );
+/* Return bytes written. */
+long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes );
+/* Return bytes read. */
+long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes );
+
+/* Get address of region(s) to which we can write data.
+** If the region is contiguous, size2 will be zero.
+** 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 *sizePtr2 );
+long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes );
+
+/* Get address of region(s) from which we can read data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be read or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,
+ void **dataPtr1, long *sizePtr1,
+ void **dataPtr2, long *sizePtr2 );
+
+long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _RINGBUFFER_H */