make dual streams configurable

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11259 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-01-16 19:32:47 +00:00
parent b60e399b63
commit 22bc31e19e
3 changed files with 103 additions and 17 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);