From 22bc31e19e4c0c3e1dbc7ffa0332e2a3600b23b2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Jan 2009 19:32:47 +0000 Subject: [PATCH] make dual streams configurable git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11259 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../endpoints/mod_portaudio/mod_portaudio.c | 8 +- src/mod/endpoints/mod_portaudio/pablio.c | 105 +++++++++++++++--- src/mod/endpoints/mod_portaudio/pablio.h | 7 +- 3 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index 56d5ba2fa9..9d301a5f53 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -124,6 +124,7 @@ static struct { GFLAGS flags; switch_timer_t timer; switch_timer_t hold_timer; + int dual_streams; } globals; @@ -738,6 +739,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load) memset(&globals, 0, sizeof(globals)); + globals.dual_streams = 1; + if ((status = load_config()) != SWITCH_STATUS_SUCCESS) { return status; } @@ -1287,7 +1290,7 @@ static switch_status_t engage_device(int sample_rate, int codec_ms) //globals.read_codec.implementation->samples_per_packet); err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff, - globals.read_codec.implementation->samples_per_packet); + globals.read_codec.implementation->samples_per_packet, globals.dual_streams); /* UNLOCKED ************************************************************************************************* */ switch_mutex_unlock(globals.device_lock); @@ -1324,7 +1327,8 @@ static switch_status_t engage_ring_device(int sample_rate, int channels) outputParameters.sampleFormat = SAMPLE_TYPE; outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; - err = OpenAudioStream(&globals.ring_stream, NULL, &outputParameters, sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet); + err = OpenAudioStream(&globals.ring_stream, NULL, + &outputParameters, sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams); /* UNLOCKED ************************************************************************************************* */ switch_mutex_unlock(globals.device_lock); diff --git a/src/mod/endpoints/mod_portaudio/pablio.c b/src/mod/endpoints/mod_portaudio/pablio.c index 586ebdd387..bab44c63a1 100644 --- a/src/mod/endpoints/mod_portaudio/pablio.c +++ b/src/mod/endpoints/mod_portaudio/pablio.c @@ -59,6 +59,10 @@ static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData); static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData); + +static int ioblockingIOCallback(const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData); + static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame); static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf); @@ -104,6 +108,14 @@ static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer, return 0; } +static int ioblockingIOCallback(const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData) +{ + iblockingIOCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData); + oblockingIOCallback(inputBuffer, outputBuffer, framesPerBuffer, timeInfo, statusFlags, userData); + return 0; +} + /* Allocate buffer. */ static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame) { @@ -230,7 +242,10 @@ static unsigned long RoundUpToNextPowerOf2(unsigned long n) */ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, const PaStreamParameters * inputParameters, - const PaStreamParameters * outputParameters, double sampleRate, PaStreamFlags streamFlags, long samples_per_packet) + const PaStreamParameters * outputParameters, + double sampleRate, PaStreamFlags streamFlags, + long samples_per_packet, + int do_dual) { long bytesPerSample = 2; PaError err; @@ -239,12 +254,16 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, //long numBytes; int channels = 1; + if (!(inputParameters || outputParameters)) { + return -1; + } + /* Allocate PABLIO_Stream structure for caller. */ aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream)); if (aStream == NULL) return paInsufficientMemory; memset(aStream, 0, sizeof(PABLIO_Stream)); - + /* Initialize PortAudio */ err = Pa_Initialize(); if (err != paNoError) @@ -265,12 +284,17 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame); if (err != paNoError) goto error; + + aStream-> has_in = 1; + } if (outputParameters) { err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame); if (err != paNoError) goto error; + + aStream-> has_out = 1; } /* Make Write FIFO appear full initially. */ @@ -280,18 +304,51 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, /* Open a PortAudio stream that we will use to communicate with the underlying * audio drivers. */ - err = Pa_OpenStream(&aStream->istream, inputParameters, NULL, sampleRate, samples_per_packet, streamFlags, iblockingIOCallback, aStream); - err = Pa_OpenStream(&aStream->ostream, NULL, outputParameters, sampleRate, samples_per_packet, streamFlags, oblockingIOCallback, aStream); + + aStream->do_dual = do_dual; + + + + if (aStream->do_dual) { + err = Pa_OpenStream(&aStream->istream, inputParameters, NULL, sampleRate, samples_per_packet, streamFlags, iblockingIOCallback, aStream); + if (err != paNoError) { + goto error; + } + err = Pa_OpenStream(&aStream->ostream, NULL, outputParameters, sampleRate, samples_per_packet, streamFlags, oblockingIOCallback, aStream); + if (err != paNoError) { + goto error; + } + } else { + err = Pa_OpenStream(&aStream->iostream, inputParameters, outputParameters, sampleRate, samples_per_packet, streamFlags, ioblockingIOCallback, aStream); + } if (err != paNoError) goto error; + + if (aStream->do_dual) { + err = Pa_StartStream(aStream->istream); + + if (err != paNoError) { + goto error; + } - err = Pa_StartStream(aStream->istream); - err = Pa_StartStream(aStream->ostream); + err = Pa_StartStream(aStream->ostream); - if (err != paNoError) + if (err != paNoError) { + goto error; + } + + + } else { + err = Pa_StartStream(aStream->iostream); + } + + if (err != paNoError) { goto error; + } + *rwblPtr = aStream; + return paNoError; error: @@ -315,14 +372,34 @@ PaError CloseAudioStream(PABLIO_Stream * aStream) } } - if (Pa_IsStreamActive(aStream->istream)) { - Pa_StopStream(aStream->istream); - Pa_CloseStream(aStream->istream); - } + if (aStream->do_dual) { + if (aStream->has_in && aStream->istream) { + if (Pa_IsStreamActive(aStream->istream)) { + Pa_StopStream(aStream->istream); + } - if (Pa_IsStreamActive(aStream->ostream)) { - Pa_StopStream(aStream->ostream); - Pa_CloseStream(aStream->ostream); + Pa_CloseStream(aStream->istream); + aStream->istream = NULL; + } + + if (aStream->has_out && aStream->ostream) { + if (Pa_IsStreamActive(aStream->ostream)) { + Pa_StopStream(aStream->ostream); + } + + Pa_CloseStream(aStream->ostream); + aStream->ostream = NULL; + } + + } else { + if (aStream->iostream) { + if (Pa_IsStreamActive(aStream->iostream)) { + Pa_StopStream(aStream->iostream); + } + + Pa_CloseStream(aStream->iostream); + aStream->iostream = NULL; + } } PABLIO_TermFIFO(&aStream->inFIFO); diff --git a/src/mod/endpoints/mod_portaudio/pablio.h b/src/mod/endpoints/mod_portaudio/pablio.h index 1949ff8b0c..c933a11426 100644 --- a/src/mod/endpoints/mod_portaudio/pablio.h +++ b/src/mod/endpoints/mod_portaudio/pablio.h @@ -61,7 +61,11 @@ extern "C" { PaUtilRingBuffer outFIFO; PaStream *istream; PaStream *ostream; + PaStream *iostream; int bytesPerFrame; + int do_dual; + int has_in; + int has_out; } PABLIO_Stream; /* Values for flags for OpenAudioStream(). */ @@ -105,7 +109,8 @@ extern "C" { */ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr, const PaStreamParameters * inputParameters, - const PaStreamParameters * outputParameters, double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_packet); + const PaStreamParameters * outputParameters, + double sampleRate, PaStreamCallbackFlags statusFlags, long samples_per_packet, int do_dual); PaError CloseAudioStream(PABLIO_Stream * aStream);