From df1f3209d931db3178ed9ef960cb1228ad3ef1c6 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 30 Mar 2006 01:37:57 +0000 Subject: [PATCH] dos2unix git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@968 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/endpoints/mod_portaudio/pablio.c | 584 +++++++++---------- src/mod/endpoints/mod_portaudio/pablio.h | 218 +++---- src/mod/endpoints/mod_portaudio/ringbuffer.c | 384 ++++++------ src/mod/endpoints/mod_portaudio/ringbuffer.h | 206 +++---- 4 files changed, 696 insertions(+), 696 deletions(-) diff --git a/src/mod/endpoints/mod_portaudio/pablio.c b/src/mod/endpoints/mod_portaudio/pablio.c index b393aeacf1..d7008ce5e3 100644 --- a/src/mod/endpoints/mod_portaudio/pablio.c +++ b/src/mod/endpoints/mod_portaudio/pablio.c @@ -1,333 +1,333 @@ -/* - * $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 -#include -#include -#include "portaudio.h" -#include "ringbuffer.h" -#include "pablio.h" -#include - -/************************************************************************/ -/******** 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) +/* + * $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 +#include +#include +#include "portaudio.h" +#include "ringbuffer.h" +#include "pablio.h" +#include + +/************************************************************************/ +/******** 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) { - PABLIO_Stream * data = (PABLIO_Stream *) userData; - long numBytes = data->bytesPerFrame * framesPerBuffer; - (void) outTime; - - /* This may get called with NULL inputBuffer during initial setup. */ + 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); - - /* Zero out remainder of buffer if we run out of data. */ + { + 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) + +/* 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) + +/* 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; +} - -/************************************************************ - * Write data to ring buffer. - * Will not return until all the data has been written. - */ -long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames) + +/************************************************************ + * Write data to ring buffer. + * Will not return until all the data has been written. + */ +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; +} - -/************************************************************ - * Read data from ring buffer. - * Will not return until all the data has been read. - */ -long ReadAudioStream(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) { - 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; +} - -/************************************************************ - * Return the number of frames that could be written to the stream without - * having to wait. - */ -long GetAudioStreamWriteable(PABLIO_Stream * aStream) -{ - int bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO); - return bytesEmpty / aStream->bytesPerFrame; - } - -/************************************************************ - * Return the number of frames that are available to be read from the - * stream without having to wait. - */ -long GetAudioStreamReadable(PABLIO_Stream * aStream) +/************************************************************ + * Return the number of frames that could be written to the stream without + * having to wait. + */ +long GetAudioStreamWriteable(PABLIO_Stream * aStream) { - int bytesFull = RingBuffer_GetReadAvailable(&aStream->inFIFO); - return bytesFull / aStream->bytesPerFrame; - } + int bytesEmpty = RingBuffer_GetWriteAvailable(&aStream->outFIFO); + return bytesEmpty / aStream->bytesPerFrame; +} - -/************************************************************/ -static unsigned long RoundUpToNextPowerOf2(unsigned long n) + +/************************************************************ + * Return the number of frames that are available to be read from the + * stream without having to wait. + */ +long GetAudioStreamReadable(PABLIO_Stream * aStream) { - long numBits = 0; - if (((n - 1) & n) == 0) + 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) 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); +} - -/************************************************************ - * 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) + +/************************************************************ + * 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) { - long bytesPerSample; - long doRead = 0; - long doWrite = 0; - PaError err; - PABLIO_Stream * aStream; - long minNumBuffers; - long numFrames; - - /* Allocate PABLIO_Stream structure for caller. */ + 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)); - - /* Determine size of a sample. */ + 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; - - /* Initialize PortAudio */ + 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. - */ + + /* 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; - - /* 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. - */ + 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); - - /* Initialize Ring Buffers */ + 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. */ + + /* Make Write FIFO appear full initially. */ numBytes = RingBuffer_GetWriteAvailable(&aStream->outFIFO); - 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) + 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; - 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 CloseAudioStream(PABLIO_Stream * aStream) { - 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. */ + 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; +} + - diff --git a/src/mod/endpoints/mod_portaudio/pablio.h b/src/mod/endpoints/mod_portaudio/pablio.h index 25bccf8998..609c88da5b 100644 --- a/src/mod/endpoints/mod_portaudio/pablio.h +++ b/src/mod/endpoints/mod_portaudio/pablio.h @@ -1,109 +1,109 @@ -#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 -#include -#include -#include "portaudio.h" -#include "ringbuffer.h" -#include - -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 */ +#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 +#include +#include +#include "portaudio.h" +#include "ringbuffer.h" +#include + +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 */ diff --git a/src/mod/endpoints/mod_portaudio/ringbuffer.c b/src/mod/endpoints/mod_portaudio/ringbuffer.c index fc9b495d17..36d06a49d7 100644 --- a/src/mod/endpoints/mod_portaudio/ringbuffer.c +++ b/src/mod/endpoints/mod_portaudio/ringbuffer.c @@ -1,219 +1,219 @@ -/* - * $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 -#include -#include -#include "ringbuffer.h" -#include - -/*************************************************************************** - * Initialize FIFO. - * numBytes must be power of 2, returns -1 if not. - */ -long RingBuffer_Init(RingBuffer * rbuf, long numBytes, void *dataPtr) +/* + * $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 +#include +#include +#include "ringbuffer.h" +#include + +/*************************************************************************** + * Initialize FIFO. + * numBytes must be power of 2, returns -1 if not. + */ +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 number of bytes available for writing. */ -long RingBuffer_GetWriteAvailable(RingBuffer * rbuf) +/*************************************************************************** +** Return number of bytes available for reading. */ +long RingBuffer_GetReadAvailable(RingBuffer * rbuf) { - return (rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf)); - } + return ((rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask); +} - -/*************************************************************************** -** Clear buffer. Should only be called when buffer is NOT being read. */ -void RingBuffer_Flush(RingBuffer * rbuf) -{ - 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) +/*************************************************************************** +** Return number of bytes available for writing. */ +long RingBuffer_GetWriteAvailable(RingBuffer * rbuf) { - long index; - long available = RingBuffer_GetWriteAvailable(rbuf); - if (numBytes > available) + 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; +} + +/*************************************************************************** +** 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 index; + long available = RingBuffer_GetWriteAvailable(rbuf); + if (numBytes > available) numBytes = available; - - /* Check to see if write is not contiguous. */ + + /* Check to see if write is not contiguous. */ index = rbuf->writeIndex & rbuf->smallMask; - if ((index + numBytes) > rbuf->bufferSize) - { - - /* Write data in two blocks that wrap the buffer. */ + 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; - } - -/*************************************************************************** -** 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) +/*************************************************************************** +*/ +long RingBuffer_AdvanceWriteIndex(RingBuffer * rbuf, long numBytes) { - long index; - long available = RingBuffer_GetReadAvailable(rbuf); - if (numBytes > available) + 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) +{ + long index; + long available = RingBuffer_GetReadAvailable(rbuf); + if (numBytes > available) numBytes = available; - - /* Check to see if read is not contiguous. */ + + /* Check to see if read is not contiguous. */ index = rbuf->readIndex & rbuf->smallMask; - if ((index + numBytes) > rbuf->bufferSize) - { - - /* Write data in two blocks that wrap the buffer. */ + 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 bytes written. */ -long RingBuffer_Write(RingBuffer * rbuf, void *data, long numBytes) +/*************************************************************************** +*/ +long RingBuffer_AdvanceReadIndex(RingBuffer * rbuf, 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); - } - + 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); + } + 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) + +/*************************************************************************** +** 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; +} + - diff --git a/src/mod/endpoints/mod_portaudio/ringbuffer.h b/src/mod/endpoints/mod_portaudio/ringbuffer.h index 3cd559488b..556aae24da 100644 --- a/src/mod/endpoints/mod_portaudio/ringbuffer.h +++ b/src/mod/endpoints/mod_portaudio/ringbuffer.h @@ -1,103 +1,103 @@ -#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 -#include -#include -#include "ringbuffer.h" -#include - -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 */ +#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 +#include +#include +#include "ringbuffer.h" +#include + +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 */