mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-15 13:58:32 +00:00
merge in newer portaudio
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8835 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
1 parent
50e9411c82
commit
625c524db7
62 files changed
+23721
-8516
No files matched your search
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: pa_unix_oss.c 1103 2006-08-29 20:56:04Z aknudsen $
|
||||
* $Id: pa_unix_oss.c 1296 2007-10-28 22:43:50Z aknudsen $
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Latest Version at: http://www.portaudio.com
|
||||
* OSS implementation by:
|
||||
@@ -32,19 +32,19 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* 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. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
/**
|
||||
@file
|
||||
@ingroup hostaip_src
|
||||
@ingroup hostapi_src
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -84,6 +84,7 @@
|
||||
#include "pa_cpuload.h"
|
||||
#include "pa_process.h"
|
||||
#include "pa_unix_util.h"
|
||||
#include "pa_debugprint.h"
|
||||
|
||||
static int sysErr_;
|
||||
static pthread_t mainThread_;
|
||||
@@ -113,7 +114,7 @@ static pthread_t mainThread_;
|
||||
*/
|
||||
static int Get_AFMT_S16_NE( void )
|
||||
{
|
||||
long testData = 1;
|
||||
long testData = 1;
|
||||
char *ptr = (char *) &testData;
|
||||
int isLittle = ( *ptr == 1 ); /* Does address point to least significant byte? */
|
||||
return isLittle ? AFMT_S16_LE : AFMT_S16_BE;
|
||||
@@ -278,7 +279,7 @@ error:
|
||||
PaUtil_FreeAllAllocations( ossHostApi->allocations );
|
||||
PaUtil_DestroyAllocationGroup( ossHostApi->allocations );
|
||||
}
|
||||
|
||||
|
||||
PaUtil_FreeMemory( ossHostApi );
|
||||
}
|
||||
return result;
|
||||
@@ -289,7 +290,7 @@ PaError PaUtil_InitializeDeviceInfo( PaDeviceInfo *deviceInfo, const char *name,
|
||||
PaTime defaultHighOutputLatency, double defaultSampleRate, PaUtilAllocationGroup *allocations )
|
||||
{
|
||||
PaError result = paNoError;
|
||||
|
||||
|
||||
deviceInfo->structVersion = 2;
|
||||
if( allocations )
|
||||
{
|
||||
@@ -384,7 +385,7 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
|
||||
{
|
||||
maxNumChannels = (stereo) ? 2 : 1;
|
||||
}
|
||||
PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels ))
|
||||
PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels ));
|
||||
}
|
||||
|
||||
/* During channel negotiation, the last ioctl() may have failed. This can
|
||||
@@ -440,7 +441,7 @@ static PaError QueryDevice( char *deviceName, PaOSSHostApiRepresentation *ossApi
|
||||
|
||||
/* douglas:
|
||||
we have to do this querying in a slightly different order. apparently
|
||||
some sound cards will give you different info based on their settins.
|
||||
some sound cards will give you different info based on their settins.
|
||||
e.g. a card might give you stereo at 22kHz but only mono at 44kHz.
|
||||
the correct order for OSS is: format, channels, sample rate
|
||||
*/
|
||||
@@ -507,9 +508,9 @@ static PaError BuildDeviceList( PaOSSHostApiRepresentation *ossApi )
|
||||
/* Find devices by calling QueryDevice on each
|
||||
* potential device names. When we find a valid one,
|
||||
* add it to a linked list.
|
||||
* A: Can there only be 10 devices? */
|
||||
* A: Set an arbitrary of 100 devices, should probably be a smarter way. */
|
||||
|
||||
for( i = 0; i < 10; i++ )
|
||||
for( i = 0; i < 100; i++ )
|
||||
{
|
||||
char deviceName[32];
|
||||
PaDeviceInfo *deviceInfo;
|
||||
@@ -596,7 +597,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||
int tempDevHandle = -1;
|
||||
int flags;
|
||||
PaSampleFormat inputSampleFormat, outputSampleFormat;
|
||||
|
||||
|
||||
if( inputParameters )
|
||||
{
|
||||
inputChannelCount = inputParameters->channelCount;
|
||||
@@ -625,7 +626,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||
{
|
||||
outputChannelCount = outputParameters->channelCount;
|
||||
outputSampleFormat = outputParameters->sampleFormat;
|
||||
|
||||
|
||||
/* unless alternate device specification is supported, reject the use of
|
||||
paUseHostApiSpecificDeviceSpecification */
|
||||
|
||||
@@ -661,7 +662,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||
return paInvalidChannelCount;
|
||||
|
||||
/* open the device so we can do more tests */
|
||||
|
||||
|
||||
if( inputChannelCount > 0 )
|
||||
{
|
||||
result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, inputParameters->device, hostApi);
|
||||
@@ -677,7 +678,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||
|
||||
deviceInfo = hostApi->deviceInfos[device];
|
||||
deviceName = (char *)deviceInfo->name;
|
||||
|
||||
|
||||
flags = O_NONBLOCK;
|
||||
if (inputChannelCount > 0 && outputChannelCount > 0)
|
||||
flags |= O_RDWR;
|
||||
@@ -695,7 +696,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||
|
||||
error:
|
||||
if( tempDevHandle >= 0 )
|
||||
close( tempDevHandle );
|
||||
close( tempDevHandle );
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -882,7 +883,7 @@ static PaError PaOssStream_Initialize( PaOssStream *stream, const PaStreamParame
|
||||
{
|
||||
PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
|
||||
&ossApi->blockingStreamInterface, callback, userData );
|
||||
}
|
||||
}
|
||||
|
||||
ENSURE_( sem_init( &stream->semaphore, 0, 0 ), paInternalError );
|
||||
|
||||
@@ -948,7 +949,7 @@ static PaError GetAvailableFormats( PaOssStreamComponent *component, PaSampleFor
|
||||
frmts |= paInt16;
|
||||
else
|
||||
result = paSampleFormatNotSupported;
|
||||
|
||||
|
||||
*availableFormats = frmts;
|
||||
|
||||
error:
|
||||
@@ -975,8 +976,8 @@ static int CalcHigherLogTwo( int n )
|
||||
return log2;
|
||||
}
|
||||
|
||||
static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long framesPerBuffer,
|
||||
StreamMode streamMode, PaOssStreamComponent *master )
|
||||
static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long
|
||||
framesPerBuffer, StreamMode streamMode, PaOssStreamComponent *master )
|
||||
{
|
||||
PaError result = paNoError;
|
||||
int temp, nativeFormat;
|
||||
@@ -986,7 +987,7 @@ static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component,
|
||||
int frgmt;
|
||||
int numBufs;
|
||||
int bytesPerBuf;
|
||||
double bufSz;
|
||||
unsigned long bufSz;
|
||||
unsigned long fragSz;
|
||||
audio_buf_info bufInfo;
|
||||
|
||||
@@ -998,21 +999,21 @@ static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component,
|
||||
* The hardware need not respect the requested fragment size, so we may have to adapt.
|
||||
*/
|
||||
if( framesPerBuffer == paFramesPerBufferUnspecified )
|
||||
{
|
||||
bufSz = component->latency * sampleRate;
|
||||
{
|
||||
bufSz = (unsigned long)(component->latency * sampleRate);
|
||||
fragSz = bufSz / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
fragSz = framesPerBuffer;
|
||||
bufSz = component->latency * sampleRate + fragSz; /* Latency + 1 buffer */
|
||||
bufSz = (unsigned long)(component->latency * sampleRate) + fragSz; /* Latency + 1 buffer */
|
||||
}
|
||||
|
||||
PA_ENSURE( GetAvailableFormats( component, &availableFormats ) );
|
||||
hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, component->userFormat );
|
||||
|
||||
/* OSS demands at least 2 buffers, and 16 bytes per buffer */
|
||||
numBufs = PA_MAX( bufSz / fragSz, 2 );
|
||||
numBufs = (int)PA_MAX( bufSz / fragSz, 2 );
|
||||
bytesPerBuf = PA_MAX( fragSz * Pa_GetSampleSize( hostFormat ) * chans, 16 );
|
||||
|
||||
/* The fragment parameters are encoded like this:
|
||||
@@ -1042,7 +1043,7 @@ static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component,
|
||||
/* reject if there's no sample rate within 1% of the one requested */
|
||||
if( (fabs( sampleRate - sr ) / sampleRate) > 0.01 )
|
||||
{
|
||||
PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));
|
||||
PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));
|
||||
PA_ENSURE( paInvalidSampleRate );
|
||||
}
|
||||
|
||||
@@ -1119,7 +1120,8 @@ static PaError PaOssStream_Configure( PaOssStream *stream, double sampleRate, un
|
||||
if( stream->capture )
|
||||
{
|
||||
PaOssStreamComponent *component = stream->capture;
|
||||
PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In, NULL );
|
||||
PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In,
|
||||
NULL ) );
|
||||
|
||||
assert( component->hostChannelCount > 0 );
|
||||
assert( component->hostFrames > 0 );
|
||||
@@ -1187,6 +1189,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||
const PaDeviceInfo *inputDeviceInfo = 0, *outputDeviceInfo = 0;
|
||||
int bpInitialized = 0;
|
||||
double inLatency = 0., outLatency = 0.;
|
||||
int i = 0;
|
||||
|
||||
/* validate platform specific flags */
|
||||
if( (streamFlags & paPlatformSpecificFlags) != 0 )
|
||||
@@ -1222,7 +1225,15 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||
return paInvalidChannelCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Round framesPerBuffer to the next power-of-two to make OSS happy. */
|
||||
if( framesPerBuffer != paFramesPerBufferUnspecified )
|
||||
{
|
||||
framesPerBuffer &= INT_MAX;
|
||||
for (i = 1; framesPerBuffer > i; i <<= 1) ;
|
||||
framesPerBuffer = i;
|
||||
}
|
||||
|
||||
/* allocate and do basic initialization of the stream structure */
|
||||
PA_UNLESS( stream = (PaOssStream*)PaUtil_AllocateMemory( sizeof(PaOssStream) ), paInsufficientMemory );
|
||||
PA_ENSURE( PaOssStream_Initialize( stream, inputParameters, outputParameters, streamCallback, userData, streamFlags, ossHostApi ) );
|
||||
@@ -1230,7 +1241,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||
PA_ENSURE( PaOssStream_Configure( stream, sampleRate, framesPerBuffer, &inLatency, &outLatency ) );
|
||||
|
||||
PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
|
||||
|
||||
|
||||
if( inputParameters )
|
||||
{
|
||||
inputHostFormat = stream->capture->hostFormat;
|
||||
@@ -1352,7 +1363,7 @@ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *fr
|
||||
pollCapture = 0;
|
||||
}
|
||||
*/
|
||||
else if( stream->playback ) /* Timed out, go on with playback? */
|
||||
else if( stream->playback ) /* Timed out, go on with playback? */
|
||||
{
|
||||
/*PA_DEBUG(( "%s: Trying to poll again for capture frames, pollTimeout: %d\n",
|
||||
__FUNCTION__, stream->pollTimeout ));*/
|
||||
@@ -1463,7 +1474,7 @@ static PaError PaOssStream_Prepare( PaOssStream *stream )
|
||||
|
||||
/* Ok, we have triggered the stream */
|
||||
stream->triggered = 1;
|
||||
|
||||
|
||||
error:
|
||||
return result;
|
||||
}
|
||||
@@ -1502,7 +1513,7 @@ static void OnExit( void *data )
|
||||
PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
|
||||
|
||||
PaOssStream_Stop( stream, stream->callbackAbort );
|
||||
|
||||
|
||||
PA_DEBUG(( "OnExit: Stoppage\n" ));
|
||||
|
||||
/* Eventually notify user all buffers have played */
|
||||
@@ -1550,13 +1561,13 @@ static void *PaOSS_AudioThreadProc( void *userData )
|
||||
int initiateProcessing = triggered; /* Already triggered? */
|
||||
PaStreamCallbackFlags cbFlags = 0; /* We might want to keep state across iterations */
|
||||
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* TODO: IMPLEMENT ME */
|
||||
|
||||
|
||||
/*
|
||||
#if ( SOUND_VERSION > 0x030904 )
|
||||
audio_errinfo errinfo;
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
assert( stream );
|
||||
|
||||
pthread_cleanup_push( &OnExit, stream ); /* Execute OnExit when exiting */
|
||||
@@ -1594,7 +1605,8 @@ static void *PaOSS_AudioThreadProc( void *userData )
|
||||
*/
|
||||
if( !initiateProcessing )
|
||||
{
|
||||
PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) ); /* Wait on available frames */
|
||||
/* Wait on available frames */
|
||||
PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) );
|
||||
assert( framesAvail % stream->framesPerHostBuffer == 0 );
|
||||
}
|
||||
else
|
||||
@@ -1937,8 +1949,7 @@ static signed long GetStreamWriteAvailable( PaStream* s )
|
||||
|
||||
if( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ) < 0 )
|
||||
return paUnanticipatedHostError;
|
||||
|
||||
|
||||
return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback );
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user