mod_portaudio: update to support multiple io buffers

This commit is contained in:
Moises Silva 2011-03-19 13:24:02 -04:00
parent df43e51ca5
commit b05965c88d
3 changed files with 37 additions and 42 deletions

View File

@ -98,41 +98,36 @@ struct private_object {
typedef struct private_object private_t; typedef struct private_object private_t;
struct audio_stream { struct audio_stream {
/*! Sampling rate */
int sample_rate;
/*! Buffer packetization (and therefore timing) */
int codec_ms;
/*! The PA input device */
int indev; int indev;
/*! The PA output device */
int outdev; int outdev;
/*! The io stream helper to buffer audio */
PABLIO_Stream *stream; PABLIO_Stream *stream;
/*! How often to write */
switch_timer_t write_timer; switch_timer_t write_timer;
/*! Next stream */
struct audio_stream *next; struct audio_stream *next;
}; };
typedef struct audio_stream audio_stream_t; typedef struct audio_stream audio_stream_t;
typedef struct _pa_shared_device { typedef struct audio_endpoint {
/*! Sampling rate */ /*! Input stream for this endpoint */
int sample_rate; audio_stream_t *in_stream;
/*! */
int codec_ms;
/*! Device number */
int devno;
/*! Running stream (if a stream is already running for devno) */
audio_stream_t *stream;
/*! The actual portaudio device number */
/*! It's a shared device after all */
switch_mutex_t *mutex;
} pa_shared_device_t;
typedef struct _pa_endpoint { /*! Output stream for this endpoint */
/*! Input device for this endpoint */ audio_stream_t *out_stream;
pa_shared_device_t *indev;
/*! Output device for this endpoint */ /*! Channel index within the input stream where we get the audio for this endpoint */
pa_shared_device_t *outdev;
/*! Channel index within the input device stream */
int inchan; int inchan;
/*! Channel index within the input device stream */ /*! Channel index within the output stream where we get the audio for this endpoint */
int outchan; int outchan;
} pa_endpoint_t; } audio_endpoint_t;
static struct { static struct {
int debug; int debug;

View File

@ -83,9 +83,9 @@ static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer,
/* This may get called with NULL inputBuffer during initial setup. */ /* This may get called with NULL inputBuffer during initial setup. */
if (inputBuffer != NULL) { if (inputBuffer != NULL) {
if (PaUtil_WriteRingBuffer(&data->inFIFO, inputBuffer, numBytes) != numBytes) { if (PaUtil_WriteRingBuffer(&data->inFIFOs[0], inputBuffer, numBytes) != numBytes) {
PaUtil_FlushRingBuffer(&data->inFIFO); PaUtil_FlushRingBuffer(&data->inFIFOs[0]);
PaUtil_WriteRingBuffer(&data->inFIFO, inputBuffer, numBytes); PaUtil_WriteRingBuffer(&data->inFIFOs[0], inputBuffer, numBytes);
} }
} }
@ -100,7 +100,7 @@ static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer,
if (outputBuffer != NULL) { if (outputBuffer != NULL) {
int i; int i;
int numRead = PaUtil_ReadRingBuffer(&data->outFIFO, outputBuffer, numBytes); int numRead = PaUtil_ReadRingBuffer(&data->outFIFOs[0], outputBuffer, numBytes);
/* Zero out remainder of buffer if we run out of data. */ /* Zero out remainder of buffer if we run out of data. */
for (i = numRead; i < numBytes; i++) { for (i = numRead; i < numBytes; i++) {
((char *) outputBuffer)[i] = 0; ((char *) outputBuffer)[i] = 0;
@ -151,12 +151,12 @@ long WriteAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switc
switch_core_timer_next(timer); switch_core_timer_next(timer);
bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFO, p, numBytes); bytesWritten = PaUtil_WriteRingBuffer(&aStream->outFIFOs[0], p, numBytes);
numBytes -= bytesWritten; numBytes -= bytesWritten;
p += bytesWritten; p += bytesWritten;
if (numBytes > 0) { if (numBytes > 0) {
PaUtil_FlushRingBuffer(&aStream->outFIFO); PaUtil_FlushRingBuffer(&aStream->outFIFOs[0]);
return 0; return 0;
} }
return numFrames; return numFrames;
@ -177,17 +177,17 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch
while (totalBytes < neededBytes && --max > 0) { while (totalBytes < neededBytes && --max > 0) {
avail = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFO); avail = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[0]);
//printf("AVAILABLE BYTES %ld pass %d\n", avail, 5000 - max); //printf("AVAILABLE BYTES %ld pass %d\n", avail, 5000 - max);
if (avail >= neededBytes * 6) { if (avail >= neededBytes * 6) {
PaUtil_FlushRingBuffer(&aStream->inFIFO); PaUtil_FlushRingBuffer(&aStream->inFIFOs[0]);
avail = 0; avail = 0;
} else { } else {
bytesRead = 0; bytesRead = 0;
if (totalBytes < neededBytes && avail >= neededBytes) { if (totalBytes < neededBytes && avail >= neededBytes) {
bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFO, p, neededBytes); bytesRead = PaUtil_ReadRingBuffer(&aStream->inFIFOs[0], p, neededBytes);
totalBytes += bytesRead; totalBytes += bytesRead;
} }
@ -208,7 +208,7 @@ long ReadAudioStream(PABLIO_Stream * aStream, void *data, long numFrames, switch
*/ */
long GetAudioStreamWriteable(PABLIO_Stream * aStream) long GetAudioStreamWriteable(PABLIO_Stream * aStream)
{ {
int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO); int bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[0]);
return bytesEmpty / aStream->bytesPerFrame; return bytesEmpty / aStream->bytesPerFrame;
} }
@ -218,7 +218,7 @@ long GetAudioStreamWriteable(PABLIO_Stream * aStream)
*/ */
long GetAudioStreamReadable(PABLIO_Stream * aStream) long GetAudioStreamReadable(PABLIO_Stream * aStream)
{ {
int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFO); int bytesFull = PaUtil_GetRingBufferReadAvailable(&aStream->inFIFOs[0]);
return bytesFull / aStream->bytesPerFrame; return bytesFull / aStream->bytesPerFrame;
} }
@ -274,7 +274,7 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
/* Initialize Ring Buffers */ /* Initialize Ring Buffers */
if (inputParameters) { if (inputParameters) {
err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame); err = PABLIO_InitFIFO(&aStream->inFIFOs[0], numFrames, aStream->bytesPerFrame);
if (err != paNoError) { if (err != paNoError) {
goto error; goto error;
} }
@ -282,7 +282,7 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
} }
if (outputParameters) { if (outputParameters) {
err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame); err = PABLIO_InitFIFO(&aStream->outFIFOs[0], numFrames, aStream->bytesPerFrame);
if (err != paNoError) { if (err != paNoError) {
goto error; goto error;
} }
@ -355,15 +355,15 @@ PaError CloseAudioStream(PABLIO_Stream * aStream)
int byteSize; int byteSize;
byteSize = aStream->outFIFO.bufferSize; byteSize = aStream->outFIFOs[0].bufferSize;
if (aStream->has_out) { if (aStream->has_out) {
/* If we are writing data, make sure we play everything written. */ /* If we are writing data, make sure we play everything written. */
if (byteSize > 0) { if (byteSize > 0) {
bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO); bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[0]);
while (bytesEmpty < byteSize) { while (bytesEmpty < byteSize) {
Pa_Sleep(10); Pa_Sleep(10);
bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFO); bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[0]);
} }
} }
} }
@ -399,11 +399,11 @@ PaError CloseAudioStream(PABLIO_Stream * aStream)
} }
if (aStream->has_in) { if (aStream->has_in) {
PABLIO_TermFIFO(&aStream->inFIFO); PABLIO_TermFIFO(&aStream->inFIFOs[0]);
} }
if (aStream->has_out) { if (aStream->has_out) {
PABLIO_TermFIFO(&aStream->outFIFO); PABLIO_TermFIFO(&aStream->outFIFOs[0]);
} }
free(aStream); free(aStream);

View File

@ -65,8 +65,8 @@ typedef struct {
int do_dual; int do_dual;
int has_in; int has_in;
int has_out; int has_out;
PaUtilRingBuffer inFIFOs[2] PaUtilRingBuffer inFIFOs[2];
PaUtilRingBuffer outFIFOs[2] PaUtilRingBuffer outFIFOs[2];
int channelCount; int channelCount;
} PABLIO_Stream; } PABLIO_Stream;