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:
parent
b60e399b63
commit
22bc31e19e
|
@ -124,6 +124,7 @@ static struct {
|
||||||
GFLAGS flags;
|
GFLAGS flags;
|
||||||
switch_timer_t timer;
|
switch_timer_t timer;
|
||||||
switch_timer_t hold_timer;
|
switch_timer_t hold_timer;
|
||||||
|
int dual_streams;
|
||||||
} globals;
|
} globals;
|
||||||
|
|
||||||
|
|
||||||
|
@ -738,6 +739,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_portaudio_load)
|
||||||
|
|
||||||
memset(&globals, 0, sizeof(globals));
|
memset(&globals, 0, sizeof(globals));
|
||||||
|
|
||||||
|
globals.dual_streams = 1;
|
||||||
|
|
||||||
if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
|
if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
|
||||||
return status;
|
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);
|
//globals.read_codec.implementation->samples_per_packet);
|
||||||
|
|
||||||
err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
|
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 ************************************************************************************************* */
|
/* UNLOCKED ************************************************************************************************* */
|
||||||
switch_mutex_unlock(globals.device_lock);
|
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.sampleFormat = SAMPLE_TYPE;
|
||||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
|
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
|
||||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
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 ************************************************************************************************* */
|
/* UNLOCKED ************************************************************************************************* */
|
||||||
switch_mutex_unlock(globals.device_lock);
|
switch_mutex_unlock(globals.device_lock);
|
||||||
|
|
|
@ -59,6 +59,10 @@ static int iblockingIOCallback(const void *inputBuffer, void *outputBuffer,
|
||||||
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
|
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
|
||||||
static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer,
|
static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer,
|
||||||
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
|
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_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame);
|
||||||
static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf);
|
static PaError PABLIO_TermFIFO(PaUtilRingBuffer * rbuf);
|
||||||
|
|
||||||
|
@ -104,6 +108,14 @@ static int oblockingIOCallback(const void *inputBuffer, void *outputBuffer,
|
||||||
return 0;
|
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. */
|
/* Allocate buffer. */
|
||||||
static PaError PABLIO_InitFIFO(PaUtilRingBuffer * rbuf, long numFrames, long bytesPerFrame)
|
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,
|
PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
|
||||||
const PaStreamParameters * inputParameters,
|
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;
|
long bytesPerSample = 2;
|
||||||
PaError err;
|
PaError err;
|
||||||
|
@ -239,12 +254,16 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
|
||||||
//long numBytes;
|
//long numBytes;
|
||||||
int channels = 1;
|
int channels = 1;
|
||||||
|
|
||||||
|
if (!(inputParameters || outputParameters)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate PABLIO_Stream structure for caller. */
|
/* Allocate PABLIO_Stream structure for caller. */
|
||||||
aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream));
|
aStream = (PABLIO_Stream *) malloc(sizeof(PABLIO_Stream));
|
||||||
if (aStream == NULL)
|
if (aStream == NULL)
|
||||||
return paInsufficientMemory;
|
return paInsufficientMemory;
|
||||||
memset(aStream, 0, sizeof(PABLIO_Stream));
|
memset(aStream, 0, sizeof(PABLIO_Stream));
|
||||||
|
|
||||||
/* Initialize PortAudio */
|
/* Initialize PortAudio */
|
||||||
err = Pa_Initialize();
|
err = Pa_Initialize();
|
||||||
if (err != paNoError)
|
if (err != paNoError)
|
||||||
|
@ -265,12 +284,17 @@ PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
|
||||||
err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
|
err = PABLIO_InitFIFO(&aStream->inFIFO, numFrames, aStream->bytesPerFrame);
|
||||||
if (err != paNoError)
|
if (err != paNoError)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
aStream-> has_in = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outputParameters) {
|
if (outputParameters) {
|
||||||
err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
|
err = PABLIO_InitFIFO(&aStream->outFIFO, numFrames, aStream->bytesPerFrame);
|
||||||
if (err != paNoError)
|
if (err != paNoError)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
aStream-> has_out = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make Write FIFO appear full initially. */
|
/* 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
|
/* Open a PortAudio stream that we will use to communicate with the underlying
|
||||||
* audio drivers. */
|
* 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)
|
if (err != paNoError)
|
||||||
goto error;
|
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;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
*rwblPtr = aStream;
|
*rwblPtr = aStream;
|
||||||
|
|
||||||
return paNoError;
|
return paNoError;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -315,14 +372,34 @@ PaError CloseAudioStream(PABLIO_Stream * aStream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Pa_IsStreamActive(aStream->istream)) {
|
if (aStream->do_dual) {
|
||||||
Pa_StopStream(aStream->istream);
|
if (aStream->has_in && aStream->istream) {
|
||||||
Pa_CloseStream(aStream->istream);
|
if (Pa_IsStreamActive(aStream->istream)) {
|
||||||
}
|
Pa_StopStream(aStream->istream);
|
||||||
|
}
|
||||||
|
|
||||||
if (Pa_IsStreamActive(aStream->ostream)) {
|
Pa_CloseStream(aStream->istream);
|
||||||
Pa_StopStream(aStream->ostream);
|
aStream->istream = NULL;
|
||||||
Pa_CloseStream(aStream->ostream);
|
}
|
||||||
|
|
||||||
|
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);
|
PABLIO_TermFIFO(&aStream->inFIFO);
|
||||||
|
|
|
@ -61,7 +61,11 @@ extern "C" {
|
||||||
PaUtilRingBuffer outFIFO;
|
PaUtilRingBuffer outFIFO;
|
||||||
PaStream *istream;
|
PaStream *istream;
|
||||||
PaStream *ostream;
|
PaStream *ostream;
|
||||||
|
PaStream *iostream;
|
||||||
int bytesPerFrame;
|
int bytesPerFrame;
|
||||||
|
int do_dual;
|
||||||
|
int has_in;
|
||||||
|
int has_out;
|
||||||
} PABLIO_Stream;
|
} PABLIO_Stream;
|
||||||
|
|
||||||
/* Values for flags for OpenAudioStream(). */
|
/* Values for flags for OpenAudioStream(). */
|
||||||
|
@ -105,7 +109,8 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
|
PaError OpenAudioStream(PABLIO_Stream ** rwblPtr,
|
||||||
const PaStreamParameters * inputParameters,
|
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);
|
PaError CloseAudioStream(PABLIO_Stream * aStream);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue